Code snippets.
Examples to connect to the API with different languages and tools. Use https://api.nan.builders/v1 as base URL and your personal API key.
model: deepseek-v4-flash
text generation, chat and vision
curl
curl https://api.nan.builders/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "deepseek-v4-flash",
"messages": [{"role": "user", "content": "Hello, how are you?"}],
"max_tokens": 500
}'
python (openai)
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "Write a hello world in Rust"}],
max_tokens=500,
stream=True
)
for chunk in response:
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
Install: pip install openai
node.js (openai)
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "sk-your-key-here",
baseURL: "https://api.nan.builders/v1",
});
const stream = await client.chat.completions.create({
model: "deepseek-v4-flash",
messages: [{ role: "user", content: "Write a hello world in Zig" }],
max_tokens: 500,
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) process.stdout.write(content);
}
Install: npm install openai
structured output on deepseek-v4-flash
On api.nan.builders, deepseek-v4-flash rejects response_format json_schema with a 400 (on api.helmcode.com it is accepted), and json_object only guarantees valid JSON, not its shape. To get output that follows a schema, define one function tool whose parameters is your JSON Schema (root "type": "object", "strict": true) and force it with tool_choice. The model returns arguments that follow the schema in choices[0].message.tool_calls[0].function.arguments, as a JSON string. strict asks for an exact match; it is enforced where the model supports strict decoding, so validate the arguments if your code depends on them.
curl https://api.nan.builders/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "deepseek-v4-flash",
"messages": [{"role": "user", "content": "Ana García is 34 and lives in Valencia."}],
"tools": [{
"type": "function",
"function": {
"name": "save_person",
"description": "Save the person mentioned in the text.",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age", "city"],
"additionalProperties": false
}
}
}],
"tool_choice": {"type": "function", "function": {"name": "save_person"}}
}'
# → choices[0].message.tool_calls[0].function.arguments:
# {"name": "Ana García", "age": 34, "city": "Valencia"}
import json
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age", "city"],
"additionalProperties": False
}
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "Ana García is 34 and lives in Valencia."}],
tools=[{
"type": "function",
"function": {
"name": "save_person",
"description": "Save the person mentioned in the text.",
"strict": True,
"parameters": schema
}
}],
tool_choice={"type": "function", "function": {"name": "save_person"}}
)
person = json.loads(response.choices[0].message.tool_calls[0].function.arguments)
print(person) # {'name': 'Ana García', 'age': 34, 'city': 'Valencia'}
model: qwen3-embedding
vector embeddings
curl
curl https://api.nan.builders/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "qwen3-embedding",
"input": ["Hello world", "Hola mundo"],
"encoding_format": "float"
}'
# → 4096-dimensional vectors per input
python
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
response = client.embeddings.create(
model="qwen3-embedding",
input=["Kubernetes pod scheduling", "Pod scheduling in Kubernetes"],
encoding_format="float"
)
embeddings = [d.embedding for d in response.data]
print(len(embeddings[0])) # 4096
node.js
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "sk-your-key-here",
baseURL: "https://api.nan.builders/v1",
});
const response = await client.embeddings.create({
model: "qwen3-embedding",
input: ["Hello world", "Hola mundo"],
encoding_format: "float",
});
const embeddings = response.data.map((d) => d.embedding);
console.log(embeddings[0].length); // 4096
model: rerank
semantic reranking — completes the RAG stack
curl
curl https://api.nan.builders/v1/rerank \
-H "Authorization: Bearer $NAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "rerank",
"query": "What is the capital of France?",
"documents": [
"Paris is the capital of France and home to the Eiffel Tower.",
"Berlin is the capital of Germany.",
"Madrid is the capital of Spain."
]
}'
# → results[] ordered by relevance_score desc, with original index
python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["NAN_API_KEY"],
base_url="https://api.nan.builders/v1"
)
# The /rerank endpoint is not part of the standard OpenAI client,
# but we can invoke it with client.post().
response = client.post(
path="/rerank",
cast_to=object,
body={
"model": "rerank",
"query": "What is the capital of France?",
"documents": [
"Paris is the capital of France and home to the Eiffel Tower.",
"Berlin is the capital of Germany.",
"Madrid is the capital of Spain.",
],
},
)
for r in response["results"]:
print(f"{r['index']}: {r['relevance_score']:.3f}")
Also works with raw requests or any HTTP client — the endpoint is OpenAI-compatible in authentication and payload format.
model: kokoro
text-to-speech
curl
curl https://api.nan.builders/v1/audio/speech \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "kokoro",
"input": "Welcome to NaN builders.",
"voice": "af_heart"
}' \
-o speech.mp3
# English female voice (af_heart), Spanish (ef_dora), etc.
# See all voices: https://github.com/hexgrad/Kokoro-82M
python
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
response = client.audio.speech.create(
model="kokoro",
voice="af_heart",
input="Hello, welcome to NaN builders.",
speed=1.0,
response_format="mp3"
)
response.stream_to_file("output.mp3")
# Spanish voice
response = client.audio.speech.create(
model="kokoro",
voice="ef_dora",
input="Hola, bienvenido a NaN builders.",
response_format="mp3"
)
node.js
import OpenAI from "openai";
import fs from "fs";
const client = new OpenAI({
apiKey: "sk-your-key-here",
baseURL: "https://api.nan.builders/v1",
});
const response = await client.audio.speech.create({
model: "kokoro",
voice: "af_heart",
input: "Hello, welcome to NaN builders.",
speed: 1.0,
response_format: "mp3",
});
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("output.mp3", buffer);
model: whisper
speech-to-text
curl
# Transcribe audio file
curl https://api.nan.builders/v1/audio/transcriptions \
-H "Authorization: Bearer sk-your-key-here" \
-F "model=whisper" \
-F "file=@recording.mp3" \
-F "language=en"
# → {"text":"Transcribed text","language":"en","duration":5.2}
# Translate to English
curl https://api.nan.builders/v1/audio/translations \
-H "Authorization: Bearer sk-your-key-here" \
-F "model=whisper" \
-F "file=@recording.mp3"
python
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
# Transcribe English audio
with open("recording.mp3", "rb") as f:
result = client.audio.transcriptions.create(
model="whisper",
file=f,
language="en",
response_format="verbose_json"
)
print(result.text) # Transcribed text
print(result.language) # "en"
print(result.duration) # 5.2 (seconds)
# Translate to English
with open("recording.mp3", "rb") as f:
translation = client.audio.translations.create(
model="whisper",
file=f
)
print(translation.text) # English translation
node.js
import OpenAI from "openai";
import fs from "fs";
const client = new OpenAI({
apiKey: "sk-your-key-here",
baseURL: "https://api.nan.builders/v1",
});
// Transcribe audio
const file = fs.createReadStream("recording.mp3");
const result = await client.audio.transcriptions.create({
model: "whisper",
file,
language: "en",
response_format: "verbose_json",
});
console.log(result.text); // Transcribed text
console.log(result.language); // "en"
console.log(result.duration); // 5.2
model: mimo-v2.6-flash
omnimodal — chat, vision, and audio
curl
curl https://api.nan.builders/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "mimo-v2.6-flash",
"messages": [{"role": "user", "content": "Hello, how are you?"}],
"max_tokens": 500
}'
With reasoning enabled, max_tokens ≥ 300 is recommended to leave room for reasoning.
vision (curl)
curl https://api.nan.builders/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "mimo-v2.6-flash",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}
]
}],
"max_tokens": 500
}'
python (openai)
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
response = client.chat.completions.create(
model="mimo-v2.6-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image."},
{"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}
]
}],
max_tokens=500
)
print(response.choices[0].message.content)
model: flux-2-klein
image generation and editing
curl
curl https://api.nan.builders/v1/images/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "flux-2-klein",
"prompt": "A lighthouse at sunset over cliffs, photographic",
"size": "1024x1024",
"n": 1
}'
# → {"created":...,"data":[{"url":"https://..."}]}
Each side of size has to be divisible by 16 and between 256 and 1536, with an aspect ratio between 1:3 and 3:1. n goes up to 4.
python
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
image = client.images.generate(
model="flux-2-klein",
prompt="A lighthouse at sunset over cliffs, photographic",
size="1024x1024",
extra_body={"seed": 42}
)
print(image.data[0].url)
The link is temporary, about 60 minutes. Ask for response_format="b64_json" and the bytes arrive inline in data[0].b64_json instead, base64-encoded. seed and guidance are NaN extensions, so the OpenAI SDK sends them through extra_body.
node.js (image to image)
import OpenAI from "openai";
import fs from "fs";
const client = new OpenAI({
apiKey: "sk-your-key-here",
baseURL: "https://api.nan.builders/v1",
});
const image = await client.images.edit({
model: "flux-2-klein",
image: fs.createReadStream("reference.png"),
prompt: "Turn the scene into winter, with snow",
size: "1024x1024",
});
console.log(image.data[0].url);
/images/edits takes up to four reference images (PNG, JPEG or WebP, under 25 MB each) and does not support mask: sending one returns 400.
Images need inference membership, 403 otherwise, and they run on their own budget: 20 requests per minute and 100 per month, which does not touch your token quota.
model: qwen-image-2.1
text-to-image generation
curl
curl https://api.nan.builders/v1/images/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key-here" \
-d '{
"model": "qwen-image-2.1",
"prompt": "A chalkboard with the word lighthouse written on it, clean lettering",
"size": "1024x1024",
"n": 1
}'
# → {"created":...,"data":[{"url":"https://..."}]}
Each side of size has to be divisible by 16 and between 512 and 1280, with an aspect ratio between 1:3 and 3:1. n goes up to 4. No reference images: this model is text-to-image only. seed is an integer in 0..2147483647.
python
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key-here",
base_url="https://api.nan.builders/v1"
)
image = client.images.generate(
model="flux-2-klein",
prompt="A chalkboard with the word lighthouse written on it, clean lettering",
size="1024x1024",
extra_body={"seed": 42}
)
print(image.data[0].url)
The link is temporary, about 60 minutes. Ask for response_format="b64_json" and the bytes arrive inline in data[0].b64_json instead, base64-encoded. seed and guidance are NaN extensions, so the OpenAI SDK sends them through extra_body.
node.js (image to image)
import OpenAI from "openai";
import fs from "fs";
const client = new OpenAI({
apiKey: "sk-your-key-here",
baseURL: "https://api.nan.builders/v1",
});
const image = await client.images.edit({
model: "flux-2-klein",
image: fs.createReadStream("reference.png"),
prompt: "Turn the scene into winter, with snow",
size: "1024x1024",
});
console.log(image.data[0].url);
/images/edits takes up to four reference images (PNG, JPEG or WebP, under 25 MB each) and does not support mask: sending one returns 400.
Images need inference membership, 403 otherwise, and they run on their own budget: 20 requests per minute and 100 per month, which does not touch your token quota.
Connect your editor or your agent
The configurations for Cursor, Claude Code, Codex, Cline, OpenCode, Zed and the rest are in Set up your agent, with one page per tool.