Base URL
Two authentication models
Public endpoints
No key required. Used directly by browsers — a
<form>, submit.js, or the SDK’s client-side adapters. Protected by CAPTCHA, honeypot, rate limiting, and origin allowlisting instead of a credential, since a browser can’t keep a secret.Server Data API
Requires a secret API key (
Authorization: Bearer rk_live_...). Server-side only — never ship a key to a browser. Used by your backend to submit on someone’s behalf, or to read submissions/analytics/files.Public endpoints
Notice
submit lives at its own top-level path, not nested under /forms/p/... — it’s the one endpoint that writes; everything else is a read or a side-effect-free helper around a form you’ve already fetched.
Rate limits
Every public endpoint is rate-limited per identity (IP, or workspace for the Server Data API), backed by a shared store — not an in-memory counter that resets per server replica.
A
429 includes a human-readable message; there’s currently no Retry-After header, so back off with a fixed or exponential delay rather than parsing one.
Errors
Every error is a JSON body with anerror message and, where relevant, a machine-readable code:
Response headers
Every response echoesX-Request-Id — include it when reporting an issue; it’s the fastest way to find the exact server-side log line for your request.