DeepSeek OpenAI API: cómo usar el SDK y migrar tu código

Sí, puedes usar DeepSeek con el SDK de OpenAI. Para una llamada de texto básica, conserva la biblioteca openai, utiliza una API key de DeepSeek, configura su URL base y selecciona un modelo de ese proveedor. La guía oficial de primera llamada muestra esta integración en Python y JavaScript.

La búsqueda DeepSeek OpenAI API suele referirse a esa compatibilidad, no a una API conjunta. El paquete que instalas es el cliente; el servidor al que lo conectas determina qué modelos, parámetros y funciones puedes utilizar.

En esta guía configurarás una llamada directa a DeepSeek y revisarás qué debes adaptar al migrar una aplicación. Los ejemplos no utilizan intermediarios, modelos locales ni el chat del navegador.

Configuración rápida: qué necesitas cambiar

Estos son los datos de conexión para los ejemplos. La documentación de modelos y configuración de DeepSeek distingue el formato OpenAI del formato Anthropic; aquí utilizaremos el primero.

ElementoConfiguración para DeepSeek
Bibliotecaopenai.
CredencialUna API key creada en la plataforma de DeepSeek.
Variable usada en esta guíaDEEPSEEK_API_KEY.
URL basehttps://api.deepseek.com.
Nombre de la opción en Pythonbase_url.
Nombre de la opción en JavaScriptbaseURL.
Modelos documentadosdeepseek-flash y deepseek-v4-pro.
Autenticación HTTPAuthorization: Bearer seguido de tu clave.
Tabla de conexión de DeepSeek con las URL base para OpenAI y Anthropic, el requisito de API key y los modelos.

No pongas el endpoint completo en el campo de URL base del SDK. La base identifica el servidor; el método que invocas añade la ruta. En una petición HTTP directa sí necesitas la URL completa, como verás en el ejemplo de cURL.

Si una aplicación externa tiene un campo llamado “OpenAI-compatible”, comprueba qué espera: una base, un endpoint completo o una ruta que la propia aplicación modifica. No añadas segmentos como /v1 o /chat/completions por intuición; revisa la URL final que construye.

API de OpenAI, SDK y compatibilidad: no son lo mismo

El SDK de OpenAI es una biblioteca para construir solicitudes y leer respuestas. Usarlo con la configuración de esta guía dirige las llamadas del cliente a DeepSeek. No convierte un modelo de DeepSeek en un modelo de OpenAI ni habilita automáticamente todos los servicios que aparecen en la biblioteca.

Por eso, cambiar únicamente la clave no basta. Si mantienes el destino de otro proveedor, enviarás la credencial al servidor equivocado. Y si conservas un identificador de modelo de OpenAI, no estarás seleccionando un modelo válido del catálogo de DeepSeek.

Para un chat sencillo, la adaptación puede ser pequeña. Para una aplicación con herramientas, archivos, estado conversacional y salidas estructuradas, trata el cambio como una migración que necesita pruebas, no como un reemplazo universal.

Prepara tu clave y el entorno de ejecución

Crea tu clave en la plataforma de DeepSeek y comprueba que la cuenta tenga saldo disponible. Las llamadas de generación de este artículo pueden consumir saldo; instalar la biblioteca no financia las solicitudes.

Utiliza un entorno local controlado o un servidor. Las recomendaciones de seguridad para claves API desaconsejan incluir secretos en aplicaciones del navegador y repositorios. En producción, configura el secreto en el servidor o en un gestor de credenciales.

En Bash, puedes introducir la clave sin mostrarla en pantalla. Ejecuta este bloque en la misma terminal desde la que lanzarás los ejemplos:

read -r -s -p "API key de DeepSeek: " DEEPSEEK_API_KEY
printf '\n'
export DEEPSEEK_API_KEY

La variable se asignará explícitamente al cliente. No asumas que el SDK reconocerá DEEPSEEK_API_KEY por su nombre sin indicárselo. Si ejecutas el código desde un editor, un contenedor o un servicio, configura la variable también en ese entorno.

Primera solicitud con cURL

Esta prueba utiliza el endpoint de Chat Completions. Envía un mensaje sencillo y desactiva el pensamiento mediante reasoning_effort="none", sin añadir un campo thinking que lo contradiga.

curl --silent --show-error --include \
  --connect-timeout 10 --max-time 60 \
  https://api.deepseek.com/chat/completions \
  --header "Authorization: Bearer ${DEEPSEEK_API_KEY}" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "deepseek-flash",
    "messages": [
      {"role": "system", "content": "Responde en español latinoamericano neutro."},
      {"role": "user", "content": "Explica qué es una API en dos frases."}
    ],
    "reasoning_effort": "none",
    "max_tokens": 256,
    "stream": false
  }'

Revisa el estado HTTP y el cuerpo recibido. En una respuesta de texto de Chat Completions, el contenido se encuentra en choices[0].message.content. Comprueba también finish_reason: un texto cortado no debe guardarse como una respuesta completa.

Los 60 segundos y los 256 tokens son decisiones para esta prueba breve, no límites oficiales del servicio. Si funciona, ya tienes una referencia mínima para comparar con tu aplicación. Si falla, conserva el error sin publicar la clave ni el encabezado de autenticación.

Cómo usar DeepSeek con el SDK de OpenAI en Python

Instala el paquete dentro del entorno de tu proyecto. El cliente oficial de Python permite configurar la URL base, los tiempos de espera y los reintentos:

python -m pip install --upgrade openai

Guarda el siguiente archivo como deepseek_openai.py. Usa la variable del paso anterior y valida que esta solicitud de texto haya terminado correctamente:

import os
import openai


def main() -> int:
    key = os.environ.get("DEEPSEEK_API_KEY", "").strip()
    if not key:
        print("Falta la variable DEEPSEEK_API_KEY.")
        return 1

    try:
        with openai.OpenAI(
            api_key=key,
            base_url="https://api.deepseek.com",
            timeout=60.0,
            max_retries=0,
        ) as client:
            response = client.chat.completions.create(
                model="deepseek-flash",
                messages=[
                    {"role": "system", "content": "Responde en español latinoamericano neutro."},
                    {"role": "user", "content": "Explica qué es una API en dos frases."},
                ],
                reasoning_effort="none",
                max_tokens=256,
                stream=False,
            )
    except openai.APIError as error:
        print(f"Error del cliente: {type(error).__name__}")
        print(f"Estado HTTP: {getattr(error, 'status_code', 'no disponible')}")
        return 1

    if not response.choices:
        print("La respuesta no contiene choices.")
        return 1

    choice = response.choices[0]
    text = (choice.message.content or "").strip()
    if choice.finish_reason != "stop" or not text:
        print(f"Respuesta no completa: {choice.finish_reason}")
        return 1

    print(text)
    if response.usage:
        print("Uso:", response.usage.model_dump_json())
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Ejecuta python deepseek_openai.py. Si aparece una excepción cuyo nombre empieza por openai, no significa que la solicitud haya ido a OpenAI: es el nombre de la biblioteca que maneja la respuesta del proveedor configurado.

Durante el diagnóstico, max_retries=0 evita reintentos automáticos. Para producción, define una política limitada y evita que el SDK y tu aplicación repitan la misma operación por separado. La comprobación de stop corresponde a este ejemplo sin herramientas, no a todos los flujos posibles.

Ejemplo oficial de DeepSeek en Python con el SDK de OpenAI y el modo de pensamiento activado.

Cómo usar DeepSeek con OpenAI en Node.js

Para un proyecto de JavaScript del lado del servidor, instala el SDK de JavaScript y TypeScript:

npm install openai

Guarda este ejemplo como deepseek-openai.mjs. En JavaScript se utilizan apiKey, baseURL y maxRetries; no copies los nombres de configuración de Python.

import OpenAI from "openai";

async function main() {
  const apiKey = process.env.DEEPSEEK_API_KEY?.trim();
  if (!apiKey) {
    throw new Error("Falta la variable DEEPSEEK_API_KEY.");
  }

  const client = new OpenAI({
    apiKey,
    baseURL: "https://api.deepseek.com",
    timeout: 60_000,
    maxRetries: 0,
  });

  const response = await client.chat.completions.create({
    model: "deepseek-flash",
    messages: [
      { role: "system", content: "Responde en español latinoamericano neutro." },
      { role: "user", content: "Explica qué es una API en dos frases." },
    ],
    reasoning_effort: "none",
    max_tokens: 256,
    stream: false,
  });

  const choice = response.choices?.[0];
  const text = choice?.message?.content?.trim();
  if (choice?.finish_reason !== "stop" || !text) {
    throw new Error("No se recibió una respuesta de texto completa.");
  }
  console.log(text);
  if (response.usage) console.log("Uso:", response.usage);
}

main().catch((error) => {
  if (error instanceof OpenAI.APIError) {
    console.error("Error de API:", error.name, "HTTP:", error.status ?? "no disponible");
  } else {
    console.error(error instanceof Error ? error.message : "Error desconocido.");
  }
  process.exitCode = 1;
});

Ejecuta node deepseek-openai.mjs desde la terminal que tiene la variable configurada. El timeout del SDK de JavaScript se expresa en milisegundos; en el ejemplo de Python se expresa en segundos.

No pegues este código con tu clave en el JavaScript público de una página. Para una aplicación web, el navegador debe llamar a tu servidor y este al proveedor. Añade autenticación y límites a tu propio endpoint para que terceros no consuman tu saldo sin autorización.

Ejemplo de DeepSeek con el SDK de OpenAI en Node.js y las opciones baseURL y apiKey.

Chat Completions y Responses API: elige el formato correcto

DeepSeek documenta también Responses API. Por tanto, una guía que limita toda la integración a chat.completions no refleja las interfaces actuales. Sin embargo, sus cuerpos de solicitud y objetos de respuesta no son intercambiables.

ElementoChat CompletionsResponses
Ruta HTTP/chat/completions/responses
Método del SDKclient.chat.completions.create()client.responses.create()
Entradamessagesinput e instructions
Texto en el SDKchoices[0].message.contentoutput_text
Presupuesto de salidamax_tokensmax_output_tokens
Desactivar pensamientoreasoning_effort="none", sin un thinking contradictorioreasoning={"effort":"none"}

Este ejemplo independiente usa Responses con la misma clave y biblioteca. Guárdalo como deepseek_responses.py y ejecútalo con Python:

import os
import openai


def main() -> int:
    key = os.environ.get("DEEPSEEK_API_KEY", "").strip()
    if not key:
        print("Falta la variable DEEPSEEK_API_KEY.")
        return 1

    try:
        with openai.OpenAI(
            api_key=key,
            base_url="https://api.deepseek.com",
            timeout=60.0,
            max_retries=0,
        ) as client:
            response = client.responses.create(
                model="deepseek-flash",
                instructions="Responde en español latinoamericano neutro.",
                input="Explica qué es una API en dos frases.",
                reasoning={"effort": "none"},
                max_output_tokens=256,
            )
    except openai.APIError as error:
        print(f"Error de API: {type(error).__name__}")
        print(f"HTTP: {getattr(error, 'status_code', 'no disponible')}")
        return 1

    if response.status != "completed" or not response.output_text.strip():
        print(f"Respuesta no completa: {response.status}")
        return 1
    print(response.output_text)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

El estado conversacional necesita atención. DeepSeek describe Responses como una API sin estado: debes reenviar el historial en input. No dependas de previous_response_id o conversation para recuperar automáticamente los turnos anteriores.

Esto describe la continuidad de la API, no una garantía general de privacidad o de ausencia de registros. Para datos sensibles, revisa por separado las condiciones del proveedor y los registros que conserva tu propia aplicación.

Streaming: cambia también el lector de eventos

En Chat Completions, el texto incremental llega en choices[0].delta.content. En Responses, escucha eventos como response.output_text.delta. No basta con activar stream=True y conservar un lector diseñado para el otro formato.

Responses termina con response.completed, response.incomplete o response.failed, no con data: [DONE]. En Chat Completions, revisa la señal de finalización y el motivo de cierre antes de marcar la operación como completa.

Diseña una prueba que corte el flujo deliberadamente. Tu aplicación debe diferenciar una respuesta terminada de texto parcial ya mostrado, y evitar duplicarlo si decide volver a intentarlo.

Límites de compatibilidad que debes revisar antes de migrar

Una solicitud aceptada no demuestra que todas sus opciones se hayan aplicado. La matriz de compatibilidad de Responses indica que los parámetros no compatibles pueden ignorarse sin provocar un error.

Función de tu aplicaciónQué revisar en DeepSeek
Herramientas integradas en Responsesfile_search, code_interpreter y mcp se ignoran. No los des por disponibles porque el SDK los acepte.
Búsqueda integrada en Responsesweb_search está admitida con deepseek-v4-pro; con Flash se ignora.
Instrucciones de tipo developerEn Responses, el rol developer se trata como user. Revisa la jerarquía de tus instrucciones.
Ejecución en segundo planobackground no está soportado en esta implementación de Responses.
Otros servicios del SDKComprueba cada endpoint. La existencia de un método en openai no prueba que DeepSeek lo implemente.
Tabla de compatibilidad de herramientas en DeepSeek Responses API, con funciones admitidas y herramientas ignoradas.

Usa instructions para las instrucciones de sistema de los ejemplos de Responses. En la migración, prueba que las reglas de tu aplicación mantengan su prioridad frente al contenido aportado por el usuario; no hagas una conversión automática de roles sin revisarla.

Pensamiento, herramientas y JSON: adapta el comportamiento

El modo de pensamiento está activado de forma predeterminada con esfuerzo high. Los ejemplos anteriores lo desactivan para aislar la conexión. Si lo necesitas, configúralo explícitamente y ajusta el presupuesto; no supongas que cambiar temperature controla el razonamiento.

En Python, el campo específico thinking se envía mediante extra_body. Por ejemplo, dentro de una llamada a Chat Completions puedes sustituir reasoning_effort="none" por estos argumentos:

reasoning_effort="high",
extra_body={"thinking": {"type": "enabled"}},

Este bloque es un fragmento de argumentos, no un programa independiente. En HTTP directo, thinking va en el nivel superior del JSON: extra_body es una opción del SDK, no un campo que debas copiar al cuerpo de cURL.

Con pensamiento y tools, conserva y reenvía íntegro el reasoning_content de los turnos anteriores, incluso cuando alguno no haya llamado a una herramienta. Separar la respuesta final del razonamiento para mostrarla en pantalla no significa que puedas borrar información necesaria del historial.

Las llamadas a funciones requieren que tu aplicación valide los argumentos, ejecute la operación y devuelva el resultado asociado a la llamada. Para el modo estricto de herramientas en Chat Completions, DeepSeek documenta una configuración beta y un subconjunto de JSON Schema; revisa esas condiciones antes de reutilizar un esquema.

Para JSON Output en Chat Completions, utiliza response_format={"type":"json_object"} y solicita JSON en el prompt. No lo confundas con text.format de Responses, cuya referencia también documenta json_schema. Valida el contenido y sus campos después de recibirlo, y maneja las respuestas vacías o truncadas.

Imágenes y archivos: verifica la capacidad del modelo

La guía de Vision documenta entrada de imágenes para deepseek-flash. No generalices una limitación de un modelo antiguo a toda la API, pero tampoco supongas que cualquier modelo o endpoint acepta el mismo contenido.

La Files API de DeepSeek permite subir imágenes y referenciarlas mediante file_id. Esto no equivale a disponer automáticamente de búsqueda sobre documentos, intérprete de código o compatibilidad con cualquier PDF. Comprueba el tipo de archivo y el formato del mensaje que necesita tu función concreta.

Cómo migrar una aplicación sin cambiar todo a la vez

Separa la configuración del proveedor del resto del programa. Guarda URL base, nombre de variable de credenciales y modelo como opciones del cliente. Evita modificar una variable global compartida si la aplicación usa más de un proveedor.

Consulta GET /models para confirmar los identificadores disponibles. La respuesta puede incluir capacidades y límites; algunos metadatos se omiten cuando no están disponibles. En Python, con el cliente ya configurado, puedes recorrer client.models.list().data y revisar cada model.id.

Empieza por una solicitud sin herramientas ni archivos. Después incorpora historial, streaming, salida estructurada y funciones, uno por uno. Si el fallo aparece al añadir una capacidad, podrás investigar ese cambio sin desmontar toda la integración.

Prepara un pequeño conjunto de pruebas propio: una respuesta en español, una instrucción que deba mantenerse durante varios turnos, un JSON con campos obligatorios y una operación con herramienta. Compara el resultado esperado, el tiempo y el consumo; no aceptes la migración solo porque recibiste HTTP 200.

Finalmente, registra la versión del SDK y la configuración utilizada, y conserva una forma de volver al proveedor anterior. Estas son medidas de implementación recomendadas, no garantías de equivalencia entre modelos.

Errores frecuentes al conectar DeepSeek con OpenAI SDK

La referencia oficial de errores de DeepSeek distingue los problemas de formato, autenticación, saldo y disponibilidad. Empieza por el código y el mensaje real:

Error o síntomaPrimera comprobación
401Confirma que envías una clave de DeepSeek al servidor correcto.
402Revisa el saldo de la cuenta asociada a esa clave.
400 o 422Inspecciona el formato y los parámetros señalados; no mezcles messages con el cuerpo de Responses.
429Reduce la carga y utiliza reintentos limitados, no bucles continuos.
500 o 503Revisa la disponibilidad del servicio y espera antes de un nuevo intento.
Modelo no encontrado o ruta incorrectaComprueba el catálogo y la URL final; no conserves automáticamente el modelo del proveedor anterior.
El SDK rechaza un argumentoDistingue un error local de una respuesta HTTP. Revisa la versión instalada y la forma de enviar campos adicionales.
Códigos de error 400, 401, 402, 422, 429, 500 y 503 en la documentación oficial de DeepSeek.

Si cURL funciona y la aplicación no, compara la clave cargada, la URL final y el cuerpo de ambas solicitudes desde el mismo entorno. Si existe un proxy o una plataforma intermediaria, comprueba también quién generó el error.

Ante un timeout, no asumas que la operación no se procesó. Evita repetir automáticamente acciones con efectos externos, como enviar un correo o modificar un registro, sin mecanismos para prevenir duplicados.

Costo y credenciales: quién recibe y factura las solicitudes

Con los ejemplos de esta guía, el cliente llama directamente a DeepSeek. Su facturación depende del uso y se descuenta del saldo de esa cuenta. Revisa la tarifa del modelo, los tokens consumidos y cualquier servicio adicional antes de estimar un costo de producción.

No uses una suscripción de ChatGPT como indicador de saldo disponible en DeepSeek. OpenAI también distingue la facturación de ChatGPT de la plataforma API. Compartir una biblioteca cliente no comparte cuentas, créditos ni condiciones comerciales.

Si añades una pasarela de terceros, revisa otra vez el destino, la credencial y la facturación. No reutilices a ciegas la clave de una cuenta en un servicio distinto, ni asumas que el nombre “compatible con OpenAI” identifica al operador del servidor.

Preguntas frecuentes

¿Necesito una API key de OpenAI para usar DeepSeek?

No para esta conexión directa. Debes proporcionar al cliente una clave de DeepSeek y su URL base. El nombre del paquete que importas no determina qué cuenta autentica la solicitud.

¿Basta con cambiar base_url?

No: revisa también la clave y el modelo. Para aplicaciones más complejas, verifica endpoints, parámetros, historial y herramientas. La llamada más sencilla puede funcionar mientras una función avanzada sigue siendo incompatible.

¿Qué diferencia hay entre base_url y baseURL?

Son nombres de opciones en bibliotecas distintas: base_url en Python y baseURL en JavaScript. En estos ejemplos, ambas reciben la misma dirección de DeepSeek.

¿Puedo utilizar DeepSeek en una aplicación que solo muestra “OpenAI”?

Depende de su configuración. Comprueba que permita modificar servidor, clave y modelo, y qué formato utiliza realmente. Si fija el servidor de OpenAI o depende de funciones no implementadas por DeepSeek, necesitarás adaptar la integración.

La ruta recomendada: confirma primero una llamada mínima y después prueba cada capacidad que usa tu aplicación. Reutilizar el SDK simplifica el acceso, pero la compatibilidad real se comprueba en el comportamiento que necesitas.

Última verificación documental: 10 de noviembre de 2026. Los ejemplos se revisaron en su sintaxis y se basan en la documentación enlazada; no se realizaron llamadas autenticadas a DeepSeek.