Payload schema validation
Describe the payload a workflow expects as a JSON Schema, reject bad trigger requests with a 400 before anything is queued, and apply defaults to gaps.
The payload of a trigger request is free-form JSON that your templates read as {{payload.<name>}}. A payload schema describes what a workflow expects there, as a JSON Schema. With validation enforced, a trigger whose payload does not match is rejected at the API with a 400 and nothing is sent, instead of rendering a notification with an empty or wrong value.
A schema does three jobs:
- Validates trigger requests, when you switch on Enforce schema validation.
- Fills in defaults for properties the request left out.
- Documents the workflow's inputs: the editor suggests the schema's properties as
payloadvariables when you write step content or step conditions.
Define a schema in the dashboard
- Open the workflow and choose Manage payload schema in the workflow's side panel. This opens the Manage workflow schema panel. It is available for workflows built in the dashboard.
- Add properties with Add property. A new workflow has no properties yet, so the panel starts empty.
- For each property, pick a type and, in its settings, a Required flag, a default value and a format.
- Turn on Enforce schema validation so the API rejects non-matching triggers.
Instead of typing properties, you can start from real data: Import schema from recent payload builds a schema from a payload the workflow actually received, and Import from JSON object builds one from JSON you paste.
The property types are String, Integer, Number, Boolean, Enum, Array, Object and Null. A property can also carry a format such as an email address or a date-time.
What the API enforces
When a workflow has a schema and Enforce schema validation is on, POST /v1/events/trigger checks the request's payload against the schema before the trigger is accepted. Validation reports every problem at once, not only the first.
For this schema:
{
"type": "object",
"properties": {
"orderId": { "type": "string" },
"total": { "type": "number" },
"currency": { "type": "string", "default": "USD" }
},
"required": ["orderId", "total"]
}a trigger with "payload": { "total": "ten" } is rejected with a 400 of type PAYLOAD_VALIDATION_ERROR:
{
"statusCode": 400,
"timestamp": "2026-10-13T12:00:00.000Z",
"path": "/v1/events/trigger",
"message": "Payload validation failed: root.orderId: must have required property 'orderId'; total: must be number",
"type": "PAYLOAD_VALIDATION_ERROR",
"errors": [
{
"field": "root.orderId",
"message": "must have required property 'orderId'",
"value": { "total": "ten" },
"schemaPath": "#/required"
},
{
"field": "total",
"message": "must be number",
"value": "ten",
"schemaPath": "#/properties/total/type"
}
]
}The response body also echoes the workflow's schema under schema (omitted above for brevity). Each entry in errors names the field that failed, the validator's message, the offending value and the schemaPath of the rule. A rejected request is also recorded as a failed request in your activity logs.
A valid payload goes through with defaults applied. Sending { "orderId": "A1", "total": 10 } to the workflow above delivers currency as "USD".
Validation applies to single triggers and to each event of a bulk trigger. Unknown properties are allowed unless the schema sets additionalProperties to false.
Manage the schema over the API
A workflow's schema is the payloadSchema field, and enforcement is the validatePayload boolean, both on the workflow create and update requests of the workflows API. payloadSchema must be a valid JSON Schema object, or null to clear it.
{
"name": "Order shipped",
"validatePayload": true,
"payloadSchema": {
"type": "object",
"properties": { "orderId": { "type": "string" } },
"required": ["orderId"]
}
}If a schema is saved but validatePayload is off, triggers are not checked; the schema still drives the editor's suggestions.
Step conditions
Run a workflow step only when its conditions are met. Build rules on the payload, subscriber and context in the visual editor, and see how skips behave.
Environment variables
Store config values and secrets once, give each environment its own value, and reference them in workflows as {{env.KEY}}. Dashboard and API guide.