MightyForms is now part of FormBuilder.AnnouncementMightyForms login
Developers

FormBuilderAPI

A small, boring REST API for getting your data out and reacting to new responses. Scoped API keys, JSON everywhere, no SDK required. Included on every plan.

Quick start

# 1. Settings → API & Zapier → Create API key
# 2. Call the API
curl https://api.formbuilder.com/api/v1/forms \
  -H "Authorization: Bearer fbpat_…"

# 3. Get pinged on every new response
curl -X POST https://api.formbuilder.com/api/v1/hooks \
  -H "Authorization: Bearer fbpat_…" \
  -H "Content-Type: application/json" \
  -d '{"target_url":"https://example.com/hook"}'

Authentication

Send your key as Authorization: Bearer <key>. Keys are created in Settings → API & Zapier, shown once, and can be revoked any time. Revoking a key deletes its hooks.

Scopes

forms:read, forms:write, responses:read, hooks:manage. A missing scope returns 403. Errors are JSON: { "error": "…" }.

Webhook payloads

Hooks POST JSON: event, response_id, form_id, form_title, submitted_at, country_code, fields (label → value) and data (field id → value). Respond 2xx; a 410 unsubscribes the hook. Held (over-limit) responses are never sent.

MCP server

Use FormBuilder from Claude, ChatGPT, Cursor or any MCP client

FormBuilder ships a remote MCP server (Streamable HTTP, OAuth 2.1) at https://api.formbuilder.com/mcp. Tools: formbuilder_signup, formbuilder_create_form, formbuilder_list_forms, formbuilder_get_form_fields, formbuilder_list_responses, formbuilder_create_webhook. Connecting opens a normal “Allow” screen and creates a 30-day API key you can revoke under Settings → API keys. Headless agents with no browser can use https://api.formbuilder.com/mcp/open: call formbuilder_signup and the new key is remembered for the session.

claude.ai · Claude Desktop · ChatGPT

Add a custom connector / app with the URL https://api.formbuilder.com/mcp. You’ll be asked to sign in and click Allow. Then: “Make me a customer feedback form and publish it.”

Claude Code · Gemini CLI

claude mcp add --transport http formbuilder \
  https://api.formbuilder.com/mcp

# or the plugin (skill + MCP):
claude plugin marketplace add bluetickventures/fb
claude plugin install formbuilder@formbuilder

gemini mcp add formbuilder https://api.formbuilder.com/mcp

Cursor · Windsurf · other stdio clients

{
  "mcpServers": {
    "formbuilder": {
      "command": "npx",
      "args": ["-y", "formbuilder-mcp"],
      "env": { "FORMBUILDER_API_KEY": "fbpat_…" }
    }
  }
}

Omit the key to use /mcp/open and sign up from inside the conversation.

OAuth discovery: /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource on api.formbuilder.com (dynamic client registration, PKCE S256, refresh tokens). Agent Skill for Claude: skills/formbuilder-forms.

Endpoints

Base URL https://api.formbuilder.com/api/v1. All responses are application/json.

POST/signupscope none (public)

Create a free account and get an API key in one call — built for AI agents and scripts. No browser or captcha. The email owner gets a claim link; until they claim, the account works like an unclaimed publish (response cap applies). Rate limit 3/hour per IP; 409 if the email already has an account.

ParamInDescription
email
string
bodyOwner email (required)
name
string
bodyOptional display name
agent
string
bodyOptional — name of the agent/tool creating the account, e.g. "claude-code"

Request

curl -X POST https://api.formbuilder.com/api/v1/signup \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "agent": "claude-code" }'

Response

201 { "user_id": "usr_…", "email": "[email protected]", "api_key": "fbpat_…",
  "abilities": ["forms:read","forms:write","responses:read","hooks:manage"],
  "verify_required": true,
  "next": { "create_form": "POST https://api.formbuilder.com/api/v1/forms", "docs": "https://formbuilder.com/developers", "openapi": "https://formbuilder.com/openapi.json" } }
POST/formsscope forms:write

Create a form from JSON, optionally publishing it in the same call. Published forms go through the same safety review as the app; if held, `publish_blocked_reasons` says why. Free plan: 5 forms.

ParamInDescription
title
string
bodyForm title (required)
fields
array
bodyAt least one { label, type, required?, placeholder?, options?, page? }. Types: text, email, textarea, select, radio, checkbox, number, date, phone, url, file, rating, signature, nps, matrix, ranking, score, calculation, payment
publish
boolean
bodyPublish immediately (default false)
description
string
bodyOptional

Request

curl -X POST https://api.formbuilder.com/api/v1/forms \
  -H "Authorization: Bearer fbpat_…" -H "Content-Type: application/json" \
  -d '{ "title": "Contact us", "publish": true,
        "fields": [ { "label": "Name", "type": "text", "required": true },
                    { "label": "Email", "type": "email", "required": true },
                    { "label": "Message", "type": "textarea" } ] }'

Response

201 { "id": "frm_…", "title": "Contact us", "slug": "contact-us", "status": "published",
  "public_url": "https://forms.formbuilder.com/f/contact-us", "edit_url": "https://formbuilder.com/forms/frm_…/edit",
  "publish_blocked_reasons": null, "fields": 3 }
GET/mescope forms:read

Identify the account behind the API key. Useful as an auth test.

Request

curl https://api.formbuilder.com/api/v1/me \
  -H "Authorization: Bearer fbpat_…"

Response

{ "id": "usr_…", "email": "[email protected]", "name": "Jordan", "plan": "pro" }
GET/formsscope forms:read

List your forms, newest first.

ParamInDescription
page
integer
queryPage number, default 1
limit
integer
queryPer page, 1–100, default 50

Request

curl "https://api.formbuilder.com/api/v1/forms?limit=20" \
  -H "Authorization: Bearer fbpat_…"

Response

{
  "data": [
    { "id": "frm_…", "title": "Contact form", "slug": "contact", "status": "published",
      "is_public": true, "response_count": 128, "view_count": 2044,
      "created_at": "2026-07-01T12:00:00.000Z", "updated_at": "2026-08-10T09:30:00.000Z" }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 3 }
}
GET/forms/{formId}/fieldsscope forms:read

Field schema for a form — ids, labels, types, required flags and options. Use this to map fields by id.

ParamInDescription
formId
string
pathForm id

Request

curl https://api.formbuilder.com/api/v1/forms/frm_123/fields \
  -H "Authorization: Bearer fbpat_…"

Response

{
  "form": { "id": "frm_123", "title": "Contact form" },
  "data": [
    { "id": "fld_a1", "label": "Full name", "type": "text", "required": true, "options": null },
    { "id": "fld_b2", "label": "Topic", "type": "select", "required": false, "options": ["Sales", "Support"] }
  ]
}
GET/forms/{formId}/responsesscope responses:read

Responses for a form, newest first. Response `data` is keyed by field id. Responses held over a free-plan limit return `locked: true` with empty data until the account upgrades.

ParamInDescription
formId
string
pathForm id
page
integer
queryPage number, default 1
limit
integer
queryPer page, 1–100, default 50

Request

curl "https://api.formbuilder.com/api/v1/forms/frm_123/responses?limit=50" \
  -H "Authorization: Bearer fbpat_…"

Response

{
  "form": { "id": "frm_123", "title": "Contact form" },
  "data": [
    { "id": "rsp_…", "form_id": "frm_123", "submitted_at": "2026-08-16T18:02:11.000Z",
      "data": { "fld_a1": "Jordan Meyer", "fld_b2": "Sales" },
      "metadata": { "payment_status": "paid" }, "is_test": false }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 128 }
}
POST/hooksscope hooks:manage

Subscribe an HTTPS URL to `response.created`. FormBuilder POSTs each new response there within seconds (REST hooks — the same mechanism the Zapier app uses). Max 100 hooks per account; a `410 Gone` from your endpoint auto-deletes the hook.

ParamInDescription
target_url
string
bodyHTTPS URL to receive POSTs (no private addresses)
event
string
bodyOnly `response.created` today (default)
form_id
string
bodyOptional — omit to receive responses from all your forms

Request

curl -X POST https://api.formbuilder.com/api/v1/hooks \
  -H "Authorization: Bearer fbpat_…" -H "Content-Type: application/json" \
  -d '{ "target_url": "https://example.com/hooks/formbuilder", "form_id": "frm_123" }'

Response

201 { "id": "hk_…", "event": "response.created", "form_id": "frm_123", "target_url": "https://example.com/hooks/formbuilder" }
DELETE/hooks/{hookId}scope hooks:manage

Unsubscribe a hook.

ParamInDescription
hookId
string
pathHook id returned on subscribe

Request

curl -X DELETE https://api.formbuilder.com/api/v1/hooks/hk_123 \
  -H "Authorization: Bearer fbpat_…"

Response

{ "message": "Hook deleted" }

Limits & conventions

  • Pagination is page/limit; limit is capped at 100.
  • Timestamps are ISO-8601 UTC strings.
  • Up to 100 hooks per account. Delivery is fire-and-forget per response (no automatic retry today) — make your endpoint idempotent and fast, and use /responses to backfill if you miss one.
  • Machine-readable spec: /openapi.json (OpenAPI 3.1). Site summary for LLM agents: /llms.txt.
  • Need more write endpoints (update forms, submit responses server-to-server)? Tell us what you're building — it shapes what ships next.

Prefer no code? Use Zapier.

The same hooks power the FormBuilder Zapier app — 6,000+ destinations, no endpoint to host.

Help & support

We use necessary cookies to run FormBuilder and optional analytics cookies to understand site usage. You can accept analytics cookies or keep only necessary cookies.