Keep the SDK you already use and point it at Lucenta. The same prepaid key and the same model ids work across all three request formats.
Three steps to a first completion. Same bearer token for model discovery and inference.
Sign up, open API Keys, mint a key, and store the token — it is shown once.
Use https://api.lucenta.ai/v1 as your OpenAI SDK baseURL (or base_url).
Call POST /v1/chat/completions with a public model id from GET /v1/models.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.LUCENTA_API_KEY!,
baseURL: "https://api.lucenta.ai/v1",
});
const res = await client.chat.completions.create({
model: "claude-sonnet-4-6",
messages: [{ role: "user", content: "Hello from Lucenta" }],
});
console.log(res.choices[0]?.message?.content);Local docker: use http://localhost:8000/v1 instead of production. Need credits first? Top up under Billing.
Create keys in the dashboard under API Keys. Send the secret on every /v1/* request. Prefer Authorization: Bearer YOUR_API_KEY. Anthropic-style clients (New API, the Anthropic SDK) may send x-api-key instead. If both headers are present they must be the same key. Usage draws from your prepaid balance — if the reserved charge exceeds the balance, Lucenta returns 402 with insufficient_credits.
| Header | Value |
|---|---|
| Authorization | Bearer sk-live_… |
| x-api-key | sk-live_… (optional; Anthropic clients) |
| Content-Type | application/json |
GET /v1/models returns the public catalog (Anthropic, OpenAI, Gemini) and Lucenta pricing under lucenta. Browse the same list on /models or in the dashboard.
curl https://api.lucenta.ai/v1/models \ -H "Authorization: Bearer YOUR_API_KEY"
OpenAI-compatible chat. Required: model and messages. Pass any public model id from GET /v1/models (for example claude-sonnet-4-6).
curl https://api.lucenta.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [
{"role": "user", "content": "Hello from Lucenta"}
]
}'| Field | Notes |
|---|---|
| model | Public model id from GET /v1/models |
| messages | OpenAI chat messages array |
| stream | Optional; SSE when true |
| max_tokens | Optional; capped per model |
| tools | When the catalog model advertises tool support |
POST /v1/messages takes an Anthropic Messages body and returns content blocks. Use it with the Anthropic SDK by setting its base URL to https://api.lucenta.ai/v1. Auth is Authorization: Bearer or x-api-key. anthropic-version is optional and forwarded when present.
curl https://api.lucenta.ai/v1/messages \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 256,
"system": "Be brief.",
"messages": [
{"role": "user", "content": [{"type": "text", "text": "Hello from Lucenta"}]}
]
}'| Field | Notes |
|---|---|
| model | Public model id from GET /v1/models |
| messages | Anthropic content blocks: text, image, document |
| max_tokens | Required; capped per model |
| tools | Client tools, including Anthropic web search tool types |
| thinking | JSON and stream copy thinking blocks and signatures when the model returns them. Stream uses Anthropic events (thinking_delta, signature_delta) |
| cache_control | Prompt cache write/read on content blocks; usage includes cache tokens when present |
Use a Lucenta public model id from GET /v1/models. Images, PDFs, tools, thinking, and prompt cache are accepted on this endpoint. JSON and stream responses return those content types when the model produces them, including server tools such as web search.
POST /v1/beta/models/{model}:generateContent takes a Gemini body —contents with parts — and returns candidates. The model goes in the path, and it is the same public id as everywhere else.
curl https://api.lucenta.ai/v1/beta/models/claude-sonnet-4-6:generateContent \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "Hello from Lucenta"}]}
],
"generationConfig": {"maxOutputTokens": 256}
}'systemInstruction, temperature, topP and maxOutputTokens are honored. Text parts only.
Set stream: true on /v1/chat/completions for text/event-stream chunks in the OpenAI SSE format. The same flag on /v1/messages streams Anthropic SSE (event: message_start, content_block_delta, thinking and signature events when requested). Gemini generateContent returns a single JSON response.
curl https://api.lucenta.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"stream": true,
"messages": [
{"role": "user", "content": "Stream a short hello"}
]
}'Errors use an OpenAI-style envelope with a Lucenta type. There is no per-key request or token cap — prepaid balance is the only stop. Insufficient credit returns 402.
| HTTP | Type | When |
|---|---|---|
| 400 | invalid_request | Missing fields or bad max_tokens |
| 404 | invalid_request | Unknown model id |
| 401 | invalid_api_key | Missing or invalid API key |
| 402 | insufficient_credits | Prepaid balance too low for the reserved charge |
| 501 | not_implemented | Disabled or unsupported model |
| 502 | provider_error | Upstream provider failure |
{
"error": {
"message": "Insufficient credits",
"type": "insufficient_credits",
"balance": 0.0
}
}