Join our community of builders on Discord!

API Reference

Base URL: https://chat-api.testnet.lightchain.ai (testnet). The OpenAI surface is under /v1; key management is under /api. The OpenAPI document is the machine-readable source of these shapes.
RouteAuthenticated byDoes
GET /v1/modelsAPI keyLists the models a worker serves now.
POST /v1/chat/completionsAPI key, or a per-call paymentRuns a chat completion as one job on chain.
GET /api/auth/challengenoneStarts a wallet sign-in.
POST /api/auth/verifynoneFinishes it and returns a sign-in token.
POST /api/api-keyssign-in tokenMints an API key.
GET /api/api-keyssign-in tokenLists the wallet's keys.
PATCH /api/api-keys/{id}sign-in tokenChanges a key's spend cap.
POST /api/api-keys/{id}/revokesign-in tokenRevokes a key.
DELETE /api/api-keys/{id}sign-in tokenDeletes a revoked key.
An API key goes in Authorization: Bearer lcai_...; a sign-in token goes in Authorization: Bearer <token>. The two are not interchangeable.

GET /v1/models

The models at least one worker serves right now. Needs an API key.
CodeJSON
Send id verbatim as model, colons included.
StatusWhen
200The list.
401Missing, unknown or revoked key (invalid_api_key).
429rate_limit_exceeded; retry after retry-after seconds.

POST /v1/chat/completions

Request headers

Header
Authorization: Bearer lcai_...The API key. Optional only on a call paid per call: see Payment.
Content-Type: application/jsonRequired.
PAYMENT-SIGNATUREOptional, experimental: a per-call payment, base64 of the JSON payload. See Payment.

Request body

FieldRequired
modelyesA model id from /v1/models.
messagesyesThe whole conversation. Roles system, developer, user, assistant; content is a string or text parts. The last message is the user's.
streamnotrue for server-sent events: see Streaming.
conversation_idnoA Lightchain AI extension, up to 64 characters: sends the call back to the session that served this conversation last, when it is free. A preference only.
Other OpenAI fields (temperature, max_tokens, top_p, ...) are accepted and ignored. Images, tools and function calling are not supported.

Response

An OpenAI chat.completion with one choice and no usage, plus the job it ran as:
CodeJSON
lightchain field
job_idThe job's id in JobRegistry.
session_idThe session it ran in.
tx_hashThe transaction that submitted the job (on a call paid per call, the settlement).
workerThe worker that served it.
dropped_messagesOnly when the job left the oldest messages out to fit one blob: how many.
With stream: true, the answer is text/event-stream, and the last chunk carries lightchain: see Streaming.

Response headers

Header
x-lightchainThe lightchain object as JSON, from the start of the response (streams included).
PAYMENT-RESPONSEOn a call paid per call: base64 of the settlement (success, transaction, network, payer, amount).
PAYMENT-REQUIREDOn a 402 (and some 400s) from a server that takes per-call payments: base64 of the requirements.
retry-afterOn a 429: seconds to wait.

Status codes

StatusWhen
200The answer.
400Invalid request (code null); the prompt is too large for one job (context_length_exceeded); or a malformed or foreign PAYMENT-SIGNATURE (invalid_payload, invalid_x402_version, unsupported_scheme, invalid_network, invalid_payment_requirements).
401Missing, unknown or revoked API key (invalid_api_key).
402The call cannot be paid: see Payment.
404No model by that name, or no worker serves it now (model_not_found).
429A limit refused the call (rate_limit_exceeded, concurrency_limit_exceeded, session_open_limit_exceeded): see Limits.
500The server failed to answer.
502The job failed (job_failed), or the per-call payment could not be checked or settled (unexpected_verify_error, unexpected_settle_error).
503No worker took a new session in time (no_worker_available), the chain's blob fee is above what the server pays (blob_fee_too_high), or completions are off on this server (not_configured).
What to do about each code is in Errors.

Wallet sign-in

Key management is authenticated by a Sign-In with Ethereum (EIP-4361) token: an ordinary message signature, no transaction. See API Keys for a full example.

GET /api/auth/challenge?address=<address>

Returns { "nonce", "message" }. Sign message with the wallet (personal_sign).

POST /api/auth/verify

Body { "message", "signature" }. Returns { "token", "expiresAt", ... }. The token lasts an hour.

API keys

All take the sign-in token. A key is listed as:
Field
idThe key's id, for the routes below.
prefixlcai_ and seven characters: identifies a key without revealing it.
nameYour label, up to 64 characters.
spendCapWeiLifetime spend cap in wei (decimal string), or null for none.
spentWeiWhat the key has spent.
limitHitsHow often each limit refused it: { rate, concurrency, spendCap, sessionOpens }.
createdAt, revokedAtTimestamps; revokedAt is null while the key is active.
RouteBodyAnswer
POST /api/api-keys{ "name"?, "spendCapWei"? }201: the key as listed, plus key (lcai_...), shown this once. A wallet holds up to 25 active keys.
GET /api/api-keys200: every key of the wallet, revoked ones included, newest first. Never the key itself.
PATCH /api/api-keys/{id}{ "spendCapWei": "<wei>" } or { "spendCapWei": null }200: the key as listed. 409 api_key_revoked on a revoked key.
POST /api/api-keys/{id}/revoke204. The key stops working at once.
DELETE /api/api-keys/{id}204 for a revoked key. 409 api_key_active for an active one: revoke it first.
Details and examples: API Keys.