Tutorial de la API de OpenAI y de Claude: primeros pasos en Python, JavaScript y curl

Crea la clave, carga crédito y haz tu primera llamada a la API de OpenAI y de Claude en Python, JavaScript y curl, con streaming y los errores 401 y 429.

8 min

Para usar la API de OpenAI o la de Claude necesitas una cuenta de desarrollador, una clave y algo de crédito. Con eso, la primera llamada son diez líneas de Python o de JavaScript: en OpenAI se usa la Responses API y en Anthropic, la Messages API. Este tutorial te lleva de cero a una respuesta en streaming con los dos proveedores.

Los ejemplos siguen la documentación oficial a 8 de octubre de 2026 (quickstart de OpenAI y de Anthropic), con un cambio: usamos los modelos más baratos de cada casa para que trastear te cueste céntimos. No los hemos lanzado con claves reales; lo que sí hemos comprobado es que cada clase, método y parámetro existe en las versiones actuales de los SDK (openai 3.26.1 y anthropic 1.12.1 en Python; openai 7.30.1 y @anthropic-ai/sdk 0.132.1 en Node) y que el código se ejecuta hasta el momento de conectarse.

Qué necesitas antes de empezar

  • Python 3.10 o superior (lo exigen los dos SDK) o Node.js 22 o superior (lo exige el SDK de OpenAI).
  • Una tarjeta para cargar crédito. Las dos API son de prepago.
  • Un terminal. En Windows vale PowerShell.

No hace falta saber nada de inteligencia artificial: llamas a un modelo ya entrenado y recibes texto, igual que con cualquier otra API web.

Paso 1: crea la cuenta y la clave

OpenAIAnthropic (Claude)
Dónde te registrasplatform.openai.complatform.claude.com
Dónde se crean las clavesSettings, API keys (enlace)Settings, API keys (enlace)
CaducidadRecomendada en claves de proyectoLa eliges: de 3 horas a nunca

Anthropic muestra la clave completa (empieza por sk-ant-) una sola vez, al crearla, y si la pierdes no se recupera: se crea otra y se borra la vieja. Haz lo mismo con las dos: cópiala directamente al sitio donde la vayas a guardar (paso 3).

Dos consejos de la propia documentación que conviene seguir desde el primer día. Anthropic recomienda claves personales para tu desarrollo y claves de cuenta de servicio para todo lo compartido. OpenAI recomienda separar proyectos por entorno (pruebas y producción), cada uno con sus claves y sus límites.

Paso 2: carga crédito y pon un tope

Las dos plataformas cobran por adelantado: compras crédito y cada llamada lo va gastando.

  • OpenAI: la compra mínima es de 5 dólares, desde Settings, Billing. Ojo, porque la recarga automática viene activada al configurar el pago: desactívala o ponle un tope mensual. En Settings, Limits puedes fijar además un límite duro de gasto para la organización o para cada proyecto.
  • Anthropic: Settings, Billing, botón Buy credits. La recarga automática es opcional. En la misma página puedes poner tu propio límite de gasto, por debajo del tope de tu nivel (500 dólares al mes en el nivel Start). Las cuentas nuevas reciben, según Anthropic, una pequeña cantidad de crédito para probar.

En ambos casos el crédito caduca al año de comprarlo y no se devuelve. Para empezar, el mínimo sobra: cuánto cuesta cada cosa lo tienes desglosado en el precio de la API de OpenAI, Claude y Gemini.

Paso 3: guarda la clave en una variable de entorno

La clave nunca va escrita dentro del código. Los SDK la leen solos de una variable de entorno: OPENAI_API_KEY y ANTHROPIC_API_KEY.

En macOS y Linux, para la sesión actual del terminal:

export OPENAI_API_KEY="tu_clave_de_openai"
export ANTHROPIC_API_KEY="tu_clave_de_anthropic"

Para que no se pierda al cerrar el terminal, añade esas líneas a tu ~/.zshrc o ~/.bashrc.

En Windows, con PowerShell, setx la guarda de forma permanente (pero solo la verán los terminales que abras después) y $env: la pone solo en el terminal actual:

setx OPENAI_API_KEY "tu_clave_de_openai"
$env:ANTHROPIC_API_KEY = "tu_clave_de_anthropic"

Si prefieres un archivo .env en la carpeta del proyecto, añádelo a .gitignore antes de tu primer commit. Una clave subida a GitHub es una clave que hay que dar por perdida: qué hacer si te pasa está en se ha filtrado tu API key.

Paso 4: tu primera llamada con curl

Con curl ves la petición tal cual, sin SDK de por medio. Es la mejor forma de entender qué viaja por la red.

OpenAI, con la Responses API (la que OpenAI recomienda para proyectos nuevos frente a la antigua Chat Completions):

curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-6-luna",
    "instructions": "Responde en español de España, en dos frases como máximo.",
    "input": "¿Qué es una API?"
  }'

Claude, con la Messages API:

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-haiku-5-5",
    "max_tokens": 1000,
    "system": "Responde en español de España, en dos frases como máximo.",
    "messages": [{"role": "user", "content": "¿Qué es una API?"}]
  }'

Las diferencias que conviene retener:

OpenAIAnthropic
Endpoint/v1/responses/v1/messages
Cabecera de la claveAuthorization: Bearerx-api-key
Versión de la APINo hace faltaanthropic-version: 2023-06-01, obligatoria
Instrucciones de sistemainstructionssystem
Límite de salidaOpcional (max_output_tokens)Obligatorio (max_tokens)
Dónde está el textooutput, o output_text en algunos SDKcontent, una lista de bloques

La respuesta llega en JSON. Además del texto trae un campo usage con los tokens de entrada y de salida que se te han cobrado: acostúmbrate a mirarlo.

Paso 5: la primera llamada en Python

Crea un entorno virtual e instala los dos SDK oficiales:

python3 -m venv .venv
source .venv/bin/activate   # en Windows: .venv\Scripts\activate
pip install openai anthropic

Con OpenAI (openai_hola.py):

from openai import OpenAI

client = OpenAI()  # lee OPENAI_API_KEY del entorno

response = client.responses.create(
    model="gpt-6-luna",
    instructions="Responde en español de España, en dos frases como máximo.",
    input="¿Qué es una API?",
)

print(response.output_text)

Con Claude (claude_hola.py):

import anthropic

client = anthropic.Anthropic()  # lee ANTHROPIC_API_KEY del entorno

message = client.messages.create(
    model="claude-haiku-5-5",
    max_tokens=1000,
    system="Responde en español de España, en dos frases como máximo.",
    messages=[{"role": "user", "content": "¿Qué es una API?"}],
)

for block in message.content:
    if block.type == "text":
        print(block.text)

Se ejecutan con python openai_hola.py y python claude_hola.py. Fíjate en el bucle del ejemplo de Claude: la respuesta es una lista de bloques (texto, llamadas a herramientas, razonamiento) y hay que quedarse con los de tipo text. OpenAI ofrece el atajo output_text, que junta todo el texto de la respuesta.

Paso 6: la primera llamada en JavaScript

En una carpeta nueva:

npm init -y
npm pkg set type=module
npm install openai @anthropic-ai/sdk

Con OpenAI (openai-hola.js):

import OpenAI from "openai";

const client = new OpenAI(); // lee OPENAI_API_KEY del entorno

const response = await client.responses.create({
  model: "gpt-6-luna",
  instructions: "Responde en español de España, en dos frases como máximo.",
  input: "¿Qué es una API?",
});

console.log(response.output_text);

Con Claude (claude-hola.js):

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic(); // lee ANTHROPIC_API_KEY del entorno

const message = await client.messages.create({
  model: "claude-haiku-5-5",
  max_tokens: 1000,
  system: "Responde en español de España, en dos frases como máximo.",
  messages: [{ role: "user", content: "¿Qué es una API?" }],
});

for (const block of message.content) {
  if (block.type === "text") console.log(block.text);
}

Se ejecutan con node openai-hola.js y node claude-hola.js. Este código es para el servidor (Node, Deno o Bun), nunca para el navegador: si lo metes en una página web, la clave viaja con ella y cualquiera puede leerla.

El mensaje de sistema: decirle cómo comportarse

El mensaje de sistema son las instrucciones que van por encima de lo que escriba el usuario: el tono, el idioma, el formato, lo que no debe hacer. En los ejemplos ya lo has usado.

  • En OpenAI es el parámetro instructions. Según su documentación, tiene prioridad sobre lo que llega en input y solo vale para esa petición: si encadenas respuestas con previous_response_id, tienes que volver a mandarlo. También puedes usar mensajes con el rol developer dentro de input.
  • En Claude es el parámetro system, aparte de la lista de mensajes.

Un buen mensaje de sistema es concreto: «Eres el asistente de una tienda de bicicletas de Valencia. Responde en español de España, en menos de 80 palabras. Si te preguntan por precios, remite a la web». Cuanto más concreto, menos se inventa.

Ten en cuenta que la Messages API de Claude no guarda la conversación: en cada llamada mandas la lista completa de mensajes anteriores, alternando user y assistant. La Responses API de OpenAI sí guarda las respuestas (30 días por defecto) y te deja encadenarlas con previous_response_id, pero, como avisa su documentación, todos los tokens anteriores de la cadena se vuelven a facturar como entrada.

Streaming: la respuesta según se escribe

Sin streaming, tu programa espera a que el modelo termine y recibe todo de golpe. Con streaming, el texto llega a trozos mientras se genera, que es lo que hace que un chat parezca vivo. Por debajo son eventos enviados por el servidor (SSE).

Python con OpenAI:

from openai import OpenAI

client = OpenAI()

stream = client.responses.create(
    model="gpt-6-luna",
    input="Explica qué es un token en tres frases.",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

Python con Claude:

import anthropic

client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-haiku-5-5",
    max_tokens=1000,
    messages=[{"role": "user", "content": "Explica qué es un token en tres frases."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

JavaScript con OpenAI:

import OpenAI from "openai";

const client = new OpenAI();

const stream = await client.responses.create({
  model: "gpt-6-luna",
  input: "Explica qué es un token en tres frases.",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.output_text.delta") {
    process.stdout.write(event.delta);
  }
}

JavaScript con Claude:

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = client.messages.stream({
  model: "claude-haiku-5-5",
  max_tokens: 1000,
  messages: [{ role: "user", content: "Explica qué es un token en tres frases." }],
});

stream.on("text", (text) => process.stdout.write(text));
await stream.finalMessage();

OpenAI emite eventos con nombre (response.output_text.delta, response.completed, error) y te quedas con los que te interesan. El SDK de Anthropic te da directamente el texto con text_stream en Python o el evento text en JavaScript, y finalMessage() devuelve el mensaje completo al acabar, con su usage. Anthropic recomienda streaming para cualquier petición larga: evita que la conexión se corte por tiempo de espera.

Errores habituales y cómo se arreglan

401: la clave no vale

Pasa en los dos proveedores cuando la clave está mal copiada, revocada o caducada. Comprueba que la variable de entorno está cargada en ese terminal (echo $OPENAI_API_KEY) y que la clave sigue activa en el panel.

429: demasiadas peticiones, o sin crédito

El mismo código significa cosas distintas. Con el tipo rate_limit_error, en los dos proveedores, has superado las peticiones o los tokens por minuto: espera lo que diga la cabecera retry-after y baja el ritmo. En OpenAI, con el código credit_balance_exhausted, no te queda crédito; recarga, porque reintentar no sirve. En Anthropic, un 429 sin retry-after significa que has llegado al tope mensual de tu nivel: pide subir de nivel en la Console o espera al mes siguiente.

400 y 402: la petición o el pago

Un 400 invalid_request_error dice que la petición está mal: falta max_tokens en Claude, un parámetro no existe o el ID del modelo está mal escrito. Lee el mensaje, que indica qué campo falla. En Anthropic, un 400 cuyo mensaje habla de «specified API usage limits» significa que has llegado al límite de gasto que pusiste tú: súbelo o quítalo en Settings, Billing. Y un 402 billing_error es un problema con el método de pago; revisa la tarjeta en la Console.

529 y 503: el servicio está saturado

Anthropic responde 529 y OpenAI 503 cuando el servicio está saturado. Reintenta pasados unos segundos.

Las listas completas están en las guías de errores de OpenAI y de Anthropic. Los dos SDK reintentan solos dos veces los errores pasajeros (conexión, 429 y 5xx), con espera creciente entre intentos.

Para tratarlos en el código, usa las clases de error de cada SDK en vez de buscar texto en el mensaje:

import anthropic
import openai

client = openai.OpenAI()

try:
    response = client.responses.create(model="gpt-6-luna", input="Hola")
    print(response.output_text)
except openai.AuthenticationError:
    print("401: la clave no vale. ¿Está cargada la variable OPENAI_API_KEY?")
except openai.RateLimitError as e:
    if e.code == "credit_balance_exhausted":
        print("Sin crédito: recarga en el panel de facturación.")
    else:
        print("Demasiadas peticiones: espera y vuelve a intentarlo.")
except openai.APIConnectionError:
    print("No hay conexión con la API.")

claude = anthropic.Anthropic()

try:
    message = claude.messages.create(
        model="claude-haiku-5-5",
        max_tokens=500,
        messages=[{"role": "user", "content": "Hola"}],
    )
except anthropic.AuthenticationError:
    print("401: revisa ANTHROPIC_API_KEY.")
except anthropic.RateLimitError:
    print("429: límite de peticiones o tope de gasto del nivel.")
except anthropic.APIStatusError as e:
    print(f"Error {e.status_code}: {e.message}")
except anthropic.APIConnectionError:
    print("No hay conexión con la API.")

De script a aplicación

Con esto ya hablas con los dos modelos desde tu terminal. Para convertirlo en algo que use más gente faltan unas cuantas piezas: un servidor propio que guarde la clave y haga de intermediario, límites de uso por usuario, registro de los tokens que gasta cada petición, reintentos y una forma de comprobar que las respuestas son buenas. Todo eso está ordenado en cómo integrar IA en una aplicación.

Si lo que vas a construir es un asistente que busca en tus documentos, el siguiente concepto que necesitas es RAG. Y si el modelo tiene que hacer cosas por su cuenta (consultar una base de datos, enviar un correo), mira qué es un agente de IA.

Por dónde seguir

Preguntas frecuentes

¿Puedo usar el SDK de OpenAI para llamar a Claude?

Sí: Anthropic tiene una capa de compatibilidad que acepta el SDK de OpenAI cambiando la URL base, la clave y el nombre del modelo. Pero la propia Anthropic dice que está pensada para probar y comparar modelos, no como solución de producción, y remite a su API nativa para usar del todo la caché de prompts, el razonamiento o las citas. Para algo serio, usa su SDK.

¿Las claves de API caducan?

En Anthropic eliges la caducidad al crear la clave: 3 horas, 1 día, 7 días, 30 días, una duración a medida o nunca. OpenAI recomienda poner fecha de caducidad a las claves de proyecto y rotarlas con regularidad, y permite a los administradores imponer una vida máxima.

¿Cuánto me va a costar seguir este tutorial?

Menos de un céntimo. Con GPT-6 Luna o Claude Haiku 5.5, una prueba de 300 tokens de entrada y 500 de salida cuesta unos 0,00028 dólares, así que veinte pruebas no llegan a 0,006.

Escrito por

Equipo editorial

No te pierdas nada.

Lo importante de la semana en IA, en un email que se lee en cinco minutos.