Quickstart
Get up and running with Mittr in three steps.
1. Create an account
Section titled “1. Create an account”Sign up at app.mittr.io/signup. You’ll get an API key immediately. No credit card required.
2. Create an endpoint
Section titled “2. Create an endpoint”An endpoint is a URL that receives webhooks. Create one via the API:
curl -X POST https://app.mittr.io/api/v1/endpoints \ -H "X-API-Key: mtr_your_key" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/webhooks", "eventTypes": ["order.created", "order.updated"] }'await fetch("https://app.mittr.io/api/v1/endpoints", { method: "POST", headers: { "X-API-Key": "mtr_your_key", "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://your-app.com/webhooks", eventTypes: ["order.created", "order.updated"], }),});import requests
requests.post( "https://app.mittr.io/api/v1/endpoints", headers={"X-API-Key": "mtr_your_key"}, json={ "url": "https://your-app.com/webhooks", "eventTypes": ["order.created", "order.updated"], },)body, _ := json.Marshal(map[string]any{ "url": "https://your-app.com/webhooks", "eventTypes": []string{"order.created", "order.updated"},})req, _ := http.NewRequest("POST", "https://app.mittr.io/api/v1/endpoints", bytes.NewReader(body))req.Header.Set("X-API-Key", "mtr_your_key")req.Header.Set("Content-Type", "application/json")http.DefaultClient.Do(req)Or create it from the dashboard.
3. Send an event
Section titled “3. Send an event”curl -X POST https://app.mittr.io/api/v1/events \ -H "X-API-Key: mtr_your_key" \ -H "X-Idempotency-Key: ord_123_created" \ -H "Content-Type: application/json" \ -d '{ "eventType": "order.created", "payload": { "orderId": "ord_123", "amount": 9900, "currency": "USD", "customer": { "email": "[email protected]" } } }'await fetch("https://app.mittr.io/api/v1/events", { method: "POST", headers: { "X-API-Key": "mtr_your_key", "X-Idempotency-Key": "ord_123_created", "Content-Type": "application/json", }, body: JSON.stringify({ eventType: "order.created", payload: { orderId: "ord_123", amount: 9900, currency: "USD", }, }),});import requests
requests.post( "https://app.mittr.io/api/v1/events", headers={ "X-API-Key": "mtr_your_key", "X-Idempotency-Key": "ord_123_created", }, json={ "eventType": "order.created", "payload": { "orderId": "ord_123", "amount": 9900, "currency": "USD", }, },)body, _ := json.Marshal(map[string]any{ "eventType": "order.created", "payload": map[string]any{ "orderId": "ord_123", "amount": 9900, "currency": "USD", },})req, _ := http.NewRequest("POST", "https://app.mittr.io/api/v1/events", bytes.NewReader(body))req.Header.Set("X-API-Key", "mtr_your_key")req.Header.Set("X-Idempotency-Key", "ord_123_created")req.Header.Set("Content-Type", "application/json")http.DefaultClient.Do(req)Mittr will deliver the event to all endpoints subscribed to order.created.
What happens next
Section titled “What happens next”- Mittr fans out the event to matching endpoints
- Each delivery is attempted with your configured retry policy
- Failed deliveries are retried with exponential backoff
- After all retries are exhausted, events move to the dead letter queue
- You can monitor and replay events from the dashboard
Verify delivery
Section titled “Verify delivery”Check the delivery status in the dashboard, or query the API:
curl https://app.mittr.io/api/v1/events?status=delivered \ -H "X-API-Key: mtr_your_key"const res = await fetch( "https://app.mittr.io/api/v1/events?status=delivered", { headers: { "X-API-Key": "mtr_your_key" } },);const { data } = await res.json();import requests
data = requests.get( "https://app.mittr.io/api/v1/events", params={"status": "delivered"}, headers={"X-API-Key": "mtr_your_key"},).json()["data"]Verify webhook signatures
Section titled “Verify webhook signatures”Every delivery includes an X-Mittr-Signature header. Verify it to ensure the webhook is authentic. Or paste the headers + body + secret into the in-browser verifier — it tells you whether they match and the most likely reason if not.
import crypto from "node:crypto";
export function verifyWebhook(secret, signatureHeader, timestampHeader, rawBody) { const expected = "v1=" + crypto .createHmac("sha256", secret) .update(`${timestampHeader}.${rawBody}`) .digest("hex"); return crypto.timingSafeEqual( Buffer.from(signatureHeader), Buffer.from(expected), );}import hmac, hashlib
def verify_webhook(secret: str, signature_header: str, timestamp_header: str, raw_body: bytes) -> bool: msg = f"{timestamp_header}.".encode() + raw_body expected = "v1=" + hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest() return hmac.compare_digest(signature_header, expected)import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt")
func VerifyWebhook(secret, signatureHeader, timestampHeader string, rawBody []byte) bool { mac := hmac.New(sha256.New, []byte(secret)) fmt.Fprintf(mac, "%s.", timestampHeader) mac.Write(rawBody) expected := "v1=" + hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(signatureHeader), []byte(expected))}High-volume sending
Section titled “High-volume sending”For high-throughput scenarios, use the batch endpoint to send up to 100 events in a single request. 10x faster than individual POSTs:
curl -X POST https://app.mittr.io/api/v1/events/batch \ -H "X-API-Key: mtr_your_key" \ -H "Content-Type: application/json" \ -d '{ "events": [ { "idempotencyKey": "order-1", "destination": "https://api.example.com/webhooks", "payload": {"orderId": "1"} }, { "idempotencyKey": "order-2", "destination": "https://api.example.com/webhooks", "payload": {"orderId": "2"} } ] }'await fetch("https://app.mittr.io/api/v1/events/batch", { method: "POST", headers: { "X-API-Key": "mtr_your_key", "Content-Type": "application/json", }, body: JSON.stringify({ events: orders.map((o) => ({ idempotencyKey: `order-${o.id}`, destination: "https://api.example.com/webhooks", payload: { orderId: o.id }, })), }),});import requests
requests.post( "https://app.mittr.io/api/v1/events/batch", headers={"X-API-Key": "mtr_your_key"}, json={ "events": [ { "idempotencyKey": f"order-{o['id']}", "destination": "https://api.example.com/webhooks", "payload": {"orderId": o["id"]}, } for o in orders ], },)Each event needs its own unique idempotencyKey. Fan-out (via eventType),
scheduling, and non-default priority require the single-event endpoint.
Use the SDK
Section titled “Use the SDK”If you’re on Node, @mittr/sdk-node is a typed wrapper around the same REST API plus a webhook signature verifier:
npm install @mittr/sdk-nodeimport { Mittr } from "@mittr/sdk-node";
const mittr = new Mittr({ apiKey: process.env.MITTR_API_KEY });await mittr.events.send({ eventType: "order.created", payload: { orderId: "ord_123" },});The SDK is open source under the MIT License and calls through it are billed identically to raw HTTP — see the SDK guide for the full surface (pagination iterators, webhook middleware, error handling) plus the SDKs overview for the roadmap (Python, Go).
Next steps
Section titled “Next steps”- Webhook Security — signature verification in depth
- Retry Strategies — configure backoff and circuit breakers
- REST API Reference — full endpoint documentation
- Node.js SDK guide — full reference for
@mittr/sdk-node - SDKs overview — coverage across languages