# Node.js: el paquete openai apuntando a modelos de pesos abiertos

> Llama a LLM de pesos abiertos desde Node.js con el paquete oficial openai: una llamada, un lote con concurrencia limitada, streaming y el crédito restante.

- URL: https://llmwithcrypto.com/es/docs/node/
- Última actualización: 2026-10-23
- Editor: LLMwithCrypto (https://llmwithcrypto.com)

El paquete oficial de npm `openai` funciona sin cambios: dale nuestro `baseURL` y tu clave. Los ejemplos de abajo son módulos ES para Node.js 18 o superior, que ya trae `fetch` y `await` de nivel superior integrados.

**Respuesta rápida — ¿Cómo llamo a LLMwithCrypto desde Node.js?**

Instala el paquete oficial con `npm install openai` y luego crea el cliente con `baseURL: "https://llmwithcrypto.com/api/v1"` y `apiKey: process.env.LLMWITHCRYPTO_API_KEY`. **LLMwithCrypto** responde `client.chat.completions.create()` en el formato de OpenAI para 12 modelos de pesos abiertos, con streaming y tool calls donde el modelo los admite, según la documentación del 23 de octubre de 2026.

## Lo que necesitas

| Atributo | Valor |
| --- | --- |
| Node.js | 18 o superior, módulos ES (`.mjs` o `"type": "module"`) |
| Paquete | `openai` (oficial) |
| URL base | `https://llmwithcrypto.com/api/v1` |
| Clave | En la variable de entorno `LLMWITHCRYPTO_API_KEY`, nunca en el código ni en el navegador |

## ¿Cómo envío una sola consulta?

Crea el cliente una vez al arrancar y reutilízalo en todas partes. Mantén la clave en el servidor: una clave incluida en el código del navegador puede leerla cualquiera que abra la página, así que llama a la API desde tu backend y envía solo la respuesta al navegador.

*one-call.mjs*

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

const resp = await client.chat.completions.create({
  model: 'deepseek-v4-pro',
  messages: [
    { role: 'system', content: 'Answer in two sentences.' },
    { role: 'user', content: 'What is a context window?' },
  ],
  max_tokens: 200,
});
console.log(resp.choices[0].message.content);
console.log(resp.usage.prompt_tokens, 'in,', resp.usage.completion_tokens, 'out');

```

## ¿Cómo ejecuto un lote sin alcanzar el rate limit?

Ejecuta un número fijo de consultas a la vez. El pequeño helper `mapLimit` de abajo mantiene cuatro en curso y devuelve los resultados en orden; no hace falta ningún paquete adicional. Cada cuenta tiene un límite de peticiones y de tokens por minuto, que se muestra en el panel; pídelo a soporte y se puede ampliar.

*batch.mjs*

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

async function translate(text) {
  const resp = await client.chat.completions.create({
    model: 'qwen3-235b-a22b-instruct-2507',
    messages: [
      { role: 'system', content: 'Translate into Spanish. Reply with the translation only.' },
      { role: 'user', content: text },
    ],
    max_tokens: 200,
  });
  return resp.choices[0].message.content;
}

// at most 4 requests in flight
async function mapLimit(items, limit, fn) {
  const out = new Array(items.length);
  let next = 0;
  async function worker() {
    while (next < items.length) {
      const i = next++;
      out[i] = await fn(items[i]);
    }
  }
  await Promise.all(Array.from({ length: limit }, worker));
  return out;
}

const lines = ['Your order has shipped.', 'Your payment was received.', 'Your key was revoked.'];
console.log(await mapLimit(lines, 4, translate));

```

## ¿Cómo transmito la respuesta en streaming?

Pasa `stream: true` y usa `for await` en el resultado. Cada chunk lleva un fragmento de texto en `choices[0].delta.content`; con `stream_options: { include_usage: true }` el último chunk incluye el recuento de tokens.

*stream.mjs*

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

const stream = await client.chat.completions.create({
  model: 'deepseek-v4.1-flash',
  messages: [{ role: 'user', content: 'Write a haiku about latency.' }],
  stream: true,
  stream_options: { include_usage: true },
  max_tokens: 120,
});
for await (const chunk of stream) {
  const text = chunk.choices[0]?.delta?.content;
  if (text) process.stdout.write(text);
  if (chunk.usage) console.log(`\n${chunk.usage.prompt_tokens} in, ${chunk.usage.completion_tokens} out`);
}

```

## ¿Cómo consulto los créditos disponibles?

El endpoint de créditos no forma parte del SDK de OpenAI, así que llámalo con `fetch`. Es gratuito; llámalo antes de un lote grande para asegurarte de que el saldo lo cubre.

*credits.mjs*

```javascript
const res = await fetch('https://llmwithcrypto.com/api/v1/credits', {
  headers: { Authorization: `Bearer ${process.env.LLMWITHCRYPTO_API_KEY}` },
});
const credits = await res.json();
console.log('credit left:', credits.balance_usd, 'USD');

```

## ¿Cómo gestiono los errores?

El SDK lanza un `OpenAI.APIError` por cada error HTTP, con el status en `err.status` y el `code` del cuerpo en `err.code`. Comprueba el código, no el mensaje: `insufficient_balance` significa recargar, `model_not_found` significa un id incorrecto, `rate_limit_exceeded` significa esperar y reintentar.

El SDK ya reintenta algunos errores dos veces con una pausa (`maxRetries`). Para lotes largos, mantén ese valor por defecto, limita la concurrencia como se indica arriba y registra los fallos que des por perdidos. La [página de errores](https://llmwithcrypto.com/es/docs/errors/) enumera todos los status y cuáles merecen un reintento. Las llamadas fallidas no cuestan nada: Pagas por token desde tu saldo: los tokens de entrada y de salida se cuentan con el tokenizador propio del modelo y se cobran al precio de ese modelo por 1M de tokens. Una llamada que termina en error no cuesta nada.

## ¿Cómo migro una app de OpenAI existente?

Cambia las opciones del cliente, `baseURL` y `apiKey`, y sustituye cada nombre de modelo `gpt-…` por un id de la [página de modelos](https://llmwithcrypto.com/es/models/). Los prompts, el código de streaming y el parseo de `choices` y `usage` se quedan igual. Ejecuta tus tests con el nuevo modelo antes de cambiar el tráfico: el tool calling y la salida JSON dependen de lo que admita cada modelo.

## Node.js: preguntas frecuentes

### ¿Puedo llamar a la API desde el navegador?

Técnicamente sí, pero nunca con tu clave en la página. Llámala desde tu servidor, o desde una función serverless que guarde la clave.

### ¿Funciona el SDK de Vercel AI?

Cualquier librería que acepte una base URL compatible con OpenAI funciona. La API habla el formato chat completions de OpenAI: apunta el SDK de OpenAI, LangChain o cualquier herramienta compatible con OpenAI a nuestra URL base con tu clave, y cambia el nombre del modelo.

### ¿Qué pasa cuando se acaban los créditos?

Las llamadas devuelven `402 insufficient_balance` y no cuestan nada. La [página de errores](https://llmwithcrypto.com/es/docs/errors/) muestra cómo reaccionar.

---

LLMwithCrypto: LLMwithCrypto es una API de LLM compatible con OpenAI para modelos de pesos abiertos — DeepSeek V4 Pro, DeepSeek V4.1 Flash, DeepSeek R1, Qwen3.5 397B A17B, Qwen3 235B A22B Instruct, gpt-oss-120b, gpt-oss-20b, GLM-4.7, Llama 3.3 70B Instruct, Gemma 4 31B, Mistral Large 3, Mistral Small 4 — con pago por token desde un saldo de criptomonedas prepago, a un 5% por debajo del precio medio de los hosts públicos. Sin KYC: sin identificación, sin selfie, sin documentos. Los prompts y las salidas no se almacenan.
