Build against the API
The LightHouse API is described by an OpenAPI 3 document. Atlantic does not publish client libraries for the API. To call it from your own code, generate a client from the OpenAPI document, or call the routes directly with any HTTP client.
The OpenAPI document
Section titled “The OpenAPI document”| Document | Address | Contents |
|---|---|---|
| Public | https://docs.atlanticagenticlabs.com/openapi.json |
The client API, as documented in the API reference. No credential is required to read it |
| Per tenant | https://<tenant id>.atlanticagenticlabs.com/api/v1/openapi.json |
The document served by your tenant’s LightHouse. Reading it requires the same authentication as any other route |
The public document matches the release these docs describe. Regenerate your client when LightHouse is upgraded; the changelog lists each release’s changes.
Authentication
Section titled “Authentication”Code that runs unattended uses a machine key (aalcp-), issued under Settings → Keys, and your tenant’s Access service token. Every request carries three headers:
| Header | Value |
|---|---|
Authorization |
Bearer aalcp-… |
CF-Access-Client-Id |
The Access service token’s client ID |
CF-Access-Client-Secret |
The Access service token’s client secret |
A machine key reads. It cannot approve, decide or pay. See Machine keys and The Access service token at the edge. Keep the key and the service token in your secret store or masked CI variables, not in source code.
A direct call
Section titled “A direct call”The examples read AAL_TENANT, AAL_KEY, CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET from the environment and call GET /api/v1/me.
curl "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/me" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}base = f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com"
with httpx.Client(base_url=base, headers=headers, timeout=30) as client: response = client.get("/api/v1/me") response.raise_for_status() print(response.json())const base = `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com`;const headers = { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!,};
const response = await fetch(`${base}/api/v1/me`, { headers });if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);console.log(await response.json());If Cloudflare Access answers instead of LightHouse (a redirect to a sign-in page), the Access service token is missing or wrong.
Generate a client
Section titled “Generate a client”Any OpenAPI 3 generator can produce a client. The two below are maintained open-source projects; Atlantic does not maintain either.
Python: openapi-python-client
Section titled “Python: openapi-python-client”openapi-python-client generates a typed Python package, built on httpx, with one function per operation.
pipx install openapi-python-clientopenapi-python-client generate --url https://docs.atlanticagenticlabs.com/openapi.jsonThe generated package’s AuthenticatedClient sends the machine key as Authorization: Bearer. Pass the Access service token as two more headers when the client is created. The package’s own README lists its modules and functions.
TypeScript: openapi-typescript and openapi-fetch
Section titled “TypeScript: openapi-typescript and openapi-fetch”openapi-typescript generates the API’s types; openapi-fetch is a small fetch wrapper that checks paths, parameters and responses against them.
npm install openapi-fetchnpm install --save-dev openapi-typescriptnpx openapi-typescript https://docs.atlanticagenticlabs.com/openapi.json -o lighthouse.d.tsimport createClient from "openapi-fetch";import type { paths } from "./lighthouse";
const lighthouse = createClient<paths>({ baseUrl: `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com`, headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, },});
const { data, error } = await lighthouse.GET("/api/v1/me");if (error) throw new Error(JSON.stringify(error));console.log(data);Behaviour a client must implement
Section titled “Behaviour a client must implement”A generated client sends requests and parses responses. The following behaviour is the caller’s responsibility:
| Behaviour | Requirement | Reference |
|---|---|---|
| Retries | Retry only 429, 502, 503 and network failures. Honour Retry-After, or RateLimit-Reset on a 429 without it; otherwise back off exponentially with jitter |
Rate limits |
| Idempotency | Send an Idempotency-Key on every write, the same on each retry of that write |
Idempotency |
| Pagination | Follow next until it is absent |
Pagination |
| Errors | Branch on the fixed error code in the response body, not on the message text |
Errors |
From a terminal or CI
Section titled “From a terminal or CI”The CLI covers the same reads from a shell and in CI, with retries, pagination and JSON output built in.