Linework Developers
EN
Get access

Concepts

Errors

Errors use standard HTTP status codes and always have the same JSON shape.

Error format#

{
  "error": {
    "code": "INSUFFICIENT_SCOPE",
    "message": "This API key does not have the scope posts:write"
  }
}
  • code is stable: use it in your code.
  • message is for humans and may change.
  • Some errors add extra fields next to code and message (for example the invalid field of a validation error).

Error codes#

StatusCodeMeaning · what to do
400VALIDATION_ERRORA parameter or body field is missing or invalid. Fix the request; do not retry as is.
400INVALID_JSONThe body is not valid JSON. Send Content-Type: application/json and a valid body.
401INVALID_API_KEYMissing, malformed or revoked key. Check the Authorization header.
403INSUFFICIENT_SCOPEThe key lacks the scope this endpoint needs. Create a key with the right scopes.
403DEVELOPER_ACCESS_REVOKEDDeveloper access for this account was suspended or revoked. Contact developers@linework.app.
403PROFILE_INCOMPLETEAdd a profile photo and a cover to the account before using write endpoints.
403CHAT_NOT_ALLOWEDThe anti-spam rule does not allow this message: the person has not written to you and does not follow you.
403CHAT_BLOCKEDOne of you blocked the other. Do not retry.
403STORE_BLOCKEDThis store blocked you.
403USER_UNAVAILABLEThe user is not available (blocked, private or suspended).
403FORBIDDENThe action is not allowed for this account (for example editing somebody else's post).
404NOT_FOUNDThe resource does not exist or you cannot see it.
409CONFLICTThe request conflicts with the current state (for example shipping an order twice).
413PAYLOAD_TOO_LARGEThe body or the uploaded file is too large. See the media limits in Post with media.
429RATE_LIMITEDToo many requests, or a daily quota is used up. Wait for Retry-After. See Rate limits.
500INTERNAL_ERRORSomething went wrong on our side. Retry later with backoff.

New codes may be added over time: treat an unknown code with the generic meaning of its HTTP status.

Retry or not?#

StatusRetry?
400, 401, 403, 404, 409, 413No. Fix the request, the key or the account first.
429Yes, after Retry-After.
500, 502, 503, 504Yes, with exponential backoff. For writes that are not idempotent (for example POST /posts), check first that the action did not already happen.

Example handler#

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')}")