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.
Authentication
Section titled “Authentication”# 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/eventsError format
Section titled “Error format”{ "error": "Human-readable error message", "code": "MACHINE_CODE"}| Code | HTTP | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid API key/session |
NOT_FOUND | 404 | Resource not found |
BAD_REQUEST | 400 | Invalid request body or parameters |
CONFLICT | 409 | Duplicate idempotency key or invalid state transition |
RATE_LIMITED | 429 | Rate limit exceeded (see Retry-After header) |
QUOTA_EXCEEDED | 402 | Monthly message quota exceeded |
INVALID_STATE | 409 | Operation not allowed in current state |
Pagination
Section titled “Pagination”All list endpoints use cursor-based pagination:
# First pagecurl "https://app.mittr.io/api/v1/events?limit=20"
# Next pagecurl "https://app.mittr.io/api/v1/events?limit=20&cursor=c89f3557-326a-470e"Response always includes:
{ "data": [...], "pagination": { "hasMore": true, "cursor": "next_page_token" }}Rate limiting
Section titled “Rate limiting”When rate-limited, the response includes:
HTTP/1.1 429 Too Many RequestsX-RateLimit-Limit: 100X-RateLimit-Remaining: 0X-RateLimit-Reset: 1712678460Retry-After: 5Events
Section titled “Events”Create event
Section titled “Create event”POST /api/v1/eventsCreates a webhook event for delivery. Requires X-Idempotency-Key header.
Request fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
destination | string | * | Direct delivery URL | |
eventType | string | * | Fan-out to subscribed endpoints | |
payload | object | yes | JSON payload to deliver | |
headers | object | no | Custom HTTP headers included in delivery | |
maxAttempts | int | no | 5 | Override max delivery attempts for this event. Capped at 25 system-wide; values above 25 are silently clamped. |
priority | int | no | 5 | 1 (highest) to 10 (lowest) |
delaySeconds | int | no | 0 | Delay delivery by N seconds |
*Either destination or eventType is required (not both).
Example — fan-out by event type:
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:
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"}List events
Section titled “List events”GET /api/v1/events?status=delivered&limit=20&cursor=...Query parameters: status (queued/delivering/delivered/failed/dead), limit (1-100, default 20), cursor.
curl "https://app.mittr.io/api/v1/events?status=failed&limit=10" \ -H "X-API-Key: mtr_your_key"Get event
Section titled “Get event”GET /api/v1/events/{eventId}Returns full event with delivery attempt history.
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" } ]}Update event (edit & resend)
Section titled “Update event (edit & resend)”PATCH /api/v1/events/{eventId}Edit destination, payload, or headers on a failed/dead event. Optionally replay.
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 }'| Field | Type | Description |
|---|---|---|
destination | string | New destination URL |
payload | object | New payload |
headers | object | New headers |
replay | bool | Reset attempts and re-queue |
Replay event
Section titled “Replay event”POST /api/v1/events/{eventId}/replayRe-queues a failed/dead event as-is with reset attempt counter. No request body.
curl -X POST "https://app.mittr.io/api/v1/events/c89f3557-.../replay" \ -H "X-API-Key: mtr_your_key"Batch create events
Section titled “Batch create events”POST /api/v1/events/batchCreate 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
destinationper event) - No fan-out (use the single-event endpoint with
eventTypefor routing) - No scheduling (
delaySeconds) or non-default priority - Each event must have its own unique
idempotencyKey
Request:
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:
| Status | Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | Empty events array, missing fields |
| 400 | BATCH_TOO_LARGE | More than 100 events |
| 402 | QUOTA_EXCEEDED | Client quota exhausted |
| 409 | DUPLICATE_EVENT | One or more idempotency keys already exist |
Batch retry
Section titled “Batch retry”POST /api/v1/events/batch/retry# Retry by IDscurl -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 eventscurl -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 endpointcurl -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 }'Deliveries
Section titled “Deliveries”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.
Query deliveries (list with filters)
Section titled “Query deliveries (list with filters)”GET /api/v1/deliveriesPaginated list of delivery attempts across all events, with time-range and outcome filters.
# Last 24 hourscurl "https://app.mittr.io/api/v1/deliveries?range=24h&limit=50" \ -H "X-API-Key: mtr_your_key"
# Custom range with filterscurl "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.
List deliveries for an event
Section titled “List deliveries for an event”GET /api/v1/events/{eventId}/deliveriesReturns every attempt recorded for the event, in chronological order.
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 a delivery attempt
Section titled “Get a delivery attempt”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).
curl https://app.mittr.io/api/v1/deliveries/5f9d8a2b-1c4e-4f3a-9b8c-7d2e1f4a5b6c \ -H "X-API-Key: mtr_your_key"Endpoints
Section titled “Endpoints”Create endpoint
Section titled “Create endpoint”POST /api/v1/endpointscurl -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:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | yes | Webhook destination URL | |
eventTypes | string[] | yes | Subscribe to these types (supports * wildcard) | |
description | string | no | ||
filter | object | no | JSONPath content filter | |
transformation | string | no | JavaScript transform code | |
fifo | bool | no | false | Enable ordered delivery |
fifoPartitionKey | string | no | JSONPath for partition (e.g. $.data.orderId) | |
maxRetries | int | no | 5 | Max delivery attempts |
retryBackoffMs | int | no | 1000 | Initial backoff in ms |
retryBackoffMax | int | no | 86400000 | Max backoff in ms (24h) |
retryBackoffMult | float | no | 2.0 | Backoff multiplier |
timeoutMs | int | no | 30000 | HTTP request timeout in ms |
rateLimitPerSec | int | no | 0 | Rate limit (0 = unlimited, capped by plan) |
circuitThreshold | int | no | 5 | Consecutive failures to trip breaker |
circuitResetMs | int | no | 300000 | Breaker recovery interval in ms (5 min) |
customHeaders | object | no | Static headers sent with every delivery | |
allowedCidrs | string[] | no | IP allowlist in CIDR notation | |
blockedCidrs | string[] | no | IP blocklist in CIDR notation | |
deliveryMode | string | no | push | push, poll, or storage |
storageConfig | object | no | Required when deliveryMode is storage. See Storage Sinks | |
signingSecret | string | no | Custom per-endpoint signing secret (overrides global) | |
mtlsCert | string | no | PEM client certificate for mTLS | |
mtlsKey | string | no | PEM private key for mTLS |
Example with FIFO and filter:
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 }'List endpoints
Section titled “List endpoints”curl "https://app.mittr.io/api/v1/endpoints?limit=20" \ -H "X-API-Key: mtr_your_key"Get endpoint
Section titled “Get endpoint”curl "https://app.mittr.io/api/v1/endpoints/ep_uuid" \ -H "X-API-Key: mtr_your_key"Update endpoint
Section titled “Update endpoint”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 }'Delete endpoint
Section titled “Delete endpoint”curl -X DELETE "https://app.mittr.io/api/v1/endpoints/ep_uuid" \ -H "X-API-Key: mtr_your_key"Pause / Resume
Section titled “Pause / Resume”# 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"
# Resumecurl -X POST "https://app.mittr.io/api/v1/endpoints/ep_uuid/resume" \ -H "X-API-Key: mtr_your_key"Upload mTLS client certificate
Section titled “Upload mTLS client certificate”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-----" }'Remove mTLS certificate
Section titled “Remove mTLS certificate”curl -X DELETE "https://app.mittr.io/api/v1/endpoints/ep_uuid/mtls" \ -H "X-API-Key: mtr_your_key"Endpoint versioning
Section titled “Endpoint versioning”# List version historycurl "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions" \ -H "X-API-Key: mtr_your_key"
# Get specific versioncurl "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions/3" \ -H "X-API-Key: mtr_your_key"
# Diff two versionscurl "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions/diff?v1=1&v2=3" \ -H "X-API-Key: mtr_your_key"
# Rollback to versioncurl -X POST "https://app.mittr.io/api/v1/endpoints/ep_uuid/versions/2/rollback" \ -H "X-API-Key: mtr_your_key"Event Types
Section titled “Event Types”Create event type
Section titled “Create event type”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" }'List / Get / Update / Delete
Section titled “List / Get / Update / Delete”# Listcurl "https://app.mittr.io/api/v1/event-types" -H "X-API-Key: mtr_your_key"
# Get by IDcurl "https://app.mittr.io/api/v1/event-types/et_uuid" -H "X-API-Key: mtr_your_key"
# Get by namecurl "https://app.mittr.io/api/v1/event-types/by-name/order.created" -H "X-API-Key: mtr_your_key"
# Updatecurl -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" }'
# Deletecurl -X DELETE "https://app.mittr.io/api/v1/event-types/et_uuid" -H "X-API-Key: mtr_your_key"Inbound Endpoints
Section titled “Inbound Endpoints”Create inbound endpoint
Section titled “Create inbound endpoint”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).
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name |
pathSuffix | string | yes | URL path segment |
source | string | yes | Platform preset (130+ available) |
sourceConfig | object | no | Credentials (varies by verification mode) |
destinationIds | string[] | no | Forward to specific endpoints |
eventTypeMapping | string | no | JSONPath to extract event type |
description | string | no | |
transformation | string | no | JavaScript transform |
List platform presets
Section titled “List platform presets”curl "https://app.mittr.io/api/v1/inbound-presets" -H "X-API-Key: mtr_your_key"Returns 130+ presets with source, name, description, mode.
List / Get / Update / Delete
Section titled “List / Get / Update / Delete”# Listcurl "https://app.mittr.io/api/v1/inbound-endpoints" -H "X-API-Key: mtr_your_key"
# Getcurl "https://app.mittr.io/api/v1/inbound-endpoints/inb_uuid" -H "X-API-Key: mtr_your_key"
# Updatecurl -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" }'
# Deletecurl -X DELETE "https://app.mittr.io/api/v1/inbound-endpoints/inb_uuid" -H "X-API-Key: mtr_your_key"Alert Rules
Section titled “Alert Rules”Create alert rule
Section titled “Create alert rule”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:
| Type | Required | Optional |
|---|---|---|
slack | webhookUrl | channel, message |
email | to (string[]) | subject, message |
webhook | webhookUrl | headers, message |
pagerduty | routingKey | severity, message |
List / Get / Update / Delete / Enable / Disable
Section titled “List / Get / Update / Delete / Enable / Disable”# List rulescurl "https://app.mittr.io/api/v1/alerting/rules" -H "X-API-Key: mtr_your_key"
# Get rulecurl "https://app.mittr.io/api/v1/alerting/rules/rule_uuid" -H "X-API-Key: mtr_your_key"
# Update rulecurl -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 rulecurl -X DELETE "https://app.mittr.io/api/v1/alerting/rules/rule_uuid" -H "X-API-Key: mtr_your_key"
# Enable / Disablecurl -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 manuallycurl -X POST "https://app.mittr.io/api/v1/alerting/evaluate" -H "X-API-Key: mtr_your_key"
# Alert historycurl "https://app.mittr.io/api/v1/alerting/history?limit=20" -H "X-API-Key: mtr_your_key"Connectors
Section titled “Connectors”Create connector
Section titled “Create connector”# Slackcurl -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" } }'
# Emailcurl -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]", "toEmails": ["[email protected]", "[email protected]"] } }'Types: slack, discord, teams, email, webhook
List / Get / Update / Delete
Section titled “List / Get / Update / Delete”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"API Keys
Section titled “API Keys”Create API key
Section titled “Create API key”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"}List / Revoke
Section titled “List / Revoke”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"# List memberscurl "https://app.mittr.io/api/v1/team" -H "X-API-Key: mtr_your_key"
# Invite membercurl -X POST https://app.mittr.io/api/v1/team/invite \ -H "X-API-Key: mtr_your_key" \ -H "Content-Type: application/json" \
# 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 membercurl -X DELETE "https://app.mittr.io/api/v1/team/user_uuid" -H "X-API-Key: mtr_your_key"Projects
Section titled “Projects”# Listcurl "https://app.mittr.io/api/v1/projects" -H "X-API-Key: mtr_your_key"
# Createcurl -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" }'
# Updatecurl -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" }'
# Deletecurl -X DELETE "https://app.mittr.io/api/v1/projects/proj_uuid" -H "X-API-Key: mtr_your_key"Account & Settings
Section titled “Account & Settings”# Get account infocurl "https://app.mittr.io/api/v1/me" -H "X-API-Key: mtr_your_key"
# Complete onboardingcurl -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 limitscurl "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"Usage & Billing
Section titled “Usage & Billing”# Current period usagecurl "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 fetchescurl "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"Sub-Accounts (Embedded Portal)
Section titled “Sub-Accounts (Embedded Portal)”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.
Create sub-account
Section titled “Create sub-account”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" } }'List / Get / Update / Deactivate
Section titled “List / Get / Update / Deactivate”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"Mint a portal session (embed link)
Section titled “Mint a portal session (embed link)”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.
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=..." }List / revoke active sessions
Section titled “List / revoke active sessions”curl "https://app.mittr.io/api/v1/sub-accounts/{id}/sessions" -H "X-API-Key: mtr_your_key"# Revoke a single sessioncurl -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-accountcurl -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 tokenGET /sub-account-api/session # current session infoGET /sub-account-api/endpointsPOST /sub-account-api/endpointsGET /sub-account-api/endpoints/{id}GET /sub-account-api/eventsGET /sub-account-api/events/{id}POST /sub-account-api/events/{id}/retryGET /sub-account-api/events/{id}/deliveriesPolling (Pull-based delivery)
Section titled “Polling (Pull-based delivery)”# 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 processedcurl -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"] }'Stats & Metrics
Section titled “Stats & Metrics”# 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 metricscurl "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"Analytics
Section titled “Analytics”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.
# 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 chartcurl "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 timecurl "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 bucketcurl "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"Inbound webhook ingestion
Section titled “Inbound webhook ingestion”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 Provisioning
Section titled “SCIM v2 Provisioning”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/ServiceProviderConfigGET /scim/v2/ResourceTypesGET /scim/v2/SchemasGET /scim/v2/Users # list with filter/paginationPOST /scim/v2/Users # create user → provisions a team memberGET /scim/v2/Users/{id}PATCH /scim/v2/Users/{id} # update attributes / deactivate via active=falseDELETE /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.
Compliance
Section titled “Compliance”# Audit logcurl "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"Auth (Public endpoints)
Section titled “Auth (Public endpoints)”# Sign upcurl -X POST https://app.mittr.io/auth/signup \ -H "Content-Type: application/json" \
# Log incurl -X POST https://app.mittr.io/auth/login \ -H "Content-Type: application/json" \
# SSO providerscurl 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)
# 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 verificationcurl -X POST https://app.mittr.io/auth/verify-email \ -H "Content-Type: application/json" \ -d '{ "token": "verification-token" }'
# Forgot passwordcurl -X POST https://app.mittr.io/auth/forgot-password \ -H "Content-Type: application/json" \
# Reset passwordcurl -X POST https://app.mittr.io/auth/reset-password \ -H "Content-Type: application/json" \ -d '{ "token": "reset-token", "newPassword": "new-secure-password" }'
# Session managementcurl -X POST https://app.mittr.io/auth/session # Create from API keycurl https://app.mittr.io/auth/session # Get currentcurl -X DELETE https://app.mittr.io/auth/session # LogoutHealth
Section titled “Health”curl https://app.mittr.io/healthWebhook Signature
Section titled “Webhook Signature”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.