Create a new form programmatically by providing a source form as a template and defining the steps and components for the new form. The generated form inherits all styling, fonts, backgrounds, and layout settings from the source form.
You’ll need an API key to use this endpoint. See the
API Keys documentation to create one.
How It Works
You provide a source form ID — this form acts as a style template. The generated form inherits its fonts, colors, backgrounds, and component styles.
You define the steps and components for the new form. Each step contains one or more components (inputs, dropdowns, scheduling widgets, etc.).
The API creates the form, publishes it, and returns the form ID and URL.
The source form must belong to the same environment and must not be deleted. Component types that are not in the source form’s styles will automatically receive default styling.
Request
curl -X POST 'https://forms.withsurface.com/api/v1/environments/{environmentId}/forms/generate' \
-H 'x-api-key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"sourceFormId": "your-source-form-id",
"name": "My Generated Form",
"steps": [
{
"name": "Contact Info",
"components": [
{
"type": "IdentityInfo",
"content": {
"fields": [
{ "key": "firstName", "label": "First Name" },
{ "key": "lastName", "label": "Last Name" },
{ "key": "emailAddress", "label": "Email" }
]
}
},
{
"type": "NextButton",
"content": { "label": "Continue" }
}
]
},
{
"name": "Additional Details",
"components": [
{
"type": "Dropdown",
"content": {
"question": "What is your role?",
"options": ["Engineering", "Product", "Design", "Marketing", "Sales", "Other"]
}
},
{
"type": "NextButton",
"content": { "label": "Submit" }
}
]
}
]
}'
Body Parameters
The ID of an existing form to use as a style template. The generated form inherits all visual settings (fonts, colors, backgrounds, component styles) from this form.
Display name for the generated form.
Array of step objects (minimum 2). Each step represents a page/screen in the form. Show Step object properties
Display name for the step.
Array of component objects (minimum 1). Each component is a form element within the step. Show Component object properties
Component-specific content. The shape depends on the component type.
Supported Component Types
Single-line text input. Field Type Description questionstring The question/label text
Multi-line text area. Field Type Description questionstring The question/label text
Collects identity fields (name, email, company, etc.). This component has a strict schema — only the fields array is accepted. Field Type Required Description fieldsarray Yes Array of field objects fields[].keystring Yes Field identifier. Valid keys: "firstName", "lastName", "fullName", "emailAddress", "workEmailAddress", "phoneNumber", "companyName", "numberOfEmployees", "websiteUrl", "title", "streetAddress", "aptSuiteEtc", "city", "state", "country", "zipCode", "companyRevenue", "profilePictureUrl" fields[].labelstring Yes Display label fields[].placeholderstring No Placeholder text fields[].includeDialCodeboolean No Include dial code selector (for phone fields) fields[].defaultDialCodeCountrystring No Default country for dial code fields[].blockPersonalEmailsboolean No Block personal email domains (for email fields) fields[].revealAfterstring No Key of another field that must be filled before this one is shown
Selection Components
Dropdown select menu. Requires at least one option. Field Type Required Description questionstring No The question/label text optionsstring[] Yes Array of dropdown options (at least 1). You can also use choices as an alias. placeholderstring No Placeholder text isMultiboolean No Allow multiple selections hideQuestionboolean No Hide the question label
Single or multi-select options question. Field Type Description questionstring The question/label text choicesstring[] Array of choice options. You can also use options as an alias. subheadingstring Subheading text below the question isMultiboolean Allow multiple selections
Scheduling Components
Embeds a calendar scheduling widget (supports Calendly, Cal.com, HubSpot, SavvyCal, RevenueHero, and more). Requires a calendar URL. Field Type Required Description dataUrlstring Yes The calendar scheduling URL. You can also use url or calendarUrl as aliases. messagestring No Message displayed above the calendar calendarTypestring No Calendar provider: "Calendly", "Cal", "Hubspot", "SavvyCal", "RevenueHero", "ReclaimAI", "Clari", "ChiliCal" prefillEmailboolean No Auto-fill email from earlier form steps
Navigation Components
Button to advance to the next step. Field Type Description labelstring Button text (alias for buttonText)
Display Components
A text header displayed at the top of a step. Field Type Description titlestring The heading text subheadingstring Optional subheading text below the title
A block of disclaimer or legal text. Field Type Description textstring The disclaimer text content
Other Components
Additional component types are supported: EmailForm, FileUploader, GraphicOptions, PasswordInput, and more. These follow the same pattern — pass the type and relevant content fields.
Response
Whether the form was created successfully.
Show Result object properties
Show Form object properties
Unique identifier for the generated form.
The public URL path for the form (e.g., /s/{formId}).
Example Response
{
"success" : true ,
"result" : {
"form" : {
"id" : "cm5abc123def456" ,
"url" : "/s/cm5abc123def456"
}
}
}
Error Responses
400 - Invalid Request
404 - Source Form Not Found
{
"message" : "Invalid request body" ,
"errors" : [
{
"message" : "CalendlyScreen requires a calendar URL (via 'dataUrl', 'url', or 'calendarUrl')" ,
"path" : [ "steps" , 0 , "components" , 1 , "content" ]
}
]
}
Create a lead capture form with a scheduler step:
curl -X POST 'https://forms.withsurface.com/api/v1/environments/{environmentId}/forms/generate' \
-H 'x-api-key: your-api-key-here' \
-H 'Content-Type: application/json' \
-d '{
"sourceFormId": "your-source-form-id",
"name": "Demo Booking Form",
"steps": [
{
"name": "Your Info",
"components": [
{
"type": "IdentityInfo",
"content": {
"fields": [
{ "key": "firstName", "label": "First Name" },
{ "key": "lastName", "label": "Last Name" },
{ "key": "emailAddress", "label": "Work Email" },
{ "key": "companyName", "label": "Company" }
]
}
},
{
"type": "NextButton",
"content": { "label": "Book a Demo" }
}
]
},
{
"name": "Schedule",
"components": [
{
"type": "CalendlyScreen",
"content": {
"dataUrl": "https://calendly.com/your-team/30min",
"message": "Pick a time that works for you"
}
}
]
}
]
}'