Every NueForm webhook request sends a JSON payload in the request body. This page documents the complete payload schema for each event type.
Common Structure
All webhook payloads share these top-level fields:
| Field | Type | Description |
|---|---|---|
event | string | The event type (e.g., form.submitted) |
formId | string | The unique ID of the form |
formTitle | string | The title of the form at the time of submission |
responseId | string | The unique ID of the response |
answers | array | Array of answer objects |
submittedAt | string | ISO 8601 timestamp of when the event was dispatched |
form.submitted Payload
This is the payload sent when a respondent submits a complete form response.
Full Example
{
"event": "form.submitted",
"formId": "507f1f77bcf86cd799439011",
"formTitle": "Customer Feedback Survey",
"responseId": "507f1f77bcf86cd799439022",
"answers": [
{
"questionId": "507f1f77bcf86cd799439033",
"value": "Jane Doe"
},
{
"questionId": "507f1f77bcf86cd799439044",
"value": "jane@example.com"
},
{
"questionId": "507f1f77bcf86cd799439055",
"value": 4
},
{
"questionId": "507f1f77bcf86cd799439066",
"value": "The onboarding flow was smooth and intuitive."
},
{
"questionId": "507f1f77bcf86cd799439077",
"value": ["Feature A", "Feature C"]
},
{
"questionId": "507f1f77bcf86cd799439088",
"value": true
}
],
"submittedAt": "2025-03-15T14:32:07.123Z"
}
Field Reference
Top-Level Fields
event --- string
Always "form.submitted" for this event type.
formId --- string
The MongoDB ObjectId of the form. This is a 24-character hexadecimal string.
formTitle --- string
The human-readable title of the form at the time the webhook fires. Note that if you rename the form later, previously delivered webhooks will still contain the old title.
responseId --- string
The MongoDB ObjectId of the stored response. You can use this to fetch the full response via the Responses API or as an idempotency key to deduplicate webhook deliveries.
submittedAt --- string
ISO 8601 timestamp indicating when the webhook was dispatched. This is generated at dispatch time and will be very close to (but not necessarily identical to) the response's submittedAt field in the database.
Answer Objects
Each entry in the answers array represents a single question's response:
| Field | Type | Description |
|---|---|---|
questionId | string | The MongoDB ObjectId of the question |
value | any | The respondent's answer (format varies by question type) |
Answer Values by Question Type
The value field in each answer object varies depending on the question type. Here is the format for each type:
Text Inputs
| Question Type | Value Type | Example |
|---|---|---|
short_text | string | "Jane Doe" |
long_text | string | "I really enjoyed the product..." |
email | string | "jane@example.com" |
phone | string | "+1 (555) 123-4567" |
number | number | 42 |
url | string | "https://example.com" |
Choice Questions
| Question Type | Value Type | Example |
|---|---|---|
multiple_choice (single) | string | "Option A" |
multiple_choice (multi) | array<string> | ["Option A", "Option C"] |
dropdown | string | "United States" |
yes_no | boolean | true |
picture_choice (single) | string | "choice_id_abc123" |
picture_choice (multi) | array<string> | ["choice_id_abc123", "choice_id_def456"] |
For multiple_choice questions, the value is a single string when allowMultiple is false, and an array of strings when allowMultiple is true. If the respondent selects the "Other" option, the array will contain their free-text entry as a string.
Rating Questions
| Question Type | Value Type | Example | Range |
|---|---|---|---|
rating | number | 4 | 1 to steps (default 5) |
opinion_scale | number | 7 | min to max |
nps | number | 9 | 0 to 10 |
Date and Time
| Question Type | Value Type | Example |
|---|---|---|
date | string | "2025-03-15" |
The date string format matches the dateFormat property configured on the question (defaults to YYYY-MM-DD).
Legal and Statements
| Question Type | Value Type | Example |
|---|---|---|
legal | boolean | true |
statement | string | "" (always empty --- statements collect no data) |
Ranking
| Question Type | Value Type | Example |
|---|---|---|
ranking | array<string> | ["Speed", "Price", "Quality"] |
The array reflects the respondent's chosen order, from first to last.
Matrix
| Question Type | Value Type | Example |
|---|---|---|
matrix | object | { "Speed": "Satisfied", "Price": "Neutral" } |
The object maps row labels to the selected column label for each row.
File Upload
| Question Type | Value Type | Example |
|---|---|---|
file_upload | string | "https://storage.nueform.com/uploads/abc123.pdf" |
The value is the URL of the uploaded file in NueForm's storage.
Signature and Drawing
| Question Type | Value Type | Example |
|---|---|---|
signature | string | "data:image/png;base64,iVBOR..." |
drawing | string | "data:image/png;base64,iVBOR..." |
Both return a base64-encoded PNG data URI of the captured image.
Recording
| Question Type | Value Type | Example |
|---|---|---|
recording | string | "https://storage.nueform.com/recordings/abc123.webm" |
The value is the URL of the uploaded recording file.
Composite Questions
Composite question types (contact_info, address, question_group, multi_question_page) produce multiple answer entries in the answers array --- one for each sub-field. Each sub-field answer uses the sub-field's own questionId.
For example, a contact_info question might produce:
[
{ "questionId": "first_name", "value": "Jane" },
{ "questionId": "last_name", "value": "Doe" },
{ "questionId": "email", "value": "jane@example.com" },
{ "questionId": "phone_number", "value": "+1 555-0100" },
{ "questionId": "company", "value": "Acme Inc." }
]
Quiz Results
For forms running in a quiz mode (knowledge_quiz, lead_qualification, or match_quiz), the stored response includes a quizResults object. While this object is not directly included in the webhook payload, you can retrieve it via the Responses API using the responseId from the webhook.
The quizResults object has the following structure:
{
"formMode": "knowledge_quiz",
"score": 7,
"correctAnswers": 7,
"totalScorableQuestions": 10,
"maxScore": 10,
"matchedEndingId": "507f1f77bcf86cd799439099"
}
| Field | Type | Description |
|---|---|---|
formMode | string | The quiz mode: knowledge_quiz, lead_qualification, or match_quiz |
score | number | The respondent's total score |
correctAnswers | number | Number of questions answered correctly (knowledge quiz only; 0 for other modes) |
totalScorableQuestions | number | Total number of questions that contribute to the score |
maxScore | number | The maximum achievable score |
matchedEndingId | string or undefined | The ID of the end screen shown to the respondent based on their score |
endingTallies | object or undefined | Match quiz only: maps each end screen ID to its tally count |
Metadata
The stored response may also include a metadata object containing hidden fields passed via URL parameters. This is available via the Responses API but is not included in the webhook payload.
{
"hiddenFields": {
"utm_source": "google",
"utm_campaign": "spring_sale",
"user_id": "ext_12345"
}
}
To access metadata for a webhook-delivered response, fetch it using the responseId:
curl https://app.nueform.com/api/v1/forms/FORM_ID/responses/RESPONSE_ID \
-H "Authorization: Bearer nf_your_api_key"
HTTP Headers
Every webhook request includes these HTTP headers:
| Header | Value |
|---|---|
Content-Type | application/json |
X-NueForm-Signature | HMAC-SHA256 hex digest of the raw request body |
See Verification for how to validate the signature.
Payload Size
Webhook payloads are typically small (under 10 KB). The size depends primarily on the number of questions and the length of text answers. File upload answers contain URLs (not file contents), so they do not significantly increase payload size.
Next Steps
- Verification --- Validate webhook signatures
- Testing --- Test webhook payloads locally
- Events --- Event types and delivery guarantees