API Overview

Owlat exposes authenticated API endpoints under your Convex site URL.

Owlat exposes authenticated API endpoints under your Convex site URL.

Base URL

Use your deployment URL:

https://<your-deployment>.convex.site

Authenticated endpoints are currently under:

/api/v1/*

Authentication

Send your API key in Authorization:

Authorization: Bearer lm_live_...

API keys are created in Settings → API.

SDKs

For server-side integrations, use an official SDK instead of raw HTTP calls:

  • TypeScript SDK -- @owlat/sdk-js for Node.js, Bun, and Deno
  • Java SDK -- com.owlat:owlat-sdk for JVM applications (Java 11+)

Current endpoint groups

Response format

Most endpoints return JSON in this shape:

{
  "data": {}
}

Errors use the locked Operation-error envelope — a human-readable message, a closed category, and an optional data object carrying specifics:

{
    "error": {
        "category": "invalid_input",
        "message": "Human readable message",
        "data": { "field": "email" }
    }
}

category is one of: unauthenticated (401), limit_reached (402), forbidden (403), not_found (404), invalid_input (400), already_exists (409), conflict (409), invalid_state (422), rate_limited (429), internal (500).

CORS

Private API endpoints (/api/v1/*) are restricted by the ALLOWED_ORIGINS environment variable. Set it to a comma-separated list of allowed origins in the Convex dashboard:

npx convex env set ALLOWED_ORIGINS "https://app.example.com,http://localhost:3000"

Public endpoints (forms, unsubscribe, preference center) allow all origins.

Rate limits

Authenticated API requests are limited to 10 requests per second per API key.

Headers:

X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset

When exceeded, responses return 429 with Retry-After.