Saltar al contenido principal

Errores

Cada fallo es un cuerpo JSON con un estado HTTP. Esta es la respuesta a una solicitud enviada sin clave:

{
"error": {
"message": "Missing API key. Send it as: Authorization: Bearer <your OceanToken key>.",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}

Bifurca según code. Es un vocabulario fijo que mantenemos estable; message es para personas y su redacción puede cambiar. type agrupa los códigos en familias que se tratan igual. El estado HTTP dice lo mismo con menos detalle, así que los clientes existentes que bifurcan según él siguen funcionando.

Códigos​

HTTPtypecodeQué pasóQué hacer
400invalid_request_errorinvalid_requestLa solicitud estaba mal formada: falta un campo, un valor que el modelo no acepta, una imagen dañada.Corrige la solicitud. No la reintentes tal cual.
400not_found_errormodel_not_foundEl nombre de model no existe.Elige un nombre de GET /v1/models.
400insufficient_creditsinsufficient_creditsSe agotaron tus créditos disponibles. No se ejecutó nada ni se cobró nada.Agrega créditos y vuelve a intentarlo.
400insufficient_creditskey_budget_exceededSe agotó el límite de créditos propio de esta clave (tu cuenta puede tener créditos todavía).Sube el límite de la clave, espera a que se reinicie o usa otra clave.
400insufficient_creditsrequest_exceeds_balanceTu saldo es mayor que $0, pero lo que queda después de lo reservado por tus solicitudes en curso es menor que lo máximo que podría costar esta solicitud. Ese peor caso es la entrada al precio completo de entrada más max_tokens de salida (limitado a la salida máxima del modelo; sin max_tokens, ese límite, como máximo 16,384 tokens), por n, más cualquier tarifa por solicitud o de búsqueda, al precio más alto que pueda cobrar cualquiera de los canales del modelo, incluidos los precios de contexto largo y de razonamiento. No se ejecutó nada ni se cobró nada.Baja max_tokens o acorta la entrada, o agrega créditos.
400content_policy_violationcontent_filteredUna verificación de seguridad rechazó la solicitud antes de ejecutar el modelo. Sin cargo.Cambia la entrada. Reintentar con la misma entrada da la misma respuesta.
401authentication_errorinvalid_api_keySin clave, una clave desconocida o una clave eliminada.Revisa el encabezado Authorization: Bearer sk-....
401authentication_errorkey_expiredLa fecha de vencimiento de la clave ya pasó.Crea una clave nueva.
403permission_errormodel_not_allowedLa clave es válida, pero este modelo está fuera del conjunto permitido de tu cuenta.Usa un modelo de GET /v1/models.
403permission_errorforbiddenLa clave no puede realizar esta operación. Administrar claves de API es una de ellas: una clave de API no puede crear, cambiar, rotar ni eliminar claves.Administra las claves en la consola; en otros casos, usa una clave con el alcance correcto.
404not_found_errornot_foundRuta desconocida, o un id de video / trabajo que no existe.Revisa la URL y el id.
409idempotency_erroridempotency_key_reusedEl Idempotency-Key ya se usó con un cuerpo distinto.Usa una clave nueva para una solicitud nueva. Consulta Reintentos.
409idempotency_erroridempotency_key_in_progressLa primera solicitud con esta clave todavía se está ejecutando.Espera Retry-After segundos y reintenta la misma solicitud.
429rate_limit_errorrate_limitedSuperaste el límite de solicitudes o tokens por minuto de tu clave.Espera hasta Retry-After; consulta Límites.
429rate_limit_errorprovider_overloadedTodos los canales del modelo están a plena capacidad en este momento. Consulta Reintentos y conmutación por error.Reintenta con espera progresiva o cambia de modelo.
501invalid_request_errornot_supportedEl endpoint no se ofrece: lotes (/v1/batches), ajuste fino (/v1/fine_tuning) y listar, leer o eliminar archivos en /v1/files.No reintentes. Envía cada solicitud a su endpoint habitual.
503api_errortemporarily_unavailableEl gateway no pudo comprobar en ese momento lo que necesita para aceptar la solicitud, como el saldo de tu organización. No se ejecutó nada ni se cobró nada.Reintenta después de Retry-After segundos.
5xxapi_errorprovider_errorEl modelo falló después de los reintentos y la conmutación por error del propio gateway. Sin cargo.Reintenta con espera progresiva; si persiste, cambia de modelo.
408api_errortimeoutUn stream no recibió nada del modelo durante 120 segundos después de empezar.Reintenta con espera progresiva.
504api_errortimeoutLa solicitud superó la ventana de 240 segundos.Usa streaming, acorta la solicitud o usa un endpoint asíncrono.

Todo lo que no está en esta tabla es un api_error. Pueden agregarse códigos nuevos; los existentes no se renombran ni se eliminan.

El ID de solicitud​

Las respuestas a solicitudes de modelos llevan el encabezado x-oceantoken-request-id. Regístralo junto con tus errores y cítalo cuando nos escribas. Una solicitud rechazada por su clave (401) nunca llegó a un modelo y no tiene ninguno.

Una respuesta correcta también tiene un id en su cuerpo, y cada fragmento de un stream lleva el mismo id. Ese es el Request ID que la consola muestra en Logs, con el estado, la latencia y el costo de la solicitud, y el id que consulta GET /v1/usage/{request_id}.

Reintentos​

Antes de que un error te llegue, el gateway ya lo reintentó y, si el modelo tiene otro canal, movió la solicitud allí. Reintentos y conmutación por error explica qué resuelve y qué te deja a ti.

Reintenta solo en estos casos: 429; cualquier 5xx excepto 501; un error timeout; un fallo de red (una conexión cortada, un tiempo límite del lado del cliente). Todo lo del rango 400, y 501 not_supported, fallará igual hasta que cambie la solicitud o la cuenta.

Usa espera exponencial con variación aleatoria, empezando en torno a un segundo y con un tope de unos treinta; cuando la respuesta trae Retry-After (un número de segundos), espera al menos ese tiempo. Retry-After solo está garantizado en 409 idempotency_key_in_progress; en un 429 o un 503 puede faltar, así que recurre a tu propia espera progresiva.

# Retry only what can succeed on a second try: 429, 408 (timeout), every 5xx
# except 501 (an endpoint that is not offered) and network failures,
# with exponential backoff and jitter, honouring Retry-After when it is sent.
import os
import random
import time

from openai import APIConnectionError, APIStatusError, OpenAI

client = OpenAI(
base_url=os.getenv("OCEANTOKEN_BASE_URL", "https://api.oceantoken.ai/v1"),
api_key=os.environ["OCEANTOKEN_API_KEY"],
max_retries=0, # the loop below does the retrying
)


def with_retries(call, attempts=5):
for attempt in range(attempts):
try:
return call()
except APIConnectionError:
if attempt == attempts - 1:
raise
delay = None # network failure: back off and try again
except APIStatusError as e:
retryable = e.status_code in (408, 429) or (e.status_code >= 500 and e.status_code != 501)
if not retryable or attempt == attempts - 1:
raise
retry_after = e.response.headers.get("retry-after")
delay = float(retry_after) if retry_after else None
time.sleep(delay if delay is not None else min(30, 2**attempt) + random.random())


models = with_retries(lambda: client.models.list())
print(len(models.data), "models")

Reintentar una solicitud que cuesta dinero​

Las solicitudes de imágenes, video y voz se cobran al ejecutarse. Un reintento tras un tiempo límite de red las ejecutaría por segunda vez. Envía un encabezado Idempotency-Key (cualquier cadena única, de hasta 255 caracteres, por ejemplo un UUID) en POST /v1/images/generations, /v1/images/edits, /v1/videos y /v1/audio/speech:

  • La primera solicitud se ejecuta con normalidad y su respuesta se guarda 24 horas.
  • Un reintento con la misma clave y el mismo cuerpo recibe esa respuesta, marcada con el encabezado Idempotency-Replayed: true. No se ejecuta nada ni se cobra nada.
  • La misma clave con un cuerpo distinto se rechaza con 409 idempotency_key_reused.
  • Un reintento mientras la primera solicitud sigue ejecutándose recibe 409 idempotency_key_in_progress con Retry-After.
  • Una respuesta 5xx no se guarda, así que un reintento tras un fallo del proveedor se vuelve a ejecutar.

Las claves se limitan a tu clave de API. El encabezado se ignora en los demás endpoints, y en los de arriba una solicitud sin él se comporta exactamente igual que antes. Las respuestas de más de 8 MB no se guardan; la solicitud se ejecuta igual, solo que no se aplica la repetición.

Errores durante el streaming​

Con "stream": true, un error que ocurre antes del primer token es una respuesta de error JSON normal con el estado de arriba. Un error después de empezar el stream llega como un último fragmento data: cuyo contenido es el mismo objeto error, y luego el stream termina.

Un stream que termina antes de tiempo, porque se cortó la conexión, te desconectaste o un error lo interrumpió, se cobra a los precios habituales del modelo por:

  • su prompt, completo;
  • la salida transmitida hasta ese momento. El razonamiento transmitido por un modelo de razonamiento cuenta como salida, aunque todavía no hubiera llegado texto de respuesta.

La salida que el modelo pudo seguir generando después de que se detuvo el stream no se cobra. Un stream que terminó antes de producir salida no se cobra en absoluto.

Saldo agotado​

Cuando tu saldo es de $0 o menos, toda solicitud a un modelo de pago se rechaza con 400 insufficient_credits. No se ejecuta nada ni se cobra nada. Agrega créditos y vuelve a intentarlo. Los modelos cuyo ID termina en :free siguen funcionando con un saldo de $0.

Cuando tu saldo es mayor que $0 pero menor que lo máximo que podría costar una solicitud, solo esa solicitud se rechaza con 400 request_exceeds_balance; las más pequeñas siguen ejecutándose. El mensaje indica cuánto podría costar la solicitud y cuál es tu saldo. Baja max_tokens o acorta la entrada para ejecutarla dentro de tu saldo, o agrega créditos.

Migrar desde OpenAI​

Los cuerpos de error tienen el mismo objeto error que los de OpenAI. Dos casos responden con un estado o código distinto:

CasoOpenAIOceanToken
Saldo agotado429 insufficient_quota400 insufficient_credits
Modelo desconocido404 model_not_found400 model_not_found

Los valores de code son todos nuestros; Códigos los lista. Algunos estados tienen un significado propio: un modelo a plena capacidad es 429 provider_overloaded (OpenAI responde 503), 408 timeout es un stream que se quedó en silencio, 409 es un conflicto de idempotencia y 501 not_supported es un endpoint que no ofrecemos. Si tu código interpreta 429 insufficient_quota como falta de dinero, busca en su lugar 400 insufficient_credits; no es un 429, así que un bucle de reintentos no gira sobre él. Un modelo desconocido es un 400, así que un manejador que espera un 404 no lo ve; bifurca según code y la comprobación funciona en ambos.

Política de contenido​

Las solicitudes que activan una verificación de seguridad se rechazan con 400 content_filtered. La verificación se hace antes de llamar al modelo, así que la solicitud no se cobra.

Encontrar una solicitud fallida​

Cada fallo queda registrado en la consola en Logs, con su estado y el cuerpo de la respuesta. Búscalo por hora y modelo, y cita su x-oceantoken-request-id cuando nos escribas.