Última atualização
Erros
Toda resposta fora da faixa 2xx é um envelope JSON com os mesmos quatro campos. Decida pelo code, mostre a message para pessoas, registre o requestId nos logs e só tente de novo quando retryable for true.
O envelope
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 estável e legível por máquina, em snake_case. Decida com base nele, nunca em message. |
message | string | Explicação legível por pessoas, em inglês. Pode ser mostrada a um operador; o texto pode mudar. |
requestId | string | UUID da requisição, gerado pelo servidor. Inclua-o ao falar com o suporte; é a única forma de encontrarmos a requisição nos nossos logs. |
retryable | boolean | true quando a mesma requisição pode dar certo mais tarde sem alterações (limites de requisição, falhas temporárias). Todo o resto exige uma requisição diferente. |
Os códigos de status continuam importando
O status HTTP é a classe geral (4xx é com você, 5xx é com a gente);
code é o motivo específico. Um cliente que olha só o status perde a diferença entre um escopo ausente e um plano sem o módulo (ambos 403).Tratamento de erros
O padrão abaixo é o que o próprio painel da RoomScope usa: interpretar o envelope, recorrer a http_error quando o corpo não é JSON e tentar de novo com backoff exponencial só quando o servidor marca o erro como retryable.
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 status
Os códigos são estáveis; novos podem ser adicionados, então trate um código desconhecido pelo seu status. Cada endpoint da referência lista os códigos que pode retornar.
| Status | Código | Quando | Pode repetir |
|---|---|---|---|
| 400 | validation_error | O corpo ou um parâmetro está malformado. A mensagem indica o campo. | não |
| 400 | invalid_rankings_input | Rankings: board ausente, um valor com mais de 128 caracteres, ou limit, leagueTier, period ou liveOnly inválido. | não |
| 400 | invalid_cursor · invalid_region · invalid_trend_type | Um cursor, uma região (duas letras nos insights) ou um tipo de tendência que o endpoint não aceita. | não |
| 400 | invalid_live_history_input · invalid_alert_input · invalid_dataset · invalid_format | Erros de entrada específicos do endpoint; a mensagem diz o que corrigir. | não |
| 401 | unauthorized | Chave ausente, malformada, desconhecida, revogada ou expirada, ou espaço de trabalho inativo. Enviado com WWW-Authenticate: Bearer. | não |
| 402 | credit_cap_exceeded | A requisição faria o gasto do período ultrapassar o limite de créditos. | não |
| 403 | insufficient_scope | A chave não tem o escopo, ou a rota é exclusiva do painel. | não |
| 403 | module_not_entitled | O plano do espaço de trabalho não inclui o módulo LIVE ou Consulta. | não |
| 403 | export_format_not_entitled | O plano não inclui esse formato de exportação. | não |
| 404 | not_found | Nenhuma rota corresponde ao método e ao caminho. | não |
| 404 | creator_not_found · video_not_found · live_session_not_found · alert_not_found · export_not_found | O recurso não existe ou pertence a outro espaço de trabalho. | não |
| 409 | export_not_ready · api_key_limit_reached | A exportação ainda está sendo gerada, ou o limite de chaves do plano foi atingido. | não |
| 429 | rate_limit_exceeded | A chave ultrapassou seu limite de requisições por segundo. Respeite o Retry-After. | sim |
| 429 | daily_quota_exceeded | A chave esgotou sua cota diária. O Retry-After conta até a meia-noite UTC. | sim |
| 503 | rate_limit_unavailable · metering_unavailable · webhook_unavailable | Uma dependência está fora do ar. Tente de novo com backoff. | sim |
| 500 | internal_error | Algo falhou do nosso lado. Tente de novo com backoff; inclua o requestId ao relatar o problema. | sim |
O que não é erro
- Uma
regiondesconhecida ou sem cobertura nos rankings não é um erro: a resposta é200compublishable: false, uma listaentriesvazia e umaprovenanceque explica o motivo. - Seguidos, seguidores e comentários que ainda estão sendo coletados respondem
202comstatus: "collecting", umjobIde um cabeçalhoRetry-After. Chame de novo depois desse número de segundos.
Os limites de requisição têm uma página própria: Limites de requisição.
Esta página foi útil?