REST API v1

API Documentation

Create forms, retrieve submissions, and manage your form backend programmatically. Full CRUD access with API key authentication.

Base URL

https://formslist.com/api/v1

Authentication

All API requests require a Bearer token using your API key. Generate API keys from your dashboard under Account → API Keys.

API keys are hashed (SHA-256) before storage and cannot be retrieved after creation. Keep your key secure: treat it like a password. If compromised, revoke it immediately from the dashboard and generate a new one.

Request Header
Authorization: Bearer fl_your_api_key_here
Example: cURL
curl https://formslist.com/api/v1/forms \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6"
Example: JavaScript (fetch)
const response = await fetch('https://formslist.com/api/v1/forms', {
  headers: {
    'Authorization': 'Bearer fl_live_a1b2c3d4e5f6',
    'Content-Type': 'application/json',
  },
});

const { data } = await response.json();
console.log(data); // Array of forms
Example: Python (requests)
import requests

headers = {"Authorization": "Bearer fl_live_a1b2c3d4e5f6"}
response = requests.get("https://formslist.com/api/v1/forms", headers=headers)

data = response.json()["data"]
print(data)  # List of forms

Security: Never expose your API key in client-side JavaScript (browser code). API keys should only be used in server-side code, environment variables, or CI/CD pipelines.

Rate Limits

All endpoints are rate-limited to 100 requests per 60-second window per API key. Exceeding the limit returns 429 Too Many Requests.

Response Format

All successful responses return JSON with a data field. List endpoints include a meta field with pagination info.

Success Response
{
  "data": { ... },
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 42,
    "total_pages": 2
  }
}
Error Response
{
  "error": "Missing or invalid Authorization header"
}

Forms

Create, read, update, and delete form endpoints. Each form has a unique hash used as the submission endpoint at /f/{hash}.

List Forms

GET
/api/v1/forms

Returns all forms belonging to your team.

Response Fields

ParameterTypeRequiredDescription
idstringOptionalUnique form ID
namestringOptionalForm name
hashstringOptionalPublic form hash for the submission endpoint
endpointstringOptionalFull submission path (/f/{hash})
submission_countnumberOptionalTotal submissions received
is_activebooleanOptionalWhether the form accepts submissions
created_atstringOptionalISO 8601 timestamp
cURL
curl https://formslist.com/api/v1/forms \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6"
Response (200 OK)
{
  "data": [
    {
      "id": "frm_8kTn2xLm",
      "name": "Contact Form",
      "hash": "abc123def",
      "endpoint": "/f/abc123def",
      "submission_count": 47,
      "is_active": true,
      "created_at": "2026-03-15T10:30:00Z"
    }
  ],
  "meta": { "total": 1 }
}

Create Form

POST
/api/v1/forms

Creates a new form endpoint.

Request Body

ParameterTypeRequiredDescription
namestringRequiredForm name
descriptionstringOptionalForm description
cURL
curl -X POST https://formslist.com/api/v1/forms \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -d '{"name": "Contact Form", "description": "Main site contact"}'
Response (201 Created)
{
  "data": {
    "id": "frm_9pQr3yMn",
    "name": "Contact Form",
    "hash": "xyz789abc",
    "endpoint": "/f/xyz789abc",
    "is_active": true,
    "created_at": "2026-03-22T14:00:00Z"
  }
}

Get Form

GET
/api/v1/forms/:formId

Returns details for a single form.

cURL
curl https://formslist.com/api/v1/forms/frm_8kTn2xLm \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6"

Update Form

PATCH
/api/v1/forms/:formId

Updates a form's properties. All fields are optional.

Request Body

ParameterTypeRequiredDescription
namestringOptionalNew form name
descriptionstringOptionalNew description
is_activebooleanOptionalEnable or disable the form
cURL
curl -X PATCH https://formslist.com/api/v1/forms/frm_8kTn2xLm \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -d '{"name": "Updated Contact Form", "is_active": false}'

Delete Form

DELETE
/api/v1/forms/:formId

Permanently deletes a form and all its submissions. This action cannot be undone.

cURL
curl -X DELETE https://formslist.com/api/v1/forms/frm_8kTn2xLm \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6"
Response (200 OK)
{
  "data": { "deleted": true }
}

Submissions

Retrieve form submissions programmatically. Submissions are created when users submit forms via the /f/{hash} endpoint; they cannot be created via the API.

List Submissions

GET
/api/v1/forms/:formId/submissions

Returns paginated submissions for a form, newest first.

Query Parameters

ParameterTypeRequiredDescription
pagenumberOptionalPage number (default: 1)
per_pagenumberOptionalResults per page (max 100) (default: 25)

Response Fields

ParameterTypeRequiredDescription
idstringOptionalSubmission ID
dataobjectOptionalSubmitted form data as key-value pairs
is_spambooleanOptionalWhether flagged as spam by AI scoring
created_atstringOptionalISO 8601 timestamp
cURL
curl "https://formslist.com/api/v1/forms/frm_8kTn2xLm/submissions?page=1&per_page=50" \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6"
Response (200 OK)
{
  "data": [
    {
      "id": "sub_4jKp7rWs",
      "data": {
        "name": "Sarah Chen",
        "email": "sarah@example.com",
        "message": "Interested in your Pro plan. Can we schedule a demo?"
      },
      "is_spam": false,
      "created_at": "2026-03-22T09:15:00Z"
    },
    {
      "id": "sub_2mNq9tYu",
      "data": {
        "name": "Marcus Rivera",
        "email": "marcus@agency.co",
        "message": "We build 20+ client sites per year. Is there an agency plan?"
      },
      "is_spam": false,
      "created_at": "2026-03-21T16:42:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 50,
    "total": 47,
    "total_pages": 1
  }
}

Get Submission

GET
/api/v1/submissions/:submissionId

Returns a single submission with full details including metadata.

Response Fields

ParameterTypeRequiredDescription
idstringOptionalSubmission ID
form_idstringOptionalParent form ID
dataobjectOptionalSubmitted form data
metadataobject | nullOptionalRequest metadata (IP geolocation, user agent, UTM params)
is_spambooleanOptionalWhether flagged as spam
is_readbooleanOptionalWhether marked as read in the dashboard
created_atstringOptionalISO 8601 timestamp
cURL
curl https://formslist.com/api/v1/submissions/sub_4jKp7rWs \
  -H "Authorization: Bearer fl_live_a1b2c3d4e5f6"
Response (200 OK)
{
  "data": {
    "id": "sub_4jKp7rWs",
    "form_id": "frm_8kTn2xLm",
    "data": {
      "name": "Sarah Chen",
      "email": "sarah@example.com",
      "message": "Interested in your Pro plan."
    },
    "metadata": {
      "ip": "203.0.113.42",
      "country": "US",
      "city": "San Francisco",
      "user_agent": "Mozilla/5.0...",
      "utm_source": "twitter",
      "utm_medium": "social"
    },
    "is_spam": false,
    "is_read": true,
    "created_at": "2026-03-22T09:15:00Z"
  }
}

Submitting Forms

Form submissions are sent to https://formslist.com/f/{hash}. This is a separate endpoint from the REST API and does not require authentication.

HTML Form

HTML
<form action="https://formslist.com/f/your_form_hash" method="POST">
  <input name="name" type="text" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <button type="submit">Send</button>
</form>

AJAX / Fetch (JSON response)

Set Accept: application/json to receive a JSON response instead of a redirect.

JavaScript
const response = await fetch('https://formslist.com/f/your_form_hash', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({
    name: 'Sarah Chen',
    email: 'sarah@example.com',
    message: 'Hello from JavaScript!',
  }),
});

const result = await response.json();
// { "ok": true, "submission_id": "..." }

Special Fields

ParameterTypeRequiredDescription
_nextstringOptionalURL to redirect to after submission (HTML forms only). `_redirect` also works
_subjectstringOptionalOverrides the notification email subject
_replytostringOptionalEmail address for auto-responder (overrides "email" field)
_gotchastringOptionalHoneypot field: leave empty. If filled, submission is marked as spam
_captchastringOptionalCAPTCHA token (reCAPTCHA, Turnstile, or hCaptcha)

Widget, SDK & Partial Capture

Popup widget (Formbutton)

One script tag adds a floating contact button that opens a form. Optional attributes: data-color, data-position, data-title, data-fields. The “Powered by FormsList” badge is removed on paid plans.

HTML
<script src="https://formslist.com/widget.js" data-form="your_form_hash"></script>

JavaScript SDK + React hook

A small client for custom forms. It posts to formslist.com, attaches UTM parameters and exposes a useFormsList React hook.

JavaScript
<script src="https://formslist.com/sdk/formflow.js"></script>
<script>
  const fl = new FormsList('your_form_hash');
  fl.submit({ name: 'Sarah', email: 'sarah@example.com', message: 'Hi!' })
    .then((r) => console.log(r)); // { ok: true, submission_id: '...' }
</script>

// React (with the script loaded):
const { submit, submitting, success, error } = useFormsList('your_form_hash');

Partial capture & abandoned-form follow-ups Business

Add this next to your form to see what visitors typed before leaving. A visitor who entered an email address and left without submitting gets one short “you were almost done” email after an hour; people who submit are never emailed. Passwords, card numbers and similar fields are never captured. Results appear under each form’s Partials tab.

HTML
<script src="https://formslist.com/capture.js" data-form="your_form_hash" defer></script>

Use FormsList in ChatGPT, Claude & your IDE

FormsList runs a remote MCP server. Connect it once and ask your assistant to create a form, wire it into your site and summarise the submissions. You sign in with your FormsList account and choose what the app may do, so there is no API key to copy. Only a workspace owner or admin can connect apps.

Server URL

https://formslist.com/mcp

Claude (claude.ai, desktop and mobile)

Open Settings → Connectors → Add custom connector, name it FormsList, paste the server URL and click Add. Click Connect, sign in to FormsList and choose Allow. On Team and Enterprise plans an owner adds it once under organization settings, then each person connects.

ChatGPT

Open Settings → Apps & Connectors. Under Advanced settings, turn on Developer mode, then Create a connector: name FormsList, MCP server URL as above, authentication OAuth. Sign in to FormsList and choose Allow.

Claude Code

Terminal
claude mcp add --transport http formslist https://formslist.com/mcp
# then run /mcp inside Claude Code and choose "Authenticate"

Cursor

Add FormsList to Cursor (one click), or add it to ~/.cursor/mcp.json:

mcp.json
{ "mcpServers": { "formslist": { "url": "https://formslist.com/mcp" } } }

VS Code (GitHub Copilot)

Install in VS Code (one click), or add it to .vscode/mcp.json:

.vscode/mcp.json
{ "servers": { "formslist": { "type": "http", "url": "https://formslist.com/mcp" } } }

Any other MCP client (Copilot Studio, Perplexity, your own agent)

Point it at the server URL; it discovers sign-in through standard OAuth metadata. Clients without OAuth can send an API key from Account → API keys as a header:

HTTP header
Authorization: Bearer ff_sk_your_api_key

Tools

ToolAccessWhat it does
list_formsreadEvery form with its id, endpoint URL, submission count and status
get_formreadOne form’s settings: notification emails, auto-response, redirect, validation
create_formwriteCreate a form and get its live https://formslist.com/f/… endpoint
update_formwriteRename, set notification emails, add validation, turn a form on or off
configure_autoresponsewriteSet the automatic reply people get after submitting (Pro)
get_submissionsreadRead submissions, newest first, 20 per page (up to 100)
get_embed_snippetreadReady-to-paste HTML form (with spam honeypot) for a form

Permissions and disconnecting

The consent screen asks for forms:read, forms:write and submissions:read. Connected apps can never delete forms or submissions, or see billing and API keys. Access tokens last an hour and renew automatically; see and revoke connected apps under Account → API keys. Prefer a local server? npx -y formslist-mcp runs the stdio version.

Error Codes

StatusMeaningCommon Cause
400Bad RequestMissing required fields (e.g., name on form creation)
401UnauthorizedMissing, malformed, or invalid API key
403ForbiddenTeam has reached its plan's form limit
404Not FoundResource does not exist or belongs to a different team
429Too Many RequestsRate limit exceeded (100 req/min per key)
500Server ErrorInternal error; contact support if persistent

Ready to integrate?

API access is available on Pro ($15/mo) and Business ($45/mo) plans.