API Overview
The RapidForm API lets you create and manage forms, read submissions, pull analytics and wire up webhooks from your own code, from no-code tools, or from AI agents. Everything you can do in the form builder you can do over the API.
API access is included in the Pro and Business plans. Free accounts receive a 403 with the code plan_required.
Base URL
https://rapidform.com/api/v1
All endpoints are relative to this base URL. Requests and responses are JSON. Send Content-Type: application/json on requests with a body. You do not need an Accept header — the API always answers in JSON, including errors.
Authentication
- Open API in the sidebar of your RapidForm dashboard.
- Give the key a name (for example
ZapierorClaude MCP) and pick the workspace it should have access to. - Copy the key. It is shown once and cannot be retrieved later — create a new key if you lose it.
Send the key as a bearer token on every request:
curl https://rapidform.com/api/v1/me \
-H "Authorization: Bearer 12|rf_9Xk3...your-key..."
Keys look like 12|rf_…. Send the whole string, including the numeric prefix and the pipe.
Workspace scoping
Every key belongs to exactly one workspace. A key can only see and change forms in that workspace — forms in other workspaces behave as if they do not exist (404), even if your user account has access to them. Create one key per workspace if you need to automate several.
If you leave a team workspace, keys scoped to it stop working with the code workspace_unavailable. Revoking a key under Settings → API keys invalidates it immediately.
Rate limits
Each key may make 120 requests per minute. Every response includes:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Requests allowed per minute (120). |
X-RateLimit-Remaining |
Requests left in the current minute. |
Retry-After |
Only on 429 responses — seconds to wait before retrying. |
When you exceed the limit the API responds with 429 Too Many Requests. Back off for Retry-After seconds and retry.
Errors
The API uses standard HTTP status codes. Error bodies always contain a human-readable message; access and limit errors also carry a machine-readable code.
| Status | When | Body |
|---|---|---|
401 |
Missing, malformed or revoked key. | {"message": "Unauthenticated."} |
403 |
Key is valid but not allowed. | {"message": "…", "code": "plan_required" \| "account_deactivated" \| "workspace_unavailable"} |
404 |
The form, submission or webhook does not exist in this key's workspace. | {"message": "…"} |
422 |
Validation failed, or a plan limit was hit. | See below. |
429 |
Rate limit exceeded. | {"message": "Too Many Attempts."} |
Validation errors list every failing attribute. Array items use dot notation with their index:
{
"message": "Every field needs a label. (and 1 more error)",
"errors": {
"fields.0.label": ["Every field needs a label."],
"fields.1.options": ["This field type needs at least one option."]
}
}
Limit errors carry a code instead of errors:
| Code | Endpoint | Meaning |
|---|---|---|
form_limit_reached |
POST /forms |
Your plan's form limit is reached. |
webhook_limit_reached |
POST /forms/{id}/webhooks |
A form already has 5 webhooks. |
Pagination
Two styles are used, chosen for what each list is good at:
Page-based (forms): pass page and per_page (default 25, max 100). The response has meta.current_page, meta.last_page, meta.total and links.next.
Cursor-based (submissions): pass per_page and, for the next page, the cursor from meta.next_cursor. Cursors stay stable while new submissions arrive, so you never skip or repeat a row. meta.next_cursor is null on the last page.
Both styles wrap results in a data array.
Your account: GET /me
Returns who the key belongs to, the workspace it operates on, and the plan limits and usage. Agents should call this first to learn what they can create.
curl https://rapidform.com/api/v1/me \
-H "Authorization: Bearer $RAPIDFORM_API_KEY"
{
"user": {
"id": 7,
"name": "Ada Lovelace",
"email": "[email protected]"
},
"workspace": {
"id": 3,
"name": "Acme Marketing",
"role": "owner"
},
"plan": "pro",
"limits": {
"forms": null,
"submissions_per_month": 5000,
"team_members": 3
},
"usage": {
"forms": 12,
"submissions_this_period": 1284,
"period_start": "2026-08-15",
"period_end": "2026-09-14"
}
}
| Field | Type | Description |
|---|---|---|
user.id |
integer | Your user ID. |
user.name |
string | Your display name. |
user.email |
string | Your account email. |
workspace.id |
integer | Workspace this key is scoped to. All form IDs you see belong to it. |
workspace.name |
string | Workspace name. |
workspace.role |
string | owner, editor or viewer — your role in that workspace. |
plan |
string | pro or business (lifetime accounts report business). |
limits.forms |
integer or null | Maximum number of forms across all workspaces. null means unlimited. |
limits.submissions_per_month |
integer or null | Submissions accepted per billing period. null means unlimited. |
limits.team_members |
integer or null | Team members allowed. null means unlimited. |
usage.forms |
integer | Forms you currently have, across all workspaces. |
usage.submissions_this_period |
integer | Submissions received in the current billing period. |
usage.period_start |
date | First day of the current billing period (YYYY-MM-DD). |
usage.period_end |
date | Last day of the current billing period. |
Endpoint index
| Method | Path | Description |
|---|---|---|
GET |
/me |
Account, workspace, limits and usage. |
GET |
/forms |
List forms. |
POST |
/forms |
Create a form with fields. |
GET |
/forms/{form} |
Get a form with its fields. |
PATCH |
/forms/{form} |
Update a form. |
DELETE |
/forms/{form} |
Delete a form. |
GET |
/forms/{form}/fields |
List a form's fields. |
PUT |
/forms/{form}/fields |
Replace a form's fields. |
GET |
/forms/{form}/submissions |
List submissions. |
GET |
/submissions/{submission} |
Get a submission. |
GET |
/forms/{form}/analytics |
Views, submissions and conversion. |
GET |
/forms/{form}/webhooks |
List webhooks. |
POST |
/forms/{form}/webhooks |
Add a webhook. |
DELETE |
/forms/{form}/webhooks/{webhook} |
Remove a webhook. |
All {form}, {submission} and {webhook} parameters are the integer IDs returned by the API.