Developers

Use the API for mailboxes you own.

Base URL https://api.mailbelo.com. The interactive reference is at api.mailbelo.com/docs. Keys are created in the dashboard.

Authenticate

Create a key in the dashboard on Pro or Business. Send it as Authorization: Bearer. The full key is shown once. Every response includes request_id. The API sends X-RateLimit-Limit: 120.

curl https://api.mailbelo.com/v1/mailboxes \
  -H "Authorization: Bearer $MAILBELO_KEY"
{
  "mailboxes": [],
  "next_cursor": null,
  "request_id": "…"
}

Create a mailbox

POST /v1/mailboxes with local_part. Add domain when the mailbox should live on a domain you have verified. Send Idempotency-Key so a retry returns the first response. Reusing that key with a different body returns 409 idempotency_conflict. The password is in this response only.

curl -X POST https://api.mailbelo.com/v1/mailboxes \
  -H "Authorization: Bearer $MAILBELO_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"local_part":"ada","display_name":"Ada"}'
{
  "mailbox": {
    "id": "…",
    "address": "[email protected]",
    "display_name": "Ada",
    "disabled": false,
    "quota_bytes": 1073741824,
    "password": "shown-once",
    "created_at": "2026-10-07T00:00:00+00:00"
  },
  "request_id": "…"
}

List mailboxes

GET /v1/mailboxes?limit=20. limit is between 1 and 100. Pass the returned next_cursor back as cursor to read the next page. A null cursor means you are done.

curl "https://api.mailbelo.com/v1/mailboxes?limit=20&cursor=$CURSOR" \
  -H "Authorization: Bearer $MAILBELO_KEY"
{
  "mailboxes": [{ "id": "…", "address": "[email protected]", "display_name": "Ada", "disabled": false }],
  "next_cursor": null,
  "request_id": "…"
}

Send a message

POST /v1/mailboxes/{address}/messages with to, subject, and text. html is optional. The address must belong to the key’s organization.

curl -X POST https://api.mailbelo.com/v1/mailboxes/[email protected]/messages \
  -H "Authorization: Bearer $MAILBELO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":["[email protected]"],"subject":"Hello","text":"From MailBelo."}'
{ "ok": true, "request_id": "…" }

Read messages

GET /v1/mailboxes/{address}/messages?limit=20 lists the inbox. GET /v1/mailboxes/{address}/messages/{id} returns one message, including text when the mail server has it.

curl "https://api.mailbelo.com/v1/mailboxes/[email protected]/messages?limit=20" \
  -H "Authorization: Bearer $MAILBELO_KEY"
{
  "messages": [{
    "id": "…",
    "subject": "Hello",
    "from": "[email protected]",
    "preview": "From MailBelo.",
    "received_at": "2026-10-07T12:00:00Z",
    "unread": true
  }],
  "request_id": "…"
}

Delete a mailbox

DELETE /v1/mailboxes/{address}. Reserved company locals such as support, info, security, abuse, and postmaster return 404. They are not mailboxes you can create or read through this API.

curl -X DELETE https://api.mailbelo.com/v1/mailboxes/[email protected] \
  -H "Authorization: Bearer $MAILBELO_KEY"
{ "ok": true, "request_id": "…" }

Domains

POST /v1/domains with name. The response includes verification_txt. Publish that TXT record, then POST /v1/domains/{name}/verify. GET /v1/domains lists domains that are not the shared mailbelo.com domain.

curl -X POST https://api.mailbelo.com/v1/domains \
  -H "Authorization: Bearer $MAILBELO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"example.com"}'
{
  "domain": { "name": "example.com", "verification_txt": "mailbelo-verification=…" },
  "request_id": "…"
}

Errors

Failures use a JSON object with code, message, and request_id. A missing or reserved mailbox is 404 not_found. Reusing an Idempotency-Key with a different body is 409 idempotency_conflict. A missing or revoked key is unauthorized.

{ "error": { "code": "not_found", "message": "Mailbox not found", "request_id": "…" } }
{ "error": { "code": "idempotency_conflict", "message": "This key was used with a different request", "request_id": "…" } }

The same error object is on every failure. GET /v1/errors lists the codes. GET /v1/openapi.txt lists the paths. Send can take the same Idempotency-Key header as create. The clients retry 429 and 5xx responses.

Webhook deliveries send MailBelo-Signature, the hex HMAC-SHA256 of the raw JSON body, signed with the secret returned when the endpoint is created.

Python and TypeScript

The clients in packages/sdk-python and packages/sdk-ts call the same endpoints.

from mailbelo import MailBelo
client = MailBelo("mb_live_…")
created = client.create_mailbox("ada", idempotency_key="once")
client.send_message(created["mailbox"]["address"], ["[email protected]"], "Hello", "From MailBelo.")
print(client.messages("[email protected]"))
client.delete_mailbox("[email protected]")
domain = client.create_domain("example.com")
client.verify_domain("example.com")
import { MailBelo } from "@mailbelo/sdk";
const client = new MailBelo("mb_live_…");
const created = await client.createMailbox("ada");
await client.sendMessage(created.mailbox.address, ["[email protected]"], "Hello", "From MailBelo.");
await client.messages("[email protected]");
await client.deleteMailbox("[email protected]");
await client.createDomain("example.com");
await client.verifyDomain("example.com");