Free email API
Free email API to send from your code
One POST /emails request sends the email. REST API with an API key, SDKs for Node.js and PHP, batch sending, scheduling and webhooks, all on the Free plan.
Free plan, no credit card
curl -X POST https://api.postal.so/emails \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Loja Exemplo <[email protected]>",
"to": ["[email protected]"],
"subject": "Your order #10482 is out for delivery",
"html": "<p>Order <b>#10482</b> is on its way.</p>"
}'No cost
What the Free plan includes
The numbers come straight from the plan, always up to date.
Resources
Everything the API does
The features of an email API for your product, without asking for a paid plan.
Single and batch sending
One email per request, or up to 100 in one. In a batch, either all are queued or none are.
Scheduling
Pass scheduled_at with a date and time up to 30 days ahead.
Templates with variables
Send with template and variables: the HTML stays in the dashboard and your code only sends the values.
Webhooks and events
Receive delivery, bounce, open, click and complaint in your system, with a signature to verify.
Idempotency and retry
Resend without fear of duplicating: the idempotency key guarantees a single send.
MCP server
Connect Claude, Cursor and other AI tools to your account through the MCP server.
See how to connectHow to start
Send your first email in 3 steps
Create the account and verify the domain
In the dashboard, under Domains, add the domain and create the DNS records shown.
Getting startedCreate an API key
Under API keys, create a send-only key and store it in POSTAL_API_KEY.
Make a POST /emails
Use the example alongside (cURL, Node.js, PHP or Python) with a sender from your verified domain.
API referenceCode
Examples in several languages
Swap in your key and sender.
curl -X POST https://api.postal.so/emails \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Loja Exemplo <[email protected]>",
"to": ["[email protected]"],
"subject": "Your order #10482 is out for delivery",
"html": "<p>Order <b>#10482</b> is on its way.</p>"
}'import { Postal } from 'postal-so'
const postal = new Postal() // reads POSTAL_API_KEY
const { id } = await postal.emails.send(
{
from: 'My company <[email protected]>',
to: '[email protected]',
subject: 'Welcome!',
html: '<p>Great to have you here.</p>',
text: 'Great to have you here.',
},
{ idempotencyKey: 'welcome-42' },
)use Postal\Client;
$postal = new Client(); // reads POSTAL_API_KEY
$result = $postal->emails->send([
'from' => 'My company <[email protected]>',
'to' => '[email protected]',
'subject' => 'Welcome!',
'html' => '<p>Great to have you here.</p>',
]);import os
import requests
response = requests.post(
"https://api.postal.so/emails",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"from": "Loja Exemplo <[email protected]>",
"to": ["[email protected]"],
"subject": "Your order #10482 is out for delivery",
"html": "<p>Order <b>#10482</b> is on its way.</p>",
},
timeout=10,
)
data = response.json(){
"from": "Loja Exemplo <[email protected]>",
"to": "[email protected]",
"template": {
"id": "order-shipped",
"variables": { "NAME": "Ana", "ORDER": "10482" }
}
}Compatible
Already using Resend? Just swap the URL and the key
Postal's API uses the same features and formats, so you can keep the SDK you already have.
Antes
base URL: https://api.resend.com
chave: re_…
Depois
base URL: https://api.postal.so
chave: ps_…Questions about the free email API
Is Postal's email API free?
Yes. The Free plan includes the complete API: 1,500 emails per month and 50 per day, with one domain and 5 requests per second. There is no trial period and no credit card.
What is the request limit?
On the Free plan, 5 requests per second per team, across all keys. Batch sending helps: 100 emails count as one request. Every response carries the X-RateLimit-* headers.
How do I authenticate?
With an API key in the Authorization: Bearer ps_… header. Create a send-only key for your system and store it in an environment variable, never in the browser.
Is there an SDK?
Yes: postal-so for Node.js and TypeScript (npm install postal-so) and postal-so/postal-php for PHP and Laravel (composer require postal-so/postal-php), with typed errors, idempotency and retry. For other languages, the API is HTTP with JSON.
Can I use the Resend SDK?
Yes. Postal's API uses the same features and formats: point the base URL to https://api.postal.so and use your Postal key. See the guide to migrating from Resend.
Can I send from any address?
Only from domains you have verified. You add the domain in the dashboard, create the DNS records shown, and Postal checks on its own.
API or SMTP?
Use the API to get tags, scheduling, templates with variables and batch sending. If your system only speaks SMTP, use the free SMTP with the same key.
Send your first email through the API
Create the account, verify the domain and make your first POST on the Free plan.