spicyapiDocumentación
Referencia
Contenido principal

Errores

Consulta cada código de negocio, su estado HTTP, cómo resolverlo y cuándo conviene reintentar.

Cuando una llamada falla, la respuesta indica dos cosas: un número (code) que identifica el tipo de problema y una frase (msg) para que una persona la lea. Esta página enumera los números, sus significados y si reintentar puede ayudar. Si solo necesitas resolver un síntoma rápidamente, empieza por Solución de problemas.

Formato de la respuesta

Las respuestas JSON de la API nativa de tareas utilizan este formato: los mismos cuatro campos alrededor de cada respuesta. Interpreta las respuestas compatibles de /v1 y SSE según sus propios protocolos:

{ "code": 200, "msg": "success", "data": { }, "request_id": "req_…" }
  • code es un código de negocio, no un estado HTTP. 200 significa éxito.
  • En caso de fallo, data no aparece, en lugar de ser null: recibes code, msg y request_id. La única excepción: algunos fallos de la biblioteca de recursos añaden data.reason.
  • msg es para personas: su redacción y su idioma pueden cambiar (véase más abajo). Nunca bases una condición en ese texto; usa code.
  • request_id también se devuelve en el encabezado X-Request-Id. Indícalo al informar de un problema.

El estado HTTP también se establece correctamente. Puedes basar las condiciones en cualquiera de los dos, pero solo en uno: sus valores difieren para códigos concretos, como saldo insuficiente, que es code: 40201 con HTTP 402. Mezclarlos acabará dejando algún caso sin cubrir.

Recomendamos utilizar code. 404 solo puede indicar «no encontrado»; 40201 indica que el saldo disponible es insuficiente.

No todas las respuestas son JSON

Una respuesta que no se puede interpretar como JSON, por ejemplo una página de texto o HTML de nuestra red de borde, no tiene code. Trátala según su estado HTTP, registra el inicio del cuerpo y no reintentes un 403 a ciegas: podría ser un bloqueo regional que ningún reintento cambiará.

Idioma de los mensajes de error

El texto de error para personas puede llegar en el idioma que elijas. El predeterminado es inglés. Solo estos tres lugares siguen esa elección:

  • msg en el formato de respuesta;
  • errorMessage de una tarea fallida, tanto en recordInfo como en callbacks de webhook, con una excepción indicada a continuación;
  • error.message en los objetos de error de endpoints compatibles, tanto con el formato de OpenAI o Anthropic como con el de Google Gemini (/v1beta).

Códigos de idioma admitidos: en, ja, ko, de, fr, es, pt-BR, ru, it, pl.

La excepción: si el propio modelo proporcionó un motivo concreto de fallo, como una imagen de referencia que no pudo leer o una restricción de derechos de autor sobre audio generado, errorMessage incluye ese motivo en inglés, sin detalles internos como nombres de servicios, hosts, URL e ID de solicitudes, para que veas qué falló realmente. Los motivos sobre el estado de cuenta o facturación nunca se transmiten; recibes nuestro mensaje. Content-Language sigue describiendo msg, y errorCode siempre es el valor que debes usar para las condiciones.

Elegir el idioma

Se utiliza la primera opción aplicable:

  1. El encabezado de solicitud Accept-Language, solo para esa solicitud. Se aplica la ponderación HTTP estándar: elegimos el idioma reconocido con el mayor valor q. Las variantes regionales se asignan a su idioma: de-DE cuenta como de y pt-PT como pt-BR. No se ofrece chino, por lo que sus etiquetas no coinciden con ningún idioma y se prueba el siguiente candidato. * significa sin preferencia.
  2. El ajuste de tu cuenta, en Configuración → Idioma de errores de API de la consola. Abarca todas las solicitudes con una clave de esa cuenta que no incluyan un Accept-Language reconocible. La mayoría de los SDK de servidor y curl no envían ese encabezado de forma predeterminada, por lo que es la opción usada por la mayoría de las integraciones. Los callbacks de webhook no tienen un encabezado de solicitud para elegir el idioma y siempre siguen el ajuste de cuenta.
  3. En los demás casos, inglés.

Las respuestas de error incluyen un encabezado Content-Language con el idioma en el que se escribió realmente el mensaje.

Solo cambia el texto para personas

code, errorCode, los campos type y code compatibles con OpenAI, los campos code y status compatibles con Gemini y todos los nombres de campos permanecen iguales en cualquier idioma. Basa las condiciones en códigos y nunca interpretes la redacción; registra code y request_id en logs y alertas.

Ejemplo

El mismo 40201, saldo insuficiente, llega en inglés de forma predeterminada:

Default
HTTP/1.1 402 Payment Required
Content-Language: en

{ "code": 40201, "msg": "Insufficient balance", "request_id": "req_…" }

Añade un encabezado Accept-Language: ja; el resto es la misma llamada de creación de tarea de la guía de inicio:

curl -X POST https://api.spicyapi.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
  -H "Accept-Language: ja" \
  --data "$TASK_PAYLOAD"

Ahora msg está en japonés; code sigue siendo 40201:

Accept-Language: ja
HTTP/1.1 402 Payment Required
Content-Language: ja

{ "code": 40201, "msg": "残高が不足しています", "request_id": "req_…" }

Códigos generales

codeHTTPSignificado¿Reintentar?
200200Éxito—
400400Solicitud mal formada o parámetros no válidosNo. Corrige y vuelve a enviar
40003400El tamaño, tipo o contenido de un archivo subido no coincide con lo declarado al solicitar la URL de subidaNo. Solicita una URL nueva con el contentType y tamaño correctos, vuelve a subir y confirma
40004400La solicitud es válida, pero este modelo no puede servir esa combinación de ajustes en este momentoNo. Cambia el ajuste indicado en msg, como resolución o relación de aspecto, o elige otro modelo. Véase más abajo
401401Falló la autenticación; msg indica cuál de tres casosNo. Corrige el encabezado o la clave
403403No permitido. En una llamada con clave válida, la cuenta está restringida; véase más abajo. Un correo no verificado devuelve 40310No
404404No existe o no te perteneceNo
409409Conflicto con el estado actualA veces; véase más abajo
40901409La cotización venció, cambió la solicitud o cambió el precioCotiza y confirma otra vez; recupera las solicitudes aceptadas con la clave de idempotencia original
413413El cuerpo supera el tamaño máximo que acepta el servidorNo. Reduce el cuerpo o sube los medios mediante el flujo de archivos
429429Demasiadas solicitudesNormalmente sí. Espera según Retry-After. Uno de los casos 429 no tiene que ver con la velocidad; consulta Límites de solicitudes
500500Algo falló de nuestro ladoSí. Espera y reintenta
503503Un servicio auxiliar, como cotizaciones, almacenamiento de imágenes en línea o subidas, no está disponible temporalmenteSí. Espera lo indicado en Retry-After, si aparece, y reintenta; en createTask, con el mismo Idempotency-Key. Si persiste sin Retry-After, sigue msg, por ejemplo usa una URL HTTPS pública en lugar de una imagen en línea

503 y 50301 comparten estado HTTP, pero son códigos de negocio distintos: 503 se refiere a un servicio auxiliar y 50301 al propio modelo.

Distinguir los tres casos de 401

Tres errores distintos de autenticación devuelven 401 y se resuelven de formas diferentes. El code permanece en 401 en todos; msg permite distinguirlos.

msg en inglésQué ocurrió realmenteQué cambiar
Missing credentials: send your API key in the Authorization header as "Bearer sk-spicy-..." (en endpoints compatibles /v1 y /v1beta: …as "Authorization: Bearer sk-spicy-...", x-api-key, or x-goog-api-key)La solicitud llegó sin ninguna credencialTu cliente está omitiendo el encabezado. Comprueba el interceptor, el proxy y si la variable de entorno se cargó en el proceso en ejecución
API key format is not recognized: keys begin with sk-spicy-Llegó una credencial, pero no es nuestraPegaste un valor de sesión de consola o la clave de otro proveedor. Las claves de SpicyAPI empiezan por sk-spicy-; echo "${SPICY_API_KEY:0:9}" debe mostrar exactamente ese prefijo
Credentials are invalid or expiredLa clave tiene nuestro formato, pero no existe, fue revocada o vencióComprueba la clave en la página de claves de API; si está revocada o vencida, crea otra. Reintentar nunca convertirá la respuesta en un 200

El caso intermedio se decide sin consultar la base de datos; por eso puede indicar algo que el tercero no: esa cadena nunca pudo funcionar. El tercer mensaje es deliberadamente idéntico para una clave inexistente, revocada o vencida, de modo que no permite investigar qué claves existen.

Aquí se muestran las cadenas en inglés; msg sigue la selección de idioma anterior y su redacción no es un contrato. Basa las condiciones en code y trata el mensaje como algo que lees, muestras o registras, no como un patrón que debes comparar.

La cuenta no puede llamar a la API

La clave es válida en ambos casos siguientes; es la cuenta la que todavía no puede llamar a la API.

40310 significa que no se ha verificado el correo. El mensaje es Verify your account email to run models and call the API…:

  1. Abre la consola. Un aviso superior indica que el correo no está verificado y permite enviar de nuevo el mensaje de verificación.
  2. Sigue el enlace del correo de verificación; revisa también la carpeta de spam.
  3. Reintenta la misma llamada. No hace falta una clave nueva.

La consola sigue funcionando mientras la API está bloqueada, así que todavía puedes consultar tu historial.

Un 403 simple con This account cannot call the API right now indica que la cuenta está restringida. Contacta con soporte e incluye el request_id.

Saldo y límites de gasto

codeHTTPSignificadoQué hacer
40201402El saldo no cubre el costo estimadoAñade fondos en Facturación dentro de la consola; consulta Configuración de la cuenta. Comprueba GET /api/v1/chat/credit
40202402Se alcanzó un límite de gastoLee msg para identificarlo. Límite de clave (This key has reached its …): auméntalo en claves de API o espera al reinicio. Límite de equipo (Workspace … budget has been reached): pide a un propietario, administrador o responsable de presupuesto que lo aumente en la página del equipo. Límite de plataforma (Platform quota for today is exhausted…): no puedes cambiarlo; reintenta después de las 00:00 UTC. Los diarios se reinician a las 00:00 UTC y los mensuales el día 1 a las 00:00 UTC; el total nunca se reinicia

Ninguno se resuelve reintentando: los saldos y límites no cambian porque vuelvas a preguntar. Consulta Límites de gasto.

Permisos

codeHTTPSignificadoQué hacer
40301403Esta clave no puede llamar a este modeloAmplía la lista de modelos permitidos de la clave en la consola
40302403La dirección de origen no está en la lista de IP permitidas de la claveAñádela o elimina la restricción de IP de esa clave
40303403El servicio no se ofrece en esta regiónNo se puede eludir. Consulta dónde operamos
40310403El correo de la cuenta todavía no está verificado y no puede ejecutar modelosAbre el enlace de verificación del correo de registro o envía otro desde la consola. La clave funciona en cuanto se verifica la dirección, sin cambios de tu lado

Ninguno de estos errores se resuelve reintentando.

Códigos de motivo de la biblioteca de recursos

Los fallos en los endpoints de la biblioteca de recursos (/api/v1/assets…) pueden añadir al envoltorio habitual un campo legible por máquina, data.reason:

{ "code": 400, "msg": "…", "data": { "reason": "asset_library_locked" }, "request_id": "req_…" }

code, el estado HTTP, msg y el errorCode de la tarea son los mismos con o sin motivo, así que tu gestión actual sigue funcionando. El motivo aparece solo en los endpoints de la biblioteca de recursos, nunca en otros endpoints nativos, y la capa compatible con OpenAI y las demás capas de compatibilidad conservan sus propias formas de error. La lista puede crecer: trata un valor desconocido como un motivo ausente.

data.reasonHTTPSignificadoQué hacer
asset_library_locked400La biblioteca de recursos se abre con la primera recargaRecarga. Los recursos ya guardados siguen siendo utilizables
asset_library_full400La cuota de almacenamiento (elementos o bytes) está llenaElimina recursos o sube de plan; GET /api/v1/assets/usage muestra el siguiente
asset_file_too_large400El archivo supera el límite por archivo del planUsa un archivo más pequeño o sube de plan
asset_daily_limit429Se alcanzó el número diario de recursos nuevosEspera hasta las 00:00 UTC y respeta Retry-After
asset_storage_full503El almacenamiento de toda la plataforma está llenoVuelve a intentarlo más tarde
asset_permission_denied403Tu rol en el equipo no permite este cambioPide a un propietario o administrador del equipo, o usa una clave cuyo creador tenga un rol que lo permita
asset_workspace_forbidden403Esta clave no llega a esa biblioteca, por ejemplo porque el miembro que creó la clave de equipo ha salido del equipoCrea una clave nueva en el espacio de trabajo que necesites
asset_entity_name_taken409La biblioteca ya tiene un personaje con ese nombre (sin distinguir mayúsculas). Los personajes se nombran en la página Assets de la web, así que la API de solo lectura, por ahora, no lo devuelveElige otro nombre

Disponibilidad de los modelos

codeHTTPSignificado¿Reintentar?
50301503El modelo no está disponible en este momentoSí. Reintenta más tarde o elige otro modelo
50302503Una solicitud de texto, con o sin streaming, falló en el modelo antes de entregar una respuesta; se devolvió la retenciónSí. Vuelve a enviar con un Idempotency-Key nuevo
40004400El modelo está funcionando, pero no con estos ajustesNo. Cambia el ajuste indicado en msg

50301 significa que el modelo no pudo aceptar la tarea al enviarla: no está publicado, no tiene precios activos o no tiene capacidad de generación disponible. Los problemas temporales de capacidad pueden resolverse con reintentos limitados. Un modelo no disponible o un precio activo ausente no se arreglan repitiendo solicitudes. Actualiza el catálogo y pide confirmación al usuario antes de cambiar de modelo.

40004 y 50301 son deliberadamente distintos. 50301 significa que el modelo no puede aceptar ninguna tarea en este momento; esperar podría ayudar. 40004 significa que funciona, pero no puede servir esta combinación de ajustes; msg indica el ajuste entre paréntesis, por ejemplo This model cannot serve this parameter combination right now (…). Esperar no ayudará; cambiar un valor sí. Ninguno crea una tarea ni retiene dinero.

Los fallos de generación posteriores a la aceptación aparecen como state: failed

Un fallo de generación después de que createTask devuelva un ID aparece en recordInfo como state: "failed" con errorCode / errorMessage; normalmente se libera toda la retención, salvo determinados rechazos de contenido que la página del modelo indique expresamente como cobrables. La misma situación que 40004, descubierta solo después de aceptar, aparece como errorCode: "unsupported_combination". No añadas condiciones para códigos de negocio síncronos que no figuren en esta página.

Códigos de fallo de tareas

Un fallo posterior a la aceptación aparece en errorCode de recordInfo. El conjunto es cerrado: aquí nunca aparecen diagnósticos internos, por lo que debes tratar cualquier valor fuera de la lista como upstream_failed.

errorCodeSignificado¿Reintentar?
invalid_requestNo se aceptaron los parámetrosNo. Corrígelos y vuelve a enviar
unsupported_combinationLa combinación no se admite en este momentoNo. Elige otros ajustes
content_rejectedEl modelo seleccionado rechazó el contenido. La propia SpicyAPI no revisa las solicitudes; consulta Contenido y responsabilidad de usoNo. Cambia el prompt o elige otro modelo
rate_limitedEl servicio de generación estaba ocupadoSí. Espera y reintenta
upstream_unavailableLa generación no está disponible temporalmenteSí. Reintenta en un momento
invalid_assetUn archivo de referencia ya no está disponibleNo mediante un reintento. retry reutiliza la entrada original; vuelve a subir el archivo y crea una tarea con la URI nueva
generation_failedLa generación comenzó y no produjo nadaTal vez. Las mismas entradas normalmente fallarán del mismo modo
timeoutLa tarea llegó a su plazo límite sin terminarTal vez. Prueba una duración más corta o una resolución menor
upstream_failedCategoría general para cualquier otro falloSí. Espera y reintenta

Las tareas fallidas o vencidas normalmente liberan toda la retención. Algunos rechazos de contenido se cobran al precio aceptado únicamente si la página del modelo informa expresamente de esa excepción. Consulta settled y cost para conocer el cargo final. errorMessage es para personas: explica el motivo, puede citar en inglés la explicación del modelo (véase arriba) y su redacción cambia; basa las condiciones solo en errorCode. Aquí «reintentar» significa enviar una tarea nueva, que se cobra de nuevo si termina correctamente.

Qué errores cuestan dinero

El estado de la tarea y el de la conexión son hechos diferentes.

Las creaciones rechazadas expresamente, las tareas vencidas y los registros históricos cancelados no tienen cargo de generación. Las fallidas normalmente son gratuitas, salvo determinados rechazos de contenido que la página del modelo indique expresamente como cobrables. Un tiempo de espera agotado o una desconexión del cliente no es un fallo de tarea. Las tareas aceptadas no pueden cancelarse: recupera la original y revisa su estado final y liquidación. Un stream de texto desconectado puede cobrarse si ya se registró un uso válido.

Situación¿Se cobra?
La API rechaza expresamente createTask sin crear una tarea, por ejemplo 40201, 40202, 40004 o 50301No. La creación y la retención comparten una transacción; un error del gateway o la falta de respuesta no demuestra un rechazo
El envío agota el tiempo, se cierra una pestaña o se pierde la conexiónTodavía no se sabe. Recupera la aceptación con la clave de idempotencia original; no lo trates como un reintento gratuito
createTask devuelve 202 y la tarea termina en failed / expiredNormalmente no se cobra. Ciertos resultados failed / content_rejected se cobran al precio aceptado si la página del modelo lo indica expresamente. Lee settled y cost
Una tarea histórica está en canceledNo. Es un estado de compatibilidad, no una acción actualmente disponible
createTask devuelve 202 y la tarea termina en succeededSí, se liquida el uso real con el límite de la retención aceptada. Los fondos no utilizados se liberan; no se cobra después nada por encima de esa retención
Cualquier error de recordInfo, chat/credit o common/*No. Esos endpoints nunca se cobran
Limitación de solicitudes (429) o deduplicación mediante clave de idempotenciaNo. El primero nunca se aceptó; el segundo devuelve la tarea original, cobrada una vez

La liquidación o liberación se completa automáticamente, incluso tras interrumpirse un proceso. Los fallos ordinarios liberan toda la retención; determinados rechazos de contenido indicados expresamente en la página del modelo se cobran al precio aceptado. Consulta la liquidación y el saldo para verificar el resultado; véase Facturación.

Cuándo conviene reintentar un 409

Caso¿Reintentar?
Conflicto concurrente poco frecuente de createTask con la misma clave y el mismo contenidoSí. Espera unos cientos de milisegundos y reintenta con la misma clave. Consulta Idempotencia
La misma clave ya se utilizó con otro contenido o clave de APINo. Detente y corrige a qué solicitud pertenece la clave; reintentar no cambia el conflicto
Se siguen procesando imágenes en línea o la confirmación de una subida; puede aparecer Retry-AfterSí. Espera según Retry-After o un par de segundos y vuelve a enviar con el mismo Idempotency-Key
Cambiaron los precios o la configuración de tu cuenta durante la solicitudSí. Cotiza de nuevo si usas cotizaciones y vuelve a enviar
El archivo generado sigue copiándoseSí. Espera unos segundos y solicita de nuevo el enlace de descarga
jobs/retry sobre una tarea que no terminó o no se liquidóSí, más tarde. Espera a que la tarea de origen alcance un estado final y settled sea true; después reintenta
jobs/retry sobre una tarea correcta o cuya entrada ya se eliminó por retenciónNo. Crea una tarea nueva con createTask
Venció una URL de subida o un archivo subidoNo. Vuelve a subir el archivo

Implementar los reintentos

No reintentes a ciegas

400, 401, 40004, 40201 y otros errores similares de entrada o autorización devuelven lo mismo por muchos reintentos que hagas. Cada intento marcado «No» es un desperdicio y consume tu propio límite de solicitudes.

Usa espera exponencial con variación aleatoria para que un lote de fallos no vuelva a intentarlo al mismo instante:

JavaScript
// 409 is operation-specific and must be handled at the call site.
const RETRYABLE = new Set([429, 500, 503, 50301]);

async function callWithRetry(path, init, { attempts = 4 } = {}) {
  for (let i = 0; i < attempts; i++) {
    const res = await fetch(`https://api.spicyapi.ai/api/v1${path}`, init);

    // A page from the edge network is not our JSON envelope
    if (!res.headers.get('content-type')?.includes('json')) {
      const text = await res.text();
      throw new Error(`HTTP ${res.status}, not JSON: ${text.slice(0, 200)}`);
    }
    const body = await res.json();

    if (body.code === 200) return body.data;
    if (!RETRYABLE.has(body.code)) {
      throw new Error(`${body.code} ${body.msg} (request_id=${body.request_id})`);
    }

    // When the server says how long to wait, trust it
    const retryAfter = Number(res.headers.get('retry-after'));
    const backoff = Number.isFinite(retryAfter) && retryAfter > 0
      ? retryAfter * 1000
      : 2 ** i * 1000 + Math.random() * 500;

    await new Promise((r) => setTimeout(r, backoff));
  }
  throw new Error('out of retries');
}
Python
import random, time, requests

# 409 is operation-specific and must be handled at the call site.
RETRYABLE = {429, 500, 503, 50301}
BASE = "https://api.spicyapi.ai/api/v1"


def call_with_retry(method: str, path: str, attempts: int = 4, **kwargs) -> dict:
    for i in range(attempts):
        res = requests.request(method, f"{BASE}{path}", **kwargs)

        # A page from the edge network is not our JSON envelope
        try:
            body = res.json()
        except ValueError:
            raise RuntimeError(f"HTTP {res.status_code}, not JSON: {res.text[:200]}")

        if body["code"] == 200:
            return body["data"]
        if body["code"] not in RETRYABLE:
            raise RuntimeError(f'{body["code"]} {body["msg"]} (request_id={body.get("request_id")})')

        # When the server says how long to wait, trust it
        retry_after = res.headers.get("retry-after")
        backoff = float(retry_after) if retry_after else 2**i + random.random() * 0.5
        time.sleep(backoff)

    raise RuntimeError("out of retries")
Go
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

// retryable lists the codes worth another attempt. Anything else returns
// the same answer however many times you ask — and each ask eats your own
// rate limit.
// Whether the generation itself failed is read from recordInfo's state.
var retryable = map[int]bool{429: true, 500: true, 503: true, 50301: true}

type envelope struct {
	Code      int             `json:"code"`
	Msg       string          `json:"msg"`
	Data      json.RawMessage `json:"data"`
	RequestID string          `json:"request_id"`
}

func callWithRetry(newReq func() (*http.Request, error), attempts int, out any) error {
	for i := 0; i < attempts; i++ {
		req, err := newReq()
		if err != nil {
			return err
		}
		res, err := http.DefaultClient.Do(req)
		if err != nil {
			// Transport-level failure: the request may well have arrived.
			// On createTask, send the same Idempotency-Key or this retry
			// turns into a second generation and a second charge.
			time.Sleep(backoff(i, ""))
			continue
		}

		var env envelope
		decErr := json.NewDecoder(res.Body).Decode(&env)
		io.Copy(io.Discard, res.Body)
		res.Body.Close()
		if decErr != nil {
			// Not our JSON envelope, for example a page from the edge network.
			return fmt.Errorf("HTTP %d, response is not JSON: %w", res.StatusCode, decErr)
		}

		if env.Code == 200 {
			return json.Unmarshal(env.Data, out)
		}
		if !retryable[env.Code] {
			return fmt.Errorf("%d %s (request_id=%s)", env.Code, env.Msg, env.RequestID)
		}
		// When the server says how long to wait, trust it
		time.Sleep(backoff(i, res.Header.Get("Retry-After")))
	}
	return fmt.Errorf("out of retries")
}

// backoff trusts Retry-After when present, otherwise backs off
// exponentially with jitter so a batch of failures does not come back
// as one thundering herd.
func backoff(attempt int, retryAfter string) time.Duration {
	if s, err := strconv.Atoi(retryAfter); err == nil && s > 0 {
		return time.Duration(s) * time.Second
	}
	base := time.Duration(1<<attempt) * time.Second
	return base + time.Duration(rand.Intn(500))*time.Millisecond
}

Al reintentar createTask, envía siempre el mismo Idempotency-Key; de lo contrario, «la tarea sí tuvo éxito, solo perdimos la respuesta» se convierte en una generación duplicada y un cargo duplicado.

Depuración

Si un error no tiene sentido, sigue esta lista:

  1. request_id: con él podemos encontrar la solicitud exacta.
  2. code: consulta las tablas anteriores.
  3. Logs de la consola: pega el ID de tarea o request_id en el buscador de Logs para abrirla y ver estado, costo, latencia, clave que la envió, código de error y motivo. Los parámetros y resultados solo se muestran mientras se conservan y, dentro de un equipo, solo a roles autorizados a leer contenido.

El msg de 500 siempre es un mensaje genérico de «servicio temporalmente no disponible», sin detalles internos: nunca aparecen estructuras internas, nombres de componentes ni trazas de pila en una respuesta. Solo se pueden investigar con request_id.

Para contactarnos, abre una conversación en Soporte dentro de la consola o escribe a support@spicyapi.ai. Incluye el request_id o ID de tarea, la hora en UTC y el code. Nunca envíes una clave de API.

En esta página