Introduction
Mailbox infrastructure for developers. Provision real mailboxes over REST, then send, receive, stream, and read mail.
Postbox is API-first email hosting. You provision a real mailbox on a domain you own with one HTTP call, then send, receive, stream, and read its mail over REST. Deliverability, DKIM signing, and DNS are managed for you.
It is not a transactional-send API with a mailbox bolted on. Every address you create is a real, addressable mailbox with folders, threading, storage, and an inbound pipeline behind it.
Start here
Quickstart
Domain to live mailbox to a round-trip send.
Authentication
Key types, project scoping, and what each credential reaches.
Errors
The error envelope, the status codes, and what is safe to retry.
The shape of the API
One base URL, https://api.postboxapp.cloud/v1, and one bearer credential per
request:
import { Postbox } from "@postbox/sdk";
const pb = new Postbox({
apiKey: process.env.PB_KEY!,
projectId: process.env.PROJECT_ID!,
});
const mailboxes = await pb.mailboxes.list();import os
from postbox import Postbox
pb = Postbox(api_key=os.environ["PB_KEY"], project_id=os.environ["PROJECT_ID"])
mailboxes = pb.mailboxes.list()using Postbox;
var pb = new PostboxClient(
new PostboxOptions
{
ApiKey = Environment.GetEnvironmentVariable("PB_KEY")!,
ProjectId = Environment.GetEnvironmentVariable("PROJECT_ID")!,
}
);
var mailboxes = await pb.Mailboxes.ListAsync();import cloud.postboxapp.*;
import cloud.postboxapp.gen.*;
import java.util.*;
Postbox pb = new Postbox(PostboxOptions.builder().apiKey(System.getenv("PB_KEY")).projectId(System.getenv("PROJECT_ID")).build());
var mailboxes = pb.mailboxes.list();import postbox "github.com/postboxapp/postbox-go"
pb, err := postbox.New(postbox.Options{
APIKey: os.Getenv("PB_KEY"),
ProjectID: os.Getenv("PROJECT_ID"),
})
ctx := context.Background()
mailboxes, err := pb.Mailboxes.List(ctx)curl https://api.postboxapp.cloud/v1/mailboxes \
-H "Authorization: Bearer pb_live_..."Every successful response is wrapped in the same envelope, so data is always
where the payload lives:
{ "success": true, "data": { "id": "…", "email": "[email protected]" } }Some routes are scoped to a project by the key itself; others act at the org
level and take an X-Project-Id header to target one project:
| Routes | Project scoping |
|---|---|
messages, events, tokens, actions | The key is already project-scoped. Send nothing extra. |
projects, domains, mailboxes, folders, webhooks, policies, keys, stats | Send X-Project-Id to target one project. |
See Authentication for the detail, and what happens when you leave the header off.
How mail flows
Outbound. POST /messages/send validates and stores the message and returns
its ID. Delivery is asynchronous. message.sent fires when the message is
accepted for delivery, typically within seconds. The receiving server's outcome
arrives separately and later, as message.delivered, message.bounced, or
message.complained. Acceptance and delivery are distinct events with distinct
timing. See Sending.
Inbound. Mail addressed to one of your mailboxes is authenticated,
spam-scored, parsed, and threaded, then stored. message.received fires on both
your webhooks and the event stream. See Receiving.
Every event is available two ways with an identical payload: as a signed webhook, durable and retried, or over the SSE stream, live and resumable. Use either or both.
Deliverability
Postbox authenticates and signs every message and manages sending reputation. Inbox placement also depends on what you send and who you send it to, which no provider can control on your behalf. Deliverability covers the split and what to check before a first production send.