API overview
Base URL, authentication, API key types, errors, pagination, rate limits and idempotency of the Resend-compatible Stamp0 REST API.
The pages in this section are generated from the OpenAPI 3.1 document the API serves at https://api.stamp0.com/openapi.json. Every operation lists its parameters, request body, responses and errors, with request samples.
Base URL
https://api.stamp0.comPaths, request bodies, responses and errors follow Resend's for the resources Stamp0 has (/emails, /emails/batch, /emails/receiving, /domains, /api-keys, /webhooks, /suppressions, /logs, /templates, /contacts, /contact-properties, /broadcasts, /topics, /segments, /audiences), so the official Resend SDKs work once their base URL points here. The migration guide lists what is not supported yet or behaves differently, and Resend aliases shows how Resend's marketing paths map to Stamp0's. Stamp0's own resources sit next to them: /events (plus /emails/{id}/events and /webhooks/{id}/deliveries), /inboxes, /connections and /deliverability for sending, and /properties, /lists, /companies, /campaigns, /sequences, /forms and /settings/marketing for marketing. /v1/… is an alias of every path.
import { Resend } from 'resend';
const resend = new Resend(process.env.STAMP0_API_KEY, { baseUrl: 'https://api.stamp0.com' });@stamp0/sdk extends that client with the Stamp0-only resources.
Authentication
Send a project API key as a bearer token:
Authorization: Bearer s0_…A key belongs to one project. Create keys in the dashboard under Developers → API keys, or with POST /api-keys; the token is shown once.
| Key | Can call |
|---|---|
| Full access | Every endpoint of its project, and read access to the organization's /connections (without the external ID or setup link; connections are managed in the dashboard) |
| Sending access | POST /emails and POST /emails/batch only |
Sending access with domain_id | Sending only, and only from that domain |
Agent key (sending access with inbox_id) | One inbox: its threads, messages, drafts and received mail, and sending from its address. See agent keys |
The API sends no CORS headers: call it from your server, never from a browser.
Errors
Errors use Resend's body, so SDK error handling keeps working:
{ "statusCode": 422, "name": "validation_error", "message": "html or text is required" }| Status | Names |
|---|---|
| 400 | invalid_idempotency_key |
| 401 | missing_api_key, restricted_api_key, unauthorized |
| 403 | invalid_api_key, invalid_access, security_error, plan_limit_exceeded |
| 404 | not_found |
| 405 | method_not_allowed |
| 409 | invalid_idempotent_request, concurrent_idempotent_requests, conflict, connection_not_ready |
| 422 | validation_error, missing_required_field, invalid_parameter, invalid_region, invalid_from_address, invalid_attachment, invalid_scheduled_at |
| 429 | rate_limit_exceeded, daily_quota_exceeded, monthly_quota_exceeded |
| 500 | application_error, internal_server_error |
| 501 | provider_not_configured |
| 502 | provider_error |
A body without a required field answers Resend's missing_required_field (for example Missing `to` field.). Two statuses differ from Resend on purpose: invalid_access is 403 (Resend: 422) and security_error is 403 (Resend: 451).
Stamp0 adds a few names to Resend's:
invalid_scheduled_at:scheduled_atis not a time Stamp0 can schedule (in the past, more than 30 days ahead, or not understood).connection_not_ready: the AWS connection the request needs is notconnectedyet (see Connect AWS).conflict: the request clashes with the current state, for example an SES identity for the domain already exists in your account and Stamp0 did not create it, or the resource changed since you read it.plan_limit_exceeded: creating the resource would exceed your plan (projects, connections, domains, webhook endpoints, contacts). Connections are counted per provider: Free and Pro include one SES connection and one Cloudflare connection (beta); Scale has no limit. On Free, sending beyond 50,000 emails in a calendar month (UTC) answers429 monthly_quota_exceededwith aretry-afterheader.provider_error: SES returned an error; the message says which.
Pagination
List endpoints return Resend's list shape:
{ "object": "list", "has_more": true, "data": [ … ] }Pass limit (1–100) and either after or before with an ID from the previous page.
Rate limits
Each project has a token bucket of 10 requests per second with bursts up to 20. Every response carries ratelimit-limit (the bucket size, 20), ratelimit-remaining (never more than the limit), ratelimit-reset (seconds until the bucket is full again) and ratelimit-policy (20;w=2); a 429 rate_limit_exceeded also carries retry-after in seconds.
Idempotency
POST /emails and POST /emails/batch accept an Idempotency-Key header of up to 256 characters, remembered for 24 hours. See Send email. POST /events takes one too (or idempotency_key in the body): a retry returns the first event. See Events.
IDs
IDs are prefixed by type and are opaque strings: em_ emails, evt_ email events, rcv_ received emails, dom_ domains, snd_ senders, key_ API keys, whk_ webhooks, whd_ webhook deliveries, ibx_ inboxes, thr_ threads, msg_ messages, drf_ drafts, con_ connections, sup_ suppressions, req_ request logs, prj_ projects.
Marketing: ct_ contacts, prop_ properties, lst_ lists (Resend topics, manual segments and audiences), seg_ filter segments, co_ companies, cim_ contact imports, cev_ custom events, tpl_ templates, tplv_ template versions, cmp_ campaigns (and broadcasts), seq_ sequences, enr_ sequence enrollments, frm_ forms.