POST /v1/completions
The legacy OpenAI Completions API. You send a raw prompt and the model continues it, with no chat template around it. Any OpenAI SDK or tool works when you point its base URL at https://api.abliteratedllm.dev/v1. For conversations, instructions, tools, images or reasoning output, use POST /v1/chat/completions instead.
Placeholders:
$API_BASEishttps://api.abliteratedllm.dev/v1,$API_ORIGINishttps://api.abliteratedllm.dev, and$YOUR_KEYis your API key.
Request
curl $API_BASE/completions \
-H "Authorization: Bearer $YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash-abliterated",
"prompt": "The lighthouse keeper opened the logbook and wrote:",
"max_tokens": 256,
"temperature": 0.8
}'
Abridged response:
{
"id": "…",
"object": "text_completion",
"created": 1793700000,
"model": "glm-5.3-flash-abliterated",
"choices": [
{ "index": 0, "text": " Day 41. The fog came in before the gulls did…", "finish_reason": "stop" }
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 187,
"total_tokens": 199,
"prompt_tokens_details": { "cached_tokens": 0 }
}
}
Not on Official DeepSeek API models
DeepSeek's API has no completions endpoint, so a request for a model labelled Official DeepSeek API (variant "official_api" in GET /v1/models) fails with 400 invalid_request before anything is charged. Every other model in GET /v1/models works here.
Parameters
Fields not listed here are passed to the model unchanged. Sampling parameters are range-checked first: a value outside its range fails with 400 invalid_request before anything is charged.
| Field | Notes |
|---|---|
model | Required. Any id from GET /v1/models that isn't an Official DeepSeek API model. |
prompt | Required. A string, or an array of 1 to 4 strings to complete several prompts in one request: each prompt gets its own choice, in order of index. 5 or more prompts, an empty array or a prompt of token ids (numbers) fail with 400 invalid_request. Text only: this endpoint takes no image input. |
max_tokens | Output budget. Default 16384. Lowered to the model's max output (max_output_tokens in GET /v1/models), and to 4096 on trial accounts. A value above the limit is lowered, not rejected. |
stream | true for server-sent events. Without it, the answer is generated as a stream on our side and returned as one text_completion when it ends, so a request cut by the time limit or a disconnect is billed for the output generated so far. |
stream_options | include_usage is always switched on, so streams always end with a usage chunk. |
temperature | 0 to 2. |
top_p | 0 to 1. |
top_k | 0 to 100. |
frequency_penalty, presence_penalty | -2 to 2. |
stop | A string or up to 4 strings. |
logprobs | An integer from 0 to 5: the log probability of each output token, plus that many of the most likely alternatives, in the format shown under Logprobs below. true with top_logprobs (0 to 5) works too, and returns the chat completions format instead. |
echo | true puts the prompt in front of the generated text in text. |
suffix | Text that should follow the completion. Passed through; not every model supports it. |
n, best_of | Only 1 (the default). Any other value fails with 400 invalid_request; to complete several prompts at once, send them as a prompt array. |
service_tier | "priority" runs the request on the priority tier of a model that has one, at its priority prices (pricing.priority in GET /v1/models). On a model without one it fails with 400 invalid_request. Any other value is ignored. The tier is described on POST /v1/chat/completions. |
context_length_exceeded_behavior | "truncate" (the default) or "error". See Context length below. |
seed, user | Passed through. |
Streaming
With "stream": true the response is a stream of data: lines. Headers are sent as soon as the model accepts the request. Until the first token arrives, the stream carries an SSE comment line, : ping, every 15 seconds, so proxies don't close an idle connection. SSE clients and the OpenAI SDKs ignore comment lines.
: ping
data: {"id":"…","object":"text_completion","choices":[{"index":0,"text":" Day","logprobs":null,"finish_reason":null}]}
data: {"id":"…","object":"text_completion","choices":[{"index":0,"text":"","logprobs":null,"finish_reason":"stop"}]}
data: {"id":"…","object":"text_completion","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":187,"total_tokens":199,"prompt_tokens_details":{"cached_tokens":0}}}
data: [DONE]
Each chunk carries the next piece of text for one choice, finish_reason arrives on a chunk of its own, and usage always arrives in a final chunk whose choices array is empty. Check that choices isn't empty before reading choices[0]:
from openai import OpenAI
client = OpenAI(base_url="$API_BASE", api_key="$YOUR_KEY")
stream = client.completions.create(
model="glm-5.3-flash-abliterated",
prompt="The lighthouse keeper opened the logbook and wrote:",
max_tokens=256,
stream=True,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].text, end="")
if chunk.usage:
print("\n", chunk.usage)
With an array prompt, each chunk belongs to the choice in its choices[].index, and chunks for different prompts can carry different id values.
Logprobs
An integer logprobs returns the legacy format on each choice: parallel arrays with one entry per output token.
{
"tokens": [" Day", " 41"],
"token_logprobs": [-0.21, -1.73],
"top_logprobs": [{ " Day": -0.21, " The": -2.05 }, { " 41": -1.73, " 12": -1.94 }],
"text_offset": [51, 55]
}
While streaming, each chunk carries the entries for its own tokens. The non-streaming response joins them per choice.
Context length
The prompt plus the output budget must fit in the model's context window, context_length in GET /v1/models. With the default "context_length_exceeded_behavior": "truncate", the output budget is lowered to the room the prompt leaves; with "error", such a request fails with 400 invalid_request. A prompt that is longer than the context window on its own always fails, and is never cut.
Prompt caching
Caching is automatic, as on chat completions: when a prompt starts with the same tokens as a recent one, those tokens are read from cache and billed at the cached-input price. usage.prompt_tokens_details.cached_tokens reports how many.
Billing
prompt_tokens includes cached tokens, which are billed at the cached-input price:
cost = (prompt_tokens - cached_tokens) × input price
+ cached_tokens × cached-input price
+ completion_tokens × output price
Prices are per 1M tokens and each term is rounded up to the next $0.000001. With "service_tier": "priority", the model's priority prices replace its standard ones. Current prices are on GET /v1/models, which also explains holds, aborted streams and failed requests.
Errors
Errors use the OpenAI shape, {"error": {"type", "code", "message"}}. The codes are on the Errors page. Every response carries x-request-id.