Skip to content

Legacy Completions

POST https://api.bve.me/v1/completions

Requires Authorization: Bearer sk-bve-YOUR_KEY.

  • best_of and logprobs are not supported by the emulation layer and return 400 unsupported_parameter.
  • Array prompts are joined with \n\n before being sent as a single user message.
  • The emulated id is derived from the chat completion id (chatcmpl-cmpl-).
{
"model": "gpt-4o",
"prompt": "The capital of France is",
"max_tokens": 10
}
FieldTypeRequiredDescription
modelstringYesModel ID
promptstring | string[]NoPrompt text. Arrays are joined with \n\n.
max_tokensintegerNoMax tokens to generate
temperaturenumberNoSampling temperature (0–2)
top_pnumberNoNucleus sampling (0–1)
nintegerNoNumber of completion choices to generate; must be ≥ 1
best_ofintegerNoMust be ≥ 1; always rejected — not supported by the emulation layer (returns 400 unsupported_parameter)
echobooleanNoPrepend the normalized prompt text to each returned choice
logprobsintegerNoTop-N log probabilities; must be ≥ 0. Always rejected — not supported by the emulation layer (returns 400 unsupported_parameter)
stopstring | string[]NoUp to 4 stop sequences
presence_penaltynumberNoPresence penalty (−2 to 2)
frequency_penaltynumberNoFrequency penalty (−2 to 2)
userstringNoEnd-user identifier (max 256 chars)
seedintegerNoDeterministic seed
streambooleanNoEnable streaming SSE mode. Chunks use object: "text_completion" format (same as non-streaming but delivered as SSE).
{
"id": "cmpl-abc123",
"object": "text_completion",
"created": 1716288000,
"model": "gpt-4o",
"choices": [
{
"text": " Paris",
"index": 0,
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 7,
"completion_tokens": 2,
"total_tokens": 9
}
}

BVE Gateway adds the following headers to every /v1/completions response:

HeaderExampleDescription
X-Request-Id550e8400-…Server-generated UUID for this request
X-BVE-Client-Idmy-trace-123Echo of the client-supplied X-Request-Id (when present and valid: alphanumeric + -_., ≤ 128 chars). Absent when the client did not send X-Request-Id or the value failed validation.
X-BVE-Latency87Total gateway latency in milliseconds
X-BVE-Modelgpt-4oModel ID for this request
X-BVE-Key-Nameprod-keyDisplay name of the authenticated key

The standard X-RateLimit-* per-key headers (requests per minute, per day, monthly caps, token limits) are also present. See Rate Limits & Quotas for the full table and example output.

Terminal window
curl https://api.bve.me/v1/completions \
-H "Authorization: Bearer sk-bve-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"prompt": "The capital of France is",
"max_tokens": 5
}'
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const completion = await client.completions.create({
model: 'gpt-4o',
prompt: 'The capital of France is',
max_tokens: 5,
});
console.log(completion.choices[0].text);

Array prompts are joined with \n\n before being forwarded as a single user message.

import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const completion = await client.completions.create({
model: 'gpt-4o',
prompt: ['Translate to French:', 'Hello, world!'],
max_tokens: 20,
});
console.log(completion.choices[0].text);

When echo: true is set, the normalized prompt text is prepended to each choice’s text field.

import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const completion = await client.completions.create({
model: 'gpt-4o',
prompt: 'The capital of France is',
max_tokens: 5,
echo: true,
});
// text includes the prompt: "The capital of France is Paris"
console.log(completion.choices[0].text);

Streaming is supported. Set "stream": true and BVE Gateway will transform the upstream chat.completion.chunk SSE events into text_completion SSE events in real time.

Terminal window
curl https://api.bve.me/v1/completions \
-H "Authorization: Bearer sk-bve-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4o", "prompt": "The capital of France is", "max_tokens": 10, "stream": true}'

Each SSE chunk uses object: "text_completion" with a choices[].text field instead of choices[].delta.content:

data: {"id":"cmpl-abc","object":"text_completion","created":1716288000,"model":"gpt-4o","choices":[{"text":" Paris","index":0,"logprobs":null,"finish_reason":null}]}
data: {"id":"cmpl-abc","object":"text_completion","created":1716288000,"model":"gpt-4o","choices":[{"text":"","index":0,"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const stream = await client.completions.create({
model: 'gpt-4o',
prompt: 'The capital of France is',
max_tokens: 10,
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.text ?? '');
}

The gateway validates required fields before forwarding to the emulation path.

Missing / invalidCodeparam
model absentmissing_required_parameter"model"
model not a stringinvalid_type"model"
prompt not a string or arrayinvalid_type"prompt"
stream not a booleaninvalid_type"stream"
ConditionCodeparam
best_of not a positive integerinvalid_value"best_of"
best_of set (any valid integer)unsupported_parameter"best_of"
logprobs not a non-negative integerinvalid_value"logprobs"
logprobs set (any valid integer)unsupported_parameter"logprobs"
ParameterInvalid conditionCodeparam
temperatureNot a numberinvalid_type"temperature"
temperatureOutside [0, 2]invalid_value"temperature"
top_pNot a numberinvalid_type"top_p"
top_pOutside [0, 1]invalid_value"top_p"
max_tokensNot a number (e.g. a string)invalid_type"max_tokens"
max_tokensNot a positive integer (float or ≤ 0)invalid_value"max_tokens"
nNot a number (e.g. a string)invalid_type"n"
nNot a positive integer (float or ≤ 0)invalid_value"n"
echoNot a booleaninvalid_type"echo"
presence_penaltyNot a numberinvalid_type"presence_penalty"
presence_penaltyOutside [-2, 2]invalid_value"presence_penalty"
frequency_penaltyNot a numberinvalid_type"frequency_penalty"
frequency_penaltyOutside [-2, 2]invalid_value"frequency_penalty"
stopNot a string or arrayinvalid_type"stop"
stopArray with more than 4 elementsinvalid_value"stop"
stop[N]Not a stringinvalid_type"stop[N]"
userNot a stringinvalid_type"user"
userLonger than 256 charactersinvalid_value"user"
seedNot a number (e.g. a string)invalid_type"seed"
seedA float (e.g. 1.5)invalid_value"seed"

All 400 responses use the standard error envelope:

{
"error": {
"message": "temperature must be between 0 and 2",
"type": "invalid_request_error",
"param": "temperature",
"code": "invalid_value"
}
}