Sawala CloudSawala Cloud — Docs
FormulirReference

Formulir API Reference

Formulir's public REST API — fetch a form definition and submit a response. Project-scoped publishable key required.

TODO: translate to Indonesian. English source is authoritative; render it into Indonesian below.

The Formulir public API has exactly two endpoints: fetch a form definition, and submit a response. Reading submissions is a dashboard feature and is not part of the public API.

For day-to-day embedding you usually do not call this API directly — use the iframe, React component, or script tag. This reference is for posting submissions yourself.

Base URL

https://api.sawala.cloud/public/formulir

The embed delivery host (iframe, formulir.js, formulir.css) is https://formulir.id — see how to embed a form.

Authentication

Send a project-scoped publishable key (pk_live_…) in the X-API-Key header. The key must be scoped to a single organization and project; an org-only key is rejected.

X-API-Key: pk_live_…

A request whose key carries no project scope returns 400 with { "error": "API_KEY_REQUIRES_PROJECT_SCOPE" }. A bad or revoked key returns 401. See API keys and access and CLI and SDK.

Endpoints

Get a form definition

GET /forms/{slug}

Returns the form's fields and settings. Use this to render the form yourself.

Submit a response

POST /forms/{slug}/submit

On success returns 201 with:

{ "id": "…", "status": "received" }

id is a UUID identifying the stored submission.

Submit body

Send the field values as JSON. The canonical form wraps them in a data object:

{
  "data": {
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "message": "Hello!"
  }
}

A flat { "field": value } object (no data wrapper) is also accepted. Keys match each field's name.

curl -X POST https://api.sawala.cloud/public/formulir/forms/contact/submit \
  -H "X-API-Key: pk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "name": "Ada", "email": "ada@example.com", "message": "Hello!" } }'

File upload fields

For media fields, submit the request as multipart/form-data in a single request — include the file alongside the other fields. Formulir stores the file for you; there is no separate upload step or assetId to manage.

curl -X POST https://api.sawala.cloud/public/formulir/forms/contact/submit \
  -H "X-API-Key: pk_live_…" \
  -F "name=Ada" \
  -F "resume=@./resume.pdf"

Spam protection

If a form has Cloudflare Turnstile enabled, include the challenge token in the submission under the key cf-turnstile-response. See spam protection for setup.

Error codes

Errors are returned as a flat { "error": "CODE" } body.

HTTPerrorCause
400API_KEY_REQUIRES_PROJECT_SCOPEKey is not scoped to a project
400INVALID_JSONRequest body is not valid JSON
400CAPTCHA_REQUIREDForm requires Turnstile but no token was sent
401Missing, invalid, or revoked API key
403FORM_PRIVATEForm visibility is set to private
403CAPTCHA_FAILEDTurnstile token was rejected
404FORM_NOT_FOUNDNo published form matches the slug
413Payload too large
429RATE_LIMITEDSubmission rate limit exceeded
503CAPTCHA_NOT_CONFIGUREDForm has Turnstile enabled but the project has no Turnstile keys saved

Rate limit

Submissions are limited to 60 per minute, per API key, per form. Over the limit, the gateway returns 429 with { "error": "RATE_LIMITED" }.

Stored metadata

Each submission is stored with its timestamp, the submitter's IP address, and user agent. Submissions and any uploaded files are viewable in the dashboard inbox.

Daftar Isi