Webhook Relay Service API Data Model: Why Event Flows Need Structure

By William Zhu & the InfiniSynapse Data Team · Last updated: 2026-07-31 · Last verified: 2026-07-31 · About / team · Vision · 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.

Hero image for webhook-relay-api-data-model


Table of Contents

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

TL;DR

Direct answer: For webhook relay design, your API data model must treat webhooks as durable event records with subscriptions, delivery attempts, and retry state—not as fire-and-forget HTTP POSTs from your app server.

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.

  • The API data model centers on five entities: subscription, event, delivery, attempt, endpoint.
  • 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: An API data model for webhook relay is the structured representation of how a relay service 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.

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.

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.

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.

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:

  • 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.

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.

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.

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.

Customer Endpoint Registration

Expose self-service endpoint CRUD so buyers do not email you to rotate URLs:

  • 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.

Monitoring and Alerts

Track relay health independently of application metrics:

SignalAlert threshold
Ingress lag (receive → persist)p95 > 500ms
Dead letter rate> 1% over 1h
Attempt 5xx to customer URLs> 5% over 15m
Queue depth (pending deliveries)sustained growth 30m
Signature verify failuresspike vs 7d baseline

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

Operating Model

Assign one relay owner—even in a small team:

  • 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 relay schema 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.

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 store.

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 store (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

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: 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 Service Api Data Model: Complete 2026 Guide