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 returns422 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 viaIdempotency-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”:
Success response
Quotas
Workspaces on a plan with a submission limit get a429 once it’s reached:
A closed form
A form with submissions turned off in its settings returns423, not 404 — the form exists, it’s just not currently accepting data: