Thanks for signing up.
", "text": "Welcome! Thanks for signing up.", "tags": { "workflow": "welcome" } }' ``` A successful send returns `200`: ```json { "messageId": "0100019a-1b2c-4d5e-8f90-abcdef123456", "status": "queued", "overage": false, "remainingQuota": { "current": 48, "total": 10000, "resetAt": "2026-09-01T00:00:00.000Z", "percentUsed": 0.0048, "softWarnAt": 0.8, "softWarnTriggered": false, "dailyCap": null, "creditBalance": 0 } } ``` `status` is always `"queued"` on success - orboto Mail hands the message to SES synchronously and returns immediately; delivery, bounce, and complaint outcomes arrive later as [delivery events](/mail/suppression-and-events). `remainingQuota` reports the account's quota state after this send so you can decide client-side whether to slow down before the next one. ### Request fields [#request-fields] | Field | Required | Notes | | -------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `from` | yes | Must be on a [verified sending domain](/mail/domains) for your account. Accepts a bare address or `Display Name `. | | `to` | yes | A single recipient address. | | `cc`, `bcc` | no | Arrays, up to 50 addresses each. Bcc recipients never appear in headers seen by anyone else on the message. | | `subject` | conditionally | Required unless `templateId` supplies one. Max 998 characters (RFC 5322 line length). | | `html`, `text` | conditionally | At least one of `html`, `text`, or `templateId` is required. `html` and `text` cannot be combined with `templateId` in the same call - pick raw content or a template. | | `templateId` + `variables` | no | Send via a [stored template](/mail/templates) instead of raw content. | | `tags` | no | A flat object of string keys/values (max 256 chars each), stored on the send record for your own filtering/reporting. | | `attachments` | no | Array, max 20 items. See below. | ### Attachments [#attachments] ```json { "attachments": [ { "filename": "invoice.pdf", "contentType": "application/pdf", "content": "Hi A
" }, { "from": "support@yourdomain.example", "to": "b@example.com", "subject": "Hi B", "html": "Hi B
" } ] }' ``` `POST /v1/send/batch` runs every message through the same validation, quota, and send pipeline as a single send, up to 100 messages per call. It always returns `200`, even if every message failed - read `summary` and each item's `ok` flag rather than the HTTP status: ```json { "results": [ { "index": 0, "ok": true, "messageId": "...", "status": "queued", "overage": false }, { "index": 1, "ok": false, "error": "recipient_suppressed", "message": "..." } ], "remainingQuota": { "...": "last snapshot after the batch" }, "summary": { "queued": 1, "rejected": 0, "suppressed": 1, "skipped": 0 } } ``` Messages are processed in array order. If the account's quota runs out partway through the batch, every remaining item comes back with `quotaSkipped: true` instead of being retried - the quota won't refill mid-batch, so there's no point checking again. ## Checking your quota without sending [#checking-your-quota-without-sending] ```bash curl https://mail.orboto.io/api/v1/quota \ -H "Authorization: Bearer oms_live_your_key_here" ``` Returns the same `remainingQuota` shape shown above, wrapped in `{ "quota": { ... } }` - useful before kicking off a large batch, or for your own usage dashboards. ## Viewing what was sent [#viewing-what-was-sent] ```bash curl "https://mail.orboto.io/api/v1/sends?limit=20&status=bounced" \ -H "Authorization: Bearer oms_live_your_key_here" ``` `GET /v1/sends` lists your account's sends, most-recent first, cursor- paginated via `?cursor=Activate your account: click here.
", "bodyText": "Hi {{name}}, activate your account: {{activationUrl}}", "variablesSchema": { "type": "object", "required": ["name", "activationUrl"], "properties": { "name": { "type": "string" }, "activationUrl": { "type": "string", "format": "uri" } } } }' ``` Placeholders use `{{variableName}}` syntax in both `subject` and the body fields. An unknown placeholder (a typo, or a variable you forgot to pass) renders as an empty string rather than failing the send - so a mistake shows up as missing text in the delivered email, not a crash. Values substituted into `bodyHtml` are HTML-escaped automatically, so a variable containing `