API

API reference

Ingress forms exposes JSON route handlers under /api. The same surface is used by the admin app, public forms, webhooks, and server-to-server clients.

Base URL

Use the origin where your Ingress forms app is deployed. In development this is usually http://localhost:3000/api; in production it is your primary app host plus /api.

text
http://localhost:3000/api
https://forms.example.com/api

Authentication

Admin and workspace routes require authentication. Browser requests use Supabase session cookies. Programmatic requests can use an API key in the Authorization header.

bash
curl https://forms.example.com/api/forms \
  -H "Authorization: Bearer $INGRESS_FORMS_API_KEY"

API keys use the ak_live_ prefix. The raw key is shown once when created, then only a SHA-256 hash is stored. API-key requests are converted into an RLS-scoped Supabase client for the key owner.

Public endpoints

All /api/* routes are private by default. These endpoints are intentionally public because they are called before a user has an admin session, by respondents, or by provider webhooks.

http
POST        /api/submissions
GET PATCH   /api/approvals/:id
POST        /api/quiz/tab-switch
POST        /api/uploads
GET PUT DELETE /api/forms/:id/draft
POST        /api/address/autocomplete
POST        /api/address/validate
POST        /api/stripe/webhook
POST        /api/auth/sso/start

Response format

Responses are JSON unless the route returns an empty 204. Successful responses are resource-specific, for example { forms: [...] }, { form }, { submission }, or { ok: true }. Errors use a simple shape:

json
{
  "error": "Unauthorized"
}

Common status codes are 400 for validation errors, 401 for missing or invalid auth, 403 for forbidden actions, 404 for missing resources, 409 for conflicts, 429 for rate limits, and 5xx for provider or server failures.

Forms

Forms contain title, slug, visibility, status, draft schema, and live published schema. Schema writes go through the branching model and do not affect the public form until the form is published.

Core form lifecycle

Create, read, update, delete, publish, and restore forms.

http
GET          /api/forms
POST         /api/forms
GET          /api/forms/:id
PATCH        /api/forms/:id
DELETE       /api/forms/:id
POST         /api/forms/:id/publish
GET          /api/forms/:id/versions
POST         /api/forms/:id/versions/:vid/restore
GET          /api/forms/:id/analytics/funnel
GET          /api/forms/:id/my-role
json
{
  "title": "Customer intake",
  "description": "Collect customer onboarding details",
  "schema": {
    "version": 1,
    "title": "Customer intake",
    "steps": [],
    "settings": {
      "submitLabel": "Submit",
      "showProgressBar": true,
      "allowBack": true,
      "successMessage": "Thanks."
    }
  }
}

Respondent drafts

Autosave endpoints for public form respondents. The form must be published and accepting responses.

http
GET          /api/forms/:id/draft
PUT          /api/forms/:id/draft
DELETE       /api/forms/:id/draft

Collaboration and branching

Branch, working-copy, commit, merge-request, collaborator, role, capability, and protection-rule endpoints for team editing.

http
GET POST     /api/forms/:id/branches
GET PATCH DELETE /api/forms/:id/branches/:bid
POST         /api/forms/:id/branches/:bid/commits
POST         /api/forms/:id/branches/:bid/merge
POST         /api/forms/:id/branches/:bid/restore
GET PUT DELETE /api/forms/:id/branches/:bid/working-copy
GET          /api/forms/:id/commits
GET          /api/forms/:id/commits/:cid
GET POST     /api/forms/:id/merge-requests
GET PATCH    /api/forms/:id/merge-requests/:mrId
GET PATCH    /api/forms/:id/branching-settings
GET PUT      /api/forms/:id/capabilities
GET POST     /api/forms/:id/custom-roles
DELETE       /api/forms/:id/custom-roles/:roleId
GET POST     /api/forms/:id/collaborators
PATCH DELETE /api/forms/:id/collaborators/:uid
DELETE       /api/forms/:id/collaborators/invites/:inviteId
GET POST     /api/forms/:id/protection-rules
PATCH DELETE /api/forms/:id/protection-rules/:rid
POST         /api/forms/:id/fork

Submissions

The public submission endpoint validates the published form, response availability, IP access rules, spam settings, required fields, conditional page flow, calculated fields, and quiz scoring before it writes a submission. If moderation is enabled, integrations, workflows, and emails wait until the submission is approved.

Create and manage submissions

Respondents create submissions publicly; admins manage submissions with an authenticated session or API key.

http
POST         /api/submissions
GET DELETE   /api/forms/:id/submissions
GET PATCH DELETE /api/submissions/:id
POST         /api/submissions/bulk
GET          /api/submissions/:id/artifacts
GET POST DELETE /api/submissions/:id/notes
json
{
  "formId": "form_uuid",
  "data": {
    "email": "alex@example.com",
    "company": "Acme"
  },
  "spamToken": "optional-provider-token"
}

Workflows

Workflows are stored per form and run on submission events. Supported behavior includes conditions, status changes, signed webhooks, email, human approvals, PDF generation, e-sign dispatch, and Google nodes where the required provider setup exists.

Workflow definitions and runs

Create workflow definitions, update graph data, inspect run logs, and rerun failed workflow executions.

http
GET POST     /api/forms/:id/workflows
GET PATCH DELETE /api/forms/:id/workflows/:wid
PATCH        /api/forms/:id/workflows/reorder
GET          /api/forms/:id/workflows/:wid/runs
GET          /api/workflows/runs/:runId
POST         /api/workflows/runs/:runId/rerun

Files and artifacts

File uploads go to the private Supabase Storage bucket. Admins receive short-lived signed URLs when they need to view uploaded files or generated artifacts.

Uploads

Public form uploads and authenticated signed URL access.

http
POST         /api/uploads
GET          /api/uploads/signed-url?path=
GET          /api/submissions/:id/artifacts

PDF templates

Designer-authored PDF templates for generated submission artifacts.

http
GET POST     /api/forms/:id/pdf-templates
GET PATCH DELETE /api/forms/:id/pdf-templates/:templateId
POST         /api/forms/:id/pdf-templates/:templateId/preview
POST         /api/forms/:id/pdf-templates/:templateId/duplicate

Integrations

Integrations are configured server-side so provider secrets never reach the browser. Salesforce and custom database secrets are stored encrypted. Google connections use OAuth with encrypted tokens.

Form integrations

Per-form Salesforce or custom database integrations plus test and run-history endpoints.

http
GET POST     /api/forms/:id/integrations
PATCH DELETE /api/forms/:id/integrations/:integrationId
POST         /api/forms/:id/integrations/:integrationId/test
GET          /api/forms/:id/integrations/:integrationId/runs
GET          /api/integrations/salesforce
GET          /api/integrations/salesforce/:integrationId/describe

Google OAuth

Connection management for Google Drive and Sheets workflow nodes.

http
GET          /api/integrations/google/connect
GET          /api/integrations/google/callback
GET          /api/integrations/google/connections
DELETE       /api/integrations/google/connections/:id
GET          /api/integrations/google/picker

AI and address services

AI endpoints require an authenticated caller and provider keys on the server. Address endpoints are public proxies so the Geoapify key stays server-side.

AI

Form generation, PDF conversion, field-writing assistance, analytics insights, and audio transcription.

http
POST         /api/ai/generate-form
POST         /api/ai/pdf-to-form
POST         /api/ai/question-autocomplete
POST         /api/ai/transcribe
POST         /api/analytics/insights

Address

Autocomplete returns provider-backed address suggestions; validate checks address shape and formatting.

http
POST         /api/address/autocomplete
POST         /api/address/validate

Organization and settings

Workspace administration covers members, invites, SSO, API keys, audit logs, notification preferences, profile settings, clipboard notes, and search.

Workspace

Organization membership and invitation management.

http
GET POST     /api/org/members
PATCH DELETE /api/org/members/:uid
GET          /api/org/invites
DELETE       /api/org/invites/:id
GET          /api/org/invites/by-token
POST         /api/org/invites/accept
POST         /api/forms/invites/:inviteId/accept

Settings and security

User settings, API keys, SSO configuration, audit log, clipboard notes, and global search.

http
GET POST     /api/api-keys
POST DELETE  /api/api-keys/:id
GET          /api/audit-log
GET PATCH    /api/settings/profile
POST DELETE  /api/settings/profile/avatar
GET PATCH    /api/settings/notifications
GET PATCH    /api/settings/sso
GET POST     /api/clipboard-notes
PATCH DELETE /api/clipboard-notes/:id
GET          /api/search
GET          /api/profiles

Enterprise SSO

Admin-managed SSO domains and seat provisioning. The start endpoint is public because login has not happened yet.

http
POST         /api/auth/sso/start
GET POST     /api/admin/sso/domains
PATCH DELETE /api/admin/sso/domains/:id
GET POST DELETE /api/admin/sso/seats

Analytics, billing, domains

Analytics and alerts

Dashboard totals, digest triggers, alert listing, and alert updates.

http
GET          /api/analytics
GET POST     /api/analytics/digest
POST         /api/analytics/digest/opportunistic
GET POST     /api/alerts
PATCH        /api/alerts/:id

Billing

Stripe checkout, customer portal, and subscription lifecycle webhook.

http
POST         /api/stripe/checkout
POST         /api/stripe/portal
POST         /api/stripe/webhook

Domains

Custom responder domains and Resend sending-domain verification.

http
GET POST     /api/custom-domains
DELETE       /api/custom-domains/:id
POST         /api/custom-domains/:id/verify
GET POST     /api/sending-domains
DELETE       /api/sending-domains/:id
POST         /api/sending-domains/:id/default
POST         /api/sending-domains/:id/refresh
POST         /api/sending-domains/:id/verify

Webhooks

Ingress forms both receives provider webhooks and sends outbound workflow webhooks. Incoming Stripe and Anvil webhooks are signature-verified in their route handlers. Outbound workflow webhooks are validated for SSRF risk, have a 10 second timeout, cap response reads at 1 MB, and include HMAC headers.

http
X-AutoForm-Signature: sha256=<hmac-hex>
X-AutoForm-Timestamp: <unix-ms>

Incoming provider webhooks

Provider callbacks that update billing and e-sign state.

http
POST         /api/stripe/webhook
POST         /api/esign/webhooks/anvil

Approvals, onboarding, and utilities

Approvals

Public review links for human-approval workflow nodes.

http
GET PATCH    /api/approvals/:id

Onboarding

Authenticated first-run workspace and subdomain setup.

http
GET          /api/onboarding/check-subdomain?subdomain=
POST         /api/onboarding

Runtime utilities

Custom JavaScript rule evaluation and locked-quiz tab-switch reporting.

http
POST         /api/forms/custom-js/evaluate
POST         /api/quiz/tab-switch

Rate limits and browser security

Middleware applies sliding-window rate limits before route handlers run. Production rate limiting uses Upstash Redis when configured and fails open if Redis is unavailable.

text
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 / IP
analytics digest:        6 requests / hour / IP

Browser cross-origin API requests must match the same origin or be present in ALLOWED_ORIGINS. Mutating cookie-authenticated API requests also get an Origin check to reduce CSRF risk. Bearer-key server-to-server calls are not subject to browser CSRF handling.