---
title: "Relay"
tagline: "Webhooks"
language: "Go"
license: "Apache-2.0"
since: "2026"
canonical: "https://xraph.com/work/relay"
---

# Relay

Webhook delivery as a library. Event types register at runtime with an optional JSON Schema, every delivery is signed with HMAC-SHA256, retries back off from five seconds to two hours, and anything that still fails waits in the DLQ until the customer fixes their endpoint and you replay it.

## Install

```bash
go get github.com/xraph/relay
```

## What it is

Relay delivers webhooks. Tenant-scoped endpoints, event types defined at runtime, signed deliveries, retries, and a dead-letter queue you can replay, all as a library you import.

## What it does

- **Dynamic event types** registered at runtime with optional JSON Schema validation, so a new event does not require a deploy of the delivery layer.
- **HMAC-SHA256 signatures** on every delivery, with a signature package receivers can use to verify.
- **Exponential backoff**: 5s, 30s, 2m, 15m, 2h by default. What still fails lands in the DLQ.
- **Per-endpoint rate limiting** through a token bucket, so one slow customer endpoint cannot back up the queue for everyone.
- **Glob event subscriptions**: an endpoint subscribes to order.\* rather than enumerating.
- **Admin HTTP API** with full CRUD over event types, endpoints, events, deliveries and DLQ replay.
- **OpenTelemetry and Prometheus**: a trace span per delivery, plus counters, latency histograms and gauges.

## The part people underestimate

Replay is the feature customers actually ask about, and it is only useful if deliveries are stored with enough fidelity to reconstruct exactly: same body, same signature, same headers. Storing a summary instead of the payload is a decision that looks reasonable until the first support request.

---

*Unpublished draft. Not peer reviewed and not submitted to a venue.*


## Anatomy

- **Delivery**: Exponential backoff with a dead letter queue.
- **Signing**: HMAC-SHA256 signatures per endpoint.
- **Subscriptions**: Glob event matching against dynamic event types.
- **Admin API**: Endpoints, retries and deliveries inspectable over HTTP.

## Constraints and trade-offs

- (known gap) The part people underestimate is replay. Delivery is easy; proving what was delivered is not.
- (constraint) Per-endpoint rate limiting is mandatory. One slow consumer must not hold the queue.
