Relay

Getting Started

Install Relay and send your first webhook in under five minutes.

Prerequisites

  • Go 1.22 or later
  • A Go module (go mod init)

Install

go get github.com/xraph/relay

Step 1: Create a Relay instance

Every Relay instance requires a store backend. For development and testing, use the in-memory store:

package main

import (
    "context"
    "log"

    "github.com/xraph/relay"
    "github.com/xraph/relay/store/memory"
)

func main() {
    ctx := context.Background()

    r, err := relay.New(
        relay.WithStore(memory.New()),
    )
    if err != nil {
        log.Fatal(err)
    }

    _ = r
}

Step 2: Register an event type

Event types live in the catalog. Register them at boot or at runtime through the admin API:

import "github.com/xraph/relay/catalog"

r.RegisterEventType(ctx, catalog.WebhookDefinition{
    Name:        "order.created",
    Description: "Fired when a new order is placed",
    Version:     "2025-01-01",
})

Step 3: Create a webhook endpoint

Endpoints belong to tenants and subscribe to event types using glob patterns:

import "github.com/xraph/relay/endpoint"

ep, err := r.Endpoints().Create(ctx, endpoint.Input{
    TenantID:   "tenant-acme",
    URL:        "https://acme.example.com/webhook",
    EventTypes: []string{"order.*"},
})

A signing secret is auto-generated when Secret is not provided. The secret is used to compute HMAC-SHA256 signatures for every delivery.

Step 4: Send an event

import (
    "encoding/json"
    "github.com/xraph/relay/event"
)

err = r.Send(ctx, &event.Event{
    Type:     "order.created",
    TenantID: "tenant-acme",
    Data:     json.RawMessage(`{"order_id":"ORD-001","amount":99.99}`),
})

Send() validates the event type, persists the event, resolves all matching endpoints, and enqueues one delivery per endpoint.

Step 5: Start the delivery engine

r.Start(ctx)
defer r.Stop(ctx)

The engine polls for pending deliveries, dispatches them to worker goroutines, and handles retries with exponential backoff.

Step 6: Mount the admin API (optional)

import (
    "net/http"
    "github.com/xraph/relay/api"
)

handler := api.NewHandler(r.Store(), r.Catalog(), r.Endpoints(), r.DLQ(), nil)
mux := http.NewServeMux()
mux.Handle("/webhooks/", http.StripPrefix("/webhooks", handler))

log.Fatal(http.ListenAndServe(":8080", mux))

Next steps

  • Architecture -- Understand the package structure
  • Catalog -- Configure event types with JSON Schema
  • Delivery -- Tune retry schedules and concurrency
  • Stores -- Connect to PostgreSQL for production

On this page