API Reference

REST API for managing forms and submissions programmatically. Available on all plans.

API version: v1 · Base URL: https://formblade.com

Download Postman Collection v1

Personal plan — read-only access.

Personal (free) accounts are limited to GET requests only. You can list forms, view submissions, export data, and download files — but you cannot create, update, or delete anything via the API.

Upgrade to Pro for full read + write API access.

Get started:

Create an API key from the API Keys page in your dashboard. Personal plan users get read-only keys; Pro users can choose between read-only and full-access keys.

Authentication

All API requests require a Bearer token in the Authorization header:

Authorization: Bearer fb_sk_your_api_key_here

There are two layers of access control:

1. API key scope

The scope is set when you create the key and determines which HTTP methods are allowed.

ScopeAllowed methodsWho can create
readGET onlyAll plans
fullGET, POST, PATCH, DELETEPro+ only

2. Plan restrictions

Your plan determines what scope you can create:

PlanCan create read keysCan create full keys
PersonalYesNo
ProYesYes

Personal plan users can only create read-scoped keys. Even if you could somehow obtain a full-scoped key, write requests would still be rejected because your plan does not support it. See Troubleshooting below.

Error responses

All errors return JSON with a detail field:

{"detail": "Form not found"}
401 Unauthorized

Invalid or missing API key. The request has no Authorization header, or the key doesn't match any active key.

Common causes:

  • Missing Authorization: Bearer fb_sk_... header
  • Key was deleted from the API Keys page
  • Key was not fully copied (only shown once on creation)
403 Forbidden

You don't have permission for this action. Multiple possible causes:

MessageCauseFix
This API key is read-onlyWrite request with a read-scoped keyUpgrade to Pro for full-access keys, or create a full scope key if already on Pro
Full-access API keys require a Pro planCreating a full key on Personal planUpgrade to Pro
Form limit reachedHit max forms (Personal: 5, Pro: 100)Delete unused forms or upgrade
This captcha provider requires a Pro planSetting captcha_type to reCAPTCHA, Turnstile, or GeeTest (hCaptcha and math are free)Use hCaptcha or upgrade to Pro
Auto-responder requires a Pro planSetting auto_respond: trueUpgrade to Pro
Custom theme colors require a Pro planSetting form_theme_custom with color overridesUse a preset theme or upgrade to Pro
404 Not Found

The resource doesn't exist or doesn't belong to your account. Form IDs, submission IDs, and file names are scoped to your account — you cannot access other users' data.

413 Payload Too Large

A file upload exceeds your plan's limits:

MessageLimit
File exceeds X MB limitPersonal: 1 MB/file, Pro: 25 MB/file
Storage limit reachedPersonal: 100 MB total, Pro: 1 GB total

Delete old submissions or files to free space, or upgrade.

422 Validation Error

The request body is malformed or missing required fields. Check the endpoint documentation for the expected fields and types.

429 Too Many Requests

Monthly submission limit reached. This applies to form submissions via POST /f/{endpoint_id}, not to API management calls.

PlanLimit
Personal300 submissions/month
Pro3,000 submissions/month
  • Resets on the 1st of each month at midnight UTC
  • Count is across all your forms combined, not per form
  • Spam-flagged submissions still count (they were accepted before being flagged)
  • Check usage: GET /api/forms/statssubmissions_this_month vs submissions_limit

Forms

Form object fields

FieldTypeExampleDescription
iduuid"a1b2c3d4-e5f6-..."Unique form identifier
namestring (3–64)"Contact Form"Form name
endpoint_idstring (6–12)"contact"Short ID used in /f/{endpoint_id} URL
notify_emailstring | null"you@example.com"Email address for submission notifications
redirect_urlstring (max 500) | null"https://site.com/thanks"URL to redirect to after submission
is_activebooleantrueWhether the form accepts submissions
honeypot_fieldstring (max 100) | null"_fb_hp"Custom honeypot field name (default: _fb_hp)
js_honeypotbooleantrueJS verification enabled (default: true)
js_honeypot_fieldstring (max 100) | null"_fb_js"Custom JS honeypot field name (default: _fb_js)
captcha_typestring"none"none, math, hcaptcha, recaptcha_v2, recaptcha_v3, turnstile, geetest_v4
captcha_site_keystring | nullnullCaptcha provider site/public key
captcha_min_scorefloat | null0.5reCAPTCHA v3 minimum score (0.0–1.0)
form_themestring"corporate"minimal, corporate, glass, dark, warm, compact
form_fieldsarray | nullsee belowHosted form field configuration
auto_respondbooleanfalseAuto-responder enabled (Pro+)
consent_requiredbooleanfalseRequire consent checkbox
ip_anonymizebooleanfalseAnonymize stored IP addresses
store_ipbooleantrueStore submitter IP
store_user_agentbooleantrueStore submitter user agent
data_retention_daysinteger | null90Auto-delete submissions after N days (null = plan default)
view_countinteger342Hosted form page view count (read-only)
submission_countinteger57Total non-spam submissions (read-only)
created_atISO 8601"2026-03-15T10:30:00Z"When the form was created (read-only)
updated_atISO 8601"2026-03-20T14:22:00Z"When the form was last modified (read-only)

Form fields array

The form_fields array defines the hosted form layout. Each entry is an object with a type and optional properties:

[
  {"type": "heading", "name": "heading", "label": "Contact us"},
  {"type": "text", "name": "name", "label": "Name", "placeholder": "Your name", "required": true},
  {"type": "email", "name": "email", "label": "Email", "placeholder": "you@example.com", "required": true},
  {"type": "textarea", "name": "message", "label": "Message", "placeholder": "How can we help?", "required": true, "rows": 4},
  {"type": "select", "name": "priority", "label": "Priority", "options": ["Low", "Medium", "High"], "required": true},
  {"type": "submit", "name": "", "label": "Send message", "required": false}
]

Supported field types: heading, text, email, textarea, select, file, submit.

GET /api/forms

List all your forms with submission counts (excludes spam).

curl -H "Authorization: Bearer fb_sk_..." \
  https://formblade.com/api/forms

Response: Array of form objects (see fields above).

POST /api/forms PRO

Create a new form. Returns 201 Created.

curl -X POST -H "Authorization: Bearer fb_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Contact Form", "notify_email": "you@example.com"}' \
  https://formblade.com/api/forms

Request body:

FieldTypeRequiredExampleNotes
namestring (3–64)Yes"Contact Form"
notify_emailstring (max 255)No"you@example.com"Defaults to account email
redirect_urlstring (max 500)No"https://site.com/thanks"URL after submission
honeypot_fieldstring (max 100)No"_fb_hp"Default: _fb_hp
js_honeypotbooleanNotrueDefault: true
js_honeypot_fieldstring (max 100)No"_fb_js"Default: _fb_js

Response: Form object.

GET /api/forms/{form_id}

Get a single form by ID.

Path: form_id — uuid (required)

Response: Form object.

PATCH /api/forms/{form_id} PRO

Update form settings. Send only the fields you want to change.

curl -X PATCH -H "Authorization: Bearer fb_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Updated Name", "is_active": false}' \
  https://formblade.com/api/forms/{form_id}

Request body (all optional):

FieldTypeExampleNotes
namestring (3–64)"Updated Name"
notify_emailstring (max 255)"team@example.com"
redirect_urlstring (max 500)"https://site.com/thanks"
is_activebooleanfalseEnable/disable the form
honeypot_fieldstring (max 100)"_fb_hp"
js_honeypotbooleantrue
js_honeypot_fieldstring (max 100)"_fb_js"
form_fieldsarraysee form fields aboveHosted form field config
form_themestring"corporate"minimal free, others Pro+
captcha_typestring"hcaptcha"math & hcaptcha free, others Pro+
captcha_site_keystring (max 255)"10000000-ffff-..."Required with captcha_type
captcha_secret_keystring (max 255)"0x..."Required with captcha_type
captcha_min_scorefloat (0.0–1.0)0.5reCAPTCHA v3 only
auto_respondbooleantruePro+
auto_respond_subjectstring (max 255)"Thanks for reaching out"
auto_respond_bodytext"We received your message..."
data_retention_daysinteger90Capped to plan limit
consent_requiredbooleantrue
consent_messagetext"I agree to the privacy policy"
ip_anonymizebooleantrue
store_ipbooleantrue
store_user_agentbooleantrue

Response: Updated form object.

DELETE /api/forms/{form_id} PRO

Delete a form and all its submissions and files. This action is irreversible.

Response: 204 No Content

GET /api/forms/stats

Dashboard statistics: submission counts, storage usage, recent activity.

{
  "total_forms": 3,
  "total_submissions": 150,
  "submissions_today": 5,
  "submissions_this_week": 28,
  "submissions_this_month": 95,
  "spam_count": 4,
  "storage_used_mb": 12.5,
  "storage_limit_mb": 50,
  "submissions_limit": 300,
  "forms_limit": 5,
  "plan": "free",
  "recent_submissions": [...],
  "top_forms": [...]
}
POST /api/forms/{form_id}/test-email PRO

Send a test notification email using the form's email configuration.

{"ok": true, "message": "Test email sent to you@example.com"}

Submissions

Submission object fields

FieldTypeExampleDescription
iduuid"106f069f-..."Unique submission identifier
dataobject{"name": "Jane", "email": "jane@example.com"}Key-value pairs of submitted form data
filesobject | nullnullUploaded files metadata (field → {filename, stored_name, size_bytes, content_type})
ip_addressstring | null"203.0.113.42"Submitter IP (if stored, may be anonymized)
user_agentstring (max 500) | nullnullRaw user agent string (if stored)
deviceobject | null{"device_type": "desktop", "browser": "Chrome 145", "os": "Windows 10"}Parsed device info
is_spambooleanfalseWhether flagged as spam
spam_flagsstring[] | nullnullWhich checks triggered: honeypot, js_honeypot, captcha
created_atISO 8601"2026-03-23T11:02:05Z"When the submission was received
GET /api/forms/{form_id}/submissions

List submissions with pagination and spam filtering.

Query paramTypeDefault
pageinteger1
per_pageinteger (1–100)50
spambooleanall (omit to include everything)
curl -H "Authorization: Bearer fb_sk_..." \
  "https://formblade.com/api/forms/{form_id}/submissions?page=1&per_page=25&spam=false"

Response:

{
  "items": [
    {
      "id": "106f069f-...",
      "data": {"name": "Jane", "email": "jane@example.com", "message": "Hello!"},
      "files": null,
      "ip_address": "203.0.113.42",
      "device": {"device_type": "desktop", "browser": "Chrome 145.0.0", "os": "Windows 10"},
      "is_spam": false,
      "spam_flags": null,
      "created_at": "2026-03-23T11:02:05Z"
    }
  ],
  "total": 42,
  "page": 1,
  "per_page": 25
}
GET /api/forms/{form_id}/submissions/export

Export submissions as CSV, JSON, or Excel. Excludes spam. Returns a file download.

Query paramOptionsPlan
formatcsv (default), json, xlsxxlsx requires Pro+
curl -H "Authorization: Bearer fb_sk_..." \
  -o submissions.csv \
  "https://formblade.com/api/forms/{form_id}/submissions/export?format=csv"
PATCH /api/forms/{form_id}/submissions/{id}/spam PRO

Toggle the spam flag on a submission. Returns the new state.

{"ok": true, "is_spam": true}
POST /api/forms/{form_id}/submissions/{id}/resend PRO

Resend the notification email for a submission.

{"ok": true, "message": "Notification resent to you@example.com"}
DELETE /api/forms/{form_id}/submissions/{id} PRO

Delete a submission and its uploaded files.

Response: 204 No Content

Files

GET /api/forms/{form_id}/submissions/{id}/files/{stored_name}

Download an uploaded file. The stored_name comes from the submission's files object.

curl -H "Authorization: Bearer fb_sk_..." \
  -o document.pdf \
  https://formblade.com/api/forms/{form_id}/submissions/{id}/files/{stored_name}
GET /api/files

List all uploaded files across your forms with filtering and pagination.

Query paramTypeDescription
form_iduuidFilter by form
file_typestringFilter by extension (e.g. pdf)
searchstringSearch by filename or form name
pageintegerDefault: 1
per_pageintegerDefault: 50 (max 100)

Plan limits

LimitPersonal (free)Pro
API keys1 (read-only)10 (read + full)
Submissions/month3003,000
Forms5100
File upload size1 MB25 MB
Storage100 MB1 GB
Submission archive90 days1 year
Excel exportNoYes
Captcha providersHoneypot + hCaptchaAll (reCAPTCHA, Turnstile, GeeTest, hCaptcha)
Auto-responderNoYes

Postman collection

Import the collection into Postman to test all endpoints. Set the api_key variable to your API key and base_url to https://formblade.com.

Download Postman Collection v1

Rate limits

There are currently no rate limits on the API beyond your plan's monthly submission quota. We reserve the right to introduce rate limiting in the future if needed.

Troubleshooting

Common issues and how to resolve them. See Error responses above for the full list of status codes.

I get 403 on every request

Most likely a scope or plan issue. Check these in order:

  1. Are you on the Personal plan making a write request? Personal accounts can only use GET endpoints. POST/PATCH/DELETE require a Pro plan with a full-scoped key.
  2. Did you create a read-only key? Even on Pro, if you created a read key it will reject write requests. Create a new full key from API Keys.
  3. Are you trying to use a Pro feature? Some form settings (certain captcha providers, auto-responder, custom theme colors) require a Pro plan even with a full-access key.
I get 401 "Invalid API key"

The key doesn't match. Verify:

  • Header format is exactly Authorization: Bearer fb_sk_... (with space after Bearer)
  • You copied the full key when it was shown (it's only displayed once)
  • The key hasn't been deleted or disabled in API Keys
  • No extra whitespace or line breaks in the key
My submissions hit 429 but I haven't sent that many

The monthly limit counts submissions across all your forms combined, not per form. Spam-flagged submissions also count because they were accepted before being flagged.

Check your usage: GET /api/forms/stats returns submissions_this_month and submissions_limit.

Limits: Personal 300/month, Pro 3,000/month. Resets on the 1st at midnight UTC.

File upload returns 413

Two possible causes:

  • Single file too large — Personal: 1 MB max, Pro: 25 MB max
  • Total storage full — Personal: 100 MB, Pro: 1 GB. Delete old submissions or files to free space.

Check storage usage via GET /api/forms/statsstorage_used_mb and storage_limit_mb.

Form created via API has no fields

New forms get default fields (name, email, message) automatically. If you want custom fields, set form_fields in a follow-up PATCH request with your field configuration array.

Still stuck? Contact us with your error message and we'll help.