Events

The unified shape every inbound event takes in Nevo.

Every inbound event — webhook, email, future source — reaches your service as the same object: a Nevo Event. Branching on the single type field is how you route by kind.

Schema

{
  "id": "evt_01hk8…",
  "schema": "nevo.event.v1",
  "type": "webhook.received",
  "origin": "live",
  "created_at": "2026-04-17T19:22:04.123Z",
  "project_id": "…",
  "channel": { "id": "…", "label": "stripe events", "type": "webhook" },
  "data": { /* source-specific payload */ },
  "prompt_ready": "Stripe invoice.paid — $42.00 from acme.co. …",
  "prompt_ready_version": 2
}

Fields

FieldTypeNotes
idstringULID. Stable across live + replay deliveries.
schemastringnevo.event.v1 today. Bumps on breaking changes.
typestringwebhook.received or email.received.
originstringlive or replay. Use for idempotency.
created_atISO 8601Server-side ingest time.
project_idUUIDThe Nevo project this event belongs to.
channelobject{ id, label, type } — which channel received the event.
dataobjectSource-specific payload. Shape varies by type (below).
prompt_readystringLLM-friendly text rendering of the event. See prompt-ready.
prompt_ready_versionintRenderer version stamp. Bumps when we change the renderer.

data shape per type

webhook.received

{
  "method": "POST",
  "path": "/v1/webhook/abc…",
  "headers": { "content-type": "application/json", "stripe-signature": "…" },
  "body_encoding": "json",
  "body": { /* parsed JSON body when Content-Type was JSON */ },
  "body_raw_b64": "",
  "body_size_bytes": 512
}

body_encoding tells you where the body lives:

  • json → parsed payload in body
  • text → raw string in body
  • base64 → original bytes base64-encoded in body_raw_b64

email.received

{
  "resend_email_id": "re_…",
  "message_id": "<abc@mail.example>",
  "from": "alice@acme.com",
  "to": ["support@in.nevo.sh"],
  "matched_address": "support@in.nevo.sh",
  "cc": [],
  "bcc": [],
  "subject": "Re: API limits",
  "text": "can we bump our monthly quota?",
  "html": "<p>…</p>",
  "attachments": [{ "filename": "usage.csv", "content_type": "text/csv", "size_bytes": 1024 }],
  "received_at": "2026-04-17T19:22:03.999Z"
}

Live vs replay

origin is live for freshly-ingested events and replay when an operator re-delivered a historical event from the dashboard.

Delivery

The same event object is pushed to two places:

  • SDK clients connected for the project.
  • HTTP endpoints the project has configured, signed with the channel’s secret.

Either failing doesn’t fail the other. A handler that takes five minutes to process doesn’t block other events — each event gets its own task.