The API lives at https://api.overlane.app. Every path that touches team data starts with /v1/tenants/{tenantId}, so the team is part of every request and one team can never read another’s data.
Authenticate
Send Authorization: Bearer <token>. Any of these works, and each is checked against the database on every request, so a revocation takes effect on the next call:
| Credential | Prefix | Made by |
|---|---|---|
| Team API key | ovl_k_ |
overlane api-key create |
| Agent token | ovl_a_ |
overlane auth login --repo, see Agent sign-in |
| CLI session | ovl_s_ |
overlane auth login |
| OAuth access token | none | The MCP and OAuth sign-in flow |
curl -H "Authorization: Bearer $OVERLANE_KEY" https://api.overlane.app/v1/meGET /v1/me answers who the token belongs to: the team, the user, the scopes and whether it is a person or an agent.
Pin a version
The API version is a date. Send it in the Overlane-Version header; leave the header off and you get the current version. Every answer repeats the version it was served at.
curl -H "Authorization: Bearer $OVERLANE_KEY" -H "Overlane-Version: 2026-10-10" https://api.overlane.app/v1/me
overlane api versionsA date that does not exist is refused with 400 and the versions that do. API versions explains how a breaking change ships and how long an old version keeps working.
assert.equal(resolveApiVersion(undefined).version, CURRENT_API_VERSION);
assert.equal(resolveApiVersion(CURRENT_API_VERSION).ok, true);
const unknown = resolveApiVersion("2020-01-01");
assert.equal(unknown.ok, false);
assert.equal(unknown.code, "unsupported_version");
assert.equal(resolveApiVersion("latest").code, "invalid_version");Errors
Every error body has the same shape, and the connector, key and webhook routes add retryable:
{ "error": { "code": "rate_limited", "message": "more than 60 requests in one minute for this team's plan; retry in 12 seconds", "hint": "wait for the window to end; a paid plan has a higher limit", "retryable": true } }codeis stable and safe to branch on.messageis for people.hintnames the next step, often a command.retryablesays whether the same request may succeed later without a change: true for408,429and server errors.- A refusal from the autonomy gate adds
approvalwith the class, what it needs and the subject to approve.
The CLI maps these to exit codes: 3 for sign-in, 4 not found, 6 blocked by policy or an approval, 7 retry later.
const error = DeveloperError.parse({ error: { code: "rate_limited", message: "slow down", hint: "retry in 5 seconds", retryable: true } });
assert.equal(error.error.retryable, true);
assert.equal(retryableStatus(429), true);
assert.equal(retryableStatus(403), false);Rate limits
A call made with a team API key counts against the team’s per-minute limit and the key’s own cap. Over the limit you get 429, Retry-After and the RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers. See API keys and rate limits.
Writes are safe to repeat
Task and issue writes take a requestId; sending the same one again returns the first result. Connector actions and webhook events carry their own idempotency keys: a provider event ID, and the webhook event ID.
The OpenAPI document
The API serves its own description at /v1/openapi.json (a GET with any valid credential). It is generated from the same route tables the role middleware reads and from the contracts, so it cannot describe a route that is not there. A test checks both ways: every route is an operation and every operation is a route that answers. Each operation carries:
x-overlane-route, the route ID;x-overlane-action, the role right it needs;x-overlane-autonomy-classwhen the autonomy gate asks about it;x-overlane-human-onlyfor payments and legal terms.
overlane api openapi
overlane api openapi --full --jsonThe document is committed at one snapshot per version, and the TypeScript SDK and the API reference page are generated from it, so both list every operation at the current version. A few public endpoints (CLI sign-in, the CI runner broker, the release signing key, the status page data and inbound webhooks) are not operations of the document; they are on Endpoints outside the SDK.