{"removeAttribution":false,"l10n":{"translations":{"default_locale":{"translation":{}}},"defaultLocale":"default_locale","locales":[{"code":"default_locale","name":"default_locale"}]},"logo":{"srcSet":"/assets/logo.8b3ac752af5012e9734581f7f988a906a1e9a628057f4329d2c54beb8a2b74f5.9c1bb791.svg light, /assets/formsapp-logo-white.c4542c4a6a2a402e3ed36276a31607c2691c17f2bfdd8079e0a3c63c5206c206.9c1bb791.svg dark","altText":"forms.app","link":"/","favicon":"/assets/favicon.48603a38746476284b35e8ab8818103b36e909035d8edbdbb95cca7d7dc9aa6c.9c1bb791.ico"},"navbar":{"items":[{"type":"link","fsPath":"guides/index.md","metadata":{"type":"markdown"},"label":"Guides","link":"/guides","linePosition":"top","routeSlug":"/guides"},{"type":"link","fsPath":"apis/index.yaml","metadata":{"type":"openapi","title":"forms.app API","description":"## Overview\n\nThe **forms.app API** gives you programmatic, read-only access to your forms and their\nsubmissions. You can list all the forms in your account, fetch a specific form's complete\nstructure (questions, design settings, submission behaviour, thank-you pages), and page\nthrough the answers your respondents have submitted.\n\n## Authentication\n\nEvery request must be authenticated with exactly **one** of the two methods below.\nProviding both in the same request is not allowed and will return `401 Unauthorized`.\n\n### Option 1 — OAuth 2.0 Bearer Token\n\nObtain a JWT via the forms.app OAuth 2.0 flow and pass it in the `Authorization` header:\n\n```\nAuthorization: Bearer <your_token>\n```\n\n### Option 2 — API Key\n\nPass your API key in the `X-Api-Key` header:\n\n```\nX-Api-Key: <your_api_key>\n```\n\n#### How to create an API key\n\n1. Log in to [forms.app](https://forms.app).\n2. Click your avatar in the top-right corner and open **Account Settings**.\n3. Go to the **API Keys** tab.\n4. Click **Create API Key**, enter a descriptive name, and confirm.\n5. Copy the generated key immediately — it is shown **only once**.\n6. Store it securely (e.g. in an environment variable or secret manager).\n\n> You can create multiple keys (one per integration), and revoke any of them at any time\n> from the same **API Keys** settings page.\n\n> **Newly created or re-activated keys:** for up to ~30 seconds, a key whose validation\n> recently failed may keep returning `401 Unauthorized` from a short-lived cache. If a key\n> you just created or re-activated is rejected, wait ~30 seconds and retry.\n\n## Response Envelope\n\nAll endpoints return a consistent JSON envelope:\n\n**Success (`2xx`)**\n```json\n{\n  \"success\": true,\n  \"data\": { },\n  \"errors\": []\n}\n```\n\n**Error (`4xx` / `5xx`)**\n```json\n{\n  \"success\": false,\n  \"data\": null,\n  \"errors\": [\n    { \"errorCode\": 1001, \"errorMessage\": \"Unauthorized\" }\n  ]\n}\n```\n\n## Rate Limiting\n\nRequests are rate-limited per API key / token (falling back to client IP when neither is\npresent). You may send up to **300 requests per 60-second window**. When the limit is\nexceeded the API returns `429 Too Many Requests` with a `Retry-After` header indicating how\nmany seconds to wait before the window resets. Wait for that period and retry — do not spam\nthe endpoint in a tight loop.\n\nA short-term burst limit also applies per endpoint (about **50 requests per second**, with a\nburst allowance up to **100**). Spread requests out rather than firing them in a tight burst\nto avoid transient `429` responses.\n"},"label":"API Reference","link":"/apis","linePosition":"top","routeSlug":"/apis"},{"type":"link","fsPath":"changelog.md","metadata":{"type":"markdown"},"label":"Changelog","link":"/changelog","linePosition":"top","routeSlug":"/changelog"}]},"footer":{"copyrightText":"© 2018 - 2026 forms.app. All rights reserved.","items":[{"type":"link","fsPath":"legal/terms.md","metadata":{"type":"markdown"},"label":"Terms","link":"/legal/terms","linePosition":"top","routeSlug":"/legal/terms"},{"type":"link","fsPath":"legal/responsible-use.md","metadata":{"type":"markdown"},"label":"Responsible Use","link":"/legal/responsible-use","linePosition":"top","routeSlug":"/legal/responsible-use"},{"type":"link","link":"https://forms.app/en/cookie-policy","label":"Cookies","linePosition":"top"}]},"markdown":{"toc":{"depth":2,"header":"On this page"},"frontMatterKeysToResolve":["image","links"],"partialsFolders":["**/_partials/**"],"lastUpdatedBlock":{"format":"timeago"},"editPage":{}},"mcp":{"hide":false,"docs":{"hide":false,"name":"MCP server","ignore":[]}},"banner":[],"breadcrumbs":{"prefixItems":[]},"userMenu":{"hide":true},"auth":{"idpsInfo":[]},"search":{},"entitiesCatalog":{},"apiProducts":{},"searchFeatures":{"advanced":{"enabled":false},"ai":{"enabled":false}},"analytics":{"ga":{"trackingId":"","exclude":[],"trackers":{}}}}