Docs · API
Chat completions
Request schema, response shape, and limits for POST /v1/chat/completions.
On this page
POST /v1/chat/completions accepts an OpenAI-compatible chat body and returns
either a chat.completion object or a server-sent event stream. It requires a
user API key.
Request body
| Field | Type | Required | Rules |
|---|---|---|---|
model | string | Yes | 1–200 characters. Use lfm3, the only live model key. |
messages | array | Yes | 1–64 messages. Each has role and content. |
messages[].role | string | Yes | system, user, or assistant. |
messages[].content | string | Yes | 1–100,000 characters. |
maxTokens | integer | No | 1–4,096. Defaults to 512. |
max_tokens | integer | No | Same as maxTokens; the OpenAI-style name is accepted. |
stream | boolean | No | true returns SSE; default is a single JSON response. |
Unknown fields are accepted by validation but are not acted on.
The estimated input size is checked before a job is created. The gateway sums
ceil(characters / 4) over all messages; an estimate above 2,048 tokens is
rejected with 413 CONTEXT_LIMIT.
Non-streaming request
curl https://<your-domain>/v1/chat/completions \
-H "Authorization: Bearer $EASYAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "lfm3",
"messages": [
{ "role": "system", "content": "Answer concisely." },
{ "role": "user", "content": "What is a deadline in a job queue?" }
],
"maxTokens": 256
}' import os
from openai import OpenAI
client = OpenAI(
base_url="https://<your-domain>/v1",
api_key=os.environ["EASYAI_API_KEY"],
)
completion = client.chat.completions.create(
model="lfm3",
messages=[{"role": "user", "content": "What is a deadline in a job queue?"}],
max_tokens=256,
)
print(completion.choices[0].message.content) const response = await fetch("https://<your-domain>/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.EASYAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "lfm3",
messages: [
{ role: "system", content: "Answer concisely." },
{ role: "user", content: "What is a deadline in a job queue?" },
],
maxTokens: 256,
}),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();
console.log(data.choices[0].message.content); Success response
{
"id": "chatcmpl-<job-id>",
"object": "chat.completion",
"created": 1762560000,
"model": "lfm3",
"choices": [
{
"message": { "role": "assistant", "content": "..." },
"index": 0,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 42,
"total_tokens": 60
},
"jobId": "<job-id>",
"status": "COMPLETED",
"output": "..."
}
choices[0].message.content and the additive output field contain the same
answer. usage reports the tokens the gateway accounted for the request.
Job status
A non-streaming response includes jobId. You can read the lifecycle view of
your own job at:
curl https://<your-domain>/v1/jobs/<job-id> \
-H "Authorization: Bearer $EASYAI_API_KEY"
The response includes status, timestamps, failureCode, usage counters, and
metric counts. Another user’s job returns 404 JOB_NOT_FOUND, the same as a
missing job. Prompt and output content are not stored or returned by this
endpoint.
Errors
The HTTP error body is always:
{ "error": { "code": "..." } }
Common responses for this endpoint:
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | The body does not match the schema. |
| 401 | UNAUTHORIZED | The API key is missing, invalid, or inactive. |
| 402 | INSUFFICIENT_CREDITS | The request cannot reserve its credit hold. |
| 413 | CONTEXT_LIMIT | Estimated input exceeds 2,048 tokens. |
| 429 | RATE_LIMITED | The per-key request window is exhausted. |
| 503 | NO_CAPACITY | No eligible worker could be reserved. |
| 503 | PROMPT_HOLD_UNAVAILABLE | Worker-executed mode could not stage the prompt. |
| 504 | DEADLINE_EXCEEDED | The job deadline passed. |
| 504 | STAGE_TIMEOUT | A pipeline stage exceeded its deadline. |
| 500 | INTERNAL | Unexpected gateway or execution failure. |
See Errors for the full code list and Streaming for the SSE variant.