Webhook Relay Service API Data Model: Entities, Delivery, and Health

By William Zhu & the InfiniSynapse Data Team · Last updated: 2026-09-15 · Last verified: 2026-09-15 · About / team · Credentials: GitHub @allwefantasy · Builder notes for vibe-coded products moving to real APIs—not a brochure. Peer replications of the billing case metrics welcome via editorial corrections. OSS: GitHub InfiniSynapse.

Webhook relay service API data model: five entities, delivery, and endpoint health


Table of Contents

  1. TL;DR
  2. Key Definition
  3. Core Entities
  4. Monitoring and Alerts
  5. Event Envelope Schema
  6. Delivery and Retry Model
  7. Idempotency and Signatures
  8. Architecture Sketch
  9. Downloadable assets
  10. Readiness Scorecard
  11. 21-Day Rollout
  12. Failure Modes
  13. InfiniSynapse Connection
  14. Case Study
  15. FAQ
  16. Conclusion

TL;DR

Direct answer: A webhook relay API data model is five tables—endpoint, subscription, event, delivery, attempt—so you can query success rate and delivery statistics per endpoint, not grep logs. Persist the event first; health is attempts.ok / attempts.total on a time window, plus last-success and dead-letter rate.

Jump to: five entities · health metrics · starter pack

  • The API data model centers on five entities: endpoint, subscription, event, delivery, attempt.
  • Store raw payload + normalized envelope; never lose events when downstream is down.
  • Idempotency keys and signature metadata belong in the schema, not application comments.
  • Expose relay status via API so buyers debug without your on-call paging you.

Who this is for: teams building or buying webhook relay infrastructure. What you'll learn: entities, SQL/TypeScript shapes, scorecard, rollout.

Compare API Data Integration when inbound vendor webhooks are only one integration leg.

Key Definition

Key Definition: A webhook relay service API data model is the structured representation of how a relay accepts events, maps them to subscriber endpoints, records delivery attempts, and exposes queryable status over HTTP—not an undocumented queue of outbound fetch calls.

That API data model matters when Stripe, Shopify, or your own product emits events faster than customer endpoints acknowledge them—and you need replay, audit, and SLA proof.

Webhook security aligns with OWASP API Security Top 10 when relay endpoints accept unsigned or replayed payloads.

If you have spent time in r/vibecoding, r/dataengineering, r/SaaS, and r/stripe, you have seen these arguments. Here is what held up when vibe-coded products relayed vendor events to customers—not the "just forward the body" hype.

Core Entities

Every solid relay schema implements these tables (names vary; relationships do not):

EntityPurposeKey fields
endpointCustomer URL + authurl, secret, status, tenant_id
subscriptionFilter + route rulesevent_types[], endpoint_id, enabled
eventImmutable inbound recordsource, type, payload, received_at
deliveryOne event → one endpoint jobevent_id, endpoint_id, state, next_attempt_at
attemptSingle HTTP trydelivery_id, status_code, duration_ms, error

Relay rule: events are append-only; deliveries transition state; attempts are append-only audit.

Relational design follows classical event-sourcing guidance in Google SRE—operate the relay like a small data pipeline, not a cron script.

Hosted products (Hookdeck, RelayHub, and similar) name the same five ideas differently. Map their entities onto this neutral API data model before you copy a vendor SDK into your schema.

Five-entity webhook relay API data model

Monitoring and Alerts

Track relay health from the same five tables—not from application logs. Endpoint health metrics and delivery statistics are queries over attempt and delivery.

SignalHow to computeAlert threshold
Success rateattempts.ok (HTTP 2xx) / attempts.total in the window, grouped by endpoint_id< 99% over 15m
Last successmax(attempt.succeeded_at) per endpoint_idstale vs your SLA
Dead letter ratedead_letter deliveries / deliveries over 1h> 1% over 1h
Attempt 5xx5xx attempts / all attempts over 15m> 5% over 15m
Ingress lagevent.received_at − vendor timestamp; p95 persist timep95 > 500ms
Queue depthcount of delivery rows in pending / scheduledsustained growth 30m
Signature verify failuresevent.signature_verified = false vs 7d baselinespike vs baseline

Dashboard one row per endpoint_id with last success timestamp—support resolves "we did not get the webhook" without database access.

Endpoint health metrics computed from attempt and delivery rows

Event Envelope Schema

Normalize vendor payloads into a versioned envelope before fan-out:

type RelayEvent = {
  id: string;              // uuid
  source: "stripe" | "shopify" | "internal";
  type: string;            // e.g. invoice.paid
  idempotency_key: string; // vendor event id
  received_at: string;     // ISO 8601
  payload: Record<string, unknown>;
  payload_hash: string;    // sha256 for dedupe
};

Your relay HTTP API exposes:

  • POST /v1/events — ingest (internal or signed vendor ingress)
  • GET /v1/events/{id} — support lookup
  • GET /v1/deliveries?state=failed — ops dashboard

Publish OpenAPI even if the relay is internal—agent and frontend authors need the same contract as Production Ready APIs. The envelope is part of the API data model, not a comment in the worker.

Delivery and Retry Model

Delivery state machine for relay deliveries:

pending → delivering → delivered
                    ↘ failed → scheduled (backoff) → delivering
                    ↘ dead_letter (max attempts)

Retry policy stored per subscription or endpoint:

type RetryPolicy = {
  max_attempts: number;       // default 8
  backoff_seconds: number[];    // [60, 300, 900, 3600, ...]
  timeout_ms: number;         // default 10000
};

Each attempt row captures response headers (truncated), body snippet (max 4KB), and duration_ms. Support teams replay from event.payload, not from log grep. That attempt audit is why the API data model can answer success rate without opening a log stack.

NIST SP 800-53 audit expectations apply when relay events contain financial or PII data.

Idempotency and Signatures

Ingress must dedupe against the durable event store. Idempotency keys belong in the API data model, not in a worker comment:

  • Unique index on (source, idempotency_key)
  • Reject or no-op duplicate within 24h window
  • Store signature_verified: boolean and signature_algorithm on event

Verification checklist:

  1. Constant-time compare of HMAC signature
  2. Timestamp tolerance (±5 minutes) against replay
  3. Raw body preserved before JSON parse for signature input

Downstream customers receive a new signing secret per endpoint—your relay re-signs or forwards vendor signature in metadata field X-Relay-Original-Signature documented in OpenAPI.

Governance ties to API Data Governance when multiple tenants share relay infrastructure.

Architecture Sketch

[ Vendor webhook ] --> [ Ingress API ] --> [ events table ]
                              |
                              v
                     [ Router / subscriptions ]
                              |
                              v
                     [ delivery queue ]
                              |
                              v
                     [ Worker pool ] --> [ Customer endpoint ]
                              |
                              v
                     [ attempts table ] --> [ metrics / alerts ]

Webhook relay API data model architecture — ingress, events, subscriptions, deliveries, attempts

Workers pull delivery rows where next_attempt_at <= now() with FOR UPDATE SKIP LOCKED. Scale workers horizontally; never double-deliver without idempotency headers to customers. The sketch is the same API data model as the five-entity table—ingress writes event, the router writes delivery, workers append attempt.

Downloadable assets

Use these first-party starter files with the relay schema (CC BY 4.0; desk composite, not a vendor SLA):

AssetFormatLink
Postgres migration (events + deliveries + attempts)SQL001_relay_api_data_model.sql
Relay contractOpenAPI 3 YAMLopenapi-relay-api-data-model.yaml
Smoke-test requestsPostman Collection v2.1postman-relay-api-data-model.json

No hosted video or podcast on this page—the #tldr block is the speakable short answer. Import the OpenAPI into your gateway and run the SQL migration before promising enterprise webhook SLAs. The files implement this API data model; they are not a hosted relay.

Readiness Scorecard

Rate API data model readiness for webhook relay (1 point each):

CheckPass?
Events stored before delivery attempt
Dedupe on vendor event id
Delivery state machine with dead letter
Per-attempt audit row
Configurable retry backoff
Customer-facing delivery status API
Signature verify on ingress
PII redaction in attempt body logs
Replay tool for support (single delivery)
Contract tests on envelope schema

8–10: production beta. 5–7: internal pilot. Below 5: still forwarding in-request.

21-Day Rollout

HowTo: ship a production-shaped relay API data model in four weeks. Work the steps in order.

  1. Week 1 — Persist first. Apply the SQL migration; stand up signed ingress; enforce unique (source, idempotency_key).
  2. Week 2 — Deliver async. Add delivery worker + attempt audit + backoff; never POST to customers inside the ingress request.
  3. Week 3 — Expose status. Ship GET /v1/deliveries filters and a minimal dashboard; import the OpenAPI + Postman pack for contract tests.
  4. Week 4 — Operate. Replay tooling, dead-letter alerts, and a quarterly drill on a random event_id.

Skipping the event table and posting directly to customer URLs is the top anti-pattern in vibe-coded billing integrations. A thin HTTP forward is not an API data model.

SQL Schema Starter

Minimal Postgres DDL teams use when implementing relay persistence (same tables as the downloadable migration):

CREATE TABLE relay_events (
  id uuid PRIMARY KEY,
  source text NOT NULL,
  type text NOT NULL,
  idempotency_key text NOT NULL,
  payload jsonb NOT NULL,
  payload_hash text NOT NULL,
  received_at timestamptz NOT NULL DEFAULT now(),
  UNIQUE (source, idempotency_key)
);

CREATE TABLE relay_deliveries (
  id uuid PRIMARY KEY,
  event_id uuid REFERENCES relay_events(id),
  endpoint_id uuid NOT NULL,
  state text NOT NULL,
  next_attempt_at timestamptz,
  attempt_count int NOT NULL DEFAULT 0
);

Index (state, next_attempt_at) for worker polling. Partition relay_attempts by month if volume exceeds millions of rows—archival policy belongs in your governance doc alongside TTL for raw payloads. Keep the API data model in SQL first; dashboards can wait a week.

Customer Endpoint Registration

Expose self-service endpoint CRUD so buyers do not email you to rotate URLs. Endpoint rows are first-class in the API data model:

  • POST /v1/endpoints — register URL, return signing secret once
  • PATCH /v1/endpoints/{id} — disable during maintenance
  • POST /v1/endpoints/{id}/rotate-secret — invalidate old HMAC key

Validate URLs (HTTPS only in production), optionally pin allowed IP ranges for enterprise tiers. Return structured 422 when URL fails HEAD/health probe—catch typos before first real event.

Operating Model

Assign one relay owner—even in a small team. Operations sit on the same API data model as ingress:

  • Review dead letter queue daily during pilot
  • Publish status page component for relay lag
  • Coordinate vendor webhook secret rotation with endpoint secret rotation docs
  • Run quarterly replay drill: pick random event_id, verify customer receives re-delivery

Fifteen minutes daily on dead letters prevents month-two enterprise escalations.

Buyer Questions Before Launch

QuestionStrong answer
Can we replay a failed delivery without duplicate side effects?Yes, with documented idempotency header
Do you store events if our endpoint is down?Yes, with retention SLA
Can we verify signatures on ingress and egress?Yes, algorithms documented in OpenAPI
Is delivery status queryable via API?Yes, filter by state and time range
What happens at max retries?Dead letter + alert; manual replay supported

Procurement teams evaluating relay vendors ask these before signing—your internal API data model should answer them even if you are not selling relay as a standalone product yet.

Failure Modes

Failure 1: No durable event store — vendor retry storms lose data. Fix: persist first, deliver second. Without an event row there is no API data model to query.

Failure 2: Unbounded retry — hammer dead endpoints forever. Fix: max_attempts + dead letter queue.

Failure 3: Logging full payloads — PCI/PII leak in log stack. Fix: hash + redact fields in attempt rows.

Failure 4: Missing idempotency on customer POST — duplicate charges downstream. Fix: relay sends Idempotency-Key: {event.id} header contract.

Failure 5: Opaque failures — customers open tickets with no delivery id. Fix: expose a delivery status API backed by the same API data model.

Failure 6: Clock skew on signature replay — valid events rejected. Fix: NTP on ingress nodes; document tolerance in customer integration guide.

Cross-check UK NCSC guidelines for secure AI system development when relay payloads feed agent workflows downstream.

InfiniSynapse Connection

When relayed events trigger long analysis (dispute evidence, usage reconciliation), route heavy work to InfiniSynapse Server API while the relay layer ACKs vendor ingress in milliseconds. See What Is Data API for async job boundaries.

Case Study: Billing Events

A vibe-coded billing product forwarded Stripe webhooks synchronously to customer URLs—lost events during customer maintenance windows.

Fix over 20 days:

  • Implemented the full five-entity API data model (subscription, event, delivery, attempt, endpoint)
  • Ingress ACK within 200ms; delivery async
  • Customer dashboard: GET /v1/deliveries?state=failed
  • Replay button creates new delivery row, preserves original event

Measured:

  • Lost events: eliminated (was ~2% during customer outages)
  • Support tickets "missing webhook": −67%
  • p95 ingress latency: 180ms
  • Dead letter rate: 0.4% (mostly invalid customer URLs)

Week three addition: webhook simulation UI—customers send test invoice.paid to staging endpoint before go-live. Reduced onboarding support time from ~45 minutes to ~12 minutes per tenant.

Verification note: metrics are a first-party desk case (InfiniSynapse learner/build notes, composite tenant). We invite peer replications—publish your before/after dead-letter rate against the same scorecard and link us via editorial corrections. External security baselines cited above: OWASP API Security, NIST SP 800-53.

Frequently Asked Questions

What belongs in a webhook relay service API data model?

Five entities and their relationships: endpoint (customer URL + secret), subscription (event-type filters onto an endpoint), event (append-only ingress), delivery (one event → one endpoint job), and attempt (one HTTP try). That is the webhook relay service API data model—not a fire-and-forget POST from the app server.

What webhook endpoint health metrics should the schema store?

Enough columns on attempt and delivery to compute success rate (attempts.ok / attempts.total in a window), last success per endpoint, dead-letter rate, p95 attempt latency, and queue depth. See Monitoring and Alerts for the How-to-compute column.

What should I watch in SLAs for financial-data webhook queues?

Persist the event before you ACK the vendor, keep replay and signature verification in the schema, and publish a retention TTL that matches the financial record. Dead-letter plus replay beats unbounded retry. NIST SP 800-53 audit expectations apply when payloads include financial or PII data.

Relay vs message queue?

Queue is transport; a relay schema adds subscriptions, HTTP semantics, retry audit, and customer-facing status.

Store raw vendor payload?

Yes—normalized envelope plus raw body for signature disputes and replay.

How long retain events?

Align with API Data Governance retention policy—often 30–90 days for ops, longer if contract requires.

Webhook vs polling?

Relay when vendor pushes; your event store still applies if you poll and then fan-out as events.

First table to build?

event with dedupe index—everything else hangs off immutable ingress.

How long for minimal relay?

Focused MVP—ingress, event, delivery, worker—often 3–4 weeks for a small team.

Conclusion

A durable API data model turns webhook chaos into queryable infrastructure: subscriptions, immutable events, delivery state, attempt audit, and customer-visible status.

Priority order for this API data model: persist events, async deliver, dedupe, retry with dead letter, status API, then polish dashboards.

Ship the schema before you promise enterprise webhook SLAs—that discipline separates demos from B2B Data API credibility.

Document replay procedures in your customer integration guide: which delivery states allow replay, how idempotency headers behave, and expected latency for delivered confirmation. Enterprise buyers ask these questions on the first security call—answers should match your OpenAPI spec, not tribal knowledge from the founding engineer.

Load-test ingress separately from delivery workers: vendors spike during billing cycles; your ingress path must absorb bursts without dropping ACK latency below vendor timeout windows (often 5–30 seconds).

Treat vendor documentation as the source of truth for retry behavior on their side—Stripe, for example, retries inbound to your ingress for hours. Your relay must idempotently accept duplicates while still creating only one logical event row. Document that behavior in runbooks so on-call engineers do not manually re-insert events during incident response.

Keep a sandbox relay environment mirroring production schema so customers integration-test subscriptions without touching production event ids—reduces go-live support load measurably.

Archive cold events to object storage after retention window—query metadata stays in Postgres while payload bytes move to cheaper tiers without breaking delivery audit trails.

Operational reminder: keep ingress ACK paths free of customer HTTP. Vendors time out in seconds; your workers can take minutes with backoff. Document retention TTLs next to archival jobs so legal and on-call share one clock. Sandbox environments should clone production table shapes—not just mock responses—so subscription filters behave identically before go-live. When dead-letter volume spikes, triage by endpoint_id first; most pilot incidents are bad URLs, not schema bugs. Write runbooks that name the exact delivery states eligible for replay so on-call engineers never invent ad-hoc SQL during incidents.

Webhook Relay API Data Model: 5 Entities