OCNORA
opsbeginner10 min setupby Mantle

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.

How it works

What it does

  • Webhook events-in (deduplicated on event_id via idempotency_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.

Setup

  • Pick your MySQL connection on Upsert into events and set table; adjust keys / row for your columns.
  • Tighten the JSON schema on Validate payload to your event contract.

Nodes 3

  1. 01Event intrigger.webhookTrigger
  2. 02Validate payloaddata.json_validateData
  3. 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"
        },
        "connection_id": null,
        "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"
        },
        "connection_id": null,
        "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"
          }
        },
        "connection_id": null,
        "worker_type": "generic-worker",
        "position": {
          "x": 700,
          "y": 220
        }
      }
    ],
    "edges": [
      {
        "from": "webhook",
        "to": "validate"
      },
      {
        "from": "validate",
        "to": "upsert"
      }
    ]
  }
}

Use it, then make it yours.

Templates install as drafts. Change anything, and Workflow Health re-checks the graph on every save.