Fragmentos de código.
Ejemplos para conectarte a la API desde distintos lenguajes y herramientas. Usa https://api.nan.builders/v1 como base URL y tu API key personal.
model: deepseek-v4-flash
generación de texto, chat y visión
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)
Instalación: 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);
}
Instalación: npm install openai
salida estructurada en deepseek-v4-flash
deepseek-v4-flash rechaza response_format json_schema con un 400, y json_object solo garantiza JSON válido, no su forma. Para obtener una salida que siga un esquema, define una única herramienta de tipo función cuyo parameters sea tu JSON Schema (raíz "type": "object", "strict": true) y fuérzala con tool_choice. El modelo devuelve argumentos que siguen el esquema en choices[0].message.tool_calls[0].function.arguments, como una cadena JSON. strict pide que se ajusten exactamente; se aplica donde el modelo admite decodificación estricta, así que valida los argumentos si tu código depende de ellos.
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
embeddings vectoriales
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
reordenado semántico, completa el stack de RAG
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}")
También funciona con requests a pelo o con cualquier cliente HTTP: el endpoint es compatible con OpenAI tanto en la autenticación como en el formato del cuerpo.
model: kokoro
texto a voz
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
voz a texto
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, visión y 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
}'
Con el razonamiento activado se recomienda max_tokens ≥ 300, para dejarle sitio.
visión (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
generación y edición de imágenes
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": "Un faro al atardecer sobre acantilados, fotográfico",
"size": "1024x1024",
"n": 1
}'
# → {"created":...,"data":[{"url":"https://..."}]}
Cada lado de size tiene que ser divisible entre 16 y estar entre 256 y 1536, con una relación de aspecto entre 1:3 y 3:1. n llega hasta 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="Un faro al atardecer sobre acantilados, fotográfico",
size="1024x1024",
extra_body={"seed": 42}
)
print(image.data[0].url)
El enlace es temporal, alrededor de 60 minutos. Pide response_format="b64_json" y los bytes llegan en data[0].b64_json, en base64, en lugar de detrás de un enlace. seed y guidance son extensiones de NaN, así que el SDK de OpenAI las manda por extra_body.
node.js (imagen a imagen)
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("referencia.png"),
prompt: "Convierte la escena en invierno, con nieve",
size: "1024x1024",
});
console.log(image.data[0].url);
/images/edits acepta hasta cuatro imágenes de referencia (PNG, JPEG o WebP, de menos de 25 MB cada una) y no admite mask: mandar una devuelve 400.
Las imágenes necesitan membresía de inferencia, 403 si no la tienes, y van por su propio presupuesto: 20 peticiones por minuto y 100 al mes, que no toca tu cuota de tokens.
model: qwen-image-2.1
generación de texto a imagen
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": "Una pizarra con la palabra faro escrita en ella, rotulación limpia",
"size": "1024x1024",
"n": 1
}'
# → {"created":...,"data":[{"url":"https://..."}]}
Cada lado de size tiene que ser divisible entre 16 y estar entre 512 y 1280, con una relación de aspecto entre 1:3 y 3:1. n llega hasta 4. Sin imágenes de referencia: este modelo es solo texto a imagen. seed es un entero en 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="Una pizarra con la palabra faro escrita en ella, rotulación limpia",
size="1024x1024",
extra_body={"seed": 42}
)
print(image.data[0].url)
El enlace es temporal, alrededor de 60 minutos. Pide response_format="b64_json" y los bytes llegan en data[0].b64_json, en base64, en lugar de detrás de un enlace. seed y guidance son extensiones de NaN, así que el SDK de OpenAI las manda por extra_body.
node.js (imagen a imagen)
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("referencia.png"),
prompt: "Convierte la escena en invierno, con nieve",
size: "1024x1024",
});
console.log(image.data[0].url);
/images/edits acepta hasta cuatro imágenes de referencia (PNG, JPEG o WebP, de menos de 25 MB cada una) y no admite mask: mandar una devuelve 400.
Las imágenes necesitan membresía de inferencia, 403 si no la tienes, y van por su propio presupuesto: 20 peticiones por minuto y 100 al mes, que no toca tu cuota de tokens.
Conectar tu editor o tu agente
Las configuraciones de Cursor, Claude Code, Codex, Cline, OpenCode, Zed y el resto están en Configurar tu agente, con una página por herramienta.