The request
There is no API key and no authorization header here. The form id is a public identifier; the origin allowlist is the control.
The body
Send whatever your form collects. There’s no fixed schema at the endpoint — a field the form definition doesn’t know about is still stored rather than rejected. Three keys have special meaning:
And one is ignored if you send it:
consentTextId. allGood deletes it and substitutes the form’s own bound value from its own records, so the consent evidence can’t be forged from the page.
Everything else is stored as sent.
Tracking fields
None of these are required or specially handled at the endpoint — they’re just the names the install script’s own hidden fields use when it reads them off the page’s URL. Send whatever subset your own tracking actually has:utmCampaign · utmContent · utmMedium · utmOffer · utmSource · utmTerm · utmPosition · utmDevice · utmType · utmGeo · gclid · adGroupId
A server-side caller that wants parity with what the script would have sent from a real page should use these exact names rather than its own convention (utm_source, say) — otherwise the two paths report inconsistently in anything downstream that groups by UTM field.
Size limit
Your account setting, 8 KB by default, and never more than 16 KB whatever the setting says. Measured in bytes, not characters. Both the declared length and the real length are checked.The order of checks
Checks stop at the first failure, so exactly one outcome describes a submission and it names the first thing that was wrong.
Check 1 is the one to watch. A refused origin gets a bare
403 with no CORS headers, so a browser sees an opaque network error rather than a readable body. It cannot tell “not allowlisted” apart from “network down”. Use the runtime config endpoint to find out, or read the console warning the script writes.
A form’s own Test section shows this same order resolved against its real configuration — which origins are actually allowlisted, whether a bot check is actually required, what its honeypot field is really named — rather than the generic version above.

The same checks, resolved to one tenant's and one form's actual configuration.
Preflight
A cross-origin JSON POST is never a simple request, so the browser always sendsOPTIONS first.
The origin is echoed exactly, never
* — the path is credentialed, and * is invalid with credentials.
Responses
redirectUrl is present only when the form configures one and it passed the safety check.
This endpoint never returns
consent_missing. See Reason codes.
Retries
Accepted responses carry asubmissionId, and everything downstream deduplicates on it. Retrying the same HTTP request mints a new one, so a retry does create a second record. Guard against double submission on your side, as the script does.
Rate limits
Event capture has separate budgets. A caller with no
Origin header — a server — is covered by the per-IP budget only.