API
Authentication
Private API routes require either a Supabase session cookie or an Ingress forms API key. Public form, approval, upload, address, SSO-start, and provider webhook routes are explicitly allowlisted.
API keys
Create one from Settings → Security → API keys. Keys use the ak_live_ prefix and are shown once; store them in your secret manager.
curl https://forms.example.com/api/forms \
-H "Authorization: Bearer $INGRESS_FORMS_API_KEY"The server stores only a SHA-256 hash of each key. When a request is authenticated with a bearer key, Ingress forms mints a short-lived RLS-scoped Supabase client for the key owner instead of using the service-role client.
Sessions
In-app admin requests use Supabase session cookies. Mutating cookie-authenticated API requests are checked against the request origin, so same-origin admin calls work normally while cross-origin browser posts are blocked unless they are public endpoints.
Access model
API keys currently inherit the owning user's database access through Supabase RLS. Resource-level API-key scopes are not implemented yet, so treat each key like a server-side credential for that user.
Rate limits
Middleware applies IP-based sliding-window rate limits before the route handler runs. When Upstash Redis is not configured or is unavailable, rate limiting fails open so the app does not lock out legitimate users.
public submission: 5 requests / minute / IP
AI form generation: 3 requests / minute / IP
AI writing assist: 10 requests / minute / IP
SSO start: 10 requests / minute / IP
address lookup: 30 requests / minute / IP
general API: 60 requests / minute / IPA throttled request returns 429 with Retry-After and X-RateLimit-Reset headers. Successful responses do not currently include remaining-limit headers.