Última actualización
Errores
Toda respuesta que no sea 2xx es un sobre JSON con los mismos cuatro campos. Ramifica según code, muestra message a las personas, registra requestId y reintenta solo cuando retryable es true.
El sobre
429 Too Many Requests
{ "code": "rate_limit_exceeded", "message": "API key rate limit exceeded.", "requestId": "3f2b6c1e-8a4d-4f0e-9b7a-2d5c1e6f8a90", "retryable": true}| Campo | Tipo | Significado |
|---|---|---|
code | string | Identificador estable y legible por máquinas en snake_case. Ramifica según este campo, nunca según message. |
message | string | Explicación legible para personas, en inglés. Se puede mostrar a un operador; la redacción puede cambiar. |
requestId | string | UUID de la solicitud, generado por el servidor. Inclúyelo cuando contactes a soporte; es la única forma de encontrar la solicitud en nuestros registros. |
retryable | boolean | true cuando la misma solicitud puede funcionar más tarde sin cambios (límites de solicitudes, fallas transitorias). Todo lo demás requiere una solicitud distinta. |
Los códigos de estado siguen importando
El estado HTTP es la categoría general (4xx es tuyo, 5xx es nuestro);
code es el motivo concreto. Un cliente que solo mira el estado no distingue entre un alcance que falta y un plan que no incluye el módulo (ambos son 403).Manejo de errores
El patrón de abajo es el mismo que usa el panel de RoomScope: analiza el sobre, recurre a http_error cuando el cuerpo no es JSON y reintenta con backoff exponencial solo cuando el servidor marca el error como reintentable.
class ApiError extends Error { constructor(status, { code, message, requestId, retryable }) { super(message); Object.assign(this, { status, code, requestId, retryable: Boolean(retryable) }); }} async function call(path, init) { const res = await fetch(`https://api.toktokdata.live${path}`, init); if (res.ok) return res.status === 204 ? undefined : res.json(); let envelope = {}; try { envelope = await res.json(); } catch {} throw new ApiError(res.status, { code: "http_error", message: `Request failed (${res.status})`, ...envelope });} // Retry only when the server says so.async function withRetry(fn, attempts = 3) { for (let i = 0; ; i++) { try { return await fn(); } catch (e) { if (!(e instanceof ApiError) || !e.retryable || i === attempts - 1) throw e; await new Promise((r) => setTimeout(r, 500 * 2 ** i)); } }}Códigos por estado
Los códigos son estables, pero se pueden agregar nuevos, así que trata un código desconocido según su estado. Cada endpoint de la referencia indica los códigos que puede devolver.
| Estado | Código | Cuándo | Reintentable |
|---|---|---|---|
| 400 | validation_error | El cuerpo o un parámetro está mal formado. El mensaje indica el campo. | no |
| 400 | invalid_rankings_input | Rankings: falta board, un valor supera los 128 caracteres, o limit, leagueTier, period o liveOnly no son válidos. | no |
| 400 | invalid_cursor · invalid_region · invalid_trend_type | Un cursor, una región (dos letras en insights) o un tipo de tendencia que el endpoint no acepta. | no |
| 400 | invalid_live_history_input · invalid_alert_input · invalid_dataset · invalid_format | Errores de entrada propios del endpoint; el mensaje indica qué corregir. | no |
| 401 | unauthorized | Clave ausente, mal formada, desconocida, revocada o vencida, o un espacio de trabajo inactivo. Se envía con WWW-Authenticate: Bearer. | no |
| 402 | credit_cap_exceeded | La solicitud haría que el gasto del periodo superara el tope de créditos. | no |
| 403 | insufficient_scope | La clave no tiene el alcance, o la ruta es exclusiva del panel. | no |
| 403 | module_not_entitled | El plan del espacio de trabajo no incluye el módulo LIVE o Búsqueda. | no |
| 403 | export_format_not_entitled | El plan no incluye ese formato de exportación. | no |
| 404 | not_found | Ningún endpoint coincide con el método y la ruta. | no |
| 404 | creator_not_found · video_not_found · live_session_not_found · alert_not_found · export_not_found | El recurso no existe o pertenece a otro espacio de trabajo. | no |
| 409 | export_not_ready · api_key_limit_reached | La exportación todavía se está generando, o se alcanzó el límite de claves del plan. | no |
| 429 | rate_limit_exceeded | La clave superó sus solicitudes por segundo. Respeta Retry-After. | sí |
| 429 | daily_quota_exceeded | La clave agotó su cuota diaria. Retry-After cuenta hasta la medianoche UTC. | sí |
| 503 | rate_limit_unavailable · metering_unavailable · webhook_unavailable | Una dependencia no está disponible. Reintenta con backoff. | sí |
| 500 | internal_error | Algo falló de nuestro lado. Reintenta con backoff; incluye el requestId cuando lo reportes. | sí |
Lo que no son errores
- Una
regiondesconocida o sin cobertura en rankings no es un error: la respuesta es200conpublishable: false, una listaentriesvacía y unprovenanceque explica el motivo. - Los seguidos, seguidores y comentarios que se están recolectando responden
202constatus: "collecting", unjobIdy un encabezadoRetry-After. Vuelve a llamar después de esa cantidad de segundos.
Los límites de solicitudes tienen su propia página: Límites de solicitudes.
¿Te resultó útil esta página?