REST API
Bearer tokens, team isolation, and OpenAPI.
The PostShiba REST API covers the same resources as the dashboard, including clusters, domains, tenants, inboxes, webhooks, templates, and sending. It takes JSON and returns JSON.
Base URL
The OpenAPI spec is at /api/v1/openapi.yaml. Language clients are on SDKs. This reference uses curl.
Authentication
Send an API key as a Bearer token on every request. Each key belongs to one team and can only see that team's data. See Create an API key.
A missing or invalid key returns 401. Each key has one of three access levels:
- Send only can call only
POST /emails,POST /teams/{team_id}/clusters/{cluster_id}/sends, andGET /users/me. Use it for apps that only send mail. - Full access can call every endpoint.
- Support can call only
GET /users/meand the recipient, analytics, status, events, and suppression endpoints.
Any other request with a Send only or Support key returns 403 forbidden.
Ids
Ids are short public strings such as KjkAJW, never database numbers. Team-scoped paths take your team id, for example /api/v1/teams/{team_id}/clusters. Copy the team id and cluster ids from API keys in the dashboard.
A team id that doesn't match the key returns 404 team_mismatch. A record that doesn't exist, or belongs to another team, returns 404.
Request bodies
Most create and update requests wrap fields in the resource name, such as {"cluster": {...}} or {"sending_domain": {...}}. Send, network, and suppression import requests take a flat body. Each endpoint's example shows its shape.
Send Content-Type: application/json with every request that has a body.
Lists
Most lists return every matching row. Inbound messages return the newest 200 rows after filters. Events and suppressions are cursor-paginated. Pass the last id you saw as after, or for events pass before to page newest-first, and set limit up to 1000. The default limit is 200 for events and 100 for suppressions.
Rate limits
Each API key has these budgets:
| Requests | Limit |
|---|---|
POST /emails and POST /sends |
300 per minute |
| Creating SMTP credentials, inboxes, and sending domains, and running domain or inbox verification | 60 per hour |
| Suppression imports | 60 per hour |
| MCP requests | 600 per minute |
All of a team's API keys also share one send budget of 600 per minute across POST /emails and POST /sends. A send request body over 36 MB returns 413 {"error": "payload_too_large", "field": "body"}.
Going over returns 429 {"error": "rate_limited"}. Cluster sending capacity is separate. A send over your cluster's hourly or 24-hour cap returns 429 {"error": "throttled"}. See Errors and What happens at your cap.