API introduction
The SpacePost API is a JSON REST API that is compatible with the Resend API. The complete endpoint list is in the API reference, generated from the OpenAPI spec.
Base URL
Section titled “Base URL”https://api.spacepost.devPaths are at the root (/emails, /domains, …). A /v1 prefix is also accepted: https://api.spacepost.dev/v1/emails is the same endpoint. Use whichever your client prefers.
Authentication
Section titled “Authentication”Send your API key as a bearer token on every request:
curl https://api.spacepost.dev/emails -H "Authorization: Bearer sp_live_YOUR_API_KEY"Keys start with sp_live_. full_access keys can use every endpoint; sending_access keys can only send emails, optionally from one domain. See Security and API keys.
| Problem | Response |
|---|---|
No Authorization header |
401 missing_api_key |
Unknown, revoked or malformed key (including Resend re_ keys) |
403 invalid_api_key |
sending_access key on a non-sending endpoint |
401 restricted_api_key |
Requests
Section titled “Requests”- Send JSON with
Content-Type: application/json. Invalid JSON returns422 validation_error. - Fields are
snake_case(reply_to,scheduled_at). For conveniencereplyToandscheduledAtare also accepted when sending. - IDs are UUIDv7 strings; they sort by creation time, which is how pagination works.
- Timestamps are ISO 8601 in UTC (
2026-10-23T14:02:09.512Z). - Unknown fields on a request are ignored.
Responses
Section titled “Responses”Successful responses are JSON with status 200. Resources carry an object field naming their type ("email", "domain", …). Lists look like { "object": "list", "has_more": false, "data": [] }.
Errors always have the same shape:
{ "statusCode": 422, "name": "validation_error", "message": "`to`: Invalid email address" }See Errors for every name.
Idempotency
Section titled “Idempotency”POST /emails and POST /emails/batch accept an Idempotency-Key header (1 to 256 characters, remembered for 24 hours): the same key and body returns the first response instead of sending again. See Idempotency keys.
Rate limits
Section titled “Rate limits”Per team: 10 requests per second (25 on Scale), returned in ratelimit-* headers. See Rate limits.
Versioning
Section titled “Versioning”The API follows Resend’s current shapes and does not use dated versions. We only make backward-compatible changes to existing endpoints (new optional fields, new fields in responses, new event types and error names), so write clients that ignore unknown fields and handle unknown error names. Anything breaking would ship under a new path prefix with advance notice in the changelog.
The API sends permissive CORS headers so API explorers can call it, but never call it from a browser with a real key. Keys belong on servers.