La API de Responses es nuestra nueva primitiva de API. Es una evolución de Chat Completions que simplifica tus integraciones y te ofrece primitivas potentes para crear agentes.
Seguimos dando soporte a Chat Completions y recomendamos Responses para todos los proyectos nuevos.
Acerca de la API de Responses
La API de Responses ofrece una interfaz unificada para crear aplicaciones potentes que actúan como agentes. Incluye:
Interacciones fluidas de varios turnos en las que puedes pasar respuestas anteriores para obtener resultados de razonamiento más precisos.
Compatibilidad multimodal nativa con texto e imágenes.
Ventajas de Responses
La API de Responses ofrece varias ventajas respecto de Chat Completions:
Mejor rendimiento: los modelos de razonamiento como GPT-5 demuestran mayor capacidad con Responses que con Chat Completions. En nuestras evaluaciones internas, el resultado en SWE-bench mejoró un 3 % con el mismo prompt y la misma configuración.
Ciclo de agente predeterminado: en una sola solicitud a la API, el modelo puede llamar a varias herramientas, como web_search, image_generation, file_search, code_interpreter y servidores MCP remotos, así como a tus propias funciones personalizadas.
Menores costos: Responses reduce los costos al aprovechar mejor la caché. En pruebas internas, el aprovechamiento de la caché mejoró entre un 40 % y un 80 % respecto de Chat Completions.
Contexto con estado: usa store: true para mantener el estado entre turnos y conservar tanto el razonamiento como el contexto de las herramientas.
Entradas flexibles: pasa la entrada como una cadena de texto o una lista de mensajes. Usa instrucciones para dar indicaciones a nivel de sistema.
Razonamiento cifrado: usa razonamiento avanzado sin almacenar el estado.
Compatibilidad futura: la API está diseñada para admitir los próximos modelos.
Capacidades
API para completar chats
API de Responses
Generación de texto
Audio
Próximamente
Visión
Resultados estructurados
Llamada a funciones
Búsqueda web
Búsqueda de archivos
Uso de la computadora
Intérprete de código
MCP
Generación de imágenes
Resúmenes de razonamiento
Ejemplos
Compara la API de Responses con la API para completar chats en situaciones concretas.
Mensajes y elementos
Ambas API permiten generar resultados con nuestros modelos. Tanto la entrada como el resultado de una llamada a Chat Completions consisten en un arreglo de mensajes, mientras que la API de Responses usa elementos. Un elemento es una unión de tipos que representan las distintas acciones que puede realizar el modelo. Un message es un tipo de elemento, al igual que function_call y function_call_output. Un mensaje de Chat Completions reúne varios aspectos de la interacción en un solo objeto. En cambio, los elementos se mantienen separados y representan mejor la unidad básica de contexto del modelo.
Además, Chat Completions puede devolver varios resultados generados en paralelo en choices si usas el parámetro n. La API de Responses omite este parámetro y devuelve un solo resultado.
API para completar chats
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from openai import OpenAIclient = OpenAI()completion = client.chat.completions.create(model="gpt-6-astra",messages=[ {"role": "user","content": "Write a one-sentence bedtime story about a unicorn.", } ],)print(completion.choices[0].message.content)
1
2
3
4
5
6
7
8
9
10
11
12
13require "openai"client = OpenAI::Client.newcompletion = client.chat.completions.create( model: "gpt-6-astra", messages: [ { role: :user, content: "Write a one-sentence bedtime story about a unicorn." } ])puts(completion.choices.fetch(0).message.content)
API de Responses
Python
1
2
3
4
5
6
7
8
9
10from openai import OpenAIclient = OpenAI()response = client.responses.create(model="gpt-6-astra",input="Write a one-sentence bedtime story about a unicorn.",)print(response.output_text)
1
2
3
4
5
6
7
8require "openai"client = OpenAI::Client.newresponse = client.responses.create( model: "gpt-6-astra", input: "Write a one-sentence bedtime story about a unicorn.")puts(response.output_text)
Los campos de la respuesta que devuelve la API de Responses son ligeramente distintos.
En lugar de un message, recibes un objeto response tipado con su propio id.
Responses almacena las respuestas de forma predeterminada. Chat Completions también las almacena de forma predeterminada en las cuentas nuevas.
Para desactivar el almacenamiento en cualquiera de las dos API, configura store: false.
Los objetos que devuelven estas API también difieren ligeramente. En Chat Completions, recibes un arreglo de choices, cada uno con un message. En Responses, recibes un arreglo de elementos llamado output.
Chat Completions API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19{"id": "chatcmpl-C9EDpkjH60VPPIB86j2zIhiR8kWiC","object": "chat.completion","created": 1756315657,"model": "gpt-5.5","choices": [ {"index": 0,"message": {"role": "assistant","content": "Under a blanket of starlight, a sleepy unicorn tiptoed through moonlit meadows, gathering dreams like dew to tuck beneath its silver mane until morning.","refusal": null,"annotations": [] },"finish_reason": "stop" } ],...}
Responses API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{"id": "resp_68af4030592c81938ec0a5fbab4a3e9f05438e46b5f69a3b","object": "response","created_at": 1756315696,"model": "gpt-5.5","output": [ {"id": "rs_68af4030baa48193b0b43b4c2a176a1a05438e46b5f69a3b","type": "reasoning","content": [],"summary": [] }, {"id": "msg_68af40337e58819392e935fb404414d005438e46b5f69a3b","type": "message","status": "completed","content": [ {"type": "output_text","annotations": [],"logprobs": [],"text": "Under a quilt of moonlight, a drowsy unicorn wandered through quiet meadows, brushing blossoms with her glowing horn so they sighed soft lullabies that carried every dreamer gently to sleep." } ],"role": "assistant" } ],...}
Otras diferencias
Responses almacena las respuestas de forma predeterminada. Chat Completions también las almacena de forma predeterminada en las cuentas nuevas. Para desactivar el almacenamiento en cualquiera de las dos API, configura store: false.
Los modelos de razonamiento ofrecen más posibilidades en la API de Responses gracias a un mejor uso de las herramientas. A partir de GPT-5.4, Chat Completions solo admite llamadas a herramientas cuando reasoning_effort tiene el valor none.
La estructura de la API para los resultados estructurados es distinta. En lugar de response_format, usa text.format en Responses. Consulta la guía de resultados estructurados para obtener más información.
La estructura de la API para la llamada a funciones también cambia, tanto en la configuración de las funciones que envías en la solicitud como en las llamadas que recibes en la respuesta. Consulta todas las diferencias en la guía de llamada a funciones.
El SDK de Responses ofrece la utilidad output_text, que no está disponible en el SDK de Chat Completions.
En Chat Completions, debes administrar manualmente el estado de la conversación. La API de Responses admite la API de Conversations para mantener conversaciones persistentes. También puedes pasar un previous_response_id para encadenar respuestas.
Migración desde Chat Completions
La migración implica tres cambios relacionados: enviar solicitudes a /v1/responses, leer la salida de un arreglo tipado output y decidir cómo mantendrá tu aplicación el estado entre turnos.
1. Actualiza los puntos de acceso de generación
Primero, cambia los puntos de acceso de generación de post /v1/chat/completions a post /v1/responses.
Si no usas funciones ni entradas multimodales, puedes usar los mismos mensajes de entrada de solo texto en ambas API:
2. Identifica los elementos que corresponden a cada mensaje
Chat Completions usa messages tanto para la entrada como para la salida. Responses usa los arreglos input y output, que contienen elementos tipados. Un message es un tipo de elemento. Otros tipos son reasoning, function_call y function_call_output.
Concepto de Chat Completions
Equivalente en Responses
messages[]
input, como cadena de texto o arreglo de elementos de entrada
Indicaciones del sistema o del desarrollador
El campo instructions de nivel superior o, si necesitas conservar una transcripción existente, elementos de mensaje compatibles
Mensaje del usuario
Un elemento de mensaje de entrada con role: "user"
Mensaje del asistente
Un elemento de mensaje de salida en response.output. Si administras el estado manualmente, vuelve a pasarlo en input
Llamada a una herramienta o función
Un elemento de salida de tipo function_call
Resultado de una herramienta o función
Un elemento de entrada de tipo function_call_output vinculado a la llamada mediante call_id
Varios resultados generados con n
Esta opción no está disponible en Responses. Si necesitas varias salidas candidatas, haz solicitudes por separado
Si solo necesitas el texto final, usa la utilidad output_text del SDK. Si tu flujo usa razonamiento, herramientas o salidas multimodales, recorre response.output y procesa cada elemento según su type.
3. Actualiza las conversaciones de varios turnos
Si tu aplicación admite conversaciones de varios turnos, actualiza la lógica que administra el contexto. Responses ofrece tres opciones habituales para administrar el estado:
Usa previous_response_id si quieres que OpenAI administre el contexto de las respuestas anteriores. Vuelve a enviar las instructions que deban mantenerse en cada solicitud, ya que previous_response_id no conserva las instructions de nivel superior de la respuesta anterior.
Vuelve a pasar los elementos de output de las respuestas anteriores en la siguiente solicitud si necesitas administrar o recortar el contexto por tu cuenta.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.chat.completions.ChatCompletionCreateParams;var params = ChatCompletionCreateParams.builder() .model("gpt-6-astra") .addSystemMessage("You are a helpful assistant.") .addUserMessage("What is the capital of France?") .build();var first = client.chat().completions().create(params);var second = client .chat() .completions() .create( params.toBuilder() .addAssistantMessage(first.choices().get(0).message().content().orElseThrow()) .addUserMessage("And its population?") .build());second.choices().stream() .flatMap(choice -> choice.message().content().stream()) .forEach(System.out::println);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18using OpenAI.Chat;string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;string model = "gpt-6-astra";ChatClient client = new(model, key);List<ChatMessage> messages =[ new SystemChatMessage("You are a helpful assistant."), new UserChatMessage("What is the capital of France?"),];ChatCompletion first = await client.CompleteChatAsync(messages);messages.Add(new AssistantChatMessage(first));messages.Add(new UserChatMessage("And its population?"));ChatCompletion second = await client.CompleteChatAsync(messages);Console.WriteLine(second.Content[0].Text);
En Responses, puedes pasar manualmente las salidas de una respuesta como
entrada de otra.
Conversación de varios turnos
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import { toResponseInputItems } from"openai/lib/responses/ResponseInputItems";let context = [{ role: "user", content: "What is the capital of France?" }];constres1=await client.responses.create({ model: "gpt-6-astra", input: context,});// Append the first response’s output to contextcontext = context.concat(toResponseInputItems(res1.output));// Add the next user messagecontext.push({ role: "user", content: "And its population?" });constres2=await client.responses.create({ model: "gpt-6-astra", input: context,});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16context = [{"role": "user", "content": "What is the capital of France?"}]res1 = client.responses.create( model="gpt-6-astra", input=context,)# Append the first response's output to contextcontext += res1.output# Add the next user messagecontext += [{"role": "user", "content": "And its population?"}]res2 = client.responses.create( model="gpt-6-astra", input=context,)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17using OpenAI.Responses;#pragma warning disable OPENAI001string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;ResponsesClient client = new(key);ResponseResult first = await client.CreateResponseAsync( "gpt-6-astra", "What is the capital of France?");ResponseResult second = await client.CreateResponseAsync( "gpt-6-astra", "And its population?", previousResponseId: first.Id);Console.WriteLine(second.GetOutputText());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18require "openai"client = OpenAI::Client.newfirst = client.responses.create( model: "gpt-6-astra", input: "What is the capital of France?", store: true)second = client.responses.create( model: "gpt-6-astra", previous_response_id: first.id, input: "And its population?", store: true)puts(second.output_text)
Aunque uses previous_response_id, la API factura como tokens de entrada todos los tokens de entrada de las respuestas anteriores de la cadena.
4. Decide cuándo almacenar el estado
Responses almacena las respuestas de forma predeterminada. Chat Completions también las almacena de forma predeterminada en las cuentas nuevas. Para desactivar el almacenamiento en cualquiera de las dos API, configura store: false.
Las políticas de cumplimiento o retención de datos impiden que algunas organizaciones, como las sujetas a requisitos de retención cero de datos (ZDR), usen la API de Responses con estado. Para estos casos, OpenAI ofrece elementos de razonamiento cifrados, que te permiten aprovechar el razonamiento y mantener un flujo de trabajo sin estado.
Para dejar de almacenar el estado y seguir usando el razonamiento:
Conserva y vuelve a enviar todos los elementos de razonamiento que recibas. Cuando creas una respuesta, cada elemento de razonamiento incluye encrypted_content de forma predeterminada.
La API devolverá una versión cifrada de los tokens de razonamiento, que podrás volver a enviar en solicitudes posteriores como cualquier otro elemento de razonamiento.
En las organizaciones con ZDR, OpenAI aplica store: false automáticamente. Si una solicitud incluye encrypted_content, OpenAI descifra ese contenido en memoria, lo usa para generar la siguiente respuesta y luego lo descarta de forma segura. OpenAI cifra de inmediato los nuevos tokens de razonamiento y te los devuelve sin guardar ningún estado intermedio.
5. Actualiza las definiciones y las salidas de las funciones
Hay dos diferencias en la forma en que Chat Completions y Responses definen las funciones:
En Chat Completions, la etiqueta de tipo se coloca fuera de la definición de la función. En Responses, se coloca dentro de la definición.
En Chat Completions, las funciones usan el modo no estricto de forma predeterminada. Si omites strict en Responses, la API intenta usar el modo estricto. Si no puede adaptar el esquema a ese modo, hace la llamada a funciones en modo no estricto, intenta ajustarse al esquema y devuelve la herramienta con la configuración resultante strict: false. Para conservar explícitamente el modo no estricto en Responses, configura strict: false.
El ejemplo de función de la API de Responses que aparece a la derecha es funcionalmente equivalente al ejemplo de Chat Completions de la izquierda.
Aplica las prácticas recomendadas para la llamada a funciones
En Responses, las llamadas a herramientas y sus salidas son dos tipos de elementos distintos que se vinculan mediante un call_id. Consulta la documentación sobre la llamada a funciones para obtener más información sobre cómo funciona en Responses.
6. Actualiza las definiciones de los resultados estructurados
En la API de Responses, las definiciones de los resultados estructurados pasaron de response_format a text.format:
7. Actualiza el código que procesa las transmisiones
En Chat Completions, las transmisiones devuelven fragmentos incrementales con un campo delta. En Responses, el servidor envía eventos tipados. Actualiza el código que procesa la transmisión para que distinga los eventos según su type y procese los que necesite tu interfaz o tu capa de orquestación.
Para recibir texto en una transmisión, escucha eventos como estos:
Si las herramientas nativas de OpenAI son útiles para algún caso de uso de tu aplicación, puedes actualizar las llamadas a herramientas para usar directamente las que ofrece OpenAI.
Chat Completions
En Chat Completions, no puedes usar de forma nativa las herramientas alojadas por OpenAI y debes escribir tu propia integración.
Este ejemplo usa GPT-5.6 Terra con el razonamiento desactivado. GPT-6 Astra y
GPT-6.1 Sol
requieren la API de Responses para llamar a herramientas.
Herramienta de búsqueda web
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25asyncfunctionweb_search(query) {constres=awaitfetch(`https://api.example.com/search?q=${query}`);constdata=await res.json();return data.results;}constcompletion=await client.chat.completions.create({ model: "gpt-5.6-terra", reasoning_effort: "none", messages: [ { role: "system", content: "You are a helpful assistant." }, { role: "user", content: "Who is the current president of France?" }, ], functions: [ { name: "web_search", description: "Search the web for information", parameters: { type: "object", properties: { query: { type: "string" } }, required: ["query"], }, }, ],});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27import requestsdef web_search(query): r = requests.get(f"https://api.example.com/search?q={query}") return r.json().get("results", [])completion = client.chat.completions.create( model="gpt-5.6-terra", reasoning_effort="none", messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Who is the current president of France?"}, ], functions=[ { "name": "web_search", "description": "Search the web for information", "parameters": { "type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], }, } ],)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34package mainimport ( "context" "fmt" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/shared")func main() { client := openai.NewClient() completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ Model: "gpt-5.6-terra", Messages: []openai.ChatCompletionMessageParamUnion{ openai.SystemMessage("You are a helpful assistant."), openai.UserMessage("Who is the current president of France?"), }, Functions: []openai.ChatCompletionNewParamsFunction{{ Name: "web_search", Description: openai.String("Search the web for information"), Parameters: map[string]any{ "type": "object", "properties": map[string]any{"query": map[string]any{"type": "string"}}, "required": []string{"query"}, }, }}, ReasoningEffort: shared.ReasoningEffortNone, }) if err != nil { panic(err) } fmt.Println(completion.Choices[0].Message)}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.core.JsonValue;import com.openai.models.FunctionParameters;import com.openai.models.ReasoningEffort;import com.openai.models.chat.completions.ChatCompletionCreateParams;import java.util.List;import java.util.Map;ChatCompletionCreateParams params = ChatCompletionCreateParams.builder() .model("gpt-5.6-terra") .reasoningEffort(ReasoningEffort.NONE) .addSystemMessage("You are a helpful assistant.") .addUserMessage("Who is the current president of France?") .addFunction( ChatCompletionCreateParams.Function.builder() .name("web_search") .description("Search the web for information") .parameters( FunctionParameters.builder() .putAdditionalProperty("type", JsonValue.from("object")) .putAdditionalProperty( "properties", JsonValue.from(Map.of("query", Map.of("type", "string")))) .putAdditionalProperty("required", JsonValue.from(List.of("query"))) .build()) .build()) .build();client.chat().completions().create(params).choices().stream() .map(choice -> choice.message()) .forEach(System.out::println);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31require "openai"client = OpenAI::Client.newcompletion = client.chat.completions.create( model: "gpt-5.6-terra", reasoning_effort: :none, messages: [ { role: :system, content: "You are a helpful assistant." }, { role: :user, content: "Who is the current president of France?" } ], functions: [ { name: "web_search", description: "Search the web for information", parameters: { type: "object", properties: { query: { type: "string" } }, required: ["query"] } } ])puts(completion.choices.fetch(0).message)
En Responses, puedes especificar qué herramientas quieres que use el modelo.
Herramienta de búsqueda web
JavaScript
1
2
3
4
5
6
7constanswer=await client.responses.create({ model: "gpt-6-astra", input: "Who is the current president of France?", tools: [{ type: "web_search" }],});console.log(answer.output_text);
1
2
3
4
5
6
7answer = client.responses.create( model="gpt-6-astra", input="Who is the current president of France?", tools=[{"type": "web_search"}],)print(answer.output_text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.responses.ResponseCreateParams;import com.openai.models.responses.WebSearchTool;ResponseCreateParams params = ResponseCreateParams.builder() .model("gpt-6-astra") .input("Who is the current president of France?") .addTool(WebSearchTool.builder().type(WebSearchTool.Type.WEB_SEARCH).build()) .build();client.responses().create(params).output().stream() .flatMap(item -> item.message().stream()) .flatMap(message -> message.content().stream()) .flatMap(content -> content.outputText().stream()) .forEach(text -> System.out.println(text.text()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14using OpenAI.Responses;#pragma warning disable OPENAI001string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;ResponsesClient client = new(key);CreateResponseOptions options = new() { Model = "gpt-6-astra" };options.Tools.Add(ResponseTool.CreateWebSearchTool());options.InputItems.Add( ResponseItem.CreateUserMessageItem("Who is the current president of France?"));ResponseResult response = await client.CreateResponseAsync(options);Console.WriteLine(response.GetOutputText());
1
2
3
4
5
6
7
8
9
10
11require "openai"client = OpenAI::Client.newresponse = client.responses.create( model: "gpt-6-astra", input: "Who is the current president of France?", tools: [{ type: :web_search }])puts(response.output_text)
1
2
3
4
5
6
7
8curl https://api.openai.com/v1/responses \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-6-astra", "input": "Who is the current president of France?", "tools": [{"type": "web_search"}] }'
9. Revisa los errores frecuentes de migración
Al migrar código de Chat Completions a Responses, revisa si se presentan estos problemas:
Leer choices[0].message.content en lugar de response.output_text o response.output.
Tratar cada entrada de output como un mensaje. El razonamiento, las llamadas a herramientas y las llamadas a funciones corresponden a tipos de elementos distintos.
Omitir elementos de razonamiento, de llamada a funciones o de salida de esas llamadas al pasar manualmente el contexto a la siguiente respuesta.
Enviar el resultado de una función sin el call_id correspondiente.
Usar response_format en una solicitud a Responses en lugar de text.format.
Reutilizar el código que procesa los fragmentos de transmisión de Chat Completions sin adaptarlo a los eventos tipados de Responses.
Suponer que al usar previous_response_id dejas de pagar por el contexto anterior. Los tokens de entrada anteriores de la cadena de respuestas se siguen facturando como tokens de entrada.
Lista de verificación para una migración gradual
Seguimos dando soporte a Chat Completions, así que puedes migrar un flujo de usuario a la vez.
Empieza con un flujo de generación de texto.
Actualiza el punto de acceso, el cuerpo de la solicitud y el código que procesa la salida.
Decide si el flujo usará previous_response_id, el reenvío manual de elementos o la API de Conversations.
Si el flujo funciona sin estado o está sujeto a ZDR, agrega store: false e incluye elementos de razonamiento cifrados cuando necesites conservar el contexto de razonamiento entre turnos.
Migra las definiciones de las funciones y verifica que las salidas de las llamadas incluyan el call_id correcto.
Traslada los esquemas de resultados estructurados de response_format a text.format.
Actualiza el código que procesa las transmisiones para que admita los eventos tipados de Responses.
Reemplaza la orquestación personalizada por herramientas alojadas por OpenAI cuando sean adecuadas para el flujo de trabajo.
Compara el comportamiento, la latencia, el uso de tokens y los errores antes de dirigir más tráfico a Responses.
Te recomendamos migrar gradualmente todos los flujos a la API de Responses para aprovechar las funciones y mejoras más recientes de OpenAI.
API de Assistants
A partir de los comentarios de los desarrolladores sobre la versión beta de la API de Assistants, incorporamos mejoras importantes en la API de Responses para que sea más flexible, más rápida y más fácil de usar. La API de Responses marca el rumbo para el desarrollo de agentes con OpenAI.
OpenAI retiró oficialmente la API de Assistants el 26 de agosto de 2026 y ya no está disponible. Sigue la guía de migración para actualizar tu integración y usar la API de Responses.