OpenAI Compatibility
curl --request POST \
--url https://api.example.com/v1/chat/completionsimport requests
url = "https://api.example.com/v1/chat/completions"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v1/chat/completions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/chat/completions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/chat/completions"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v1/chat/completions")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/chat/completions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyOpenAI compatibility
OpenAI Compatibility
Text chat through the official OpenAI SDK
POST
/
v1
/
chat
/
completions
OpenAI Compatibility
curl --request POST \
--url https://api.example.com/v1/chat/completionsimport requests
url = "https://api.example.com/v1/chat/completions"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v1/chat/completions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/chat/completions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/chat/completions"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v1/chat/completions")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/chat/completions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyElumenta provides OpenAI-compatible endpoints for text chat:
Copy the entire example and replace only the API key:
The
The
POST /v1/chat/completions— create a response, including streaming responses;GET /v1/models— list available text models in OpenAI format.
The exact base URL is
https://elumenta.ru/v1. Do not append /api or /chat/completions: the OpenAI SDK appends the endpoint path itself.Access
Use the samenb_... API key that you use with /api/v2; you do not need a separate key. API access requires the Advanced plan or higher (t2_advanced or vip, level 3). Lower plans receive a 403 response explaining the required plan.
Complete Python example
Install the official SDK:pip install openai
from openai import OpenAI
client = OpenAI(api_key="nb_...", base_url="https://elumenta.ru/v1")
response = client.chat.completions.create(
model="gpt-5-nano",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain recursion in one sentence."},
],
)
print(response.choices[0].message.content)
billing = getattr(response, "elumenta", {}) or {}
print(f"Charged: {billing.get('tokens_spent', 'unknown')} tkn")
print(f"Balance: {billing.get('balance', 'unknown')} tkn")
system, user, and assistant roles are supported, as are temperature and max_tokens. The final message must use the user role.
Streaming
Passstream=True to consume response chunks as they arrive:
stream = client.chat.completions.create(
model="gpt-5-nano",
messages=[{"role": "user", "content": "Name three planets."}],
stream=True,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="")
billing = getattr(chunk, "elumenta", {}) or {}
if billing:
print(f"\nCharged: {billing.get('tokens_spent', 'unknown')} tkn")
print(f"Balance: {billing.get('balance', 'unknown')} tkn")
elumenta object arrives in the final stream chunk. Its tokens_spent and balance fields are included only when their values are known, so read them with .get() as shown above. The object can be empty, for example when streaming reconciliation does not run for a web session.
Call cost
Each synchronous response contains two adjacent objects:usage— exactly the three standard OpenAI fields:prompt_tokens,completion_tokens, andtotal_tokens;elumenta.tokens_spent— the tkn actually charged for this call after reconciliation with the provider’s real usage, when known;elumenta.balance— the balance remaining after the charge, when known.
elumenta may be an empty object when neither value is known. In streaming mode Elumenta cannot completely populate usage, because the completion event does not contain the input and output token counts. To keep the response shape consistent in both modes, cost fields are placed alongside usage in elumenta, rather than inside usage.
For synchronous HTTP responses, X-RateLimit-Limit contains the request limit and X-Token-Balance contains the token balance. Streaming responses do not include X-Token-Balance: headers are sent before the stream finishes, while the final charge is not yet known. Read the current balance from elumenta.balance in the final chunk instead.
List models
models = client.models.list()
for model in models.data:
print(model.id)
GET /v1/models follows the OpenAI format and therefore does not include pricing; this is how the OpenAI specification is structured. Elumenta prices are available from GET /api/v2/models.
For images, video, audio, and other capabilities, use the unified Elumenta API.
