Skip to content
mittr

REST API Guide

Base URL: https://app.mittr.io (or your self-hosted instance)

All /api/v1/* endpoints require authentication via X-API-Key header or session cookie.


Terminal window
# API Key (recommended for programmatic access)
curl -H "X-API-Key: mtr_your_key" https://app.mittr.io/api/v1/events
# Session cookie (used by dashboard)
curl --cookie "mittr_session=..." https://app.mittr.io/api/v1/events
# Project scoping (optional — filters data to a specific project)
curl -H "X-API-Key: mtr_your_key" -H "X-Project-ID: 8bb0a314-..." https://app.mittr.io/api/v1/events
{
"error": "Human-readable error message",
"code": "MACHINE_CODE"
}
CodeHTTPMeaning
UNAUTHORIZED401Missing or invalid API key/session
NOT_FOUND404Resource not found
BAD_REQUEST400Invalid request body or parameters
CONFLICT409Duplicate idempotency key or invalid state transition
RATE_LIMITED429Rate limit exceeded (see Retry-After header)
QUOTA_EXCEEDED402Monthly message quota exceeded
INVALID_STATE409Operation not allowed in current state

All list endpoints use cursor-based pagination:

Terminal window
# First page
curl "https://app.mittr.io/api/v1/events?limit=20"
# Next page
curl "https://app.mittr.io/api/v1/events?limit=20&cursor=c89f3557-326a-470e"

Response always includes:

{
"data": [...],
"pagination": { "hasMore": true, "cursor": "next_page_token" }
}

When rate-limited, the response includes:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712678460
Retry-After: 5

POST /api/v1/events

Creates a webhook event for delivery. Requires X-Idempotency-Key header.

Request fields:

FieldTypeRequiredDefaultDescription
destinationstring*Direct delivery URL
eventTypestring*Fan-out to subscribed endpoints
payloadobjectyesJSON payload to deliver
headersobjectnoCustom HTTP headers included in delivery
maxAttemptsintno5Override max delivery attempts for this event. Capped at 25 system-wide; values above 25 are silently clamped.
priorityintno51 (highest) to 10 (lowest)
delaySecondsintno0Delay delivery by N seconds

*Either destination or eventType is required (not both).

Example — fan-out by event type:

Terminal window
curl -X POST https://app.mittr.io/api/v1/events \
-H "X-API-Key: mtr_your_key" \
-H "X-Idempotency-Key: order-123-created" \
-H "Content-Type: application/json" \
-d '{
"eventType": "order.created",
"payload": {
"orderId": "ord_4a8f",
"amount": 9900,
"currency": "USD",
"customer": { "id": "cust_001", "email": "[email protected]" }
}
}'

Example — direct delivery with priority and delay:

Terminal window
curl -X POST https://app.mittr.io/api/v1/events \
-H "X-API-Key: mtr_your_key" \
-H "X-Idempotency-Key: payment-456-notify" \
-H "Content-Type: application/json" \
-d '{
"destination": "https://billing.example.com/webhooks",
"payload": { "paymentId": "pay_456", "status": "completed" },
"headers": { "X-Custom-Auth": "Bearer token123" },
"maxAttempts": 10,
"priority": 1,
"delaySeconds": 60
}'

Response (201):

{
"id": "c89f3557-326a-470e-84a8-b62e8503781c",
"idempotencyKey": "order-123-created",
"destination": "https://api.example.com/webhooks",
"eventType": "order.created",
"status": "queued",
"attempts": 0,
"maxAttempts": 5,
"priority": 5,
"createdAt": "2026-04-13T11:39:23Z"
}
GET /api/v1/events?status=delivered&limit=20&cursor=...

Query parameters: status (queued/delivering/delivered/failed/dead), limit (1-100, default 20), cursor.

Terminal window
curl "https://app.mittr.io/api/v1/events?status=failed&limit=10" \
-H "X-API-Key: mtr_your_key"
GET /api/v1/events/{eventId}

Returns full event with delivery attempt history.

Terminal window
curl "https://app.mittr.io/api/v1/events/c89f3557-326a-470e-84a8-b62e8503781c" \
-H "X-API-Key: mtr_your_key"

Response:

{
"id": "c89f3557-326a-470e-84a8-b62e8503781c",
"status": "delivered",
"destination": "https://api.example.com/webhooks",
"payload": { "orderId": "ord_4a8f", "amount": 9900 },
"attempts": 1,
"maxAttempts": 5,
"createdAt": "2026-04-13T11:39:23Z",
"deliveredAt": "2026-04-13T11:39:25Z",
"deliveryAttempts": [
{
"id": "4d9a0503-efd9-4980-b53d-94407c4318a5",
"attemptNumber": 1,
"statusCode": 200,
"durationMs": 523,
"attemptedAt": "2026-04-13T11:39:25Z"
}
]
}
PATCH /api/v1/events/{eventId}

Edit destination, payload, or headers on a failed/dead event. Optionally replay.

Terminal window
curl -X PATCH "https://app.mittr.io/api/v1/events/c89f3557-..." \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"destination": "https://new-url.example.com/webhooks",
"payload": { "orderId": "ord_4a8f", "amount": 9900, "corrected": true },
"replay": true
}'
FieldTypeDescription
destinationstringNew destination URL
payloadobjectNew payload
headersobjectNew headers
replayboolReset attempts and re-queue
POST /api/v1/events/{eventId}/replay

Re-queues a failed/dead event as-is with reset attempt counter. No request body.

Terminal window
curl -X POST "https://app.mittr.io/api/v1/events/c89f3557-.../replay" \
-H "X-API-Key: mtr_your_key"
POST /api/v1/events/batch

Create up to 100 events in a single request. Significantly faster than individual POSTs for high-volume scenarios, measured at 10x throughput versus single-event creation.

Limitations:

  • Only simple direct-delivery events (single destination per event)
  • No fan-out (use the single-event endpoint with eventType for routing)
  • No scheduling (delaySeconds) or non-default priority
  • Each event must have its own unique idempotencyKey

Request:

Terminal window
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-1001-created",
"destination": "https://api.example.com/webhooks",
"payload": { "orderId": "1001", "amount": 4900 }
},
{
"idempotencyKey": "order-1002-created",
"destination": "https://api.example.com/webhooks",
"payload": { "orderId": "1002", "amount": 7500 }
},
{
"idempotencyKey": "order-1003-created",
"destination": "https://api.example.com/webhooks",
"payload": { "orderId": "1003", "amount": 2250 },
"headers": { "X-Custom": "value" },
"maxAttempts": 10
}
]
}'

Response (201):

{
"events": [
{ "id": "evt_abc...", "status": "queued", "createdAt": "..." },
{ "id": "evt_def...", "status": "queued", "createdAt": "..." },
{ "id": "evt_ghi...", "status": "queued", "createdAt": "..." }
],
"count": 3
}

Errors:

StatusCodeCondition
400VALIDATION_ERROREmpty events array, missing fields
400BATCH_TOO_LARGEMore than 100 events
402QUOTA_EXCEEDEDClient quota exhausted
409DUPLICATE_EVENTOne or more idempotency keys already exist
POST /api/v1/events/batch/retry
Terminal window
# Retry by IDs
curl -X POST https://app.mittr.io/api/v1/events/batch/retry \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "eventIds": ["evt_1", "evt_2", "evt_3"] }'
# Retry all failed events
curl -X POST https://app.mittr.io/api/v1/events/batch/retry \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "status": "failed", "limit": 100 }'
# Retry all failed events for an endpoint
curl -X POST https://app.mittr.io/api/v1/events/batch/retry \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "endpointId": "ep_uuid", "limit": 50 }'

Delivery attempts are first-class resources. Every time Mittr tries to deliver an event to its destination, it records a DeliveryAttempt with the response status, error (if any), duration, and attempt number. Use these endpoints to inspect delivery history, debug failures, or build custom dashboards.

GET /api/v1/deliveries

Paginated list of delivery attempts across all events, with time-range and outcome filters.

Terminal window
# Last 24 hours
curl "https://app.mittr.io/api/v1/deliveries?range=24h&limit=50" \
-H "X-API-Key: mtr_your_key"
# Custom range with filters
curl "https://app.mittr.io/api/v1/deliveries?start=2026-04-01T00:00:00Z&end=2026-04-13T23:59:59Z&outcome=failure&endpoint_id=ep_uuid" \
-H "X-API-Key: mtr_your_key"

Query params: range (1h/24h/7d/30d), start/end (RFC3339), outcome (success/failure/timeout), endpoint_id, event_type, limit (max 200), offset.

GET /api/v1/events/{eventId}/deliveries

Returns every attempt recorded for the event, in chronological order.

Terminal window
curl https://app.mittr.io/api/v1/events/evt_123/deliveries \
-H "X-API-Key: mtr_your_key"

Response:

{
"deliveries": [
{
"id": "5f9d8a2b-1c4e-4f3a-9b8c-7d2e1f4a5b6c",
"eventId": "evt_123",
"attemptNumber": 1,
"statusCode": 503,
"responseBody": "Service Unavailable",
"error": "",
"durationMs": 142,
"processingOverheadUs": 1850,
"attemptedAt": "2026-04-17T10:15:03Z"
},
{
"id": "a1b2c3d4-e5f6-4789-abcd-ef0123456789",
"eventId": "evt_123",
"attemptNumber": 2,
"statusCode": 200,
"responseBody": "OK",
"error": "",
"durationMs": 87,
"processingOverheadUs": 1620,
"attemptedAt": "2026-04-17T10:15:05Z"
}
],
"count": 2
}
GET /api/v1/deliveries/{deliveryId}

Fetch a single attempt by ID. Scoped to the requesting client, so you cannot access another tenant’s delivery even if you know the UUID (returns 404).

Terminal window
curl https://app.mittr.io/api/v1/deliveries/5f9d8a2b-1c4e-4f3a-9b8c-7d2e1f4a5b6c \
-H "X-API-Key: mtr_your_key"

POST /api/v1/endpoints
Terminal window
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://api.example.com/webhooks",
"eventTypes": ["order.created", "payment.*"],
"description": "Production order notifications",
"maxRetries": 5,
"timeoutMs": 30000,
"rateLimitPerSec": 100,
"customHeaders": {
"Authorization": "Bearer your-token",
"X-Source": "mittr"
}
}'

All fields:

FieldTypeRequiredDefaultDescription
urlstringyesWebhook destination URL
eventTypesstring[]yesSubscribe to these types (supports * wildcard)
descriptionstringno
filterobjectnoJSONPath content filter
transformationstringnoJavaScript transform code
fifoboolnofalseEnable ordered delivery
fifoPartitionKeystringnoJSONPath for partition (e.g. $.data.orderId)
maxRetriesintno5Max delivery attempts
retryBackoffMsintno1000Initial backoff in ms
retryBackoffMaxintno86400000Max backoff in ms (24h)
retryBackoffMultfloatno2.0Backoff multiplier
timeoutMsintno30000HTTP request timeout in ms
rateLimitPerSecintno0Rate limit (0 = unlimited, capped by plan)
circuitThresholdintno5Consecutive failures to trip breaker
circuitResetMsintno300000Breaker recovery interval in ms (5 min)
customHeadersobjectnoStatic headers sent with every delivery
allowedCidrsstring[]noIP allowlist in CIDR notation
blockedCidrsstring[]noIP blocklist in CIDR notation
deliveryModestringnopushpush, poll, or storage
storageConfigobjectnoRequired when deliveryMode is storage. See Storage Sinks
signingSecretstringnoCustom per-endpoint signing secret (overrides global)
mtlsCertstringnoPEM client certificate for mTLS
mtlsKeystringnoPEM private key for mTLS

Example with FIFO and filter:

Terminal window
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://billing.example.com/webhooks",
"eventTypes": ["payment.*"],
"fifo": true,
"fifoPartitionKey": "$.data.customerId",
"filter": [
{ "field": "$.data.amount", "operator": "gte", "value": 10000 }
],
"maxRetries": 10,
"rateLimitPerSec": 50
}'
Terminal window
curl "https://app.mittr.io/api/v1/endpoints?limit=20" \
-H "X-API-Key: mtr_your_key"
Terminal window
curl "https://app.mittr.io/api/v1/endpoints/ep_uuid" \
-H "X-API-Key: mtr_your_key"
Terminal window
curl -X PATCH "https://app.mittr.io/api/v1/endpoints/ep_uuid" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://new-url.example.com/webhooks",
"maxRetries": 5,
"rateLimitPerSec": 200
}'
Terminal window
curl -X DELETE "https://app.mittr.io/api/v1/endpoints/ep_uuid" \
-H "X-API-Key: mtr_your_key"
Terminal window
# Pause (stops delivery, events stay queued)
curl -X POST "https://app.mittr.io/api/v1/endpoints/ep_uuid/pause" \
-H "X-API-Key: mtr_your_key"
# Resume
curl -X POST "https://app.mittr.io/api/v1/endpoints/ep_uuid/resume" \
-H "X-API-Key: mtr_your_key"
Terminal window
curl -X POST "https://app.mittr.io/api/v1/endpoints/ep_uuid/mtls" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"certPem": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"keyPem": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
}'
Terminal window
curl -X DELETE "https://app.mittr.io/api/v1/endpoints/ep_uuid/mtls" \
-H "X-API-Key: mtr_your_key"
Terminal window
# List version history
curl "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions" \
-H "X-API-Key: mtr_your_key"
# Get specific version
curl "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions/3" \
-H "X-API-Key: mtr_your_key"
# Diff two versions
curl "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions/diff?v1=1&v2=3" \
-H "X-API-Key: mtr_your_key"
# Rollback to version
curl -X POST "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions/2/rollback" \
-H "X-API-Key: mtr_your_key"

Terminal window
curl -X POST https://app.mittr.io/api/v1/event-types \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "order.created",
"description": "Fired when a new order is placed",
"schema": {
"type": "object",
"required": ["orderId", "amount"],
"properties": {
"orderId": { "type": "string" },
"amount": { "type": "integer" }
}
},
"schemaVersion": "1.0"
}'
Terminal window
# List
curl "https://app.mittr.io/api/v1/event-types" -H "X-API-Key: mtr_your_key"
# Get by ID
curl "https://app.mittr.io/api/v1/event-types/et_uuid" -H "X-API-Key: mtr_your_key"
# Get by name
curl "https://app.mittr.io/api/v1/event-types/by-name/order.created" -H "X-API-Key: mtr_your_key"
# Update
curl -X PUT "https://app.mittr.io/api/v1/event-types/et_uuid" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "description": "Updated description", "schemaVersion": "2.0" }'
# Delete
curl -X DELETE "https://app.mittr.io/api/v1/event-types/et_uuid" -H "X-API-Key: mtr_your_key"

Terminal window
curl -X POST https://app.mittr.io/api/v1/inbound-endpoints \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub Webhooks",
"pathSuffix": "github-prod",
"source": "github",
"sourceConfig": { "secret": "your-github-webhook-secret" },
"destinationIds": ["endpoint-uuid-1", "endpoint-uuid-2"],
"eventTypeMapping": "$.headers.X-GitHub-Event",
"description": "Production GitHub webhook receiver"
}'

Webhook URL: POST https://app.mittr.io/inbound/github-prod (public, no auth).

FieldTypeRequiredDescription
namestringyesDisplay name
pathSuffixstringyesURL path segment
sourcestringyesPlatform preset (130+ available)
sourceConfigobjectnoCredentials (varies by verification mode)
destinationIdsstring[]noForward to specific endpoints
eventTypeMappingstringnoJSONPath to extract event type
descriptionstringno
transformationstringnoJavaScript transform
Terminal window
curl "https://app.mittr.io/api/v1/inbound-presets" -H "X-API-Key: mtr_your_key"

Returns 130+ presets with source, name, description, mode.

Terminal window
# List
curl "https://app.mittr.io/api/v1/inbound-endpoints" -H "X-API-Key: mtr_your_key"
# Get
curl "https://app.mittr.io/api/v1/inbound-endpoints/inb_uuid" -H "X-API-Key: mtr_your_key"
# Update
curl -X PATCH "https://app.mittr.io/api/v1/inbound-endpoints/inb_uuid" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "description": "Updated", "status": "inactive" }'
# Delete
curl -X DELETE "https://app.mittr.io/api/v1/inbound-endpoints/inb_uuid" -H "X-API-Key: mtr_your_key"

Terminal window
curl -X POST https://app.mittr.io/api/v1/alerting/rules \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "High failure rate",
"description": "Alert when failure rate exceeds 10%",
"enabled": true,
"condition": {
"metric": "failure_rate",
"operator": "gt",
"value": 0.1,
"window": "5m"
},
"action": {
"type": "slack",
"webhookUrl": "https://hooks.slack.com/services/...",
"channel": "#alerts",
"message": "Failure rate is {{.value}}% (threshold: {{.threshold}}%)"
},
"cooldown": "15m"
}'

Condition metrics: failure_rate, success_rate, latency, queue_depth, error_count, delivery_count

Condition operators: gt, gte, lt, lte, eq, ne

Action types and required fields:

TypeRequiredOptional
slackwebhookUrlchannel, message
emailto (string[])subject, message
webhookwebhookUrlheaders, message
pagerdutyroutingKeyseverity, message

List / Get / Update / Delete / Enable / Disable

Section titled “List / Get / Update / Delete / Enable / Disable”
Terminal window
# List rules
curl "https://app.mittr.io/api/v1/alerting/rules" -H "X-API-Key: mtr_your_key"
# Get rule
curl "https://app.mittr.io/api/v1/alerting/rules/rule_uuid" -H "X-API-Key: mtr_your_key"
# Update rule
curl -X PUT "https://app.mittr.io/api/v1/alerting/rules/rule_uuid" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "name": "Updated name", "condition": { "metric": "failure_rate", "operator": "gt", "value": 0.2, "window": "10m" }, "action": { "type": "slack", "webhookUrl": "https://hooks.slack.com/..." } }'
# Delete rule
curl -X DELETE "https://app.mittr.io/api/v1/alerting/rules/rule_uuid" -H "X-API-Key: mtr_your_key"
# Enable / Disable
curl -X POST "https://app.mittr.io/api/v1/alerting/rules/rule_uuid/enable" -H "X-API-Key: mtr_your_key"
curl -X POST "https://app.mittr.io/api/v1/alerting/rules/rule_uuid/disable" -H "X-API-Key: mtr_your_key"
# Trigger evaluation manually
curl -X POST "https://app.mittr.io/api/v1/alerting/evaluate" -H "X-API-Key: mtr_your_key"
# Alert history
curl "https://app.mittr.io/api/v1/alerting/history?limit=20" -H "X-API-Key: mtr_your_key"

Terminal window
# Slack
curl -X POST https://app.mittr.io/api/v1/connectors \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "prod-slack-alerts",
"type": "slack",
"config": {
"webhookUrl": "https://hooks.slack.com/services/T.../B.../xxx",
"channel": "#webhook-alerts",
"username": "Mittr Bot",
"iconEmoji": ":bell:"
},
"template": {
"title": "{{.event_type}}",
"text": "Delivery {{.status}}: {{.message}}",
"color": "#ba5b38"
}
}'
# Email
curl -X POST https://app.mittr.io/api/v1/connectors \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "ops-email",
"type": "email",
"config": {
"smtpHost": "smtp.example.com",
"smtpPort": 587,
"smtpUsername": "[email protected]",
"smtpPassword": "secret",
"fromEmail": "[email protected]",
}
}'

Types: slack, discord, teams, email, webhook

Terminal window
curl "https://app.mittr.io/api/v1/connectors" -H "X-API-Key: mtr_your_key"
curl "https://app.mittr.io/api/v1/connectors/prod-slack-alerts" -H "X-API-Key: mtr_your_key"
curl -X PUT "https://app.mittr.io/api/v1/connectors/prod-slack-alerts" \
-H "X-API-Key: mtr_your_key" -H "Content-Type: application/json" \
-d '{ "config": { "channel": "#new-channel" } }'
curl -X DELETE "https://app.mittr.io/api/v1/connectors/prod-slack-alerts" -H "X-API-Key: mtr_your_key"

Terminal window
curl -X POST https://app.mittr.io/api/v1/api-keys \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Key",
"scopes": ["events:write", "endpoints:read"],
"rateLimit": 1000,
"expiresAt": "2027-01-01T00:00:00Z"
}'

Response includes the raw key (shown only once):

{
"id": "key_uuid",
"name": "Production API Key",
"keyPrefix": "mtr_abc1",
"key": "mtr_abc1234567890abcdef...",
"isActive": true,
"createdAt": "2026-04-13T12:00:00Z"
}
Terminal window
curl "https://app.mittr.io/api/v1/api-keys" -H "X-API-Key: mtr_your_key"
curl -X DELETE "https://app.mittr.io/api/v1/api-keys/key_uuid" -H "X-API-Key: mtr_your_key"

Terminal window
# List members
curl "https://app.mittr.io/api/v1/team" -H "X-API-Key: mtr_your_key"
# Invite member
curl -X POST https://app.mittr.io/api/v1/team/invite \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "role": "editor" }'
# Update role (admin/editor/viewer)
curl -X PATCH "https://app.mittr.io/api/v1/team/user_uuid" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "role": "admin" }'
# Remove member
curl -X DELETE "https://app.mittr.io/api/v1/team/user_uuid" -H "X-API-Key: mtr_your_key"

Terminal window
# List
curl "https://app.mittr.io/api/v1/projects" -H "X-API-Key: mtr_your_key"
# Create
curl -X POST https://app.mittr.io/api/v1/projects \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "name": "Staging", "environment": "staging" }'
# Update
curl -X PATCH "https://app.mittr.io/api/v1/projects/proj_uuid" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "name": "Production", "environment": "production" }'
# Delete
curl -X DELETE "https://app.mittr.io/api/v1/projects/proj_uuid" -H "X-API-Key: mtr_your_key"

Terminal window
# Get account info
curl "https://app.mittr.io/api/v1/me" -H "X-API-Key: mtr_your_key"
# Complete onboarding
curl -X POST "https://app.mittr.io/api/v1/me/onboarding-complete" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "companyName": "Acme Corp" }'
# Get plan limits
curl "https://app.mittr.io/api/v1/entitlements" -H "X-API-Key: mtr_your_key"
# Get egress IPs (for firewall allowlisting)
curl "https://app.mittr.io/api/v1/egress-ips" -H "X-API-Key: mtr_your_key"

Terminal window
# Current period usage
curl "https://app.mittr.io/api/v1/usage/current" -H "X-API-Key: mtr_your_key"
# Monthly history (last 6 months)
curl "https://app.mittr.io/api/v1/usage/history?months=6" -H "X-API-Key: mtr_your_key"
# Billing overview (subscription + invoices + plan catalog)
curl "https://app.mittr.io/api/v1/billing/overview" -H "X-API-Key: mtr_your_key"
# Subsets — same data as /overview, split for narrower fetches
curl "https://app.mittr.io/api/v1/billing/plans" -H "X-API-Key: mtr_your_key"
curl "https://app.mittr.io/api/v1/billing/subscription" -H "X-API-Key: mtr_your_key"
curl "https://app.mittr.io/api/v1/billing/invoices" -H "X-API-Key: mtr_your_key"
# Create checkout session (signup / upgrade). cycle is "monthly" or
# "annual"; omit for monthly.
curl -X POST "https://app.mittr.io/api/v1/billing/checkout" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "planId": "growth", "cycle": "annual" }'
# Preview a plan change — returns the proration breakdown without
# applying it. Use this to show "you'll be charged $X today" before
# the customer confirms.
curl -X POST "https://app.mittr.io/api/v1/billing/preview-update" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "planId": "scale", "cycle": "annual" }'
# Cancel at period end (subscription stays active until
# currentPeriodEnd; re-enable with /resume before then).
curl -X POST "https://app.mittr.io/api/v1/billing/cancel" \
-H "X-API-Key: mtr_your_key"
# Resume a cancellation before it takes effect.
curl -X POST "https://app.mittr.io/api/v1/billing/resume" \
-H "X-API-Key: mtr_your_key"
# Undo a scheduled plan change (e.g. an annual→monthly switch that
# was queued for next renewal).
curl -X DELETE "https://app.mittr.io/api/v1/billing/scheduled-change" \
-H "X-API-Key: mtr_your_key"
# Open the provider-hosted portal (payment-method change, invoice
# PDF download). Returns { "url": "https://..." } — redirect the
# customer there.
curl -X POST "https://app.mittr.io/api/v1/billing/portal" \
-H "X-API-Key: mtr_your_key"

Customer-of-customers webhook management. Each sub-account is a scoped child of your workspace. You mint a short-lived session URL and embed it in your product; your customer manages their webhook endpoints + sees deliveries without seeing other sub-accounts.

Terminal window
curl -X POST "https://app.mittr.io/api/v1/sub-accounts" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Customer Inc.",
"subID": "cust_abc123",
"metadata": { "tier": "enterprise" }
}'
Terminal window
curl "https://app.mittr.io/api/v1/sub-accounts?limit=20" -H "X-API-Key: mtr_your_key"
curl "https://app.mittr.io/api/v1/sub-accounts/{id}" -H "X-API-Key: mtr_your_key"
curl -X PATCH "https://app.mittr.io/api/v1/sub-accounts/{id}" \
-H "X-API-Key: mtr_your_key" -H "Content-Type: application/json" \
-d '{ "name": "Acme Customer Inc. (renamed)" }'
# Deactivate (soft-delete; events stop accepting but historical data stays)
curl -X DELETE "https://app.mittr.io/api/v1/sub-accounts/{id}" -H "X-API-Key: mtr_your_key"

Returns a URL with a one-time exchange token. Embed in your product via iframe or redirect. The portal frontend exchanges the token for a short-lived session (default 1h, sliding-refresh) tied to the sub-account.

Terminal window
curl -X POST "https://app.mittr.io/api/v1/sub-accounts/{id}/sessions" \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{
"returnURL": "https://app.example.com/integrations",
"ttlSeconds": 600
}'
# Response: { "url": "https://portal.mittr.io/s/exchange?token=..." }
Terminal window
curl "https://app.mittr.io/api/v1/sub-accounts/{id}/sessions" -H "X-API-Key: mtr_your_key"
# Revoke a single session
curl -X DELETE "https://app.mittr.io/api/v1/sub-accounts/{id}/sessions/{sessionId}" \
-H "X-API-Key: mtr_your_key"
# Revoke all sessions for this sub-account
curl -X DELETE "https://app.mittr.io/api/v1/sub-accounts/{id}/sessions" -H "X-API-Key: mtr_your_key"

Sub-account runtime API (/sub-account-api/*)

Section titled “Sub-account runtime API (/sub-account-api/*)”

Called by the embedded portal frontend, not by you. Authenticated with the session token returned from the exchange step. See the Embedded Portal guide for the full flow.

POST /sub-account-api/auth/exchange # exchange one-time token → session token
GET /sub-account-api/session # current session info
GET /sub-account-api/endpoints
POST /sub-account-api/endpoints
GET /sub-account-api/endpoints/{id}
GET /sub-account-api/events
GET /sub-account-api/events/{id}
POST /sub-account-api/events/{id}/retry
GET /sub-account-api/events/{id}/deliveries

Terminal window
# Long-poll for events (blocks up to 60s)
curl "https://app.mittr.io/api/v1/poll?endpoint_id=ep_uuid&limit=10&timeout=30" \
-H "X-API-Key: mtr_your_key"
# Acknowledge events as processed
curl -X POST https://app.mittr.io/api/v1/poll/ack \
-H "X-API-Key: mtr_your_key" \
-H "Content-Type: application/json" \
-d '{ "endpoint_id": "ep_uuid", "event_ids": ["evt_1", "evt_2"] }'

Terminal window
# Queue statistics (snapshot)
curl "https://app.mittr.io/api/v1/stats" -H "X-API-Key: mtr_your_key"
# WebSocket stream (pushes stats every second)
# wscat -c "wss://app.mittr.io/api/v1/stats/ws?key=mtr_your_key"
# Rate limit metrics
curl "https://app.mittr.io/api/v1/metrics/rate-limits" -H "X-API-Key: mtr_your_key"
curl "https://app.mittr.io/api/v1/metrics/rate-limits/endpoint/ep_uuid" -H "X-API-Key: mtr_your_key"

Time-series and aggregate analytics over event/delivery telemetry. All endpoints accept ?endpointId=, ?from=, and ?to= (RFC3339) query parameters; aggregations bucket by hour up to 7 days and by day beyond that. Project scoping via the X-Project-ID header applies.

Terminal window
# Top-line counts (sent / delivered / failed / dead-lettered)
curl "https://app.mittr.io/api/v1/analytics/summary?from=2026-05-01T00:00:00Z&to=2026-05-25T00:00:00Z" \
-H "X-API-Key: mtr_your_key"
# Per-bucket outcomes — drives the stacked-area chart
curl "https://app.mittr.io/api/v1/analytics/outcomes?from=2026-05-18T00:00:00Z" \
-H "X-API-Key: mtr_your_key"
# Throughput (events/sec) over time
curl "https://app.mittr.io/api/v1/analytics/throughput?from=2026-05-18T00:00:00Z" \
-H "X-API-Key: mtr_your_key"
# Delivery latency percentiles (p50/p95/p99) per bucket
curl "https://app.mittr.io/api/v1/analytics/latency?from=2026-05-18T00:00:00Z" \
-H "X-API-Key: mtr_your_key"
# Failure breakdown by category (timeout / 4xx / 5xx / DNS / TLS / refused)
curl "https://app.mittr.io/api/v1/analytics/failures?from=2026-05-18T00:00:00Z" \
-H "X-API-Key: mtr_your_key"
# Per-endpoint health rollup (delivery rate, p95 latency, circuit state)
curl "https://app.mittr.io/api/v1/analytics/endpoint-health" \
-H "X-API-Key: mtr_your_key"

The public endpoint third-party platforms POST to. You don’t call this yourself — you configure the platform (Stripe, GitHub, Shopify, …) to point at the URL below. The path suffix comes from the inbound endpoint you created via POST /api/v1/inbound-endpoints.

POST https://app.mittr.io/inbound/{pathSuffix}

The platform preset baked into your inbound endpoint tells mittr which signature scheme to verify (HMAC-SHA256, SHA1, Stripe-style, etc.). On a successful signature verification the request returns 202 Accepted; on mismatch it returns 401. The fanned-out events flow through your normal delivery pipeline.


SCIM v2.0 endpoints called by an Identity Provider (Okta, Azure AD, JumpCloud) to provision/deprovision users. The IdP authenticates with a Bearer token issued from the dashboard’s SSO settings — you don’t call these endpoints directly. Standard SCIM v2 schemas apply.

GET /scim/v2/ServiceProviderConfig
GET /scim/v2/ResourceTypes
GET /scim/v2/Schemas
GET /scim/v2/Users # list with filter/pagination
POST /scim/v2/Users # create user → provisions a team member
GET /scim/v2/Users/{id}
PATCH /scim/v2/Users/{id} # update attributes / deactivate via active=false
DELETE /scim/v2/Users/{id}

All requests carry Authorization: Bearer <scim_token>. Configure the SCIM endpoint URL + token in your IdP and it does the calling. Available on Scale plan and above.


Terminal window
# Audit log
curl "https://app.mittr.io/api/v1/audit-logs?limit=50&resource=endpoint&action=create" \
-H "X-API-Key: mtr_your_key"
# GDPR export (all data as JSON)
curl "https://app.mittr.io/api/v1/gdpr/export" -H "X-API-Key: mtr_your_key"
# GDPR delete (permanently deletes everything)
curl -X DELETE "https://app.mittr.io/api/v1/gdpr/data" -H "X-API-Key: mtr_your_key"

Terminal window
# Sign up
curl -X POST https://app.mittr.io/auth/signup \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "password": "secure123", "companyName": "Acme" }'
# Log in
curl -X POST https://app.mittr.io/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "password": "secure123" }'
# SSO providers
curl https://app.mittr.io/auth/providers
# SSO login + callback (the callback URL is hit by the IdP, not by you)
# Browser: https://app.mittr.io/auth/sso/google/login
# Browser: https://app.mittr.io/auth/sso/github/login
# IdP: GET https://app.mittr.io/auth/sso/{provider}/callback?code=...&state=...
# SAML 2.0 (per-workspace IdP — configured in dashboard SSO settings)
# Browser: https://app.mittr.io/auth/sso/saml/{clientID}/{slug}/login
# Metadata XML: https://app.mittr.io/auth/sso/saml/{clientID}/{slug}/metadata
# IdP ACS: POST https://app.mittr.io/auth/sso/saml/{clientID}/{slug}/acs
# SSO discovery — given an email, returns the workspace's SSO method
# (drives the "Continue with SSO" button on the login page)
curl "https://app.mittr.io/auth/sso/[email protected]"
# Accept a team invite (token from the invitation email)
curl -X POST https://app.mittr.io/auth/accept-invite \
-H "Content-Type: application/json" \
-d '{ "token": "invite-token", "name": "Alice", "password": "secure123" }'
# Inspect a pending invite without accepting it (drives the
# accept-invite landing page's "you're being invited to X")
curl "https://app.mittr.io/auth/invite-status?token=invite-token"
# Email verification
curl -X POST https://app.mittr.io/auth/verify-email \
-H "Content-Type: application/json" \
-d '{ "token": "verification-token" }'
# Forgot password
curl -X POST https://app.mittr.io/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]" }'
# Reset password
curl -X POST https://app.mittr.io/auth/reset-password \
-H "Content-Type: application/json" \
-d '{ "token": "reset-token", "newPassword": "new-secure-password" }'
# Session management
curl -X POST https://app.mittr.io/auth/session # Create from API key
curl https://app.mittr.io/auth/session # Get current
curl -X DELETE https://app.mittr.io/auth/session # Logout

Terminal window
curl https://app.mittr.io/health

Every outbound delivery includes:

X-Mittr-Signature: v1=<hmac-sha256-hex>
X-Mittr-Timestamp: <unix-seconds>
X-Mittr-Event-ID: <event-uuid>

Verify: compute HMAC-SHA256(endpoint_secret, request_body) and compare to the v1= value.