NisuformDocs

Forms API

List, create, update, duplicate and delete forms, rotate form keys and send test submissions with the Nisuform API.

Every request needs an API key and works in the key's team.

The form object

{
  "id": "2f6b7c1e-9a4d-4c3e-8b21-7d5e6f4a3b2c",
  "name": "Website contact",
  "type": "contact",
  "emoji": "✉️",
  "key": "k3yz8q2m4n6p0r5t7v9w",
  "endpoint": "https://api.nisuform.com/s/k3yz8q2m4n6p0r5t7v9w",
  "status": "active",
  "closedReason": null,
  "notifyEnabled": true,
  "notifyEmail": null,
  "fields": [
    { "id": "name", "type": "text", "label": "Name", "required": true },
    { "id": "email", "type": "email", "label": "Email", "required": true },
    { "id": "message", "type": "textarea", "label": "Message", "required": true }
  ],
  "createdAt": "2026-09-29T10:00:00.000Z",
  "updatedAt": "2026-09-29T10:00:00.000Z"
}

The example is shortened. A form has these fields:

FieldDescription
idThe form ID, used in API paths.
nameThe name shown in the dashboard and in notification emails.
typecontact, waitlist, feedback, rsvp or custom. Picks the analytics summary.
emojiThe form's icon in the dashboard, or null.
keyThe public form key.
endpointThe URL your form posts to, https://api.nisuform.com/s/{key}.
statusactive or paused.
closedReasonWhy the form stopped taking submissions: manual, max_submissions, auto_close_date, or null while it is open.
maxSubmissionsClose after this many submissions, or null.
autoCloseAtClose at this time, or null.
closedMessagePro. Shown to visitors after the form closed, or null for the default.
notifyEnabledWhether new submissions are emailed.
notifyEmailPro. Where notifications go, or null for the team owner's email.
notifySubjectSubject of notification emails. Supports placeholders.
notifyFromNameSender name of notification emails.
autoreplyEnabledPro. Whether people who submit get an auto-reply.
autoreplySubject, autoreplyBodyPro. The auto-reply email, or null.
completionModeWhat browser posts see after submitting: default, message or redirect. See After submit.
completionTitle, completionMessagePro. Your thank-you page text, or null.
redirectUrlPro. Where browser posts are sent after submitting, or null.
fieldsThe form's fields, used to validate answers and label them. null accepts any fields. See Fields and validation.
designLook and copy of the styled embed from the form builder: theme, accent, title, description, submitLabel and successMessage.
allowedOriginsWebsites allowed to submit. Empty allows every website. See Access rules.
blockedIpsIP addresses whose submissions are dropped.
blockedCountriesTwo-letter country codes whose submissions are dropped.
captchaEnabledWhether a Turnstile token is required.
captchaProviderturnstile or null.
captchaSiteKeyYour Turnstile site key, or null.
captchaSecretKeySetWhether a Turnstile secret key is saved. The secret itself is never returned.
dontStoreIpWhether visitors' IP addresses are left out of submissions.
allowUploadsPro. Whether the form accepts file uploads.
uploadLimitMbLargest file size in MB.
userIdWho created the form.
createdAt, updatedAtWhen the form was created and last changed.

List forms

GET /v1/forms

Returns the team's forms, newest first, in a shorter shape.

{
  "forms": [
    {
      "id": "2f6b7c1e-9a4d-4c3e-8b21-7d5e6f4a3b2c",
      "name": "Website contact",
      "type": "contact",
      "emoji": "✉️",
      "status": "active",
      "key": "k3yz8q2m4n6p0r5t7v9w",
      "endpoint": "https://api.nisuform.com/s/k3yz8q2m4n6p0r5t7v9w",
      "createdAt": "2026-09-29T10:00:00.000Z",
      "submissionCount": 42
    }
  ]
}

submissionCount leaves out spam and test submissions.

Create a form

POST /v1/forms
Body fieldRequiredDescription
nameYes1 to 200 characters.
typeNocontact (default), waitlist, feedback, rsvp or custom. Sets the starter fields and embed design. custom starts with no fields.
curl https://api.nisuform.com/v1/forms \
  -H "Authorization: Bearer $NISUFORM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Beta waitlist","type":"waitlist"}'

Answers 201 with the new form. Point your form at its endpoint. On the Free plan, a team that already has 3 forms gets 402.

Get a form

GET /v1/forms/{id}

Returns the full form object, or 404.

Update a form

PATCH /v1/forms/{id}

Send only the fields you want to change. Leaving a field out keeps it as it is, and null clears it. Answers with the updated form.

curl -X PATCH https://api.nisuform.com/v1/forms/FORM_ID \
  -H "Authorization: Bearer $NISUFORM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"paused","notifySubject":"New lead: {{field.name}}"}'
Body fieldAccepts
name1 to 200 characters.
typecontact, waitlist, feedback, rsvp or custom. Changing it keeps your fields.
statusactive or paused. Resuming a form clears closedReason.
emojiUp to 32 characters, or null.
maxSubmissions1 to 1,000,000, or null.
autoCloseAtAn ISO 8601 time, or null.
closedMessagePro. 1 to 500 characters, or null.
notifyEnabledtrue or false.
notifyEmailPro. An email address, or null.
notifySubject1 to 500 characters.
notifyFromName1 to 100 characters. Pro to change it from the default.
autoreplyEnabledtrue or false. Pro to turn it on.
autoreplySubjectPro. 1 to 500 characters, or null.
autoreplyBodyPro. 1 to 5,000 characters, or null.
completionModedefault, message or redirect.
completionTitlePro. 1 to 200 characters, or null.
completionMessagePro. 1 to 2,000 characters, or null.
redirectUrlPro. An http or https URL. null or "" removes it.
fieldsUp to 30 fields, or null. Replaces every field.
designThe whole design object. Replaces the current design.
allowedOriginsUp to 50 website addresses. Paths are dropped, so https://example.com/contact is saved as https://example.com.
blockedIpsUp to 1,000 IP addresses.
blockedCountriesUp to 300 two-letter country codes.
captchaSiteKeyYour Turnstile site key, or null.
captchaSecretKeyYour Turnstile secret key, or null. Write only.
captchaEnabledtrue or false. Turning it on needs a site key and a secret key, saved before or in the same request.
dontStoreIptrue or false.
allowUploadstrue or false. Pro to turn it on.
uploadLimitMb1 to 100. Pro to change it from 10.

A Pro setting on a Free team answers 402 and nothing is saved.

Fields

Each field has an id, which is the name your form sends, a type, a label and required. Types are text, email, textarea, number, date, select, radio, checkbox, rating, tel, url and file.

{
  "fields": [
    { "id": "email", "type": "email", "label": "Email", "required": true },
    { "id": "plan", "type": "select", "label": "Plan", "required": false, "options": ["Starter", "Team"] },
    { "id": "score", "type": "rating", "label": "How likely are you to recommend us?", "required": true, "max": 10 }
  ]
}
Field optionTypesDescription
placeholderAllUp to 200 characters.
helpTextAllUp to 500 characters.
minLength, maxLengthtextAnswer length. textarea takes maxLength.
patterntextA regular expression the answer must match.
min, maxnumberSmallest and largest allowed value.
optionsselect, radio1 to 100 choices.
maxratingNumber of stars, 3 to 10. Defaults to 5.

Field IDs start with a letter and use letters, digits, - or _, up to 64 characters, and must be unique. See Fields and validation for how answers are checked.

Delete a form

DELETE /v1/forms/{id}

Deletes the form with all its submissions and uploaded files, and answers { "ok": true }. Its endpoint stops accepting submissions right away. This can't be undone.

Duplicate a form

POST /v1/forms/{id}/duplicate
Body fieldRequiredDescription
nameSuffixNoAdded to the copy's name. Defaults to " copy".

Copies the form's settings, fields, design and integrations into a new form with a new key. Google Sheets isn't copied, and a copied webhook gets its own signing secret. The copy starts open, without a submission limit or close date, and without submissions. Answers 201 with the copy. It counts toward the Free plan's form limit.

Rotate the form key

POST /v1/forms/{id}/rotate-key

Gives the form a new key and answers with the updated form. The old endpoint stops accepting submissions right away, so update your website with the new endpoint first.

Send a test submission

POST /v1/forms/{id}/test-submissions

Stores a sample submission marked as a test and runs the form's notifications and integrations, so you can check your setup. Answers 201 with { "submissionId": "..." }. Test submissions don't count toward your monthly limit.