Validated webhook to database
Accept events by webhook, reject malformed payloads with a JSON schema, and upsert the valid ones into a SQL table.
Drag to pan, pinch to zoom. This is the real graph the template installs.
Purpose
Accept events by webhook, reject malformed payloads with a JSON schema, and upsert the valid ones into a SQL table.
How it works
What it does
- Webhook
events-in(deduplicated onevent_idviaidempotency_path). - Validate payload fails the run on schema violations — the offending fields are listed in the step error.
- Upsert into events writes the row keyed on
event_id, so replays are idempotent end to end.
Nodes 3
- 01Event intrigger.webhookTrigger
- 02Validate payloaddata.json_validateData
- 03Upsert into eventsdb.upsertDestination
View template JSON
{
"format": "mantle-workflow/v1",
"id": "ops-webhook-validate-upsert",
"name": "Validated webhook to database",
"graph": {
"nodes": [
{
"id": "webhook",
"type": "trigger.webhook",
"label": "Event in",
"config": {
"slug": "events-in",
"idempotency_path": "event_id"
},
"worker_type": "generic-worker",
"position": {
"x": 60,
"y": 220
}
},
{
"id": "validate",
"type": "data.json_validate",
"label": "Validate payload",
"config": {
"schema": {
"type": "object",
"required": [
"event_id",
"type",
"occurred_at"
],
"properties": {
"event_id": {
"type": "string",
"minLength": 1
},
"type": {
"type": "string"
},
"occurred_at": {
"type": "string"
},
"payload": {
"type": "object"
}
}
},
"on_fail": "error"
},
"worker_type": "generic-worker",
"position": {
"x": 380,
"y": 220
}
},
{
"id": "upsert",
"type": "db.upsert",
"label": "Upsert into events",
"config": {
"table": "events",
"keys": [
"event_id"
],
"row": {
"event_id": "steps.webhook.event_id",
"type": "steps.webhook.type",
"occurred_at": "steps.webhook.occurred_at",
"payload": "steps.webhook.payload"
}
},
"worker_type": "generic-worker",
"position": {
"x": 700,
"y": 220
}
}
],
"edges": [
{
"from": "webhook",
"to": "validate"
},
{
"from": "validate",
"to": "upsert"
}
]
}
}Requirements
The connections and permissions each step needs, from the node contracts in the catalog.
- MySQLUsername & password
Used by Upsert into events.
Credential: the password, or {"password": "…"}
- MySQL/MariaDB only in v1.
Setup
- Pick your MySQL connection on Upsert into events and set
table; adjustkeys/rowfor your columns. - Tighten the JSON schema on Validate payload to your event contract.
Sample input and output
Synthetic examples: node-contract samples or placeholders, never customer data.
Input
The fields the template declares or reads from the request body. Values are placeholders.
{
"event_id": "<event_id>",
"type": "<type>",
"occurred_at": "<occurred_at>",
"payload": {}
}Output
Upsert into events db.upsert
{
"row_count": 0,
"table": ""
}Failure handling
What the graph does when a step fails, read from its retry settings, error branches and error policies.
- Validate payload: invalid input fails the step, so nothing after it runs on bad data.
- A step that fails, after any retries, fails the run. The failed step is kept with its input and error.
See it run, then make it yours.
Templates install as drafts. Edit any step, and Workflow Health re-checks the graph on every save.