lema · docs · api

API reference

Everything the hosted MCP tools can do, your own code can do directly: query your team’s decision graph — the cited answers, the raw claims, the never-reopen check — over plain HTTPS with a lema_live_ key. This page holds the conventions every call shares; the endpoint pages hold the contracts.

Base URL

All endpoints live under https://api.lema.sh — no version prefix. Requests and responses are JSON (Content-Type: application/json); request bodies are capped at 1 MiB, and an unknown JSON field is a 400, not silently ignored — a typo’d parameter fails loudly instead of quietly doing nothing.

A good first call is GET /me — it echoes who the key is and what it may do, so you prove the credential before building on it.

$ curl https://api.lema.sh/me \
  -H "Authorization: Bearer $LEMA_API_TOKEN"

Authentication

One header on every call: Authorization: Bearer lema_live_…. Keys are minted after you connect your repo (then at /account/api-keys) — you sign in once to mint; the key does the rest. There are no session cookies on this surface and no other header forms.

The scoping rule is the identity rule: a key answers over the workspaces its owner can see, and nothing else. Most read endpoints take an optional workspace_idsnarrower; omitted, they answer org-wide. A workspace that exists but isn’t yours returns 403; one that doesn’t exist is indistinguishable from one you can’t see.

Scopes

  • decisions:read — the default: ask, retrieve, check, and the meters.
  • decisions:write — capture. Mintable only up to your own role in the org.

Key management itself is deliberately not a key scope: minting, listing, and revoking keys require a signed-in browser session, and an API key calling them gets a 403 — a leaked key must never be able to mint its own successors.

Errors

Three shapes, honestly three:

  • Handler errors — a JSON object with a single error string. What the message says is the contract-level reason (missing field, foreign workspace, not configured).
  • Over a plan limit— a structured 429 your agent can act on: the limit, what’s used, when it resets, and where to upgrade. Never a silent failure.
  • The auth layer — a missing or invalid bearer returns 401, and a missing scope 403, as plain text, not JSON — they fire before any handler runs. Code against the status, not the body.
handler errors — 4xx / 5xx
{ "error": "<what went wrong, in plain words>" }
over the daily limit — 429
{
  "error": "daily_limit_reached",
  "message": "<what happened, in plain words>",
  "limit": 150,
  "used": 150,
  "resets_at": "<RFC3339 — next UTC midnight>",
  "upgrade_url": "https://lema.sh/account/plan"
}

Rate limits and the daily wallet

The query endpoints — /ask, /retrieve, /check-approach, /closed-atoms — share one daily MCP-query wallet (150 a day on Free, 2,500 on Pro), resetting at UTC midnight. Each endpoint page states what it charges; GET /usage is the live meter and never charges it.

Two things we won’t do: charge you for a request that failed validation (the wallet is debited only after the request is admitted), and fail silently at the limit — the 429 above tells your agent exactly where it stands. Allowances are on Plans & usage.