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.