Create a key to copy examples filled with your team.
Send basic transactional emails with PostShiba
Verify a domain and send your first production message.
You will create a shared-IP cluster, verify a sending domain, add the SMTP credential the cluster needs, and send one message through the REST API.
PostShiba reviews new senders before they can create a cluster. Finish that review first. Until your team is approved, cluster creation returns
403 {"error":"kyc_required"}.
What you need
- A PostShiba account with an approved team
- A domain whose DNS records you can edit
- A platform application token from Developers → Platform applications
- A server-side application that can keep that token secret
The examples use these placeholders:
CAPSULE_API_KEYis your platform application token- Team
1, cluster4, and domain8stand in for IDs from your own responses mail.example.comis the domain you will verify
Set a few shell variables so the commands are easier to read.
Run those exports in your current shell. If you save the block as setup.sh, load it with source setup.sh so later commands inherit the variables.
1. Create a cluster
A cluster is your sending environment. Customer-created clusters use PostShiba's shared IP pool.
Keep the returned id. Wait until sending_ready is true before you send. A cluster that is still starting, or one you suspended, returns cluster_not_ready.
2. Add a sending domain
Use a subdomain such as mail.example.com. It keeps your normal mailbox MX records separate from the records PostShiba needs.
The response includes the exact DNS values to publish:
Publish the DKIM CNAME and return-path CNAME exactly as returned. The SPF include is optional. PostShiba blocks sending until both dkim_status and return_path_status are verified.
Ask PostShiba to check again after you publish DNS:
DNS changes are not instant. Read the domain again and wait for the two required statuses instead of sleeping for a fixed amount of time.
Once the domain verifies, you can send from any address at that domain. There is no separate sender identity to create.
3. Issue an SMTP credential
PostShiba injects REST API messages into the cluster through an active SMTP credential. Create the credential before calling /sends.
The REST API returns the SMTP password on credential creation. Save it only if you also plan to send over SMTP. Authorized PostShiba dashboard users can currently reveal the encrypted password again. REST sends do not put that password in your application code.
4. Send a message
Start small. A from, at least one recipient, and a body are enough.
A successful request returns 201:
Check that the response has "queued": true. HTTP 201 can also carry queued: false when the injector accepts no recipients. queued: true means at least one recipient queued, not that every recipient did. Send one recipient per request when you need per-recipient certainty.
Queued mail has not reached the recipient's server yet. Use a delivery webhook or the cluster event API to learn what happened next.
Add the fields your application needs
The send API also accepts:
ccandbccheadersfor custom headersattachmentswithfilename,content_type, and base64contenttenantwhen you send for one of your own customers
When both text and html are present, PostShiba builds a multipart message. Keep the text part. It gives clients and accessibility tools a useful fallback.
This example adds a PDF attachment:
Do not put passwords, access tokens, or message contents in unique_args. PostShiba copies those values into delivery events. Good keys are IDs you already expose in logs, such as order_id, user_id, or notification_type.
Watch delivery
Create one webhook endpoint for delivery events:
Store the returned secret. Verify X-Capsule-Signature before you trust a webhook. PostShiba signs the exact body with HMAC-SHA256 over {timestamp}.{body}.
PostShiba emits processed, delivered, deferred, bounce, dropped, and spamreport. It does not emit open or click events.
Handle send errors
The send endpoint returns these error strings:
cluster_not_readymeans the cluster cannot send yetdomain_unverifiedmeans the From domain is not ready or is suspendedcredential_missingmeans the cluster has no active credential for this tenantsuppressedmeans at least one recipient is on the tenant's suppression listinvalidwith HTTP422meansfromor all recipients are missing- HTTP
502means the cluster did not accept the inject request; itserrormay beinject_failedor an upstream error string
PostShiba automatically suppresses hard bounces and spam reports. Treat a suppressed response as final until you review and remove that suppression.
PostShiba does not provide an idempotency key on this endpoint. If your connection drops after a request, you may not know whether the message queued. Put your own notification ID in unique_args, record the returned message_id, and make retry decisions in your application.