Skip to content
mittr

Quickstart

Get up and running with Mittr in three steps.

Sign up at app.mittr.io/signup. You’ll get an API key immediately. No credit card required.

An endpoint is a URL that receives webhooks. Create one via the API:

curl
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"]
}'
Node
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"],
}),
});
Python
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"],
},
)
Go
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.

curl
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]" }
}
}'
Node
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",
customer: { email: "[email protected]" },
},
}),
});
Python
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",
"customer": {"email": "[email protected]"},
},
},
)
Go
body, _ := json.Marshal(map[string]any{
"eventType": "order.created",
"payload": map[string]any{
"orderId": "ord_123",
"amount": 9900,
"currency": "USD",
"customer": map[string]string{"email": "[email protected]"},
},
})
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.

  1. Mittr fans out the event to matching endpoints
  2. Each delivery is attempted with your configured retry policy
  3. Failed deliveries are retried with exponential backoff
  4. After all retries are exhausted, events move to the dead letter queue
  5. You can monitor and replay events from the dashboard

Check the delivery status in the dashboard, or query the API:

curl
curl https://app.mittr.io/api/v1/events?status=delivered \
-H "X-API-Key: mtr_your_key"
Node
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();
Python
import requests
data = requests.get(
"https://app.mittr.io/api/v1/events",
params={"status": "delivered"},
headers={"X-API-Key": "mtr_your_key"},
).json()["data"]

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.

Node
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),
);
}
Python
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)
Go
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))
}

For high-throughput scenarios, use the batch endpoint to send up to 100 events in a single request. 10x faster than individual POSTs:

curl
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"} }
]
}'
Node
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 },
})),
}),
});
Python
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.

If you’re on Node, @mittr/sdk-node is a typed wrapper around the same REST API plus a webhook signature verifier:

Terminal window
npm install @mittr/sdk-node
Node
import { 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).