Sign in to fill these examples with your own keys. Sign in Start free trial

Send emails with HTTP

Queue a message with curl and a Bearer token.

What you'll build

A single curl request that queues an email through POST /api/v1/emails. Any language with an HTTP client can make the same call.

Before you start

  • An API key with Send only access. Full access also works. See Create an API key. Support keys cannot send.
  • A verified sending domain. See Add and verify a domain. from must be an address on it.
  • A cluster that is ready to send (sending_ready is true). See Clusters.

Install

Nothing to install. The examples use curl.

Send your first email

POST JSON with your API key as a Bearer token.

send-emails.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -d '{ 5 "from": "hello@mail.example.com", 6 "to": ["you@example.com"], 7 "subject": "Your receipt", 8 "text": "Thanks for your order.", 9 "html": "<p>Thanks for your order.</p>", 10 "unique_args": {"order_id": "ord_123"} 11 }' \ 12 https://app.postshiba.com/api/v1/emails

A queued send returns 201 Created. The message then shows under Events in the dashboard.

response.json
1{ 2 "queued": true, 3 "message_id": "abc@capsule.test", 4 "from": "hello@mail.example.com", 5 "to": ["you@example.com"], 6 "subject": "Your receipt", 7 "unique_args": {"order_id": "ord_123"} 8}

to, cc, and bcc take an array or a comma-separated string. Every field is on Sending.

Pin a cluster

Without a pin, PostShiba uses your first cluster that is ready to send. Add X-Capsule-Cluster-Id to choose one. The cluster id is on the API keys page.

pin-cluster.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -H 'X-Capsule-Cluster-Id: NmQpXr' \ 5 -d '{"from": "hello@mail.example.com", "to": ["you@example.com"], "subject": "Hello", "text": "Hello"}' \ 6 https://app.postshiba.com/api/v1/emails

For high-volume sending, use SMTP or HTTP inject. See Send emails with SMTP and Sending.

Attachments and templates

Attach a file

Add an attachments array. Each item has filename, content_type, and base64 content. The API accepts up to 10 files, 18 MB in total. Allowed types are images (including SVG and HEIC), PDF, EPUB, Office and OpenDocument files, RTF, plain text, CSV, zip archives, contact cards, and calendar invites. Files are scanned for viruses.

send-attachment.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -d '{ 5 "from": "hello@mail.example.com", 6 "to": ["you@example.com"], 7 "subject": "Your photo", 8 "text": "See attached.", 9 "attachments": [ 10 { 11 "filename": "photo.png", 12 "content_type": "image/png", 13 "content": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==" 14 } 15 ] 16 }' \ 17 https://app.postshiba.com/api/v1/emails

Send a published template

Pass template with the template's alias or public id and its variables. Leave out html and text. The template must be published.

send-template.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -d '{ 5 "from": "hello@mail.example.com", 6 "to": ["you@example.com"], 7 "template": {"id": "welcome", "variables": {"name": "Ada"}} 8 }' \ 9 https://app.postshiba.com/api/v1/emails

Keep the key safe

Use a Send only key in your app. It can send email and call GET /api/v1/users/me. Every other request returns 403 forbidden.

If this key leaks Send only Full access
Send mail from your verified domains Yes Yes
Read events, recipients, templates, and sent messages No Yes
See SMTP passwords and webhook secrets No Yes
Change clusters, domains, credentials, webhooks, and suppressions No Yes
  • Keep Full access keys for setup scripts, the CLI, and MCP. Don't deploy one with your app.
  • Read the key from an environment variable such as POSTSHIBA_API_KEY and send it as Authorization: Bearer $POSTSHIBA_API_KEY. Don't commit it, log it, or put it in a URL.
  • Send from your server. Never put a key, even a Send only key, in browser or mobile code.
  • Create one key per app and environment. If a key leaks, delete it on API keys and create a new one. Deleting stops it straight away.

Troubleshooting

Errors are JSON with an error string. Send errors also include field and message.

Status error What to do
401 Invalid token or no user signed in The API key is missing, mistyped, or deleted. Copy it again from API keys.
403 forbidden Support keys cannot send. Use a Send only or Full access key. A Send only key gets this on any call other than sending.
403 domain_unverified from is not on a verified domain. Finish Add and verify a domain.
403 domain_suspended The From domain is paused. Resume it from Managing domains.
403 kyc_required Your team is pending production approval. Until then, send only to team members, live inbox addresses, and inbox forward-to addresses. See Does PostShiba require production approval?
422 invalid field names the problem, such as a missing to, an unknown tenant, an unpublished template, or an attachment that is too large or not an allowed type.
429 throttled The cluster hit its hourly throttle or 24-hour cap. Retrying right away hits the same cap. See What happens at your cap.
429 rate_limited More than 300 send requests in one minute on one API key. Slow down and try again.

Every other status is on Errors.

Next steps