The Sendmux Management API gives you programmatic access to your email workspace: manage sending accounts, domains, mailboxes, API keys, and webhook subscriptions; read metrics and delivery logs; track billing balance and history.
Base URL
All API requests should be made to:
https://app.sendmux.ai/api/v1
Authentication
Authenticate using an API key from the Sendmux app. Pass it as a Bearer token in the Authorization header.
curl https://app.sendmux.ai/api/v1/providers \
-H "Authorization: Bearer smx_root_your_key_here"
API keys are scoped to a team and carry specific permissions. Create and manage keys under Settings > API Keys in the Sendmux app. Each team starts with 100 active API keys across root keys and mailbox-class credentials, including send-only and mailbox-scoped keys. See Team limits.
Permissions
Each endpoint requires a specific permission. Keys with wildcard permissions (e.g. domain.*) satisfy any permission in that namespace, and the built-in root:full role includes every wildcard.
| Endpoint group | Required permission(s) |
|---|
| Sending accounts | provider.read for reads; provider.create for custom SMTP account creation and sending-account limit requests; provider.update for edits, activation, connection tests, and shared Amazon SES limit requests; provider.delete for delete. |
| Email metrics | analytics.read |
| Email logs | logs.read |
| Billing | billing.read |
| Domains | domain.read for reads; domain.create, domain.verify, domain.delete for the matching mutations. |
| Mailboxes | mailbox.admin.read for reads; mailbox.admin.create for create; mailbox.admin.delete for delete; mailbox.admin.manage for update, filter management, and per-mailbox API-key management. |
| Webhooks | webhook.read for reads; webhook.create, webhook.update, webhook.delete for the matching mutations; webhook.manage for rotate-secret and test. |
Use the root:readonly role for monitoring integrations. It covers every
*.read permission. root:webhook_admin is a narrower preset for keys that
should only manage webhook subscriptions. root:provider_admin is a narrower
preset for keys that manage sending accounts, routing, domains, and logs.
All responses use a consistent JSON envelope.
Success
{
"ok": true,
"data": { ... },
"meta": {
"request_id": "req_clxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
Paginated success
List endpoints include a pagination object alongside data.
{
"ok": true,
"data": [ ... ],
"pagination": {
"has_more": true,
"next_cursor": "dlog_xxxxxxxx"
},
"meta": {
"request_id": "req_clxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
Error
{
"ok": false,
"error": {
"code": "invalid_parameter",
"message": "The 'from_date' parameter must be a valid ISO 8601 date.",
"param": "from_date",
"doc_url": "https://sendmux.ai/docs/api/errors#invalid_parameter",
"retryable": false
},
"meta": {
"request_id": "req_clxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
The retryable flag distinguishes transient failures (back off and retry) from permanent ones (fix the request). See the errors reference for the full envelope shape, the accumulated errors[] array on validation failures, and the Retry-After header semantics for 429/503.
Errors
| HTTP status | Error code | Default retryable | Description |
|---|
| 400 | invalid_parameter | false | Bad query parameter format or syntactic body validation failure. |
| 400 | missing_parameter | false | Required parameter missing. |
| 401 | authentication_required | false | No or invalid API key. |
| 403 | insufficient_permissions | false | Key lacks required permission. |
| 404 | not_found | false | Resource does not exist or belongs to a different team. |
| 409 | conflict | false | Resource state forbids the operation (e.g. If-Match mismatch). |
| 409 | limit_exceeded | false | Team resource limit reached for a create request. |
| 409 | idempotency_conflict | false | Idempotency-Key reused with a different body or while in-flight. |
| 413 | payload_too_large | false | Request body exceeds the server-side size limit. |
| 422 | validation_error | false | Body parsed but violates a semantic rule. |
| 429 | rate_limit_exceeded | true | Rate limit hit. Retry-After header included. |
| 500 | internal_error | true | Unexpected server error. |
| 503 | service_unavailable | true | Downstream component briefly unavailable. May include Retry-After. |
Rate limits
Each Management API key is rate-limited to 600 requests per 60 seconds.
Sending API keys are limited separately to 1,800 requests per 60 seconds on the Sending API. See the Sending API introduction.
Every response carries the current rate-limit state plus a request identifier:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 594
X-RateLimit-Reset: 1679313700
X-Request-Id: req_clxxxxxxxxxxxxxxxxxxxxxxxxx
X-Request-Id matches meta.request_id in the JSON envelope. Include it when contacting support.
When the limit is exceeded, the API returns a 429 status with a Retry-After header indicating how many seconds to wait before retrying.
Conditional requests
Every GET that returns a single resource emits a weak ETag. Send it back on the next request to avoid transferring unchanged data, and use If-Match on writes that document the header for optimistic concurrency control.
If-None-Match on a GET: if the resource is unchanged, the API responds 304 Not Modified with no body. Reuse your cached copy.
If-Match on a PATCH, PUT, or supported DELETE: if the resource changed since you fetched it, the API responds 409 conflict so you do not overwrite a concurrent update. Re-fetch, reapply your change, and retry.
Conditional requests are supported across mailbox, domain, webhook, and log resource GETs, and on the Sending API.
Sending account management
Use the Management API’s Sending accounts group to manage accounts used by the Sending API. Custom SMTP accounts support full create, read, update, delete, activation, deactivation, usage, and connection-test flows.
Connected account setup still starts in the Sendmux app. After connection, the API can read, activate, deactivate, delete, and update safe account metadata.
The shared Amazon SES account is protected. You can read it, activate or deactivate it, and request a daily limit increase. You cannot edit its credentials, quotas, routing weight, sender defaults, or delete it through the API.
Conventions
- snake_case fields in all JSON responses
- UTC ISO 8601 timestamps in RFC 3339 format:
2026-03-19T10:30:00Z
- Public IDs only. Private numeric IDs are never exposed.
Cache-Control: no-store on all responses
- JSON only. Use
Content-Type: application/json.
OpenAPI specification
The full OpenAPI 3.1 specification is available at:
https://app.sendmux.ai/api/v1/openapi.json
Use it with any OpenAPI-compatible tool to generate client libraries or explore the API.
You can also import the Management API Postman collection by URL.