Docs / API reference
Reference

API reference

Create an account, verify your sender domain, then use the core transactional email endpoints. Account endpoints issue API keys and track quota/credits; top-up is available after onboarding.

Answer first: create an account, submit your domain/sender, complete verification, then use the transactional email API under https://api.mailbot.id. The core endpoints are POST /v1/send, GET /v1/status, and POST /v1/test-email.

Endpoints at a glance

Core transactional email endpoints

MethodPathPurposeAuth
POST/v1/sendSend one transactional email.Bearer key
GET/v1/statusService health and account-safe send status.Optional Bearer
POST/v1/test-emailSend the standard Mailbot test email.Bearer key

Marketing / education capture endpoints (not transactional)

MethodPathPurposeAuth
POST/api/waitlistCapture a product inquiry from the public site.None
POST/api/newsletterCapture a blog newsletter subscriber.None

Self-serve account and top-up endpoints

MethodPathPurposeAuth
POST/api/account/signupCreate an account, API key, access code, and session.None
POST/api/account/loginLog in with email and account access code.None
GET/api/account/meRead account email, free quota, usage, paid credits, packages, and purchase state.Session cookie
POST/api/topup/create-orderCreate an IDR top-up checkout for more credits.Session cookie

All other HTTP methods on these routes return 405 Method not allowed.


POST /v1/send

Authenticate a developer key, validate one transactional email payload, check limits, and return an accepted response for the send.

Auth: required Authorization: Bearer <MAILBOT_API_KEY>. Create a self-serve account, then verify your sender domain before production use.

Request fields

FieldTypeRequiredNotes
tostringYesOne recipient email address.
subjectstringYesUp to 998 characters.
textstringOne requiredPlain-text body (or send html).
htmlstringOne requiredHTML body (or send text). Both may be sent.
fromstringNoVerified sender. If omitted, Mailbot uses the sender configured for your account.
idempotency_keystringNoUp to 128 characters. Use a stable value for sends you may retry.
JSON request
{
  "from": "noreply@yourdomain.com",
  "to": "user@example.com",
  "subject": "Receipt for order #1042",
  "text": "Thanks! Your payment was received.",
  "html": "<p>Thanks! Your payment was received.</p>",
  "idempotency_key": "receipt-1042"
}

Responses

The same status terms are used on the homepage, API docs, and dashboard: validated means the request is valid but not sent in test/safe mode; queued means Mailbot accepted it into the delivery queue; sent means it entered the mail pipeline; failed means Mailbot could not process it.

202 · queued
{ "ok": true, "id": "msg_3f8c1a...", "status": "queued" }
202 · validated
{ "ok": true, "id": "msg_...", "status": "validated",
  "note": "Validated by Mailbot ID. No email was sent." }
202 · sent
{ "ok": true, "id": "msg_...", "delivery_id": "delivery-...", "status": "sent" }

Error codes

StatusMeaning
400Invalid payload. Body includes details.
401Missing, unknown, or revoked API key.
402No free monthly quota or paid credits remaining for a billing-enforced self-serve key.
403Recipient or sender is not allowed for this account.
429Daily or monthly send limit reached.
502Delivery handoff could not be completed.
503Mailbot is temporarily unable to accept the send.
Privacy: usage logs store metadata only — message ids, sender/recipient domains, body-presence flags, and a hashed idempotency key. API keys, subject text, email body text, and full recipient addresses are never stored in usage logs.
Idempotency: same-account retries with the same idempotency_key can be correlated safely, so another account cannot claim your retry value.

GET /v1/status

Returns safe, non-secret service health for dashboards and machine clients. Never returns API key or delivery secret values.

Auth: optional. Without a key it returns compact public status; with a valid Bearer key it can include account-safe detail.

cURL
curl https://api.mailbot.id/v1/status
200 · service health
{
  "ok": true,
  "service": "mailbot-id",
  "status": "ready"
}

POST /v1/test-email

Builds a standardized Mailbot test message and sends it through the same validation path as /v1/send. This is the safe answer to "can Mailbot send a test email?"

Auth: required Authorization: Bearer <MAILBOT_API_KEY>.

FieldTypeRequiredNotes
tostringYesRecipient address you control.
fromstringNoVerified sender.
labelstringNoAppears in the fixed test subject line.
idempotency_keystringNoUp to 128 characters.
This endpoint does not accept arbitrary subject or body content — it generates a fixed test subject and body. Use /v1/send for real transactional content.
cURL
curl https://api.mailbot.id/v1/test-email \
  -H "Authorization: Bearer $MAILBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "safe@yourdomain.com", "label": "Smoke test" }'

Self-Serve Account And API Key

Create an account from the onboarding page or with POST /api/account/signup. Signup creates your account, starts a session, stores non-secret onboarding fields for domain/sender verification, and returns the API key plus account access code once. Raw secrets are not stored.

Signup request
{ "email": "user@example.com" }

GET /api/account/me returns account email/status, 1,000 free monthly credits, current monthly usage, paid credits, IDR package metadata, and the current purchase state.

Custom sender domain

POST /api/account/verify-domain with { "domain": "example.com" } generates account-scoped DKIM material and returns the ownership, SPF, DKIM, and DMARC DNS records. Publish every record, then call it again with { "action": "check" }. After verification, that account may use addresses such as noreply@example.com in the from field; another account cannot use the domain.


POST /api/topup/create-order

Creates an IDR top-up order for one of the packages returned to the logged-in account. Public pricing starts from Rp30rb; the Dashboard shows the current package choices. The response includes a payment URL when checkout is available, and credits are added only after payment succeeds.

Top-up
{ "package_id": "starter_30k" }
201 · payment URL
{ "ok": true, "status": "waiting_for_payment", "payment_url": "https://...", "order_id": "ord_...", "currency": "IDR", "amount": "30000", "credits": 2000 }

POST /api/waitlist lead capture

This endpoint is used only by the public site to capture a product inquiry email address. It is not part of the transactional email API and most integrations never call it.

Auth: none. Body: { "email": "user@example.com" }. Returns { "ok": true } for both new and duplicate submissions (responses never reveal whether an address is already on the list), 400 for an invalid email, and 429 when the per-client signup rate limit is exceeded.

POST /api/newsletter newsletter capture

This endpoint is used by the blog to store readers who want practical Mailbot updates. It stores subscribers; it does not send broadcasts and is not part of the transactional email API.

Auth: none. Body: { "email": "reader@example.com", "role": "Founder / OTP", "source": "blog_index" }. role is optional. Returns { "ok": true } for both new and duplicate submissions, 400 for an invalid email, and 429 when the per-client subscription rate limit is exceeded.