API Reference

Complete reference for the OgBae REST API.

Authentication

The email send endpoint uses API key authentication via the Authorization header with a Bearer token. Create API keys in the dashboard at API Keys.

Header
Authorization: Bearer sk_live_your_api_key_here

All other endpoints (domains, logs, webhooks, suppressions) use session cookie authentication from the panel.

Send Email

Base URL: https://email-api.ogbae.com

POST
/api/v1/email/send

Send an email or batch of emails

Request body

FieldTypeRequiredDescription
fromstringYesSender address. Supports "Name <email>" format.
tostring[]Yes*Recipient addresses. Ignored if personalizations is set.
ccstring[]NoCC recipients.
bccstring[]NoBCC recipients.
subjectstringYesEmail subject line.
textstringNoPlain text body.
htmlstringNoHTML body. At least one of text or html is required.
reply_tostringNoReply-To address.
headersobjectNoCustom headers as key-value pairs.
typestringNo"transactional" (default) or "marketing". Marketing costs 2 credits.
categoriesstring[]NoTags for analytics grouping.
trackingobjectNo{"opens": bool, "clicks": bool}. Overrides default tracking.
schedulestringNoISO 8601 datetime to schedule delivery.
attachmentsobject[]NoArray of {filename, content_type, data (base64), content_id}.
template_idstringNoUUID of a saved template. Renders template to HTML at send time.
variablesobjectNoKey-value pairs for {{key}} substitution in subject, text, and HTML.
personalizationsobject[]NoPer-recipient variables. See below.

Personalizations

When personalizations is provided, the root-level to, cc, and bcc fields are ignored. Each personalization creates a separate email with variable substitution using {{key}} placeholders in the subject, text, and HTML body.

Personalizations example
{
  "from": "hello@yourdomain.com",
  "subject": "Hello {{name}}",
  "html": "<p>Welcome, {{name}}!</p>",
  "personalizations": [
    {
      "to": ["alice@example.com"],
      "variables": { "name": "Alice" }
    },
    {
      "to": ["bob@example.com"],
      "variables": { "name": "Bob" }
    }
  ]
}

Response

Success (simple)
{
  "success": true,
  "data": {
    "job_id": "abc123",
    "message": "Email queued for delivery"
  }
}
Success (personalizations)
{
  "success": true,
  "data": {
    "job_ids": ["abc123", "def456"],
    "message": "2 emails queued for delivery"
  }
}

Domains

Base URL: https://panel-api.ogbae.com. Session auth required.

POST
/api/v1/domains

Add a domain. Returns DNS records to configure.

GET
/api/v1/domains

List all domains.

GET
/api/v1/domains/:id

Get domain details and DNS records.

POST
/api/v1/domains/:id/verify

Verify domain DNS records.

DELETE
/api/v1/domains/:id

Delete a domain.

Email Logs

Base URL: https://panel-api.ogbae.com. Session auth required.

GET
/api/v1/email-logs

List email logs. Supports page, per_page (max 100), status, source, category, search, from, to query params.

GET
/api/v1/email-logs/:id

Get a single email log with delivery details and tracking history.

GET
/api/v1/email-logs/stats?period=7d

Aggregate stats. period: 24h, 7d, 30d, 90d. Includes open/click rates.

GET
/api/v1/email-logs/categories

List all categories used in email logs.

Suppressions

Base URL: https://panel-api.ogbae.com. Session auth required. Suppressions are type-aware: unsubscribe blocks marketing only, while hard_bounce, spam_complaint, and manual block all mail.

GET
/api/v1/suppressions

List suppressions. Supports page, per_page, reason, search query params.

POST
/api/v1/suppressions

Add email to suppression list. Body: {"email": "user@example.com"}.

GET
/api/v1/suppressions/check?email=user@example.com

Check if an email is suppressed.

DELETE
/api/v1/suppressions/:id

Remove a suppression. spam_complaint suppressions cannot be deleted.

GET
/api/v1/suppressions/count

Get total suppression count.

Webhooks

Base URL: https://panel-api.ogbae.com. Session auth required. Each request contains an immutable event ID and is signed with HMAC-SHA256 using your webhook secret. Delivery is at least once, so consumers must deduplicate by the top-level ID.

POST
/api/v1/webhooks

Create webhook endpoint. Body: {"url": "https://...", "events": ["email.sent"]}.

GET
/api/v1/webhooks

List webhook endpoints.

GET
/api/v1/webhooks/:id

Get webhook details.

PUT
/api/v1/webhooks/:id

Update webhook URL, events, or active status.

DELETE
/api/v1/webhooks/:id

Delete a webhook endpoint.

GET
/api/v1/webhooks/:id/deliveries

List deliveries. Supports cursor, status, event type, and date filters. Statuses: pending, processing, retry, delivered, failed, paused.

GET
/api/v1/webhooks/:id/deliveries/:deliveryId/attempts

List the immutable HTTP attempt history for a delivery.

POST
/api/v1/webhooks/:id/deliveries/:deliveryId/retry

Retry a permanently failed delivery.

POST
/api/v1/webhooks/:id/test

Send a test event to the webhook URL.

POST
/api/v1/webhooks/:id/rotate-secret

Rotate the webhook signing secret after recent authentication. The new secret is returned once.

Supported events

EventDescription
email.sentOgBae's relay accepted the final send attempt.
email.failedEmail delivery failed permanently.
email.bouncedEmail bounced (hard bounce).
email.spam_complaintRecipient marked the email as spam.
email.openedRecipient opened the email. Includes "first": true/false flag.
email.clickedRecipient clicked a link. Includes link_url, link_index, and "first": true/false.

Verify requests

Read the raw request body before parsing JSON. Build the signed bytes as timestamp + "." + rawBody, calculate HMAC-SHA256 with the signing secret, and compare it in constant time with v1 from the X-OgBae-Signature header.

The signature header is t=unix_timestamp,v1=hex_digest. Reject timestamps older than five minutes, then store the payload's top-level id before processing it. Returning any 2xx status acknowledges the delivery.

Other useful headers are X-OgBae-Event, X-OgBae-Delivery-Id, and X-OgBae-Attempt.

OgBae retries failed requests using the schedule returned with the webhook list response. Attempts are serialized per endpoint. Repeated terminal failures automatically pause the endpoint; activating it again resumes deliveries that were paused while it was disabled.

Templates

Base URL: https://panel-api.ogbae.com. Session auth required. Create and manage reusable email templates with the visual drag-and-drop editor. Reference templates by template_id when sending email via the API.

GET
/api/v1/templates

List all templates.

POST
/api/v1/templates

Create a template. Body: {"name": "...", "subject": "...", "document": {...}}.

GET
/api/v1/templates/:id

Get template details including full document.

PUT
/api/v1/templates/:id

Update template name, subject, or document.

DELETE
/api/v1/templates/:id

Delete a template.

POST
/api/v1/templates/:id/render

Render template to HTML. Body: {"variables": {"key": "value"}}.

POST
/api/v1/templates/:id/duplicate

Duplicate a template.

Sending with templates

Pass template_id and variables in the send request. The template is rendered server-side and {{key}} placeholders are replaced with variable values. If subject is not provided, the template's subject is used.

Send with template
curl -X POST https://email-api.ogbae.com/api/v1/email/send \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "hello@yourdomain.com",
    "to": ["user@example.com"],
    "template_id": "your-template-uuid",
    "variables": {
      "first_name": "Alex",
      "company": "Acme Inc"
    }
  }'