Skip to content

Create a form

POST
/v1/forms
curl --request POST \
--url https://api.submeto.com/v1/forms \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "name": "example", "allowed_origins": [ "n" ], "validate_fields": true, "notifications_enabled": true, "fields": [ { "name": "example", "label": "example", "type": "string", "required": true, "options": {}, "validation": "email" } ] }'

Creates a new form. The form always starts disabled with a database delivery channel; enable it explicitly after configuring fields. Requires the forms:create scope and an Idempotency-Key header. The submission_token is returned only in the initial create response and a matching idempotency replay — never log it.

Idempotency-Key
string
Media typeapplication/json
object
name
required

Must not be greater than 255 characters.

string
allowed_origins

Must not be greater than 255 characters.

Array<string>
Example
[
"n"
]
validate_fields
required
boolean
notifications_enabled
required
boolean
fields
Array<object>
object
name
required

Must match the regex /^[a-z][a-z0-9_]{0,63}$/.

string
label

Must not be greater than 255 characters.

string
nullable
type
required
string
Allowed values: string number date boolean array file
required
boolean
options
One of:
object
key
additional properties
any
validation
string
nullable
Allowed values: email url tel ipv4 ipv6 uuid slug hex_color alpha_numeric integer

Form created

Media typeapplication/json
object
data
object
id
string
name
string
status
string
endpoint_url
string
submission_endpoint
string
allowed_origins
Array<string>
validate_fields
boolean
notifications_enabled
boolean
delivery_channel_types
Array<string>
revision
integer
field_count
integer
submissions_count
integer
unread_count
integer
latest_submission_at
string
nullable
fields
Array<object>
object
id
string
name
string
label
string
type
string
required
boolean
options
string
nullable
validation
object
kind
string
preset
string
position
integer
created_at
string
updated_at
string
created_at
string
updated_at
string
submission_token
string
request_id
string
Example
{
"data": {
"id": "REQUEST_ID",
"name": "Contact Form",
"status": "disabled",
"endpoint_url": "https://api.submeto.com/api/v1/forms/REQUEST_ID/submit",
"submission_endpoint": "https://api.submeto.com/api/v1/forms/REQUEST_ID/submit",
"allowed_origins": [
"https://example.com"
],
"validate_fields": true,
"notifications_enabled": true,
"delivery_channel_types": [
"database"
],
"revision": 1,
"field_count": 2,
"submissions_count": 0,
"unread_count": 0,
"latest_submission_at": null,
"fields": [
{
"id": "REQUEST_ID",
"name": "email",
"label": "Email",
"type": "string",
"required": true,
"options": null,
"validation": {
"kind": "preset",
"preset": "email"
},
"position": 0,
"created_at": "2026-08-31T10:00:00.000Z",
"updated_at": "2026-08-31T10:00:00.000Z"
}
],
"created_at": "2026-08-31T10:00:00.000Z",
"updated_at": "2026-08-31T10:00:00.000Z",
"submission_token": "smto_sub_9f4c8a2e7b1d4c3a"
},
"request_id": "REQUEST_ID"
}

Missing idempotency key

Media typeapplication/json
object
error
object
code
string
message
string
details
object
request_id
string
Example
{
"error": {
"code": "idempotency_key_required",
"message": "The Idempotency-Key header is required.",
"details": {}
},
"request_id": "REQUEST_ID"
}

Form quota reached

Media typeapplication/json
object
error
object
code
string
message
string
details
object
request_id
string
Example
{
"error": {
"code": "form_quota_exceeded",
"message": "The form quota has been reached.",
"details": {}
},
"request_id": "REQUEST_ID"
}

Idempotency conflict

Media typeapplication/json
object
error
object
code
string
message
string
details
object
request_id
string
Example
{
"error": {
"code": "idempotency_conflict",
"message": "The request conflicts with a previous request using the same Idempotency-Key.",
"details": {}
},
"request_id": "REQUEST_ID"
}

Validation failed

Media typeapplication/json
object
error
object
code
string
message
string
details
object
name
Array<string>
request_id
string
Example
{
"error": {
"code": "validation_failed",
"message": "The request validation failed.",
"details": {
"name": [
"The name field is required."
]
}
},
"request_id": "REQUEST_ID"
}