External API
The Deformity External API lets you create, edit, fetch, and delete forms from your own app, scripts, or automation tools. It is completely free for all users.
If you want an AI assistant to work with Deformity through conversation, use the Deformity MCP server. MCP uses the same External API keys and form payloads.
Setup
- Go to Account - API Keys and create a key in the Deformity External API section.
- Copy the key immediately. It is only shown once.
- Use
Authorization: Bearer df_your_api_keyon every form API request. - Find a workspace ID from this page, the dashboard URL, or the workspace endpoint.
- Find a form ID from Settings - Integrations - Developer inside a form, or from the list forms endpoint.
Find your workspace ID
workspaceId is required when creating a form. If you are logged in, your active organization workspaces appear below. You can also callGET /api/v1/workspaces with your API key to list workspaces programmatically.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/forms | List active forms. |
| GET | /api/v1/workspaces | List workspaces available to the API key. |
| POST | /api/v1/forms | Create an AI or static form. |
| GET | /api/v1/forms/{formId} | Fetch one form with settings and points. |
| PATCH | /api/v1/forms/{formId} | Edit metadata, settings, form type, or points. |
| DELETE | /api/v1/forms/{formId} | Soft-delete a form. |
Status codes and responses
Successful requests return a data value. Errors return anerror object with a stable code and human-readable message. Delete requests return confirmation JSON instead of an empty response.
{
"data": {
"id": "form_123"
}
}{
"error": {
"code": "invalid_request",
"message": "Request body is invalid"
}
}| Status | Meaning |
|---|---|
| 200 | Request succeeded. Delete requests return confirmation data. |
| 201 | Resource was created. |
| 400 | Invalid request, missing required fields, malformed JSON, or missing organization context. |
| 401 | Missing or invalid API key, or missing logged-in session for API key management. |
| 404 | Workspace, form, or API key was not found in the authenticated organization. |
| 429 | Rate limit exceeded. Check Retry-After and X-RateLimit headers. |
| 500 | Unexpected server error. |
AI vs static forms
Send formType on create. Use ai for conversational forms andstatic for one-question-at-a-time static forms. You can also sendformType in PATCH to switch a form.
{
"workspaceId": "workspace_123",
"formType": "ai",
"name": "Customer intake"
}Create a form
curl -X POST https://deformity.ai/api/v1/forms \
-H 'Authorization: Bearer df_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"workspaceId": "workspace_123",
"formType": "ai",
"name": "Customer intake",
"purpose": "Collect onboarding details and ask helpful follow-ups.",
"points": [
{
"pointType": "welcome_screen",
"body": {
"point": "Welcome to onboarding",
"description": "We will ask a few quick questions.",
"buttonText": "Start",
"active": true
}
},
{
"pointType": "freeform",
"required": true,
"body": {
"point": "What should we know before kickoff?",
"sampleQuestion": "Tell us about your goals"
}
}
],
"settings": {
"saveResponses": true,
"emailResponses": true
}
}'Edit a form
PATCH accepts partial form updates. If you send points, the API replaces the form's ordered points with the array you provide.
curl -X PATCH https://deformity.ai/api/v1/forms/form_123 \
-H 'Authorization: Bearer df_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"name": "Customer onboarding intake",
"formType": "static",
"settings": {
"completionRedirect": "https://example.com/thanks"
}
}'Form properties
| Property | Type | Usage |
|---|---|---|
| workspaceId | string | Required on create. Workspace where the form will be created. |
| formType | ai or static | Required on create. Use ai for conversational forms or static for non-AI forms. |
| name | string | Form name shown in the dashboard. |
| purpose | string or null | AI instruction describing what the form should accomplish. |
| personalityId | string or null | Optional AI personality to use for AI forms. |
| snippets | array of strings | Training snippets or extra instructions used by the AI. |
| url | string or null | Reference website URL for the form. |
| files | array of file objects | File references attached to the form. Shape shown below. |
| colors | array of strings | Theme colors used by the renderer, for example ["#000000", "#ffffff"]. |
| buttons | button style object or null | Button style configuration. Shape shown below. |
| font | string or null | Font family name. |
| settings | settings object | Form behavior settings. See settings reference below. |
| points | array of point objects | Ordered form elements. If sent in PATCH, replaces all points. |
Settings properties
| Property | Type | Usage |
|---|---|---|
| submissionPeriod | submission period object or null | startDate, endDate, and customMessage for opening or closing submissions by date. |
| limit | submission limit object or null | maxSubmissions and customMessage for response limits. |
| instantResponses | boolean | Enable instant AI responses when available. |
| saveResponses | boolean | Store responses in Deformity. |
| completionRedirect | string or null | URL to redirect respondents after completion. |
| collectPartials | boolean | Store partial responses. |
| multilingual | boolean | Allow multilingual behavior. |
| emailResponses | boolean | Send response notification emails. |
| completionEmail | completion email object or null | Completion email settings. Shape shown below. |
| customLogo | string or null | Custom logo URL. |
| customBranding | branding object or null | Custom logo and logo position. Shape shown below. |
| removeDeformityBranding | boolean | Hide Deformity branding when the plan allows it. |
| removeProgress | boolean | Hide progress UI. |
| allowIndexing | boolean | Allow search engine indexing. |
| formNavigation | boolean | Show form navigation controls. |
| responsePathCapture | boolean | Capture response-path data when enabled for the organization. |
| metadata | metadata object or null | Share metadata. Shape shown below. |
Settings object shapes
{
"submissionPeriod": {
"startDate": "2026-06-01T00:00:00.000Z",
"endDate": "2026-06-30T23:59:59.999Z",
"customMessage": "This form is closed."
},
"limit": {
"maxSubmissions": "100",
"customMessage": "This form has reached its response limit."
},
"completionEmail": {
"active": true,
"email": "team@example.com"
},
"customBranding": {
"logo": "https://example.com/logo.png",
"position": "bottomRight"
},
"metadata": {
"title": "Customer intake",
"description": "Tell us about your project.",
"favicon": "https://example.com/favicon.ico",
"shareImage": "https://example.com/share.png"
}
}Point properties
| Property | Type | Usage |
|---|---|---|
| id | string | Returned by the API. Optional in requests; replacement updates create new point IDs. |
| pointType | string | Required for each point. See supported point types below. |
| order | number | Optional 1-based position. Array order is used when omitted. |
| required | boolean or null | Require an answer before continuing. |
| layout | string or null | Visual layout value used by the renderer. |
| background | background object or null | Background image/color/video configuration. Shape shown below. |
| color | string or null | Text or theme color for this point. |
| opacity | number or null | Background opacity. |
| body | point body object | Question-type-specific fields. Unknown top-level point fields are also folded into body. |
Visual object shapes
Visual objects are intentionally flexible because the builder may add renderer-specific keys over time. These are the common shapes to start with.
{
"buttons": {
"backgroundColor": "#000000",
"textColor": "#ffffff",
"borderRadius": 8
},
"background": {
"type": "image",
"url": "https://example.com/background.jpg",
"position": "center",
"size": "cover"
},
"files": [
{
"id": "file_123",
"name": "Brief.pdf",
"url": "https://example.com/brief.pdf",
"type": "application/pdf"
}
]
}Point body properties
Put question-specific values inside body. For convenience, unknown top-level fields on a point are folded into body, but using body directly is clearer for integrations.
| Property | Type | Usage |
|---|---|---|
| point | string | Main prompt or screen text. |
| sampleQuestion | string | Placeholder/sample text shown to respondents. |
| description | string | Supporting text below the prompt. |
| options | array of strings or option objects | Choices for multiple choice, checkboxes, dropdown, and ranking. Shapes shown below. |
| buttonText | string | Button label for screens, embeds, statements, payments, and similar elements. |
| buttonLink | string | Link target for supported button-style elements. |
| minRating | number | Lowest rating value. |
| maxRating | number | Highest rating value. |
| ratingType | stars, hearts, numbers, smileys, or thumbs | Visual rating style. |
| showOther | boolean | Show an Other choice for choice-based questions. |
| embedLink | string | URL for embed points. |
| disclosure | string | Small disclosure text, commonly used on welcome screens. |
| defaultCountry | string | Default country code for phone/address inputs. |
| active | boolean | Used by welcome/end screens to show or hide them. |
| logic | string | Legacy/manual logic text. |
| logicImplementation | string | Executable logic implementation used by the builder/runtime. |
| isManualLogic | boolean | Marks logic as manually configured. |
| selectMultiple | boolean | Allow multiple selections for supported choice fields. |
| signatureType | pad, typing, or both | Signature input mode. |
| dateType | time, date, or date_time | Date/time input mode. |
| weekStart | number | First day of week for date inputs. |
| matrixRows | array of strings | Rows for matrix questions. |
| matrixColumns | array of strings | Columns for matrix questions. |
| amount | number | Payment amount. |
| currency | string | Payment currency code, such as USD. |
| collectName | boolean | Collect payer name for payment points. |
| collectEmail | boolean | Collect payer email for payment points. |
Choice option shapes
For simple choices, send strings. For choices that need stable IDs or metadata, send objects.
{
"options": ["Free", "Pro", "Enterprise"]
}
{
"options": [
{ "id": "free", "label": "Free", "value": "free" },
{ "id": "pro", "label": "Pro", "value": "pro" }
]
}Common body shapes by point type
{
"freeform": {
"point": "What should we know?",
"description": "Share as much detail as you want.",
"sampleQuestion": "Tell us about your goals"
},
"multiple_choice": {
"point": "Pick one",
"options": ["A", "B", "C"],
"showOther": true
},
"dropdown": {
"point": "Choose a department",
"options": ["Sales", "Support", "Product"],
"selectMultiple": false
},
"rating": {
"point": "Rate your experience",
"minRating": 1,
"maxRating": 5,
"ratingType": "stars"
},
"signature": {
"point": "Sign here",
"signatureType": "both"
},
"date_time": {
"point": "Pick a time",
"dateType": "date_time",
"weekStart": 1
},
"matrix": {
"point": "Rate each area",
"matrixRows": ["Support", "Pricing"],
"matrixColumns": ["Poor", "Okay", "Great"]
},
"payment": {
"point": "Pay your deposit",
"buttonText": "Pay now",
"amount": 5000,
"currency": "USD",
"collectName": true,
"collectEmail": true
},
"embed": {
"point": "Watch this first",
"embedLink": "https://www.youtube.com/watch?v=example",
"buttonText": "Continue"
}
}Supported point types
| pointType | Usage |
|---|---|
| welcome_screen | Opening screen with optional button and disclosure. |
| end_screen | Final completion screen. |
| freeform | Open text response. |
| Email address input. | |
| url | URL input. |
| number | Number input. |
| address | Address input. |
| phone_number | Phone number input. |
| multiple_choice | Single-choice selection. |
| multiple_select | Multiple-choice selection. |
| checkboxes | Checkbox list. |
| dropdown | Dropdown selection. |
| confirmation_statement | Statement with an acknowledgement button. |
| rating | Rating input. |
| signature | Signature input. |
| file_upload | File upload input. |
| embed | Embedded URL/content point. |
| ranking | Ranked choice input. |
| matrix | Matrix/grid question. |
| payment | Stripe payment point. |
| logic | Logic-oriented text point. |
Common point examples
[
{
"pointType": "multiple_choice",
"required": true,
"body": {
"point": "Which plan are you interested in?",
"options": ["Free", "Pro", "Enterprise"],
"showOther": true
}
},
{
"pointType": "rating",
"body": {
"point": "How urgent is this?",
"minRating": 1,
"maxRating": 5,
"ratingType": "stars"
}
},
{
"pointType": "date_time",
"body": {
"point": "When should we follow up?",
"dateType": "date_time",
"weekStart": 1
}
},
{
"pointType": "matrix",
"body": {
"point": "Rate each area",
"matrixRows": ["Support", "Pricing", "Features"],
"matrixColumns": ["Poor", "Okay", "Great"]
}
},
{
"pointType": "payment",
"body": {
"point": "Pay your deposit",
"buttonText": "Pay now",
"amount": 5000,
"currency": "USD",
"collectName": true,
"collectEmail": true
}
}
]Response shape
Successful create, fetch, and update responses return { "data": form }. Form objects include id, formType, form metadata,settings, ordered points, timestamps, andnumberOfSubmissions.
Errors
{
"error": {
"code": "invalid_request",
"message": "Request body is invalid"
}
}API keys are rate limited to 120 requests per minute by default. A rate limited request returns HTTP 429 with Retry-After, X-RateLimit-Limit,X-RateLimit-Remaining, and X-RateLimit-Reset headers.