# REST API
The MCP tools over plain HTTP: one POST per tool, an OpenAPI 3.1 description, JSON errors, and the same credentials as the connector.

Everything the MCP connector can do is also a REST API, for scripts, automations, and agents that speak function calling rather than MCP. It is the same tool set on the same encrypted, workspace-scoped paths; only the transport differs.

## Authenticate

Send a bearer token on every request: a workspace API token from Settings → API (owners and admins; the secret is shown once and starts with fbk_), or an OAuth 2.1 access token. Without one, GET /api/v1 answers 401 with a WWW-Authenticate header that points at the discovery metadata. The full walkthrough for agents, including scopes and revocation, is at https://formbear.app/auth.md.

## Call a tool

Each tool is POST /api/v1/tools/{name}with its arguments as a JSON body (an empty body for tools that take none). The response is the tool’s result as JSON.

```bash
curl https://formbear.app/api/v1/tools/list_forms -X POST \
  -H "Authorization: Bearer fbk_your_token_here" \
  -H "Content-Type: application/json" -d "{}"

curl https://formbear.app/api/v1/tools/get_form -X POST \
  -H "Authorization: Bearer fbk_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"publicId": "a1b2c3d4"}'
```

GET /api/v1 returns the workspace the credential acts on and the tools it may call; GET /api/v1/tools describes every tool with its JSON Schema input. The OpenAPI 3.1 document at https://formbear.app/openapi.json carries the same, with one operation per tool (the operation id is the tool name), so it can be loaded straight into an agent framework or an API client.

## Plans and scopes

Read tools work on every plan. Write tools (create, edit, publish, delete) need a Pro workspace and answer 403 pro_required on Free. OAuth credentials can be limited to forms:read, forms:write, responses:read, or responses:write; a missing scope answers 403 insufficient_scope. Tokens and OAuth connections share one budget: 120 requests per minute per credential, 240 per IP.

## Paging through responses

list_responses takes limit (up to 200) and offset, and answers with total, offset, count, and the page. Keep adding count to offset until it reaches total. For aggregates, summarize_responses is cheaper than paging.

## Safe retries

Send an Idempotency-Key header (any unique string, a UUID works) on a POST and you can retry it after a timeout without running the tool twice: the same key within 24 hours returns the first response again, marked Idempotency-Replayed: true. The same key with a different body is refused with 422 idempotency_key_reused.

## Rate limits

120 requests per minute per credential and 240 per IP, shared with the MCP connector. Every response carries RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset (plus the X-RateLimit-* forms), so a client can pace itself; a 429 adds Retry-After.

## Versioning and deprecation

The major version is in the path: /api/v1. Additive changes (new tools, new optional fields) ship in place and never change a version. A breaking change ships as a new version, and the version it replaces keeps working for at least six months. When that happens we announce it in the changelog and every response from the old version carries a Deprecation header (the announcement date) and a Sunset header (the date it stops responding). Nothing is deprecated today.

## Errors

Every error, on every path (including one that does not exist), is a JSON object with a stable code, a message, and a hint that says what to do next.

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | unauthorized | Missing, invalid, or expired credential. |
| 403 | insufficient_scope | The OAuth grant lacks the scope the tool needs. |
| 403 | pro_required | A write tool on a Free workspace. |
| 403 | forbidden | Your role in the workspace does not allow it. |
| 400 | invalid_arguments | The body did not match the tool's input schema. |
| 400 | tool_error | The tool refused (for example, a change that would discard answers). |
| 422 | idempotency_key_reused | The Idempotency-Key was already used with a different body. |
| 404 | not_found | No such tool, form, block, or response. |
| 429 | rate_limited | Back off for Retry-After seconds. |
| 500 | internal_error | The tool failed on our side; retry later. |

- MCP connector (/docs/mcp-connector): The same tools inside Claude, ChatGPT, or Cursor.
- Members & roles (/docs/members-and-roles): Who can create API tokens and connect apps.

Source: https://formbear.app/docs/rest-api
