Chat completions
Generate a reply to a conversation, call your own tools, constrain output to JSON, and stream the result.
On this page
POST
/api/v1/llm/v1/chat/completions OpenAI-compatible chat completions. Supports
Idempotency-Key. Every field is in the reference.Scope: llm:access or llm:chat
Request
| Field | Type | Notes |
|---|---|---|
model |
string | nebula-4.5 (default) or nebula-v for images. |
messages |
array, required | system, user, assistant and tool messages. Content is text or content parts. |
max_tokens |
integer | Output ceiling. An explicit value is clamped to the platform maximum (32,000 by default). max_completion_tokens is an alias; the smaller wins. |
temperature |
number | 0 to 2. Default 0.7. |
top_p |
number | 0 to 1. Default 1. |
stream |
boolean | Server-sent events. See Streaming. |
stop |
string or array | Stop sequences. |
tools |
array | OpenAI function tool definitions. |
tool_choice |
string or object | auto, none, required, or a named function. |
parallel_tool_calls |
boolean | Set false for at most one tool call per turn. |
response_format |
object | {"type": "json_object"} or a json_schema. |
reasoning_effort |
string | none, low, medium, high, max, xhigh or ultra. Omit for adaptive routing. |
user |
string | A stable session or end-user id, sent on every turn, so prompt caching can reuse context. |
Basic request
cURL
curl https://api.breachline.io/api/v1/llm/v1/chat/completions \
-H "Authorization: Bearer $BREACHLINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nebula-4.5",
"messages": [
{"role": "system", "content": "You triage web findings."},
{"role": "user", "content": "Is a missing HttpOnly flag on a session cookie high severity?"}
]
}'
Python
response = client.chat.completions.create(
model="nebula-4.5",
messages=[
{"role": "system", "content": "You triage web findings."},
{"role": "user", "content": "Is a missing HttpOnly flag on a session cookie high severity?"},
],
)
print(response.choices[0].message.content)
TypeScript
const response = await client.chat.completions.create({
model: 'nebula-4.5',
messages: [
{ role: 'system', content: 'You triage web findings.' },
{ role: 'user', content: 'Is a missing HttpOnly flag on a session cookie high severity?' },
],
});
console.log(response.choices[0].message.content);
Tool calling
Describe your functions in tools. When the model wants one, the response has finish_reason: "tool_calls" and a tool_calls array. Run the tool yourself, then send the result back as a tool message with the matching tool_call_id.
tools = [{
"type": "function",
"function": {
"name": "lookup_asset",
"description": "Return the owner and environment of a hostname.",
"parameters": {
"type": "object",
"properties": {"hostname": {"type": "string"}},
"required": ["hostname"],
},
},
}]
first = client.chat.completions.create(
model="nebula-4.5",
messages=[{"role": "user", "content": "Who owns staging-api.example.com?"}],
tools=tools,
)
call = first.choices[0].message.tool_calls[0]
result = {"owner": "payments team", "environment": "staging"}
final = client.chat.completions.create(
model="nebula-4.5",
messages=[
{"role": "user", "content": "Who owns staging-api.example.com?"},
first.choices[0].message,
{"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)},
],
tools=tools,
)
Structured output
Ask for JSON that matches a schema with response_format.
{
"type": "json_schema",
"json_schema": {
"name": "triage",
"schema": {
"type": "object",
"properties": {
"severity": {"type": "string", "enum": ["critical", "high", "medium", "low", "info"]},
"reason": {"type": "string"}
},
"required": ["severity", "reason"]
}
}
}
Images
Send images to nebula-v as image_url content parts (an HTTPS URL or a data: URL).
{
"model": "nebula-v",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "What does this error page reveal?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."}}
]
}]
}
Response
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1762862400,
"model": "nebula-4.5",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "Usually medium..."},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 41, "completion_tokens": 88, "total_tokens": 129}
}