Conceptos
Errores
Los errores usan códigos de estado HTTP estándar y siempre tienen la misma forma JSON.
Formato de error#
{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "This API key does not have the scope posts:write"
}
}
codees estable: úsalo en tu código.messageestá pensado para personas y puede cambiar.- Algunos errores añaden campos adicionales junto a
codeymessage(por ejemplo, el campo no válido de un error de validación).
Códigos de error#
| Estado | Código | Significado · qué hacer |
|---|---|---|
| 400 | VALIDATION_ERROR | Falta un parámetro o un campo del cuerpo, o no es válido. Corrige la solicitud; no la reintentes tal cual. |
| 400 | INVALID_JSON | El cuerpo no es JSON válido. Envía Content-Type: application/json y un cuerpo válido. |
| 401 | INVALID_API_KEY | Clave ausente, con formato incorrecto o revocada. Revisa el header Authorization. |
| 403 | INSUFFICIENT_SCOPE | La clave no tiene el scope que necesita este endpoint. Crea una clave con los scopes adecuados. |
| 403 | DEVELOPER_ACCESS_REVOKED | El acceso de desarrollador de esta cuenta se ha suspendido o revocado. Escribe a developers@linework.app. |
| 403 | PROFILE_INCOMPLETE | Añade una foto de perfil y una portada a la cuenta antes de usar los endpoints de escritura. |
| 403 | CHAT_NOT_ALLOWED | La regla antispam no permite este mensaje: la persona no te ha escrito y no te sigue. |
| 403 | CHAT_BLOCKED | Uno de los dos ha bloqueado al otro. No reintentes. |
| 403 | STORE_BLOCKED | Esta tienda te ha bloqueado. |
| 403 | USER_UNAVAILABLE | El usuario no está disponible (bloqueado, privado o suspendido). |
| 403 | FORBIDDEN | La acción no está permitida para esta cuenta (por ejemplo, editar el post de otra persona). |
| 404 | NOT_FOUND | El recurso no existe o no puedes verlo. |
| 409 | CONFLICT | La solicitud entra en conflicto con el estado actual (por ejemplo, enviar un pedido dos veces). |
| 413 | PAYLOAD_TOO_LARGE | El cuerpo o el archivo subido es demasiado grande. Consulta los límites de contenido multimedia en Publicar con contenido multimedia. |
| 429 | RATE_LIMITED | Demasiadas solicitudes, o se ha agotado una cuota diaria. Espera lo indicado en Retry-After. Consulta Límites de solicitudes. |
| 500 | INTERNAL_ERROR | Algo ha fallado por nuestra parte. Reintenta más tarde con backoff. |
Con el tiempo pueden añadirse códigos nuevos: trata un código desconocido con el significado genérico de su estado HTTP.
¿Reintentar o no?#
| Estado | ¿Reintentar? |
|---|---|
| 400, 401, 403, 404, 409, 413 | No. Primero corrige la solicitud, la clave o la cuenta. |
| 429 | Sí, después de Retry-After. |
| 500, 502, 503, 504 | Sí, con backoff exponencial. En las escrituras que no son idempotentes (por ejemplo, POST /posts), comprueba primero que la acción no se haya realizado ya. |
Ejemplo de gestión de errores#
const res = await fetch(url, options);
if (!res.ok) {
const { error } = await res.json().catch(() => ({ error: { code: "UNKNOWN" } }));
switch (error.code) {
case "RATE_LIMITED": /* wait Retry-After, then retry */ break;
case "INVALID_API_KEY":
case "DEVELOPER_ACCESS_REVOKED": /* stop the bot and alert someone */ break;
case "CHAT_NOT_ALLOWED": /* skip this user */ break;
default: throw new Error(`${res.status} ${error.code}: ${error.message}`);
}
}
r = s.post(url, json=body, timeout=30) # s = requests.Session() with the Authorization header
if not r.ok:
err = r.json().get("error", {})
code = err.get("code")
if code == "RATE_LIMITED":
... # wait Retry-After, then retry
elif code in ("INVALID_API_KEY", "DEVELOPER_ACCESS_REVOKED"):
... # stop the bot and alert someone
elif code == "CHAT_NOT_ALLOWED":
... # skip this user
else:
raise RuntimeError(f"{r.status_code} {code}: {err.get('message')}")