FormBox.ai docs

Secure form intake for modern websites.

FormBox gives websites secure Hooks, ordered Inbox submissions, notification routing, private files, AI review, approved webhooks, reports, and API/MCP operations. Your website keeps ownership of the visible form.

Product boundary

FormBox handles submission intake, storage, review, routing, and delivery. The website controls its visible fields and validation.

Quickstart

Connect a website

  1. Step 1

    Create a Site using the website's canonical domain.

  2. Step 2

    Create a Hook for the form or workflow.

  3. Step 3

    Configure notification routing, allowed origins, and optional approved-webhook delivery.

  4. Step 4

    Build the visible form in the website or install a maintained adapter.

  5. Step 5

    Submit the browser form to a same-origin site handler.

  6. Step 6

    Validate the request and verify Turnstile or captcha before forwarding.

  7. Step 7

    Forward the request to the Hook with the intake secret on the trusted server.

  8. Step 8

    Run a safe test and verify Inbox, Activity, files, and expected delivery behavior.

Hook intake URL

Every Hook receives a URL in the form https://hooks.formbox.ai/f/{hookId}/{slug}. Treat the paired intake secret as a server-side credential.

Access

Set up your agency and agent

  • Public signup is closed. Ask the operator to create your human login and a separate agency workspace with you as Owner.
  • A new agency must not be added as a team member of another agency. The create_user API creates membership inside the calling key's existing organization, not a new workspace.
  • Sign in at app.formbox.ai, confirm your agency name, and open Settings / API to create an organization-bound agent key. Human passwords and agent API keys are separate credentials.
  • Start with Agent — Read Only for audit/reporting, or explicitly choose the privileges needed for setup. Save keys in a password manager or protected agent environment, not chat, browser code, or source control.
  • All API keys, including Admin, are scoped to their issuing workspace. Read-only access still includes Inbox contact data, file downloads, user/key metadata and delivery operations.
  • Maintained Astro/WordPress adapters are privately distributed to approved operators. This product provides backend contracts, not a public form-builder or publicly installable adapter package.

Model

Core concepts

Site

A website/domain in FormBox. Sites own Hooks, timezone overrides, and scoped dashboard views.

Hook

A secure intake URL for one form or workflow. Hooks store notification routing, allowed origins, status, approved-webhook settings, and an intake secret.

Inbox

The operational queue of submissions. Each item keeps readable fields, raw payload JSON, metadata, files, delivery activity, and AI review state.

Reports

Filtered submission totals, charts by day/site/Hook, failed-delivery counts, and CSV export.

Settings

Workspace defaults for timezone, email templates, internal copies, operational alerts, AI review, users, API keys, and delivery ops.

API / MCP

REST/OpenAPI is the machine-readable source of truth. The local MCP server maps agent workflows to the same API.

Integration

The production request flow

Browser form

Collect visible fields and attribution. Never receive or expose the Hook secret.

Same-origin site handler

Validate required fields, normalize values, and verify Turnstile or captcha.

FormBox Hook

Authenticate intake, store the Inbox item and files, then start review and delivery work.

Keep credentials behind the website

Secured Hooks require X-FormBox-Secret. Send it only from a trusted server, serverless function, or terminal. Never place the intake secret in browser HTML, browser JavaScript, a hidden field, a public repository, or analytics data.

Fail closed before FormBox

When the website uses Turnstile or another bot check, a missing or invalid token must stop at the same-origin handler. Do not downgrade to a direct public browser post to make a preview work.

Quick check

One server-side request

Use this request to verify Hook connectivity from a trusted terminal or server.

Server or terminal cURL
# Run from a trusted server or terminal only.
curl "$FORMBOX_HOOK_URL" \
  -H "Content-Type: application/json" \
  -H "X-FormBox-Secret: $FORMBOX_HOOK_SECRET" \
  --data '{
    "payload": {
      "name": "Test Lead",
      "email": "test@example.com",
      "message": "Testing FormBox intake"
    }
  }'

This creates a real Inbox item

Use a non-client test Hook or approved test recipients. A successful request is stored and can start configured notification, AI-review, and delivery workflows.

Intake contract

Stored acceptance and safe retries

A trusted site backend sends POST /f/{hookId}/{slug} to the intake host. JSON may contain flat business fields or a payload/metadata envelope; URL-encoded and multipart requests are also accepted.

Validate the receipt, not just an HTTP success

Require HTTP 201, ok: true and a valid UUID inboxItemId. The response also includes integer fileCount and boolean deduplicated. This confirms storage only: AI review, client delivery, agency copies and webhooks finish separately. A generic 2xx or HTML body is not this receipt.
Idempotency-KeyOne stable key per submission attempt16–128 characters from A–Z, a–z, digits, dot, underscore, colon and hyphen. Reuse it only with the same business payload, files and direct-upload claim.
Completed retry201, original inboxItemId, deduplicated: trueNo additional Inbox item, file upload or notification is created.
Changed content409 idempotency_conflictDo not retry a changed submission under the old attempt key.
Concurrent attempt409 idempotency_in_progressHonor Retry-After: 1 and retry the unchanged request. Use a fresh key only for a genuinely new attempt.
No keyAccepted without attempt deduplicationRepeated requests can create duplicate Inbox items.
Archive / pauseArchived Site or Hook: 404; paused Hook: 409Archive is a soft lifecycle change, not deletion of historical Inbox/files. Site archive shuts down all its Hook intake/upload authorization. Archived records cannot be reactivated with ordinary PATCH.

JSON/URL-encoded bodies are limited to 64 KiB; payloads allow up to 100 fields, string values up to 10,000 characters and depth 64. Multipart uses a separate parser limit. Your hosting platform or website adapter can impose a smaller transport budget. Ordinary intake allows absent Origin/Referer, www-normalized hosts and configured wildcards. The secret is the authentication boundary; Origin is not captcha.

Data contract

Payload, metadata, and display order

Payload

Visitor-submitted business fields. FormBox preserves these values and shows them in client-facing field tables.

Metadata

Page, referrer, user-agent, UTM, click-ID, source, and system context. Keep it out of visible business fields.

Field order

Send metadata.fieldOrder for JSON or _formbox_field_order for multipart requests.

  • The website owns field names, labels, validation, normalization, conditional logic, and required-state behavior.
  • Use lowercase snake_case keys for business fields and keep the order hint aligned with the visible form.
  • FormBox applies field order to notification emails, dashboard Submitted fields, API payloadFields, and CSV exports.
  • Capture first-touch attribution before the visitor reaches the form and forward it as metadata, not payload.
  • Supported reserved metadata fields use the _formbox_ prefix; never use that prefix for normal business fields.

Files

Private upload paths

Multipart intakeUp to 5 files, 10 MiB eachJPG, JPEG, PNG, WEBP, HEIC, HEIF, PDF, DOC, DOCX, and TXT.
Direct PDF uploadOne PDF, up to 20 MiBAuthorize through the Hook upload endpoint, validate the returned versioned policy, upload to private R2, then submit the one-time claim ID.
Combined intakeUp to 6 files, 70 MiB totalFive multipart attachments plus one direct PDF. Website transport limits remain separate.
StoragePrivate objectsFormBox stores file metadata in the database and file bytes in private object storage.
DownloadsProtected deliveryDashboard downloads require organization access; email links use signed FormBox routes and private-storage redirects.

Use the Hook descriptor as the contract

Hook API responses expose a public directUpload descriptor only when the secret, exact allowed origin, and storage configuration are ready. Integrations must validate its version, limits, content type, organization, Hook, and storage host before sending bytes.
  • Authorization uses the Hook secret and an exact configured Origin. It is limited to five authorization attempts per Hook/IP window, independently from ordinary intake's thirty-attempt limit.
  • Validate the versioned directUpload descriptor and returned policy. PUT exactly the authorized PDF to the private R2 URL within five minutes, with every returned requiredHeaders value, including if-none-match: *.
  • After a successful PUT, forward _formbox_direct_upload_id with the final intake request within the thirty-minute claim window. Finalization verifies object metadata, size, type and bytes, then atomically consumes the claim with Inbox persistence.
  • The final request still needs the Hook secret and normal security checks. Failed, expired, mismatched or consumed claims are not an accepted submission; retry an accepted attempt only with its unchanged Idempotency-Key.

Routing

Notifications, AI review, and retries

Notification routing

  • Hook notification emails are the primary recipients for that workflow.
  • Hook CC recipients are configured separately.
  • Global BCC copies are separate internal emails, not literal SMTP BCC recipients. Reviewed suspicious copies use [SUSP] [BCC] in the subject; client subjects remain unchanged. This marker does not block or hold a suspicious submission.
  • A Hook may intentionally use only Global BCC routing when no primary or CC recipient is configured.
  • Client-facing notifications stay clean; source metadata appears only on internal copies when enabled.

AI review

  • Label-only mode sends normal notifications and records the review. Review processing requires a primary email, approved webhook or enabled Global BCC destination; Inbox-only Hooks with no destination may be marked Skipped without AI review.
  • Block-spam mode stores every submission and blocks client email only for a reviewed Spam verdict at or above the workspace threshold. Suspicious is a warning label, not a review hold, and passes the email gate regardless of confidence.
  • Confidence belongs to the named verdict, not a universal spam probability. The classifier distinguishes boilerplate email-contact templates with no actual customer need from short service-specific requests or meaningful structured job context. Missing optional notes, Gmail and out-of-state phone numbers alone do not make a lead spam. Classifier failures fail open for normal lead email; the product default threshold is 95 and each workspace can choose its own value.
  • Blocked spam may still send a separate [SPAM] [BCC] agency copy when enabled. Identical same-Hook fingerprints suppress additional spam copies for 15 minutes, not additional Inbox items; different contacts/messages can notify again. Dedupe infrastructure failures favor agency visibility.
  • Manual exact-email blocks are managed in Settings > Blocked senders or /api/v1/sender-blocks. An owner or manager can block an address across the agency with a reason and later unblock it. Matching submissions are retained in history but skip AI and suppress client email, approved webhooks and agency copies. Unblocking permits future submissions, never automatic replay of old blocked work. No domain/name/IP/phone bans or automatic AI-to-permanent-ban behavior is included. Already in-flight delivery cannot be recalled; uncertain historical effects require reconciliation.
  • Optional automatic repeat-spam protection starts disabled. An owner can enable it for new submissions only. Two distinct95%+ Spam reviews from the same exact email within30days, consistently explicit solicitation or scam, create a30-day automatic block with evidence links. Recent stored legitimate inquiries and operator Never-auto-block exceptions prevent promotion. Retries/manual review reruns do not add strikes; unkeyed same-form lookalikes within10minutes coalesce conservatively. Blocks expire without renewal from suppressed attempts; unblock/expiry/re-enable require fresh evidence. Existing individual-submission thresholds are unchanged. Use GET/PUT /api/v1/sender-blocks/automation; never auto-block does not cancel a manual rule. No historical backfill or automatic resend occurs.

Store first, deliver second

FormBox commits the Inbox item before external delivery. Inngest handles immediate durable delivery work; bounded hourly reconciliation re-emits pending or stuck work and provides a controlled fallback. Activity records every attempt and retry state.

Operational failure alerts

Delivery failures can alert a configured operational address. When no valid override exists, FormBox falls back to the current organization owner account email.

Outbound

Approved-submission webhooks

An approved webhook is an optional outbound delivery for systems that should receive only AI-confirmed legitimate submissions. It is separate from client notification email.

  • Configure a public HTTPS receiver and a dedicated signing secret together.
  • The signing secret is write-only, encrypted at rest, and must not reuse the public intake secret.
  • Private hosts and nonpublic/local addresses are rejected. Public HTTPS IPv4 literals are permitted; DNS destinations are validated and pinned to public addresses.
  • Webhooks require reviewed Legit with confidence at least 80. This is a separate gate from the email spam threshold. Spam, Suspicious, pending, failed or unavailable AI are withheld.
  • Webhook attempts use durable delivery records, retry behavior, and visible submission Activity.
Event / versioninbox.item.approved / 2026-07-22JSON contains version, event, deliveryId and submission (id, referenceNumber, submittedAt, payload, metadata, hook, site, files, approval). OpenAPI includes its exact schema.
Headersx-formbox-event, x-formbox-delivery-id, x-formbox-key-versionAlso x-formbox-timestamp (Unix seconds) and x-formbox-signature (v1= plus lowercase hex HMAC-SHA256).
Derived signing keyHMAC-SHA256(configured secret, formbox-approved-webhook-signing-v1)Keep the raw digest bytes as the signing key, not its hex string.
Signed messagetimestamp.deliveryId.rawBodyUTF-8 concatenation with literal dots. HMAC-SHA256 using the derived key; compare the hex signature in constant time. Verify the original request bytes before parsing or re-serializing JSON.
Receiver replay protectionTimestamp tolerance and deliveryId deduplicationChoose a bounded clock-skew window (for example five minutes), persist deliveryId before side effects, and return a 2xx for an already processed retry. Each retry has a fresh timestamp/signature.
Receiver responseAny 2xx acknowledges deliveryRedirects are not followed. Most 4xx are terminal; 408/425/429, 5xx and network failures use bounded retries. Receiver timeout is ten seconds.

Automation

Atomic Site and Hook provisioning

POST /api/v1/provision-site-intake creates one Site and between 1 and 50 Hooks in one authenticated workflow for a website integration.

RequestCanonical domain, optional Site name, and 1–50 Hook definitionsEach Hook can include notification routing, allowed origins, and a paired approved-webhook URL and signing secret.
ValidationStrict and fail closedOnly documented properties are accepted. Duplicate generated Hook slugs and malformed domains, emails, origins, or webhooks are rejected before writes.
Limits256 KiB body and 10-second read deadlineOversized and stalled requests return dedicated 413 and 408 errors.
AtomicityAll or nothingIf any Site or Hook write fails, no usable partial installation is returned.
ResponseSite plus created HooksEach Hook includes its intake URL, one-time intake secret, and directUpload descriptor when available.

Dashboard

Dashboard reference

InboxSearch and filter submissions by date, Site, Hook, delivery status, files, and payload text. Detail pages show submitted fields, raw JSON, metadata, files, Activity, AI review, and owner-only permanent delete.
SitesCreate Sites by domain, set a Site timezone, create connected Hooks, and review recent submissions for that Site.
HooksCopy the live Hook URL, explicitly reveal its intake secret as a manager or owner, send a test Inbox item, pause or reactivate intake, configure notification and CC emails, allowed origins, and an optional approved-submission webhook.
ReportsRun reports across all time, presets, custom ranges, Sites, and Hooks. Export CSV with ordered payload fields.
Settings / GeneralSet the account timezone used when a Site does not have its own timezone override.
Settings / EmailConfigure Global BCC copy recipients, operational failure alerts, metadata visibility, table or plain-text format, subject and sender templates, and reference numbers.
Settings / AI ReviewEnable spam review, choose label-only or block-high-confidence-spam behavior, and set the confidence threshold.
Settings / UsersOwner-only user creation, role changes, and non-owner user removal. Roles are owner, manager, and viewer.
Settings / APIOwner-only API key creation, creation-time secret return, later owner-authorized reveal/copy, revoke/reinstate, and delete. Presets include Agent — Read/Write, Agent — Read Only, and Admin.
Settings / OpsReview pending, failed, or stuck delivery work and retry recoverable failures.
AccountUpdate the user profile name, agency workspace name, and view the current role and preferences.

Roles

Owner manages everything, including users, API keys, and permanent deletes. Manager can manage normal records such as Sites and Hooks. Viewer is read-only.

Automation

Management API, OpenAPI, and MCP

Use FormBox API keys for agents and automation. Send Authorization: Bearer with the key from a protected environment. OpenAPI operations declare required scopes in x-required-scopes; successful and error bodies are specified. Management bodies reject unknown fields, invalid types and ambiguous mutations before writes.

Site creation/update supports name; an explicit null timezone clears the override, while omission retains it. Hook blank/omitted signing secret preserves the existing secret. API-key PATCH requires explicit boolean revoked: true revokes, false reinstates. User-role PATCH requires an explicit valid role; owner assignment requires literal Admin *. A key can create only a subset of its own scopes.

SitesGET/POST /api/v1/sitesGET/PATCH/DELETE /api/v1/sites/{siteId}
HooksGET/POST /api/v1/hooksGeneric reads exclude intake secrets. GET /api/v1/hooks/{hookId}/secret requires hooks:secrets:read; PATCH/DELETE and secret rotation remain separate privileged operations.
InboxGET /api/v1/inboxGET /api/v1/inbox/{inboxItemId}; file, download, delivery, and retry routes
SettingsGET/PUT /api/v1/settings/emailAPI key, user, and delivery-ops routes under /api/v1/settings and /api/v1/ops
ProvisioningPOST /api/v1/provision-site-intakeAtomically creates one Site plus one or more Hooks.
OpenAPIGET /api/v1/openapi.jsonAuthoritative machine-readable request, response, validation, and error contract.

API key presets

Agent — Read/Writesites:*, hooks:*, inbox:*, settings:*, api_keys:*, users:*, ops:*, provision:write
Agent — Read Onlysites:read, hooks:read, inbox:read, settings:read, api_keys:read, users:read, ops:read
Admin*

Choose privileges explicitly

API creation accepts exactly one preset (agent_rw, agent_readonly, admin) or a nonempty explicit scope list. Missing, misspelled or conflicting selections are rejected, not upgraded to a broad default. Agent Read/Write includes team/key management, email settings, Hook-secret reveal/rotation and provisioning. Use only what your agent needs. API creation returns the key secret; owners can reveal it again in Settings / API, while key listing stays secret-free.

MCP setup and tools

  • MCP uses a local stdio process, not a remote HTTP/SSE service. Obtain access to the private FormBox runtime first; an API key alone does not install the wrapper.
  • Install checkout dependencies with npm ci, including development dependencies because the wrapper uses tsx. Configure your MCP client command as npm, arguments run mcp:server, and cwd as the absolute FormBox checkout path.
  • Supply FORMBOX_API_KEY securely through your client environment or password manager. Optional FORMBOX_API_BASE_URL defaults to https://app.formbox.ai; do not append /api/v1 because the wrapper supplies that path. The wrapper does not automatically load .env.local.
  • Run initialize and tools/list to verify discovery, then a harmless list_sites read to verify auth and agency scope. The wrapper validates input schemas before forwarding, supports ping and ignores notifications without replying.

The local stdio MCP wrapper exposes these workflow tools and maps them directly to REST:

list_sitescreate_siteget_siteupdate_sitearchive_sitelist_hookscreate_hookget_hookreveal_hook_secretupdate_hookarchive_hookrotate_hook_secretlist_inboxget_inbox_itemlist_inbox_filesget_inbox_file_download_urllist_inbox_deliveriesretry_inbox_deliveryget_email_settingsupdate_email_settingslist_api_keyscreate_api_keyrevoke_api_keydelete_api_keylist_userscreate_userupdate_user_roleremove_userlist_ops_deliveriesprovision_site_intake
View the authoritative OpenAPI specification

Verification

Safe release checks

Fail-closed checks

  • A missing or wrong Hook secret returns 403 before storage.
  • A disallowed Origin returns 403 when origin restrictions are configured.
  • Missing or invalid website captcha fails before the same-origin handler forwards.
  • Honeypot and too-fast submissions fail before storage.
  • Paused Hooks return 409 and rate-limited traffic returns 429 with Retry-After.

Successful-path checks

  • Use a non-client test Hook or explicitly approved test recipients.
  • Confirm the Inbox item contains the expected ordered business fields and separate metadata.
  • Confirm files appear under the expected fields and signed downloads work.
  • Confirm Activity records the expected notification, AI, webhook, retry, or blocked state.
  • Run a landing-page navigation test to prove first-touch attribution survives before form submit.
  • Do not submit a real client lead unless explicitly approved.

Help

Troubleshooting

403 invalid_form_secretThe Hook secret is missing or wrong.Send X-FormBox-Secret only from a trusted server-side integration. Browser forms should submit to a same-origin site handler.
403 origin_not_allowedA supplied Origin or Referer fails the configured ordinary-intake allowlist.Ordinary intake allows absent headers, normalizes www and supports configured wildcards. Direct uploads require a mandatory exact allowed Origin; keep the Hook secret server-side.
400 submitted_too_fast / spam_trap_triggeredThe bot-trap values look suspicious.Keep _formbox_hp empty. _formbox_started_at uses Unix milliseconds and a two-second minimum when valid. Missing/invalid timing is not a captcha check; the website must verify captcha itself.
409 hook_pausedThe Hook is paused.Reactivate the Hook in the dashboard or PATCH the Hook status through the API.
429 rate_limit_exceededToo many submissions reached the same Hook/IP window.Honor Retry-After and reduce automated test traffic.
Fields appear in the wrong orderNo valid field-order hint was sent.Send metadata.fieldOrder for JSON or _formbox_field_order for multipart, matching visible business-field order.
Metadata appears as visible fieldsTracking values were sent in payload.Move page URL, referrer, user agent, UTMs, and click IDs into metadata or supported reserved _formbox_* fields.
Attribution is missing after navigationThe website captured attribution only on the form page.Capture first-touch attribution before navigation, then forward it as metadata when the visitor submits.
Submission stores but no email arrivesNo recipient is configured, AI blocked delivery, or delivery failed.Check Hook routing, AI Review, submission Activity, and Settings / Ops.
Approved webhook did not fireThe submission was not confirmed legitimate or webhook delivery failed.Check AI verdict and Activity. Approved webhooks are deliberately withheld unless AI confirms a legitimate lead.
File upload rejectedThe request exceeded the selected upload path's count, size, type, origin, or storage requirements.Check the multipart limits or the Hook's directUpload descriptor and policy.

Start with the Inbox item

Submission detail is the source of truth for what FormBox received: ordered fields, raw payload JSON, metadata, private files, delivery Activity, and AI review state.