| # NaN Builders LLMs.txt | |
| Documento autocontenido para configurar clientes, IDEs, agentes y SDKs contra la API de NaN Builders sin tener que abrir la documentacion durante la configuracion. | |
| Fuentes consultadas el 2026-07-11: | |
| - https://nan.builders/docs/getting-started | |
| - https://nan.builders/docs/api | |
| - https://nan.builders/docs/models | |
| - https://nan.builders/docs/examples | |
| ## Identidad del servicio | |
| NaN expone modelos de texto, vision, audio, embeddings, reranking e imagen mediante una API compatible con OpenAI, servida via LiteLLM para la parte LLM. Cualquier herramienta que acepte un base URL y una API key de tipo OpenAI-compatible deberia poder funcionar: Cursor, Cline, Continue, Aider, OpenCode/OpenCode-like, Open WebUI, Zed, SDK oficial de OpenAI, AI SDK, clientes HTTP, etc. | |
| Valores base: | |
| txt | | | Base URL: https://api.nan.builders/v1 | | | Auth: Authorization: Bearer sk-tu-key-aqui | | | Default chat model: qwen3.6 | | | | |
| Para el servicio enterprise de Helmcode, usa el host api.helmcode.com; los endpoints /v1/... son equivalentes. | |
| La API key se genera desde la plataforma de NaN, en ajustes de usuario, seccion "API Keys". La key es personal e intransferible. El soporte indicado en la documentacion es solo para temas tecnicos. | |
| ## Reglas de configuracion rapida | |
| Usa qwen3.6 como modelo general por defecto: chat, streaming, vision, tool calling y reasoning activado por defecto. | |
| Usa deepseek-v4-flash si necesitas contexto muy largo, reasoning configurable con reasoning_effort y buen rendimiento general en texto. | |
| Usa mimo-v2.5 si necesitas entrada omnimodal real: texto, imagen y audio. Su reasoning esta siempre activo, asi que reserva suficiente presupuesto de salida. | |
| Usa gemma4 para chat multimodal con vision cuando quieras reasoning opt-in. | |
| Usa qwen3-embedding para embeddings de 4096 dimensiones. | |
| Usa rerank despues de recuperar documentos por embeddings, especialmente en RAG multilingue o busqueda de codigo. | |
| Usa kokoro para text-to-speech. | |
| Usa whisper para speech-to-text. | |
| Usa flux-2-klein para imagenes text-to-image e image-to-image; requiere tier inference. | |
| ## Modelos disponibles | |
| ### deepseek-v4-flash | |
| Modelo MoE de texto/chat. Especificacion documentada: | |
| - Parametros: 284B totales, 21B activos. | |
| - Cuantizacion: FP8. | |
| - Contexto: 1M tokens. | |
| - Cuota mensual: 500M tokens por miembro. | |
| - Capacidades: chat, streaming SSE, tool calling, reasoning. | |
| - Control de reasoning: reasoning_effort con valores low, medium, high; default medium. | |
| - Enviar reasoning_effort como campo top-level del body, no dentro de extra_body. | |
| ### mimo-v2.5 | |
| Modelo MoE omnimodal. Especificacion documentada: | |
| - Parametros: 310B totales, 15B activos. | |
| - Cuantizacion: FP8. | |
| - Contexto: 1M tokens. | |
| - Input: texto, imagen, audio. | |
| - Output: texto. | |
| - Cuota mensual: 500M tokens por miembro. | |
| - Licencia: MIT. | |
| - Capacidades: chat, streaming SSE, tool calling/function calling, reasoning, vision, audio input. | |
| - Reasoning: siempre activo; actualmente no se puede controlar por API con reasoning_effort ni con enable_thinking. | |
| - Recomendacion documentada: max_tokens >= 300 como minimo para dejar margen al reasoning. | |
| ### gemma4 | |
| Modelo MoE de texto/chat multimodal con vision. | |
| - Parametros: 26B totales, 4B activos. | |
| - Cuantizacion: FP8. | |
| - Contexto: 256K tokens. | |
| - Sampling por defecto: temperature=0.6, top_p=0.95. | |
| - Capacidades: chat, streaming SSE, vision/image input, reasoning mode, tool calling documentado en formato XML. | |
| - Reasoning: desactivado por defecto; se activa con chat_template_kwargs.enable_thinking: true. | |
| ### qwen3.6 | |
| Modelo principal de NaN para uso general. | |
| - Tipo: MoE, 35B total. | |
| - Activo por token: 3B. | |
| - Cuantizacion: FP8. | |
| - Contexto: 256K tokens. | |
| - Speculative decoding: MTP, aproximadamente 2x throughput. | |
| - Sampling por defecto: temperature=0.6, top_p=0.95. | |
| - Capacidades: chat, streaming SSE, vision/image input, tool calling, reasoning. | |
| - Reasoning: activo por defecto; se desactiva con chat_template_kwargs.enable_thinking: false. | |
| - La API documenta function calling OpenAI como validado especialmente con qwen3.6; si necesitas tool calling estable, usa este modelo primero y prueba el resto antes de depender de tools en produccion. | |
| ### qwen3-embedding | |
| Modelo de embeddings vectoriales. | |
| - Parametros: 8B. | |
| - Dimension: 4096. | |
| - Precision: Float32 en CPU. | |
| - RPM documentado del modelo: 60. | |
| - Batch size: 32. | |
| - Soporta mas de 100 idiomas, español incluido, y codigo. | |
| - Casos de uso: busqueda semantica, similitud cross-lingual, clasificacion, RAG. | |
| - Score documentado: MMTEB 70.58; similitud ES-EN documentada 0.915. | |
| ### rerank | |
| Modelo Qwen3-Reranker-8B para reranking semantico. | |
| - Parametros: 8B. | |
| - Precision: BF16. | |
| - Endpoints: /v1/rerank y /v2/rerank. | |
| - Idiomas: 100+. | |
| - Casos de uso: RAG embedding -> rerank -> LLM, busqueda cross-lingual, recuperacion de codigo, scoring query-documento. | |
| - Respuesta: documentos ordenados por relevance_score descendente, manteniendo index original. | |
| ### kokoro | |
| Modelo text-to-speech. | |
| - Version: v1.0. | |
| - Parametros: 82M. | |
| - Latencia: sub-segundo en CPU segun docs. | |
| - Voces: 67 voice packs. | |
| - RPM documentado: 15. | |
| - Voces destacadas: af_heart English female, ef_dora Spanish female, em_alex Spanish male. | |
| ### whisper | |
| Modelo speech-to-text. | |
| - Variante: large-v3. | |
| - Runtime documentado: CPU con CTranslate2 e INT8. | |
| - Tamaño aproximado: 3 GB INT8. | |
| - Velocidad: aproximadamente 1x realtime. | |
| - WER ES documentado: ~3.2%. | |
| - RPM documentado: 10. | |
| - Idiomas: 99+. | |
| - Capacidades: transcripcion, deteccion automatica de idioma, API OpenAI-compatible. | |
| - Limite por request: 25 MB. | |
| - Riesgo de timeout: audios de mas de 2 minutos pueden devolver 524. Divide en segmentos de 2 minutos o menos. | |
| - Formatos recomendados: OGG/Opus y MP3; evitan archivos enormes frente a WAV sin comprimir. | |
| ### flux-2-klein | |
| Modelo de imagen. | |
| - Tipo: diffusion/FLUX. | |
| - Endpoints: /v1/images/generations y /v1/images/edits. | |
| - Modalidades: text-to-image e image-to-image. | |
| - Resolucion: de 256 a 1536 px por lado, multiples de 16, aspect ratio entre 1:3 y 3:1. | |
| - Imagenes por request: n entre 1 y 4. | |
| - Output: URL temporal R2 de unos 60 minutos o b64_json. | |
| - Extensiones NaN: seed para reproducibilidad y guidance como guidance scale. | |
| - Cuota mensual: 100 requests por miembro. | |
| - Requiere tier inference. | |
| ## Endpoints | |
| ### Autenticacion | |
| Todas las peticiones deben incluir: | |
| http | | | Authorization: Bearer sk-tu-key-aqui | | | | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/models \ | | | -H "Authorization: Bearer sk-tu-key-aqui" | | | | |
| ### GET /v1/models | |
| Devuelve los modelos disponibles para la API key. | |
| Modelos publicados en la documentacion: | |
| txt | | | deepseek-v4-flash | | | mimo-v2.5 | | | qwen3.6 | | | gemma4 | | | qwen3-embedding | | | rerank | | | kokoro | | | whisper | | | flux-2-klein | | | | |
| Request: sin body, solo autenticacion. | |
| Respuesta compatible con OpenAI: | |
| json | | | { | | | "object": "list", | | | "data": [ | | | { | | | "id": "qwen3.6", | | | "object": "model", | | | "created": 1677610602, | | | "owned_by": "openai" | | | } | | | ] | | | } | | | | |
| ### POST /v1/chat/completions | |
| Endpoint principal para chat. Compatible con OpenAI Chat Completions. | |
| Modelos compatibles documentados: | |
| txt | | | deepseek-v4-flash | | | mimo-v2.5 | | | qwen3.6 | | | gemma4 | | | | |
| Parametros principales: | |
| - model requerido: uno de los modelos anteriores. | |
| - messages requerido: array de mensajes {role, content}. | |
| - content puede ser string o array multimodal, por ejemplo partes text, image_url y, en mimo-v2.5, input_audio. | |
| - max_tokens opcional: limite de tokens generados. En modelos con reasoning, conviene dejar margen suficiente para evitar truncados. | |
| - stream opcional, default false; si es true, devuelve SSE. | |
| - tools opcional: function calling estilo OpenAI {type:"function", function:{name, description, parameters}}. | |
| - tool_choice opcional: control estandar OpenAI para seleccion de tool. | |
| - temperature opcional, default 0.6. | |
| - top_p opcional, default 0.95. | |
| - response_format opcional para structured outputs. | |
| - chat_template_kwargs opcional para enable_thinking en qwen/gemma. | |
| - reasoning_effort opcional para deepseek. | |
| Ejemplo minimo: | |
| bash | | | curl https://api.nan.builders/v1/chat/completions \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -H "Content-Type: application/json" \ | | | -d '{ | | | "model": "qwen3.6", | | | "messages": [{"role": "user", "content": "Hola"}], | | | "max_tokens": 200 | | | }' | | | | |
| Respuesta sin streaming: | |
| json | | | { | | | "id": "chatcmpl-...", | | | "created": 1778258163, | | | "model": "qwen3.6", | | | "object": "chat.completion", | | | "choices": [ | | | { | | | "finish_reason": "stop", | | | "index": 0, | | | "message": { | | | "role": "assistant", | | | "content": "...", | | | "reasoning_content": "..." | | | } | | | } | | | ], | | | "usage": { | | | "completion_tokens": 20, | | | "prompt_tokens": 17, | | | "total_tokens": 37 | | | } | | | } | | | | |
| Los clientes deben tolerar que reasoning_content exista o no exista segun modelo/configuracion. | |
| Streaming: | |
| - Enviar stream: true. | |
| - La respuesta llega como Server-Sent Events. | |
| - Cada chunk usa data: {...}\n\n. | |
| - El delta de texto esta en choices[0].delta.content. | |
| - El final llega como data: [DONE]. | |
| Tool calling: | |
| - qwen3.6 tiene soporte documentado para function calling estandar OpenAI. | |
| - Cuando el modelo llama una tool, mira choices[0].message.tool_calls. | |
| - La estructura es {id, type:"function", function:{name, arguments}}. | |
| - finish_reason sera tool_calls. | |
| Vision: | |
| - mimo-v2.5, qwen3.6 y gemma4 aceptan imagenes como input. | |
| - Usa content como array de partes. | |
| Ejemplo de vision: | |
| json | | | { | | | "model": "qwen3.6", | | | "messages": [ | | | { | | | "role": "user", | | | "content": [ | | | {"type": "text", "text": "Que hay en esta imagen?"}, | | | {"type": "image_url", "image_url": {"url": "https://example.com/foto.jpg"}} | | | ] | | | } | | | ] | | | } | | | | |
| Structured outputs: | |
| - response_format: {"type": "json_object"} fuerza JSON valido sin schema. | |
| - response_format: {"type": "json_schema", "json_schema": {...}} fuerza un JSON Schema. | |
| - Con strict: true, el modelo no debe emitir campos fuera del schema. | |
| - Funciona en qwen3.6 y gemma4. | |
| Ejemplo de JSON Schema: | |
| json | | | { | | | "model": "qwen3.6", | | | "messages": [{"role": "user", "content": "Alice, 30 anos."}], | | | "response_format": { | | | "type": "json_schema", | | | "json_schema": { | | | "name": "user", | | | "strict": true, | | | "schema": { | | | "type": "object", | | | "properties": { | | | "name": {"type": "string"}, | | | "age": {"type": "integer"} | | | }, | | | "required": ["name", "age"], | | | "additionalProperties": false | | | } | | | } | | | } | | | } | | | | |
| Reasoning por modelo: | |
| - qwen3.6: usa chat_template_kwargs.enable_thinking; activo por defecto. | |
| - gemma4: usa chat_template_kwargs.enable_thinking; desactivado por defecto. | |
| - deepseek-v4-flash: usa reasoning_effort top-level con low, medium, high; default medium. | |
| - mimo-v2.5: siempre activo y no configurable por API actualmente. | |
| Activar thinking en gemma4 o desactivarlo en qwen3.6: | |
| json | | | { | | | "model": "gemma4", | | | "messages": [{"role": "user", "content": "Que es 2+2?"}], | | | "chat_template_kwargs": {"enable_thinking": true} | | | } | | | | |
| En SDKs OpenAI, los campos no estandar suelen ir en extra_body: | |
| python | | | from openai import OpenAI | | | client = OpenAI( | | | api_key="sk-tu-key-aqui", | | | base_url="https://api.nan.builders/v1", | | | ) | | | response = client.chat.completions.create( | | | model="gemma4", | | | messages=[{"role": "user", "content": "Que es 2+2?"}], | | | extra_body={"chat_template_kwargs": {"enable_thinking": True}}, | | | ) | | | | |
| Ejemplo para DeepSeek reasoning: | |
| json | | | { | | | "model": "deepseek-v4-flash", | | | "messages": [{"role": "user", "content": "Resuelve paso a paso: 3x + 7 = 22"}], | | | "reasoning_effort": "high" | | | } | | | | |
| ### POST /v1/completions | |
| Endpoint legacy de text completion. Para conversaciones usa /v1/chat/completions. | |
| Modelo compatible documentado: qwen3.6. | |
| Parametros: | |
| - model requerido: qwen3.6. | |
| - prompt requerido. | |
| - max_tokens opcional. | |
| - temperature opcional, default 0.6. | |
| - top_p opcional, default 0.95. | |
| - stream opcional, default false. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/completions \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -H "Content-Type: application/json" \ | | | -d '{ | | | "model": "qwen3.6", | | | "prompt": "The capital of France is", | | | "max_tokens": 10 | | | }' | | | | |
| Respuesta: | |
| json | | | { | | | "id": "cmpl-...", | | | "object": "text_completion", | | | "created": 1778258166, | | | "model": "qwen3.6", | | | "choices": [ | | | { | | | "text": "...", | | | "index": 0, | | | "finish_reason": "stop", | | | "logprobs": null | | | } | | | ], | | | "usage": { | | | "completion_tokens": 10, | | | "prompt_tokens": 5, | | | "total_tokens": 15 | | | } | | | } | | | | |
| ### POST /v1/embeddings | |
| Genera embeddings vectoriales. | |
| Modelo compatible: qwen3-embedding. | |
| Parametros: | |
| - model requerido: qwen3-embedding. | |
| - input requerido: string o array de strings. | |
| - encoding_format opcional: "float" por defecto o "base64". | |
| Respuesta: | |
| - object: "list". | |
| - model: "qwen3-embedding". | |
| - data[] con object: "embedding", index y embedding. | |
| - Vectores de 4096 dimensiones. | |
| - usage con tokens. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/embeddings \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -H "Content-Type: application/json" \ | | | -d '{ | | | "model": "qwen3-embedding", | | | "input": ["Hola mundo", "Hello world"], | | | "encoding_format": "float" | | | }' | | | | |
| ### POST /v1/rerank | |
| Reordena documentos por relevancia respecto a una query. | |
| Modelo compatible: rerank. | |
| Alias: /v2/rerank. | |
| Parametros: | |
| - model requerido: rerank. | |
| - query requerido. | |
| - documents requerido: array de strings. | |
| - top_n opcional: limita cuantos resultados devolver. | |
| Respuesta: | |
| - id. | |
| - results[] con index, relevance_score entre 0 y 1 y document.text. | |
| - index es la posicion original del documento de entrada. | |
| - meta.billed_units.total_tokens y meta.tokens.input_tokens. | |
| Ejemplo: | |
| bash | | | 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." | | | ] | | | }' | | | | |
| En el SDK OpenAI puedes usar client.post(path="/rerank", cast_to=object, body={...}), porque rerank no forma parte del cliente OpenAI estandar. | |
| ### POST /v1/audio/speech | |
| Text-to-speech. | |
| Modelo compatible: kokoro. | |
| Parametros: | |
| - model requerido: kokoro. | |
| - input requerido: texto a sintetizar. | |
| - voice requerido: por ejemplo af_heart, ef_dora, em_alex. | |
| - response_format opcional: mp3 default, wav, flac, aac, pcm, opus. | |
| - speed opcional, default 1.0. | |
| Respuesta: archivo binario de audio, sin envoltorio JSON. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/audio/speech \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -H "Content-Type: application/json" \ | | | -d '{ | | | "model": "kokoro", | | | "input": "Bienvenido a NaN.", | | | "voice": "ef_dora", | | | "response_format": "mp3" | | | }' \ | | | -o speech.mp3 | | | | |
| ### POST /v1/audio/transcriptions | |
| Speech-to-text. La peticion es multipart/form-data. | |
| Modelo compatible: whisper. | |
| Parametros: | |
| - file requerido: archivo de audio. | |
| - model requerido: whisper. | |
| - language opcional: codigo ISO-639-1 como es o en; si falta, se detecta automaticamente. | |
| - response_format opcional: json default o verbose_json. Otros valores pueden funcionar pero vuelven envueltos en JSON; recomienda usar solo estos dos. | |
| - timestamp_granularities[] opcional: solo con verbose_json; word para palabras o segment default. | |
| - temperature opcional. | |
| Respuesta verbose_json: | |
| - text. | |
| - language. | |
| - task. | |
| - duration. | |
| - segments[] con timestamps, tokens y metricas. | |
| - words, si se pidio granularidad por palabra, con {word, start, end, probability}. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/audio/transcriptions \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -F "model=whisper" \ | | | -F "file=@grabacion.mp3" \ | | | -F "language=es" \ | | | -F "response_format=verbose_json" | | | | |
| Limitaciones: | |
| - Maximo 25 MB por archivo. | |
| - Audios mayores de 2 minutos pueden devolver timeout 524. | |
| - Divide audios largos en trozos de 2 minutos o menos. | |
| - Usa MP3 u OGG/Opus para mejor compresion. | |
| La pagina de ejemplos tambien muestra /v1/audio/translations con whisper para traducir audio a ingles, usando multipart con model=whisper y file=@grabacion.mp3. | |
| ### POST /v1/responses | |
| Endpoint estilo OpenAI Responses. | |
| Modelos compatibles: qwen3.6 y gemma4. | |
| Parametros: | |
| - model requerido: qwen3.6 o gemma4. | |
| - input requerido: texto o array de mensajes en formato Responses. | |
| - max_output_tokens opcional; default documentado en qwen3.6: 65536. | |
| - temperature opcional, default 0.6. | |
| - top_p opcional, default 0.95. | |
| - instructions opcional: instrucciones de sistema. | |
| Respuesta: | |
| - output[] puede incluir bloques reasoning en qwen3.6. | |
| - Tambien incluye bloques message con content[] de tipo output_text. | |
| - usage reporta input_tokens, output_tokens y total_tokens. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/responses \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -H "Content-Type: application/json" \ | | | -d '{ | | | "model": "qwen3.6", | | | "input": "Hola, como estas?" | | | }' | | | | |
| Nota de streaming: actualmente este endpoint entrega un unico evento response.completed al final, no chunks incrementales. Para streaming token a token usa /v1/chat/completions con stream: true. | |
| ### POST /v1/images/generations | |
| Text-to-image compatible con Images API de OpenAI. | |
| Modelo compatible: flux-2-klein. | |
| Body: JSON. | |
| Parametros: | |
| - prompt requerido. | |
| - model opcional, default flux-2-klein; modelo desconocido devuelve 404 model_not_found. | |
| - n opcional, entre 1 y 4, default 1; mayor que 4 devuelve 400. | |
| - size opcional: "ANCHOxALTO", ambos lados divisibles por 16, entre 256 y 1536, aspect ratio entre 1:3 y 3:1. "auto" u omitido significa 1024x1024. | |
| - response_format opcional: "url" default o "b64_json". Las URL temporales de R2 duran unos 60 minutos. | |
| Parametros aceptados pero ignorados por compatibilidad con SDKs OpenAI: | |
| - quality | |
| - style | |
| - background | |
| - moderation | |
| - output_format | |
| - output_compression | |
| - user | |
| No soporta stream: true; devuelve 400. | |
| Extensiones NaN: | |
| - seed: seed base para reproducibilidad. Si n > 1, cada variante usa offset sobre esa seed. | |
| - guidance: guidance scale de FLUX. | |
| - En SDK OpenAI, pasarlas en extra_body. | |
| Respuesta: | |
| json | | | { | | | "created": 1778258200, | | | "data": [ | | | {"url": "https://...r2.../image.png"} | | | ] | | | } | | | | |
| Con response_format: "b64_json", cada elemento usa {"b64_json": "..."}. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/images/generations \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -H "Content-Type: application/json" \ | | | -d '{ | | | "model": "flux-2-klein", | | | "prompt": "Un faro al atardecer sobre acantilados, estilo cinematico", | | | "size": "1024x1024" | | | }' | | | | |
| Python con seed y guidance: | |
| python | | | from openai import OpenAI | | | client = OpenAI( | | | api_key="sk-tu-key-aqui", | | | base_url="https://api.nan.builders/v1", | | | ) | | | response = client.images.generate( | | | model="flux-2-klein", | | | prompt="Un faro al atardecer sobre acantilados, estilo cinematico", | | | size="1024x1024", | | | n=1, | | | extra_body={"seed": 42, "guidance": 3.5}, | | | ) | | | print(response.data[0].url) | | | | |
| Limites de imagen: | |
| - No comparten los limites de chat/LiteLLM. | |
| - Rate limit de imagen: 1 request por segundo sostenido, burst hasta 3. | |
| - Al exceder rate limit: 429 rate_limit_exceeded. | |
| - Cuota mensual de imagen: 100 requests por usuario/mes. | |
| - 1 request cuenta igual aunque n sea mayor que 1. | |
| - Cuota de imagen independiente de la cuota de tokens de chat. | |
| - Requiere tier inference; tier community devuelve 403 tier_restricted. | |
| ### POST /v1/images/edits | |
| Image-to-image compatible con Images API de OpenAI. | |
| Modelo compatible: flux-2-klein. | |
| Peticion: multipart/form-data. | |
| Parametros: | |
| - image o image[] requerido: hasta 4 imagenes de referencia; las extras se descartan. | |
| - Formatos de referencia: PNG, JPEG o WebP. | |
| - Cada imagen debe pesar menos de 25 MB. | |
| - prompt requerido. | |
| - model, n, size, response_format: igual que en /v1/images/generations. | |
| - seed y guidance: aceptados como campos del form. | |
| No soporta mask; devuelve 400 porque Flux Klein no hace inpainting. | |
| Respuesta: igual que generaciones, {"created": ..., "data": [{"url": "..."}]} o b64_json. | |
| Ejemplo: | |
| bash | | | curl https://api.nan.builders/v1/images/edits \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -F "model=flux-2-klein" \ | | | -F "image[]=@ref.png" \ | | | -F "prompt=Convierte la escena en invierno con nieve" \ | | | -F "size=1024x1024" | | | | |
| ## Errores | |
| Formato de error compatible con OpenAI: | |
| json | | | { | | | "error": { | | | "message": "...", | | | "type": null, | | | "param": null, | | | "code": "..." | | | } | | | } | | | | |
| Codigos comunes: | |
| - 400: parametro invalido. En imagenes puede indicar prompt, n, size, stream, mask o image; filtro de seguridad usa content_policy_violation. | |
| - 401: Authorization ausente o invalido; invalid_api_key. | |
| - 403: tier sin acceso; tier_restricted, especialmente imagenes sin tier inference. | |
| - 404: modelo no existe; model_not_found. | |
| - 429: rate limit o concurrencia excedida; rpm_limit, max_parallel_requests, rate_limit_exceeded, quota_exceeded o insufficient_quota. | |
| - 500: error interno o upstream del modelo. | |
| - 524: timeout, tipico en audios grandes con /v1/audio/transcriptions. | |
| ## Rate limits y cuotas | |
| Limites generales por API key: | |
| - Requests por minuto: 60 rpm. | |
| - Paralelo maximo: 5 concurrentes. | |
| Tokens por minuto por modelo: | |
| - deepseek-v4-flash: 1.5M tpm. | |
| - mimo-v2.5: 1.5M tpm. | |
| - qwen3.6: 1.5M tpm. | |
| - gemma4: 1.5M tpm. | |
| Requests por minuto por modelo: | |
| - rerank: 1000 rpm. | |
| Cuotas: | |
| - deepseek-v4-flash: 500M tokens/mes por miembro. | |
| - mimo-v2.5: 500M tokens/mes por miembro. | |
| - Imagenes flux-2-klein: 100 requests/mes por usuario. | |
| ## SDKs y snippets de uso | |
| ### cURL chat | |
| bash | | | curl https://api.nan.builders/v1/chat/completions \ | | | -H "Content-Type: application/json" \ | | | -H "Authorization: Bearer sk-tu-key-aqui" \ | | | -d '{ | | | "model": "qwen3.6", | | | "messages": [{"role": "user", "content": "Hola, como estas?"}], | | | "max_tokens": 500 | | | }' | | | | |
| ### Python OpenAI SDK | |
| Instalar: | |
| bash | | | pip install openai | | | | |
| Chat streaming: | |
| python | | | from openai import OpenAI | | | client = OpenAI( | | | api_key="sk-tu-key-aqui", | | | base_url="https://api.nan.builders/v1", | | | ) | | | stream = client.chat.completions.create( | | | model="qwen3.6", | | | messages=[{"role": "user", "content": "Escribe un hola mundo en Rust"}], | | | max_tokens=500, | | | stream=True, | | | ) | | | for chunk in stream: | | | content = chunk.choices[0].delta.content | | | if content: | | | print(content, end="", flush=True) | | | | |
| Embeddings: | |
| python | | | response = client.embeddings.create( | | | model="qwen3-embedding", | | | input=["Kubernetes pod scheduling", "Programacion de pods Kubernetes"], | | | encoding_format="float", | | | ) | | | vectors = [item.embedding for item in response.data] | | | assert len(vectors[0]) == 4096 | | | | |
| Rerank: | |
| python | | | 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.", | | | "Berlin is the capital of Germany.", | | | "Madrid is the capital of Spain.", | | | ], | | | }, | | | ) | | | | |
| Text-to-speech: | |
| python | | | response = client.audio.speech.create( | | | model="kokoro", | | | voice="ef_dora", | | | input="Hola, bienvenido a NaN builders.", | | | speed=1.0, | | | response_format="mp3", | | | ) | | | response.stream_to_file("output.mp3") | | | | |
| Speech-to-text: | |
| python | | | with open("grabacion.mp3", "rb") as f: | | | result = client.audio.transcriptions.create( | | | model="whisper", | | | file=f, | | | language="es", | | | response_format="verbose_json", | | | ) | | | print(result.text) | | | | |
| ### Node.js OpenAI SDK | |
| Instalar: | |
| bash | | | npm install openai | | | | |
| Chat streaming: | |
| js | | | import OpenAI from "openai"; | | | const client = new OpenAI({ | | | apiKey: "sk-tu-key-aqui", | | | baseURL: "https://api.nan.builders/v1", | | | }); | | | const stream = await client.chat.completions.create({ | | | model: "qwen3.6", | | | messages: [{ role: "user", content: "Escribe un hola mundo en 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); | | | } | | | | |
| Embeddings: | |
| js | | | const response = await client.embeddings.create({ | | | model: "qwen3-embedding", | | | input: ["Hello world", "Hola mundo"], | | | encoding_format: "float", | | | }); | | | const vectors = response.data.map((item) => item.embedding); | | | console.log(vectors[0].length); // 4096 | | | | |
| Text-to-speech: | |
| js | | | import fs from "fs"; | | | const response = await client.audio.speech.create({ | | | model: "kokoro", | | | voice: "ef_dora", | | | input: "Hola, bienvenido a NaN builders.", | | | speed: 1.0, | | | response_format: "mp3", | | | }); | | | const buffer = Buffer.from(await response.arrayBuffer()); | | | fs.writeFileSync("output.mp3", buffer); | | | | |
| ## Configuracion de herramientas | |
| ### Variables de entorno genericas | |
| Muchos clientes OpenAI-compatible leen estas variables: | |
| bash | | | export OPENAI_BASE_URL="https://api.nan.builders/v1" | | | export OPENAI_API_KEY="sk-tu-key-aqui" | | | | |
| Si el cliente usa BASE_URL, OPENAI_API_BASE, OPENAI_API_URL o api_url, pon siempre https://api.nan.builders/v1. | |
| ### OpenAI-compatible provider generico | |
| js | | | provider: { | | | openai: { | | | npm: "@ai-sdk/openai", | | | name: "NaN", | | | apiKey: "sk-tu-key-aqui", | | | baseURL: "https://api.nan.builders/v1", | | | model: "qwen3.6" | | | } | | | } | | | | |
| ### OpenCode / opencode.json | |
| Usa @ai-sdk/openai-compatible, base URL de NaN y define modelos. En algunas herramientas conviene usar contextWindow: 500000 para modelos de 1M si la herramienta no tolera ventanas tan grandes; la capacidad documentada de deepseek-v4-flash y mimo-v2.5 es 1M. | |
| json | | | { | | | "$schema": "https://opencode.ai/config.json", | | | "provider": { | | | "nan": { | | | "npm": "@ai-sdk/openai-compatible", | | | "name": "NaN", | | | "options": { | | | "baseURL": "https://api.nan.builders/v1", | | | "apiKey": "sk-tu-key-aqui" | | | }, | | | "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 | | | } | | | } | | | | |
| ### ~/.pi/agent/models.json | |
| json | | | { | | | "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 | | | } | | | ] | | | } | | | } | | | } | | | | |
| ### ~/.openclaw/openclaw.json | |
| json | | | { | | | "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 | | | } | | | } | | | } | | | } | | | } | | | } | | | | |
| Explicacion practica: | |
| - models.providers.nan.models[].maxTokens indica la capacidad maxima configurada. | |
| - agents.defaults.models["nan/..."].params.maxTokens indica lo enviado por request. | |
| - Para qwen3.6, 16K suele ser buen balance. | |
| ### Zed settings.json | |
| Ruta habitual: ~/.config/zed/settings.json. | |
| json | | | { | | | "language_models": { | | | "openai": { | | | "api_url": "https://api.nan.builders/v1", | | | "available_models": [ | | | { | | | "name": "qwen3.6", | | | "display_name": "NaN Qwen 3.6", | | | "max_tokens": 262144 | | | } | | | ] | | | } | | | }, | | | "edit_predictions": { | | | "open_ai_compatible_api": { | | | "api_url": "https://api.nan.builders/v1", | | | "model": "qwen3.6" | | | } | | | } | | | } | | | | |
| ### Cursor | |
| Configura proveedor OpenAI-compatible: | |
| txt | | | Base URL: https://api.nan.builders/v1 | | | API Key: sk-tu-key-aqui | | | Model: qwen3.6 | | | | |
| ### Cline, Continue, Aider y clientes similares | |
| Usa las variables de entorno o la UI de proveedor OpenAI-compatible: | |
| bash | | | export OPENAI_BASE_URL="https://api.nan.builders/v1" | | | export OPENAI_API_KEY="sk-tu-key-aqui" | | | | |
| Modelo recomendado por defecto: qwen3.6. | |
| Para vision: usa qwen3.6, gemma4 o mimo-v2.5. | |
| Para audio input multimodal: usa mimo-v2.5. | |
| ## Recomendaciones operativas | |
| 1. Empieza con qwen3.6 para validar que la key y el base URL funcionan. | |
| 2. Comprueba /v1/models antes de diagnosticar problemas de modelo. | |
| 3. En clientes que soporten razonamiento separado, conserva reasoning_content si existe, pero no falles si no existe. | |
| 4. En clientes con streaming, usa /v1/chat/completions, no /v1/responses, si necesitas tokens incrementales. | |
| 5. En RAG: usa qwen3-embedding para recuperar candidatos, rerank para reordenarlos y despues qwen3.6 o deepseek-v4-flash para responder. | |
| 6. En Whisper, trocea audios largos antes de mandarlos para evitar 524. | |
| 7. En imagenes, recuerda que la cuota es por request, no por imagen generada dentro del request. |
iOS 27 Public Beta Is Live — No Developer Account Required