Overview | Brixus365 Docs
Docs API Reference Overview

Transactional Email API — for developers

Everything you need to integrate the Brixus365 transactional email API into your application — base URL, authentication, errors, rate limits, and idempotency.

For developers. The endpoints documented in this section power the transactional surface of Brixus365 — receipts, password resets, magic links, OTPs, and any other 1:1 email triggered by your app. Marketing campaigns are managed under Spark in the dashboard, not here. In the dashboard, transactional sends and per-message status are surfaced in your dashboard.

Base URL

All API endpoints are relative to:

https://app.brixus365.com/api/v1

All requests and responses use application/json.

Authentication

Pass your API key in the X-API-Key request header on every request.

X-API-Key: bx_live_your_key_here

Missing or invalid keys return 401. See Creating API keys to generate one, or run through the Quickstart for a guided 5-minute setup.

Don’t use Authorization: Bearer for API keys — that header is reserved for dashboard JWTs. Sending an API key in Authorization returns 401 missing_api_key.

Key types

Brixus365 issues two key types depending on how you signed up. Both authenticate the same way (X-API-Key); they differ in capability.

Key typePrefixWhat it can do
Preview keybx_preview_…

Send via starter templates only. Sender is fixed to noreply@brixus365.dev. Limits: 50/day, 1,500/month, 10/min. Issued instantly via the email-only widget at /developers — no full signup.

Live keybx_live_…

Send via starter templates, your saved templates, or raw HTML. Send from any verified domain. Batch send + SMTP relay supported. Issued by full signup. 9,000/month free, more on paid plans.

If you try a paid-only feature with a free-tier key, the response is 403 upgrade_required with an upgrade_url field pointing to the pricing page.

Error format

All errors use the same envelope:

{
  "error": {
    "code": "stable_machine_readable_code",
    "message": "Human-readable description.",
    "type": "invalid_request_error"
  }
}

Some errors include extra fields (upgrade_url, details). Always key on code — the human message may change.

Error types

TypeMeaning
invalid_request_errorBad input — fix the request and retry
authentication_errorMissing or invalid API key
authorization_errorKey valid but lacks permission for this action
not_foundResource doesn’t exist or isn’t accessible
idempotency_errorIdempotency-Key conflict
rate_limit_errorToo many requests — back off and retry
api_errorUnexpected server-side error
service_unavailableEmail delivery temporarily unreachable

Common codes

StatusCodeDescription
401missing_api_keyX-API-Key header not present
401invalid_api_keyKey invalid, revoked, or wrong header used
403scope_requiredKey lacks the permission this endpoint requires — see details.required_permission for the missing scope
403no_verified_senderNo sender address marked as Default. Open Settings → Email Setup and set one.
403upgrade_requiredFeature requires a paid plan — response includes upgrade_url
404template_not_foundUnknown starter-template slug, or template ID doesn’t exist on your account
404message_not_foundMessage ID doesn’t exist or belongs to a different account
422validation_failedBody shape invalid — see error.details.errors[] for the field paths
429rate_limit_exceededPer-minute send rate exceeded — see error.details.limit_per_minute
429daily_limit_exceededDaily send quota exhausted
429monthly_limit_exceededMonthly send quota exhausted

Rate limits

Limits keep delivery healthy and reputation high.

Key typePer minutePer dayPer month
Preview key (bx_preview_…)10501,500
Live key — Free plan (bx_live_…)Plan-basedPlan-based9,000
Live key — Standard / EnterprisePlan-basedPlan-based15K – 250K (Standard) · Custom (Enterprise)

When you exceed the per-minute rate, the response is 429 with code rate_limit_exceeded:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Retry in a few seconds.",
    "type": "rate_limit_error",
    "details": { "limit_per_minute": 10 }
  }
}

Daily and monthly exhaustion return 429 with codes daily_limit_exceeded and monthly_limit_exceeded respectively.

Backoff guidance: for per-minute limits, wait 60 seconds before the next request; for daily limits, wait until UTC midnight. The response does not currently include a Retry-After header — use a fixed-delay or exponential backoff instead.

Idempotency

For POST /v1/emails, pass a unique Idempotency-Key header (≤ 256 bytes) so retries on network errors don’t double-send:

Idempotency-Key: a-unique-string-per-request

Retrying with the same key within 24 hours returns the original response verbatim with Idempotent-Replay: true in the response headers. Reusing the same key with a different request body returns 409 with code idempotency_key_mismatch.

Use a UUID or hash of the payload as your idempotency key — something stable on retry but unique across distinct requests.