Send webhooks
Available — including the application/subscription model & the consumer portal.The Send side: emit your own events as webhooks-as-a-service. You don't run delivery infrastructure — Emithook signs, retries, circuit-breaks, logs, and archives every send through the same engine the relay uses. Only the ingress differs.
Three ways to resolve a destination
All three share signing, retry/backoff, the per-destination circuit breaker, SSRF protection, DLQ, and logs. They differ only in how the target is chosen:
| Pattern | Use it when | How it resolves |
|---|---|---|
| Direct send | One-off / system-to-system push, no event mapping. | POST /v1/send names a registered destination id or a validated HTTPS URL. |
| Static fan-out | An event always goes to the same place(s). | An event type → a fixed route set. |
| Per-tenant (applications) | A multi-tenant product where each customer wants their own URL/queue for the same event. | app_id = your end-customer's id; POST /v1/app/{id}/event resolves that tenant's endpoints. |
Direct send
The simplest path — one call delivers one payload:
curl -X POST https://api.emithook.com/v1/send \
-H "Authorization: Bearer $EK_KEY" \
-H "Idempotency-Key: inv_001" \
-H "Content-Type: application/json" \
-d '{
"destination": "dst_01JX9...",
"event_type": "invoice.created",
"payload": { "id": "INV-2026-001", "amount": 4999, "currency": "INR" }
}'// → 202 Accepted
{ "message_id": "msg_01JX9..." }Send Idempotency-Key so client retries can't double-deliver. See the Quickstart for the end-to-end version.
Queue and broker destinations
A destination doesn't have to be an HTTPS URL — it can be a message broker. The same engine (signing context, retry/backoff, per-destination circuit breaker, DLQ, logs) applies; only the final hop changes: instead of an HTTP POST, the event is published to the broker. One adapter class per broker implements the same QueuePort (publish and consume), so a broker can be both a delivery target and an ingestion source.
Every adapter passes the same shared QueuePort conformance suite (publish/receive, ack removes, nack redelivers with an incrementing delivery count, FIFO within a group, consume() auto-ack, health):
type | Broker | FIFO within a group | Delivery count | Conformance |
|---|---|---|---|---|
sqs | AWS SQS | FIFO queues (MessageGroupId) | ApproximateReceiveCount | CI (ElasticMQ) |
nats | NATS JetStream | stream order | JetStream redelivery count | CI |
redis | Redis Streams | stream order | XCLAIM delivery count | CI |
amqp | RabbitMQ | queue order | quorum-queue x-delivery-count | CI (RabbitMQ) |
kafka | Apache Kafka | per-key partition order | adapter-tracked per offset | CI (Redpanda) |
pubsub | Google Pub/Sub | message ordering (orderingKey) | deliveryAttempt (via DLQ policy) | CI (emulator) |
azure | Azure Service Bus | queue order | deliveryCount | conformance-ready — not CI-verified |
Azure Service Bus
The Azure adapter is implemented against the same contract and ships with the identical conformance suite, but there is no lightweight Service Bus emulator that supports dynamic queue creation, so the suite is gated on AZURE_SERVICEBUS_TEST_URL and skipped in CI. Point that variable at a real namespace to run the full contract end to end.
Broker connection details live in the destination's stored configuration, not in environment variables — only the self-host ingest/delivery backbone (QueuePort) is env-configured. See self-hosting.
The application / subscription model Available
Turn Emithook into "webhooks for your product." Register each of your end-customers as an Application (keyed by your own id), each holding endpoints (URL/queue + event-type filter + its own signing secret). Then fan out:
curl -X POST https://api.emithook.com/v1/app/cust_8f2a/event \
-H "Authorization: Bearer $EK_KEY" \
-d '{ "event_type": "invoice.created", "payload": { "id": "INV-1" } }'// → 202 Accepted — fanned out to every matching endpoint
{ "message_id": "msg_01JX9...", "fanout": 3 }Applications can be lazily auto-created on first send. The data model (Environment → Application → Endpoint, plus Message/Attempt/EventType) is defined in the glossary.
Consumer portal Available
Your end-customers manage their own endpoints, view delivery logs, replay failures, browse the event catalog, and rotate their secret — in an embeddable, white-label portal scoped to one application via a magic link, with no Emithook account. This is what offloads webhook support from your team to theirs.
Receiving side (your customers)
Every delivery is signed with Standard Webhooks, so your customers verify with any off-the-shelf library — verifying against the raw body. See signing.
Next
- API conventions — idempotency, scopes, errors, retry schedule.
- Receive webhooks — the inbound half.
- API reference · MCP server