OpenAI SDKs and plain HTTP
Call the Nebul Inference API from Python, TypeScript, JavaScript, Go, Rust, Java, C++, and the shell using the OpenAI SDKs or a plain HTTP client.
The Inference API is OpenAI-compatible, so the official OpenAI SDKs work with a two-line change: point base_url at https://api.inference.nebul.io/v1 and pass your Nebul API key. Languages without an official SDK still work with any HTTP client, because the API is plain JSON over HTTPS.
All examples assume your key is exported as NEBUL_API_KEY:
export NEBUL_API_KEY=sk-your-api-key-hereGet a key from your Nebul AI Studio project. Replace zai-org/GLM-5.3 with any model your project can access; see the Model Catalog.
Python
pip install openaiimport os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["NEBUL_API_KEY"],
base_url="https://api.inference.nebul.io/v1",
)
response = client.chat.completions.create(
model="zai-org/GLM-5.3",
messages=[{"role": "user", "content": "Say OK"}],
)
print(response.choices[0].message.content)Streaming
stream = client.chat.completions.create(
model="zai-org/GLM-5.3",
messages=[{"role": "user", "content": "Write a haiku about GPUs."}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()TypeScript
npm install openaiimport OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.NEBUL_API_KEY,
baseURL: "https://api.inference.nebul.io/v1",
});
const response = await client.chat.completions.create({
model: "zai-org/GLM-5.3",
messages: [{ role: "user", content: "Say OK" }],
});
console.log(response.choices[0].message.content);JavaScript
The SDK above works in Node and browsers. For plain fetch, with zero dependencies and any runtime, the request is ordinary JSON:
const response = await fetch("https://api.inference.nebul.io/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.NEBUL_API_KEY}`,
},
body: JSON.stringify({
model: "zai-org/GLM-5.3",
messages: [{ role: "user", content: "Say OK" }],
}),
});
const data = await response.json();
console.log(data.choices[0].message.content);Go
go get github.com/openai/openai-gopackage main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
func main() {
client := openai.NewClient(
option.WithBaseURL("https://api.inference.nebul.io/v1"),
option.WithAPIKey(os.Getenv("NEBUL_API_KEY")),
)
completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: "zai-org/GLM-5.3",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Say OK"),
},
})
if err != nil {
panic(err)
}
fmt.Println(completion.Choices[0].Message.Content)
}Rust
async-openai is the community-maintained client most Rust projects use:
# Cargo.toml
[dependencies]
async-openai = "0.28"
tokio = { version = "1", features = ["full"] }use async_openai::{
config::OpenAIConfig,
types::chat::{ChatCompletionRequestUserMessage, CreateChatCompletionRequestArgs},
Client,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = OpenAIConfig::new()
.with_api_base("https://api.inference.nebul.io/v1")
.with_api_key(std::env::var("NEBUL_API_KEY")?);
let client = Client::with_config(config);
let request = CreateChatCompletionRequestArgs::default()
.model("zai-org/GLM-5.3")
.messages([ChatCompletionRequestUserMessage::from("Say OK").into()])
.build()?;
let response = client.chat().create(request).await?;
println!("{}", response.choices[0].message.content.clone().unwrap_or_default());
Ok(())
}Java
The official com.openai:openai-java SDK supports custom base URLs on its OkHttp client:
<!-- Maven -->
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>1.6.0</version>
</dependency>import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
public class Main {
public static void main(String[] args) {
OpenAIClient client = OpenAIOkHttpClient.builder()
.baseUrl("https://api.inference.nebul.io/v1")
.apiKey(System.getenv("NEBUL_API_KEY"))
.build();
ChatCompletion completion = client.chat().completions().create(
ChatCompletionCreateParams.builder()
.model("zai-org/GLM-5.3")
.addUserMessage("Say OK")
.build());
System.out.println(completion.choices().get(0).message().content().orElse(""));
}
}C++
No official C++ SDK exists, and none is needed: the API is an HTTPS POST. With libcurl:
// g++ chat.cpp -lcurl -o chat && NEBUL_API_KEY=sk-... ./chat
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(void *data, size_t size, size_t nmemb, void *out) {
static_cast<std::string *>(out)->append(static_cast<char *>(data), size * nmemb);
return size * nmemb;
}
int main() {
const char *key = std::getenv("NEBUL_API_KEY");
std::string body = R"({
"model": "zai-org/GLM-5.3",
"messages": [{"role": "user", "content": "Say OK"}]
})";
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, std::string("Authorization: Bearer " + std::string(key)).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "https://api.inference.nebul.io/v1/chat/completions");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
if (curl_easy_perform(curl) != CURLE_OK) {
std::cerr << "request failed\n";
return 1;
}
std::cout << response << "\n";
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}Shell
curl https://api.inference.nebul.io/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $NEBUL_API_KEY" \
-d '{
"model": "zai-org/GLM-5.3",
"messages": [{"role": "user", "content": "Say OK"}]
}'With jq for a clean answer:
curl -sS https://api.inference.nebul.io/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $NEBUL_API_KEY" \
-d '{
"model": "zai-org/GLM-5.3",
"messages": [{"role": "user", "content": "Say OK"}]
}' | jq -r '.choices[0].message.content'Beyond the basics
- Streaming works on every chat model; see Examples.
- Reasoning models return the chain of thought in
reasoning_contentorreasoning, depending on the family. See Reasoning Models. - Tool calling and structured output are covered in Function Calling & Tools and Structured Output & JSON.
- Model metadata for configuring clients lives at
/v1/model/info.