Developers / Documentation

LEO OS API documentation

Version v1. This page documents only what is live today. Endpoints and events are added here as they ship.

Authentication

Create an API key on the Developers page. Send it as a Bearer token on every request. Keys start with leo_live_. The full key is shown only once when you create it, and we store only a hash, so a lost key cannot be recovered. Revoke it and create a new one.

curl https://leoos-omega.vercel.app/api/v1/projects \
  -H "Authorization: Bearer leo_live_YOUR_KEY"

Keep keys on your server. Never put them in browser code, public repositories, or client-side apps.

Scopes

Keys accept the scopes read, write, projects:read, and projects:write. Each route checks its declared scope; a denied request returns 403 INSUFFICIENT_SCOPE.

RouteRequired scope
GET /api/v1/me, project reads, usage and statusread
POST /api/v1/projectswrite

List projects

GET /api/v1/projects. Requires read; a projects:read key also satisfies this read check. Returns up to 100 of the key owner's projects. A key can only ever see projects owned by the account that created it.

{
  "data": [
    {
      "id": "uuid",
      "project_name": "Example project",
      "type": "web_app",
      "status": "draft",
      "progress": 0,
      "created_at": "2026-10-10T10:00:00.000Z"
    }
  ],
  "request_id": "uuid"
}

Rate limits

The current API-key limiter allows up to 120 requests per key in a 60-second window. Over the limit you receive 429 RATE_LIMITED with a Retry-After header (seconds). Back off and retry after that time. If the shared limiter is unavailable, requests fail closed with 503 RATE_LIMIT_UNAVAILABLE.

Errors and request IDs

Every response, success or error, includes an x-request-id header. Errors use this shape:

{
  "error": {
    "code": "INSUFFICIENT_SCOPE",
    "message": "The key requires the read scope."
  },
  "request_id": "uuid"
}
HTTPCodeMeaning
401UNAUTHORIZEDThe Authorization header is missing, malformed, or does not contain a valid LEO key.
401INVALID_API_KEYThe key is unknown, revoked, or expired. Create a replacement key.
403INSUFFICIENT_SCOPEThe key does not have the scope required by this endpoint.
429RATE_LIMITEDThe configured per-key limit was exceeded. Wait for Retry-After seconds.
503RATE_LIMIT_UNAVAILABLEThe shared rate-limit service could not be reached; retry after the supplied delay.
400VALIDATION_ERRORThe request body or parameters did not meet this endpoint’s requirements.
500DATABASE_ERRORThe request could not be completed. Retry and include the request ID if it persists.

If you contact support about an error, include its request_id.

Application liveness

GET /api/health is a lightweight liveness endpoint. A healthy response means the Next.js process can answer HTTP requests; it does not assert that Supabase, OpenAI, Paystack, or deployment services are available.

curl https://leoos-omega.vercel.app/api/health
HTTP 200
cache-control: no-store
x-request-id: 90f7a5bc-0735-46eb-8f49-a56c5d1e4210

{ "status": "ok" }

The endpoint intentionally makes no database, AI, or payment-provider calls. Use a provider-side uptime check for external reachability and service-dependent alerting.

Webhooks

Add an HTTPS endpoint on the Webhooks page. LEO OS sends a signed POST with a JSON body when an event occurs. Endpoints must be public HTTPS URLs on the default port. Localhost, private networks, and redirects are not supported.

Available events: project.created after a v1 project is created, project.deployed after deployment completes, and api.usage.completed after a metered API request completes. webhook.test is sent only when you press "Send test".

POST /your-endpoint
content-type: application/json
leo-event: webhook.test
leo-delivery-id: 6f1c...
leo-signature: t=1790000000,v1=9a3b...

{
  "id": "6f1c...",
  "type": "webhook.test",
  "created": 1790000000,
  "data": { "message": "This is a test event from LEO OS." }
}

Verify the signature. Compute HMAC-SHA256 of {t}.{raw body} with your signing secret and compare it to v1 using a constant-time comparison. Reject requests whose timestamp is more than 5 minutes old. Use the raw body, not re-serialised JSON.

Delivery and retries. Respond with any 2xx status within 8 seconds to confirm receipt. Anything else, or a timeout, counts as a failure. The delivery record schedules up to five retries after 1 minute, 5 minutes, 30 minutes, 2 hours, and 6 hours. However, the currently configured Vercel cron invokes the retry worker once daily, so these times are eligibility delays—not a promise that a retry runs at that exact time. Delivery status and errors are shown on the Webhooks page. Because retries can repeat an event, use the id field to ignore duplicates.

TypeScript SDK

@leo-os/sdk@2.0.0 is published on npm. It wraps the API with typed errors and a webhook verifier, has no runtime dependencies, and needs Node 18 or newer.

import { LeoClient, verifyWebhookSignature } from '@leo-os/sdk';

const leo = new LeoClient({ apiKey: process.env.LEO_API_KEY! });
const { data } = await leo.projects.list();

// In your webhook handler (rawBody is the unparsed request body string):
const ok = verifyWebhookSignature(secret, req.headers['leo-signature'], rawBody);

Command-line client

@leo-os/cli@1.0.0 is published on npm. Login validates credentials against /api/v1/me; project list/create and linked-project status use the v1 API.

node packages/cli/src/index.mjs login --api-key "$LEO_API_KEY" --base-url https://your-leonardx-domain
node packages/cli/src/index.mjs projects list
node packages/cli/src/index.mjs projects create "My app" --type web_app

leo deploy --brief and leo ship call the authenticated project deployment endpoint. They reuse the existing builder pipeline and only return a deployment result after Vercel confirms the deployment state.

Open the interactive CLI guide.

Workspace and extension guides

Agent & Tool Studio is available to paid Developer API plans and the platform owner. It stores private agent instructions and permits only existing account-approved read-only MCP tools. Web IDE guide describes the separate authenticated editor and non-executing console. Plugin registry guide documents the metadata-only manifest model and its current persistence/runtime limits.

Versions

The public API uses /api/v1. Existing /api/v2 routes remain as compatibility endpoints for clients already using them; new integrations should use v1. The OpenAPI document is available at /api/openapi. Its document version 1.0.0 is distinct from the URL API version and plugin manifest apiVersion.

Changelog

  • v1, 2026-10-08. Added API keys with scopes, expiry, and revocation; project listing, creation, detail/status reads, usage, and account lookup; database-backed per-key rate limits, request IDs, and request outcome logging. Signed webhooks support test delivery plus project-created, project-deployed, and completed API-usage events. The TypeScript SDK and CLI use v1 for new integrations.