Send emails with Elixir
Install the Elixir SDK from GitHub and call Emails.send.
What you'll build
An Elixir script that sends a receipt email with the postshiba package and prints the queued message.
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.
frommust be an address on it. - A cluster that is ready to send (
sending_readyistrue). See Clusters. - Elixir 1.15 or later.
Install
The package is on GitHub, not Hex. Add it to deps/0 in mix.exs, then run mix deps.get.
Send your first email
Create a client with your API key, then call PostShiba.Emails.send/2 with a map. PostShiba.new/3 also takes a base URL and a team id for team-scoped calls such as listing clusters. Those calls need a Full access key that stays out of your deployed app.
Run it from your project with mix run send.exs. Emails.send returns the decoded JSON body of the 201 response as a map, not an {:ok, body} tuple. The message then shows under Events in the dashboard.
Pin a cluster
Without a pin, PostShiba uses your first cluster that is ready to send. Pass cluster_id to choose one.
Attachments and templates
Attach a file
Add attachments with filename, content_type, and base64 content. Up to 10 files, 18 MB in total. See Attachments for allowed types.
Send a published template
Pass template with the alias or public id and its variables. Leave out html and text.
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 with
System.fetch_env!("POSTSHIBA_API_KEY")instead of a string in your code. 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
A response outside 2xx raises PostShiba.Error with error, field, and message. It does not return {:error, reason}.
| 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. A Send only key gets this on any call other than sending. |
403 |
domain_unverified |
from is not on a verified domain. |
403 |
kyc_required |
Your team is pending production approval. Until then, send only to team members, live inbox addresses, and inbox forward-to addresses. |
422 |
invalid |
field names the problem, such as a missing to, an unpublished template, or a rejected attachment. |
429 |
throttled |
The cluster hit its hourly throttle or 24-hour cap. The client does not retry, and 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. |
Every other status is on Errors.
Next steps
- Send emails with Phoenix to deliver through Swoosh.
- Unique args to get your own ids back on delivery webhooks.
- Managing webhooks to receive delivery events.
- SDKs for every language client.