Sending Emails | Brixus365 Docs
Docs API Reference Sending Emails

Sending Emails

Send transactional emails one at a time or in batches, and query your message history.


Send an email

POST/v1/emails

Send a single transactional email.

Request body

FieldTypeDescription
torequiredstring or string[]Recipient email address(es). Maximum 50 total recipients (to + cc + bcc).
starterTemplaterequired*stringSlug of a starter template (e.g. welcome, otp). See Starter templates for the full list. Exactly one of starterTemplate, templateId, or html must be provided.
templateIdrequired*UUIDID of a custom saved template. Available on free plan and above (preview keys cannot use this).
htmlrequired*stringRaw HTML body. Available on free plan and above (preview keys cannot use this).
variablesoptionalobjectKey-value pairs substituted into the template. See each template’s variable list in Starter templates.
subjectoptionalstringEmail subject line (max 998 chars). Required when sending raw html; starter templates have built-in subjects.
fromNameoptionalstringSender display name (max 1024 chars).
fromoptionalstringOverride sender email. Must be a verified sender on your account. On free plans, this field is currently ignored — every send uses your default sender. To send from a different verified sender, change the Default in Settings → Email Setup.
ccoptionalstring[]Carbon copy recipients.
bccoptionalstring[]Blind carbon copy recipients.
replyTooptionalstringReply-to address.
brandNameoptionalstringBrand name injected into template rendering (max 128 chars).
logoUrloptionalstringLogo URL injected into template rendering (max 2048 chars).
attachmentsoptionalAttachment[]Up to 10 attachments. Max 5 MB per file, 10 MB total. See below.

Attachment object

Max 10 attachments per message. Each file must not exceed 5 MB; the total across all attachments must not exceed 10 MB.

FieldTypeDescription
filenamerequiredstringFile name shown to recipient (1–255 chars).
contentTyperequiredstringMIME type. Allowed: application/pdf, text/csv, text/plain, text/calendar, common image and Office document types.
contentrequiredstringBase64-encoded file bytes.
inlineoptionalbooleanSet true to use Content-Disposition: inline. Requires contentId.
contentIdoptionalstringCID for inline embedding (e.g. reference as cid:logo in HTML).

Response

{
  "messageId": "fd92bd3f-969a-4ff6-87dc-a8b0a16e0297",
  "status": "queued",
  "from": "your-default-sender@yourbrand.com"
}

messageId is a UUID. Use it with Get a message to look up delivery status. from is the address the email was sent from — for bx_preview_ keys this is noreply@brixus365.dev; for bx_live_ keys it’s your default sender.

Example

Bash
1curl -X POST https://app.brixus365.com/api/v1/emails \
2-H "X-API-Key: bx_live_your_key_here" \
3-H "Content-Type: application/json" \
4-d '{
5  "to": "customer@example.com",
6  "starterTemplate": "password_reset",
7  "variables": {
8    "reset_url": "https://app.example.com/reset?token=abc123",
9    "expiry_minutes": 30
10  }
11}'

For 8 more languages (PHP, .NET, Java, Go, Rust, Ruby, Elixir, Swift) see Code examples.

Errors

StatusCodeDescription
400missing_fieldNone of starterTemplate / templateId / html provided
400multiple_modesMore than one of starterTemplate / templateId / html provided
400invalid_recipientRecipient address is invalid or has no MX records
400recipient_suppressedAddress has previously bounced or complained — removed from sending
400recipient_limit_exceededMore than 50 recipients (to + cc + bcc)
400attachment_type_not_allowedContent type not in the allowlist
400attachment_too_largeSingle file exceeds 5 MB or total exceeds 10 MB
400too_many_attachmentsMore than 10 attachments
401missing_api_keyX-API-Key header not present
401invalid_api_keyKey invalid or revoked
403scope_requiredKey lacks emails:send permission. Re-create the key with the Send emails (transactional) preset.
403no_verified_senderNo sender marked as Default. Open Settings → Email Setup and set one. See Before you send.
403upgrade_requiredtemplateId or html not available on preview keys — response includes upgrade_url. Upgrade to a free signup for these.
404template_not_foundUnknown starterTemplate slug
409idempotency_key_mismatchSame Idempotency-Key reused with a different request body
422validation_failedBody shape invalid — see error.details.errors[]
429rate_limit_exceededPer-minute rate exceeded — see error.details.limit_per_minute
429daily_limit_exceededDaily quota exhausted
429monthly_limit_exceededMonthly quota exhausted

Send a batch

POST/v1/emails/batch

Send up to 100 emails in a single request. Each message is processed independently — a failure on one doesn’t affect the others. Available on free plan and above (preview keys can’t use batch).

Request body

FieldTypeDescription
messagesrequiredSendEmailRequest[]1–100 message objects. Each has the same shape as POST /v1/emails. Total recipients across all messages must not exceed 1,000.

Response

{
  "results": [
    {
      "idx": 0,
      "messageId": "c2bb8f70-9ae9-4e7a-a8d1-d84a222e0849",
      "status": "queued",
      "from": "your-default-sender@yourbrand.com",
      "error": null
    },
    {
      "idx": 1,
      "messageId": null,
      "status": null,
      "from": null,
      "error": {
        "code": "recipient_suppressed",
        "message": "This address has previously bounced.",
        "type": "invalid_request_error"
      }
    }
  ]
}

idx corresponds to the zero-based position in your messages array. Always check error on each result.

Errors

StatusCodeDescription
400batch_limit_exceededMore than 100 messages or 1,000 total recipients
403upgrade_requiredPreview keys can’t use batch send. Sign up free for a bx_live_ key.

List messages

GET/v1/emails

Returns a paginated list of messages sent via API.

Query parameters

ParameterTypeDescription
fromoptionalISO 8601Filter to messages created at or after this timestamp.
tooptionalISO 8601Filter to messages created before this timestamp.
statusoptionalstringOne of: pending, sent, delivered, bounced, complained, failed.
skipoptionalintegerPagination offset. Default 0.
limitoptionalintegerResults per page. Default 50, max 100.
sortByoptionalstringSort column. One of: created_at (default), updated_at, status. Always descending.

Response

{
  "items": [
    {
      "messageId": "dceaaa96-a806-43d2-ac2d-8396bbd3188a",
      "recipientEmail": "customer@example.com",
      "subject": "Welcome to Acme",
      "status": "sent",
      "createdAt": "2026-05-04T10:45:26+00:00",
      "updatedAt": "2026-05-04T10:45:26+00:00",
      "errorMessage": null
    }
  ],
  "total": 8,
  "skip": 0,
  "limit": 50
}

Get a message

GET/v1/emails/{message_id}

Look up a single message by its ID.

Path parameters

ParameterTypeDescription
message_idrequiredUUIDThe messageId returned by POST /v1/emails.

Response

{
  "messageId": "dceaaa96-a806-43d2-ac2d-8396bbd3188a",
  "status": "sent",
  "recipientEmail": "customer@example.com",
  "subject": "Welcome to Acme",
  "fromName": null,
  "providerMessageId": "0109019df17b973a-...-000000",
  "errorMessage": null,
  "createdAt": "2026-05-04T10:45:26+00:00",
  "updatedAt": "2026-05-04T10:45:26+00:00"
}

providerMessageId is the upstream delivery provider’s tracking ID. Useful when investigating delivery issues with our support team.

Errors

StatusCodeDescription
404message_not_foundID doesn’t exist or belongs to a different account

Analytics

GET/v1/emails/analytics

Aggregate delivery metrics for a time window.

Query parameters

ParameterTypeDescription
fromrequiredISO 8601Window start (inclusive).
torequiredISO 8601Window end (exclusive). Must be after from.
bucketoptionalstringTime granularity: hour or day (default).

Response

{
  "totalMessages": 8,
  "deliveryRate": 1.0,
  "bounceRate": 0.0,
  "complaintRate": 0.0,
  "windowStart": "2026-05-03T00:00:00+00:00",
  "windowEnd": "2026-05-04T23:59:59+00:00",
  "bucket": "day",
  "volume": [
    {
      "timestamp": "2026-05-04T00:00:00+00:00",
      "count": 8,
      "sent": 8,
      "delivered": 7,
      "bounced": 0,
      "complained": 0,
      "failed": 1
    }
  ],
  "topErrors": []
}

Per-message delivery webhooks (instant notification when a message is delivered, bounced, or complained) are coming soon. Until then, poll Get a message or use this analytics endpoint for aggregate delivery health.