Formasty Forms API Machine-readable reference Canonical production base URL - https://app.formasty.com/api/v1 Authentication - Send: Authorization: Bearer - Send JSON bodies with: Content-Type: application/json - API keys are account-owned, and every request is checked against the key owner's current workspace permissions plus the scopes on the key. - The public Forms API does not currently guarantee stored-result replay semantics for Idempotency-Key. MCP access - Endpoint: https://app.formasty.com/api/mcp - Preferred auth: OAuth discovery from /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource/api/mcp - OAuth endpoints: /oauth/register, /oauth/authorize, /oauth/token - Fallback auth: Authorization: Bearer for developer-controlled clients that cannot complete OAuth yet - MCP sessions run as the authenticated Formasty user and use that user's live workspace access. - Revoking an MCP connection from Developer settings blocks future OAuth tokens and fallback /api/mcp calls for that connection without disabling standard Forms API requests. - Where an MCP tool maps to a scoped Forms API capability, the same granted session scopes apply. - Agents can create and ship forms without opening the UI by calling tools/list, then formasty.list_workspaces, formasty.create_form or formasty.get_form, formasty.validate_draft, and finally formasty.publish_form. - MCP also supports formasty.list_starter_templates, formasty.create_form_from_starter_template, formasty.clone_form, and formasty.delete_form for template-based starts and lifecycle cleanup. - MCP form creation requires a caller-supplied idempotencyKey. Reusing the same key for the same create request replays the original created form instead of creating a duplicate. GPT Action / OpenAPI pack - GPT Action OpenAPI schema: docs/gpt-actions/formasty-openapi.yaml - The schema covers the API-key-safe /api/v1 surface for GPT Actions. - Configure GPT Action authentication as API Key / Bearer with a dedicated Formasty API key. - Use MCP OAuth instead when you need per-user ChatGPT app connections and live tool discovery. - Browser-session XLSX export endpoints and public Razorpay checkout endpoints are intentionally not part of the GPT Action OpenAPI pack. App-authenticated XLSX export endpoints - POST /api/forms/{form_id}/responses/exports/xlsx - GET /api/forms/{form_id}/responses/exports/{export_id} - GET /api/forms/{form_id}/responses/exports/{export_id}/download - These endpoints use the signed-in app session, not the /api/v1 API-key transport. - Request body can include selectedSubmissionIds. If omitted, the job exports all rows matching filters.search, filters.status, filters.from, and filters.to. - XLSX jobs run in the background, store completed files in R2, expire automatically, and neutralize spreadsheet formulas in user-entered cells. Razorpay payment fields - Payment fields use type "payment" inside draftSchema steps. - Payment fields require Pro access and a workspace Razorpay connection. - Workspace admins configure Razorpay through app endpoints under /api/workspaces/{workspace_id}/integrations/razorpay. - Public runtime creates Razorpay orders through /api/public/forms/{public_id}/payments/razorpay/order and verifies checkout signatures through /api/public/forms/{public_id}/payments/razorpay/verify before accepting the final submission. - Webhooks arrive at /api/payments/razorpay/webhook and require a configured Razorpay webhook secret. - Payment amounts are recomputed server-side from fixed minor units, numeric answers, or number workflow variables. Choice labels and free-text answers cannot drive payment math. Step-by-step MCP agent setup 1. In ChatGPT on the web, open Settings -> Apps -> Advanced settings -> Developer mode and enable Developer mode. 2. Open Settings -> Apps, click Create app, and choose a remote MCP server. 3. App name: formasty 4. Server URL: https://app.formasty.com/api/mcp 5. Complete the OAuth sign-in and consent flow. Formasty MCP supports discovery, dynamic client registration, authorization-code PKCE, and refresh tokens. 6. OAuth is the recommended setup for ChatGPT, Codex, and other remote MCP clients. 7. If your client cannot complete OAuth yet, create a Formasty API key from Developer settings and use Authorization: Bearer as the fallback transport. 8. For form generation and publishing, grant or allow forms:create, forms:read, forms:publish, and add forms:update/forms:steps:write/forms:fields:write/forms:logic:write/forms:design:write when the agent should edit drafts after creation. 9. After ChatGPT imports the server, review the discovered tools and keep only the tools you want enabled. 10. Start a normal chat, attach the Formasty app to the conversation, and ask ChatGPT to begin with tools/list. 11. Call formasty.list_workspaces first. Use recommendedCreateWorkspaceId when present; if it is null, ask the user to choose a workspace instead of guessing. 12. Create the draft with formasty.create_form, a stable idempotencyKey, and a builder-compatible draftSchema. 13. Call formasty.get_form after major edits so the agent sees the latest draft_revision and schema. 14. Call formasty.validate_draft before publishing so blockers are explicit. 15. Publish with formasty.publish_form using the returned form.id and draft_revision. 16. Return the publicUrl to the user. 17. When you want a seeded starting point, prefer formasty.list_starter_templates plus formasty.create_form_from_starter_template instead of inventing the first draft from scratch. 18. Use formasty.clone_form before risky edits on an existing form, and formasty.delete_form to remove drafts the agent should not keep. ChatGPT install notes - Use regular chat with the Formasty app attached when you need write actions such as create, update, validate, or publish. - Do not rely on deep research or Agent mode for Formasty write workflows. - If your ChatGPT plan or workspace only supports read/fetch MCP access, install the app but use Codex or another MCP client for create/edit/publish actions. - These ChatGPT install steps match OpenAI's Apps and Developer mode flow as of April 22, 2026. ChatGPT menu names can change over time. Copy-paste setup prompt - You are my Formasty build agent. - Use the configured remote MCP server named formasty. - If the Formasty MCP server is unavailable in this chat, tell me what is missing and stop. - If you can browse documentation, use these Formasty references as the source of truth: - https://formasty.com/documentation/api-overview - https://formasty.com/documentation/api-authentication - https://formasty.com/documentation/api-endpoints-forms - https://formasty.com/api-docs.txt - https://formasty.com/llms.txt - Before you make changes: - Initialize MCP and inspect tools/list. - Call formasty.list_workspaces first and use recommendedCreateWorkspaceId when present. If it is null or ambiguous, ask me which workspace to use. - If a seeded template is the best fit, call formasty.list_starter_templates and formasty.create_form_from_starter_template. Otherwise call formasty.create_form with a stable idempotencyKey. - After each major change, call formasty.get_form so you are working from the latest draft state. - Make edits only through Formasty MCP tools that actually appear in tools/list. - Call formasty.validate_draft before any publish step and fix blockers first. - Publish only when I explicitly ask you to publish. - When finished, return the formId, draftRevision, and publicUrl if one exists. - Do not open the browser UI unless I explicitly ask for visual review. - When I give you a form brief, convert it into a production-ready Formasty draft, not just a generic outline. Core MCP form creation tools - formasty.list_workspaces - Required scope: forms:read - Returns: workspaces, defaultWorkspaceId, recommendedCreateWorkspaceId - formasty.create_form - Required scope: forms:create - Arguments: idempotencyKey required, workspaceId or workspace_id optional, title optional, draftSchema optional - Returns: data, draft_schema, published_schema, form, draft_revision, draft_updated_at - formasty.get_form - Required scope: forms:read - Returns: form, data, draft_schema, published_schema, draftValidation - formasty.validate_draft - Required scope: forms:read - Returns: formId, draftRevision, validation - formasty.save_draft - Required scope: forms:update - formasty.publish_form - Required scope: forms:publish - formasty.add_step / formasty.update_step / formasty.delete_step / formasty.reorder_steps / formasty.move_step - Required scope: forms:steps:write - formasty.add_field / formasty.update_field / formasty.delete_field / formasty.reorder_fields / formasty.move_field - Required scope: forms:fields:write Current scope model - Form detail responses use: - data: form summary - draft_schema: current resolved draft schema - published_schema: latest published snapshot or null - List responses use: - data: array - next_cursor: null (current implementation) - The draft_schema contract is the same shared schema/property model used by the main Formasty builder UI. - That means API clients can configure: - steps - fields - field labels - field properties/settings - workflow/routing - design/theme options Form summary fields - id - workspace_id - title - status - draft_updated_at - draft_revision - published_version - published_at - public_id - public_url - responses_count Draft vs published - All create/update/draft-save endpoints mutate the draft. - Public forms serve published snapshots only. - Publish copies the current draft into the live published snapshot. Permissions / scopes - forms:read - list forms and fetch draft/published schema for a form - forms:create - create new forms - forms:update - replace a form title or full draft schema - forms:delete - delete a form - forms:publish - publish the current draft snapshot - forms:steps:write - create, update, delete, and reorder draft steps - forms:fields:write - create, update, delete, and reorder draft fields - forms:logic:write - replace draft workflow rules/fallback for a step - forms:design:write - patch the draft theme payload - submissions:read - list submissions and fetch an individual submission when the key owner can view responses - submissions:create - create submissions against published forms when the key owner can edit forms Endpoints 1. GET /api/v1/me Purpose - Validate the current API key and inspect the owner plus key metadata. Response - owner - id - email - username - preferred_workspace - currently always null - api_key - id - name - prefix - last4 - scopes - last_used_at - revoked_at 2. POST /api/v1/forms Purpose - Create a new form. - You can create an empty starter draft or send a full draftSchema. Request body - workspaceId: optional string, required when the key owner can create forms in multiple workspaces - title: optional string - draftSchema: optional object Behavior - If draftSchema is present, its settings.name becomes the stored form title. - Returns data, draft_schema, published_schema. 3. GET /api/v1/forms Purpose - List forms the API key owner can currently access. Query - limit: optional integer, default 20, max 100 - workspaceId: optional string filter (workspace_id also accepted) Behavior - Ordered by updated_at desc, then created_at desc. - next_cursor is always null in the current implementation. - This endpoint does not currently support cursor, status, q, or sort. 4. GET /api/v1/forms/{form_id} Purpose - Reopen a form for continued API-driven editing. Response - data - draft_schema - published_schema 5. PATCH /api/v1/forms/{form_id} Purpose - Update title only, or replace the current draft with a new full draftSchema. Request body - title: optional string - draftSchema: optional object - draft_revision: optional number - force: optional boolean Behavior - If draftSchema is sent, Formasty saves it immediately as the current draft. - When draftSchema is used, the response also includes draft_updated_at and draft_revision. 6. PUT /api/v1/forms/{form_id}/draft Purpose - Save the full draft schema snapshot. Request body - draftSchema: required object - draft_revision: optional number - force: optional boolean Response - data - draft_schema - published_schema - draft_updated_at - draft_revision 7. DELETE /api/v1/forms/{form_id} Purpose - Delete the form. Response - ok - id 8. POST /api/v1/forms/{form_id}/steps Purpose - Append a new draft step, or insert at a given position. Request body - title: optional string - fields: optional array - position or index: optional integer - draft_revision: optional number Response - step - draft_revision - draft_updated_at 9. PATCH /api/v1/forms/{form_id}/steps/{step_id} Purpose - Update draft step properties except fields and id. Request body - any mutable step properties such as title - draft_revision: optional number Response - step - draft_revision - draft_updated_at 10. DELETE /api/v1/forms/{form_id}/steps/{step_id} Purpose - Delete a draft step. Behavior - The form must keep at least one draft step. - Workflow references pointing at the deleted step are cleaned up. Response - ok - deleted_step_id - draft_revision - draft_updated_at 11. POST /api/v1/forms/{form_id}/steps/reorder Purpose - Replace the draft step order with an explicit ordered list of step IDs. Request body - step_ids: complete ordered list of all current step IDs - draft_revision: optional number Response - steps - id - position - draft_revision - draft_updated_at 12. POST /api/v1/forms/{form_id}/steps/{step_id}/fields Purpose - Add a new field to a draft step. Request body - field properties such as type, label, required, placeholder, options - position or index: optional integer - draft_revision: optional number Response - field - draft_revision - draft_updated_at 13. PATCH /api/v1/forms/{form_id}/fields/{field_id} Purpose - Update a draft field. Request body - any mutable field properties except id - draft_revision: optional number Response - field - draft_revision - draft_updated_at 14. DELETE /api/v1/forms/{form_id}/fields/{field_id} Purpose - Delete a draft field. Behavior - Workflow references pointing at the deleted field are cleaned up. Response - ok - deleted_field_id - draft_revision - draft_updated_at 15. POST /api/v1/forms/{form_id}/steps/{step_id}/fields/reorder Purpose - Replace the field order within a draft step. Request body - field_ids: complete ordered list of all current field IDs in the step - draft_revision: optional number Response - fields - id - position - draft_revision - draft_updated_at 16. PUT /api/v1/forms/{form_id}/steps/{step_id}/logic Purpose - Replace workflow rules and fallback for one draft step. Request body - rules: required array - fallbackTarget: optional object|string|null - draft_revision: optional number Behavior - fallbackTarget may be: - "end" - a step ID string - "thank_you:" - { type: "end" } - { type: "step", stepId: "..." } - { type: "thank_you", screenId: "..." } Response - logic - draft_revision - draft_updated_at 17. PATCH /api/v1/forms/{form_id}/design Purpose - Merge a partial theme object into the current draft theme. Request body - theme: required object - draft_revision: optional number Response - theme - draft_revision - draft_updated_at 18. POST /api/v1/forms/{form_id}/publish Purpose - Validate the current draft and publish it. Request body - draftSchema: optional object - draft_revision: optional number - force: optional boolean Behavior - If draftSchema is included, Formasty saves that draft first and then publishes it. Response - data - draft_schema - published_schema - published_at - public_url 19. GET /api/v1/forms/{form_id}/submissions Purpose - List completed submissions for a published form. Query - limit: optional integer, default 20, max 100 - after: optional ISO timestamp lower bound on created_at Response - data: array of submission records - next_cursor: null (current implementation) Submission record shape - event - eventId - form - submission - answers - fields - meta - answersByFieldId 20. GET /api/v1/forms/{form_id}/submissions/{submission_id} Purpose - Load one submission record. Response - data: submission record 21. POST /api/v1/forms/{form_id}/submissions Purpose - Create a submission against the form's published snapshot. Behavior - The form must already be published. - This endpoint validates against the published schema. - Duplicate protection can return 409. - Closed or inactive forms can return 403. - refillToken is not supported on this endpoint. Request body - Either send the whole request body as the field-value map - Or send a wrapper object with: - values: object - hiddenValues: optional object - completedStepIds: optional string[] - analyticsSessionId: optional string - marketingTrackingAllowed: optional boolean - viewerCountry: optional string Response - submission: submission record - thank_you - redirect_to: optional string Full API workflow 1. Create a form with POST /api/v1/forms and a full draftSchema. 2. Store data.id and data.public_url. 3. Re-fetch later with GET /api/v1/forms/{form_id}. 4. Use PATCH /api/v1/forms/{form_id} or PUT /api/v1/forms/{form_id}/draft for full-schema saves. 5. Use the granular step, field, logic, and design endpoints when you only need to mutate one draft fragment. 6. Publish with POST /api/v1/forms/{form_id}/publish. 7. Use public_url for the hosted live form. 8. Use the submissions endpoints to inspect or create submission records. 9. The same saved draft can be opened in the Formasty builder UI. Schema notes - draftSchema is builder-compatible. - Use stable IDs for steps and fields. - Keep your integration as the source of truth for the full schema. - IDs, not labels, should be used when linking logic, step targets, and field updates. - Custom uploaded fonts round-trip through theme.fontFamily and theme.customFont. Set theme.fontFamily to "custom" and include theme.customFont.family, fileName, assetId, format, and url from the uploaded font asset metadata. - Recommendation and personality quiz metadata lives in draftSchema.quiz. Use quiz.type "match" with optional quiz.mode "match" or "personality" ("match" means recommendation/product-match), endings that reference settings.submissions.thankYouScreens by screenId, or "__formasty_default_thank_you__" for the default thank-you screen, and mappings that score answer option values against those endings. - Ending screen cosmetics round-trip through settings.submissions.thankYou and settings.submissions.thankYouScreens. Supported fields include showSocialShareIcons, socialShareLinks, showButton, buttonLabel, buttonUrl, buttonOpenInNewTab, mediaUrl, mediaType, mediaAlt, mediaAttribution, logoUrl, logoAttribution, titleSize, textAlign, backgroundColor, backgroundImageUrl, backgroundImageAttribution, backgroundImageBrightness, headingColor, descriptionColor, buttonBackgroundColor, buttonTextColor, and buttonRadius. - Image attribution fields use { provider: "unsplash", photographerName, photographerUrl, sourceName: "Unsplash", sourceUrl, photoUrl } and should be kept with any Unsplash image URL so public forms can render linked photographer and Unsplash credit. - socialShareLinks is optional and accepts { "facebook": "https://...", "x": "https://...", "linkedin": "https://..." }; omit a network to use the default share URL for that icon. - Workflow variables live in settings.hidden.variables. Number variables support set, add, subtract, multiply, divide, and clear. Text variables support set, append, prepend, and clear. Numeric math can only use numeric answers, numeric hidden values, numeric variables, scores, or fixed numbers. - Payment fields use type "payment" and require Pro access plus a workspace Razorpay connection. A payment field can use a fixed minor-unit amount or source the amount from a numeric answer or number workflow variable. Minimal draftSchema shape { "version": 1, "steps": [ { "id": "step_intro", "title": "Step 1", "fields": [ { "id": "fld_name", "type": "text", "label": "Full name", "required": true, "placeholder": "Jane Doe" } ] } ], "settings": { "name": "Lead Capture", "slug": "lead-capture", "submitButtonLabel": "Request demo" }, "theme": { "primaryColor": "#4C3F8C", "background": { "type": "solid", "value": "#FAFAFB" } }, "workflow": { "version": 1, "enabled": false, "rules": [] }, "quiz": { "type": "match", "mode": "personality", "enabled": false, "endings": [], "mappings": [] } } Validation highlights - invalid draftSchema returns 400 - stale draft_revision returns 409 - duplicate slug returns 409 - invalid/missing API key returns 401 - inaccessible form IDs return 404 - list forms with an inaccessible workspaceId returns 404 Important URLs - Human docs: /documentation/api-overview - Agent overview: /llms.txt - Agent plain-text API reference: /api-docs.txt