Skip to main content

Schema validation

Every submission is validated server-side against the form’s schema — this is the source of truth; any client-side validation (the SDK does a local pre-check before it even calls the network) is a UX nicety, never the actual gate. A validation failure returns 422 with a per-field breakdown:
type is one of a fixed, stable vocabulary you can key UI logic off of without parsing message text: An unrecognized field in your submission isn’t rejected — it’s tracked and surfaced in the dashboard as “unknown field detected,” which is how you notice your markup and your schema have drifted apart.

Idempotency

Every submission gets a dedup key whether you ask for one or not — the SDK auto-generates a fresh UUID per attempt if you don’t supply one via Idempotency-Key. If the same key arrives twice with the same payload, the second request returns the original result without creating a duplicate submission or consuming a second quota unit. If the same key arrives with a different payload, that’s rejected outright — a reused key is never silently treated as “close enough”:
This matters most for anything that might retry on its own — a flaky network, a backend job queue, a user double-clicking submit.

Success response

Quotas

Workspaces on a plan with a submission limit get a 429 once it’s reached:
Quota is checked atomically at insert time — a burst of concurrent submissions right at the limit can’t overshoot it via a race condition.

A closed form

A form with submissions turned off in its settings returns 423, not 404 — the form exists, it’s just not currently accepting data: