Docs

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: qwen3.6

generación de texto y chat

curl

curl https://api.nan.builders/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-your-key-here" \
  -d '{
    "model": "qwen3.6",
    "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="qwen3.6",
  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: "qwen3.6",
  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

opencode.json (config)

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "nan": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "NaN",
      "options": {
        "baseURL": "https://api.nan.builders/v1",
        "apiKey": "sk-your-key-here"
      },
      "models": {
        "qwen3.6": {
          "name": "Qwen 3.6",
          "contextWindow": 262144,
          "modalities": {
            "input": ["text", "image"],
            "output": ["text"]
          }
        },
        "gemma4": {
          "name": "Gemma 4",
          "contextWindow": 262144,
          "modalities": {
            "input": ["text", "image"],
            "output": ["text"]
          }
        },
        "deepseek-v4-flash": {
          "name": "DeepSeek V4 Flash",
          "contextWindow": 500000,
          "modalities": {
            "input": ["text"],
            "output": ["text"]
          }
        },
        "mimo-v2.5": {
          "name": "Xiaomi MiMo V2.5",
          "contextWindow": 500000,
          "modalities": {
            "input": ["text", "image", "audio"],
            "output": ["text"]
          }
        }
      }
    }
  },
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 50000
  }
}

Esta es la configuración para conectar IDEs (Cursor, OpenCode) con los 4 modelos LLM disponibles: qwen3.6, gemma4, deepseek-v4-flash y mimo-v2.5.

.pi/agent/models.json (config)

{
  "providers": {
    "nan": {
      "baseUrl": "https://api.nan.builders/v1",
      "api": "openai-completions",
      "apiKey": "<api-key>",
      "compat": {
        "supportsDeveloperRole": true
      },
      "models": [
        {
          "id": "qwen3.6",
          "name": "Qwen 3.6",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 262144,
          "maxTokens": 16384
        },
        {
          "id": "gemma4",
          "name": "Gemma 4",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 262144,
          "maxTokens": 16384
        }
      ]
    }
  }
}

Configuración para ~/.pi/agent/models.json

.pi/agent/settings.json (config)

{
  "defaultProvider": "nan",
  "defaultModel": "qwen3.6"
}

Configuración para ~/.pi/agent/settings.json. Sin defaultProvider ni defaultModel, Pi usa su proveedor por defecto y devuelve un error de autenticación (401).

openclaw.json (config)

{
  "models": {
    "providers": {
      "nan": {
        "baseUrl": "https://api.nan.builders/v1",
        "apiKey": "sk-...",
        "api": "openai-completions",
        "models": [
          {
            "id": "qwen3.6",
            "name": "Qwen 3.6",
            "reasoning": true,
            "input": ["text", "image"],
            "contextWindow": 262144,
            "maxTokens": 65536
          }
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "model": { "primary": "nan/qwen3.6" },
      "models": {
        "nan/qwen3.6": {
          "params": {
            "maxTokens": 16000
          }
        }
      }
    }
  }
}

Configuración para ~/.openclaw/openclaw.json

maxTokens: 65536 es el máximo que admite el modelo. params.maxTokens: 16000 es lo que se manda en cada petición. 16K es un buen equilibrio para la mayoría de tareas. Si necesitas respuestas más largas, súbelo, pero ten en cuenta que el razonamiento también consume de ese presupuesto.

settings.json (Zed)

{
  "language_models": {
    "openai": {
      "api_url": "https://api.nan.builders/v1",
      "available_models": [
        {
          "name": "qwen3.6",
          "display_name": "NaN",
          "max_tokens": 262144
        }
      ]
    }
  },
  "edit_predictions": {
    "open_ai_compatible_api": {
      "api_url": "https://api.nan.builders/v1",
      "model": "qwen3.6"
    }
  }
}

Configuración para ~/.config/zed/settings.json. Incluye las predicciones en línea.

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";
import FormData from "form-data";

const client = new OpenAI({
  apiKey: "sk-your-key-here",
  baseURL: "https://api.nan.builders/v1",
});

// Transcribe audio
const file = fs.createReadStream("recording.mp3");
const form = FormData();
form.append("file", file);

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.5

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.5",
    "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.5",
    "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.5",
  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)

búsqueda web autenticada para agentes: POST /v1/search

curl

curl https://api.nan.builders/v1/search \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-your-key-here" \
  -d '{
    "query": "latest go release",
    "count": 5,
    "freshness": "pw"
  }'
# → {"results":[{"title":...,"url":...,"snippet":...,"source":...}],"cached":false}

python

import os
from openai import OpenAI

client = OpenAI(
  api_key=os.environ["NAN_API_KEY"],
  base_url="https://api.nan.builders/v1"
)

# /search is not part of the standard OpenAI client, but we can invoke it with client.post().
response = client.post(
  path="/search",
  cast_to=object,
  body={
    "query": "latest go release",
    "count": 5,
    "freshness": "pw",
  },
)

for r in response["results"]:
    print(r["title"], "-", r["url"])

También funciona con requests a pelo o con cualquier cliente HTTP: manda el cuerpo JSON con tu key en el Bearer.

Integración con IDEs

  • Cursor: Settings → OpenAI API → Base URL: https://api.nan.builders/v1, API Key: tu key
  • Zed: Settings → settings.json → mira la configuración completa de arriba
  • Cline / Continue / Aider: define las variables de entorno:
export OPENAI_BASE_URL="https://api.nan.builders/v1"
export OPENAI_API_KEY="sk-your-key-here"
nan.builders © 2026
Copied to clipboard