PineMail API
Transactional send from your app. A project, a verified from-domain, a Bearer key, POST /v1/emails. 202 means queued. JSON is snake_case. Errors are RFC 7807 application/problem+json. Public URL is https://pinemail.app/v1/… (also served at /api/v1). Contract: /openapi.yaml.
Authentication
Create a key under the project’s API keys page. Pass it as a Bearer token. Keys start with pm_live_. The full token is shown once.
Access levels
Each key is either full access or a restricted set of scopes. A restricted key that hits an endpoint it does not own receives 403. Existing keys without a stored scope list keep full access.
| Scope | What it allows |
|---|---|
emails:send | POST /v1/emails |
emails:read | GET /v1/emails, GET /v1/emails/{id} |
domains:read | List and fetch sending domains |
domains:write | Add, verify, or delete a domain |
mailboxes:read | List and fetch mailboxes |
mailboxes:write | Create, update, or delete a mailbox |
webhooks:read | List webhooks and delivery history |
webhooks:write | Create, edit, test, or delete a webhook |
templates:read | List and fetch templates |
directory:read | List the organisation address book |
directory:write | Add or remove a directory person |
Send an email
from must use a verified domain on the project — your domain after DNS, or @pinemail.app immediately. Display names are kept (Acme <hello@pinemail.app>). Provide text or html. A 202 means queued — poll GET /v1/emails/{id} or watch the project email log. Retry a POST only with the same Idempotency-Key. Attachments are not on this endpoint; use the mailbox compose flow for that.
Emails
GET /v1/emails lists newest first. Optional limit (1–200) and cursor. GET /v1/emails/{id} includes the event timeline.
Domains
Add a sending domain, publish the returned DNS records, then verify. The hosted pinemail.app domain cannot be removed.
Mailboxes
Inbox addresses on a domain you already added. Each one gets its own login: the address and password sign in to the web client and to mail apps, and see only that mailbox. If you omit password, PineMail generates one and returns it once. spam_level is off, low, medium, high, or null to inherit the project default.
Templates
GET /v1/templates and GET /v1/templates/{id} return saved subjects and bodies plus discovered {{variables}}.
Directory
Organisation address book, including people shared in from other projects. Members are synced from mailboxes and cannot be deleted through the API.
Webhooks
Subscribe an HTTPS URL to email lifecycle events. Signing, payload shape, retries, and the test endpoint are documented on /docs/webhooks.
Errors
Every error uses application/problem+json with type, title, status, and usually detail. Validation failures are 422 and include an errors map. Rate limits are 429 with Retry-After.
Status codes
200 / 201 / 202 / 204 success. 400 bad request. 401 missing or invalid key. 403 missing scope. 404 unknown resource. 422 validation. 429 rate limited. 500 unexpected.