Public API Overview

Base URL: https://<host>/api/v1

All endpoints require a Bearer API key.

Authorization: Bearer sok_live_...   # or sok_test_...

Content type: application/json.

Endpoints

Method Path Purpose
POST /api/v1/emails Send one email
POST /api/v1/emails/batch Send up to 100 emails
GET /api/v1/emails List emails (cursor pagination)
GET /api/v1/emails/{id} Retrieve one email
POST /api/v1/sms Send one SMS
POST /api/v1/sms/batch Send up to 100 SMS
GET /api/v1/sms List SMS
GET /api/v1/sms/{id} Retrieve one SMS

Cross-cutting behavior

Every request passes through withApiAuth (src/lib/api/middleware.ts):

  1. Auth — validates Bearer token against api_keys table (sha256 hash).
  2. Rate limit — Upstash sliding window: 100 req / 60s per orgId. Skipped if Upstash env vars absent.
  3. Context — handler receives { orgId, apiKeyId, environment }.

POST send endpoints additionally:

  1. IdempotencyIdempotency-Key header replays the stored response for 24h.
  2. Usage limit — free-tier caps enforced in live env; Pro allows overage; test env bypasses.

Response envelopes

Single resource:

{ "id": "msg_...", "channel": "email", "status": "sent", "created_at": "..." }

List:

{ "data": [...], "has_more": true, "next_cursor": "msg_..." }

Batch:

{ "data": [{"id":"msg_...","status":"sent"}, ...], "total": 2, "successful": 2, "failed": 0 }

Error: see errors.md.

See also: authentication.md, emails.md, sms.md, rate-limits.md, idempotency.md.