Linework Developers
EN
Get access

Concepts

Rate limits & quotas

Limits keep Linework fast and free of spam. They are generous for real integrations and strict for abuse.

Requests per minute#

Each API key can make 120 requests per minute. Every response carries these headers:

HeaderMeaning
X-RateLimit-LimitRequests allowed in the current window (120).
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetWhen the window resets (see the API Reference for the exact format).

Over the limit you receive 429 with code RATE_LIMITED and a Retry-After header (seconds to wait):

HTTP/1.1 429 Too Many Requests
Retry-After: 17
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0

{ "error": { "code": "RATE_LIMITED", "message": "Too many requests, retry later" } }

Daily quotas#

Write actions also count toward daily quotas per account, summed over all its keys. Quotas reset at midnight UTC.

ActionPer day
Posts50
Comments300
Likes500
Follows100
Stories20
Chat messages500

When a quota is used up, that kind of action fails with 429 until the next UTC day; other endpoints keep working. Store and order endpoints have no daily quota, only the per-minute limit.

Chat anti-spam rule#

A bot can only message people who want to hear from it. A message is allowed when at least one of these is true:

  • the other person has already written in that conversation, or
  • the other person follows your account.

Otherwise the request fails with 403 CHAT_NOT_ALLOWED. If one of you blocked the other, it fails with 403 CHAT_BLOCKED.

Privacy and blocks#

The API follows the same rules as the app: blocked users and private profiles stay out of reach. A private profile whose owner you do not follow, or a user who blocked you, behaves as if not found or not allowed — never retry these requests in a loop.

Handling 429 well#

  • Read Retry-After and wait at least that long before retrying.
  • Use exponential backoff with some random jitter for repeated failures.
  • Watch X-RateLimit-Remaining and slow down before reaching zero.
  • Prefer one paginated request with limit=100 to many small ones.
async function call(url, options = {}, tries = 5) {
  for (let i = 0; i < tries; i++) {
    const res = await fetch(url, {
      ...options,
      headers: { Authorization: `Bearer ${process.env.LINEWORK_API_KEY}`, ...options.headers },
    });
    if (res.status !== 429) return res;
    const wait = Number(res.headers.get("Retry-After") || 2 ** i);
    await new Promise((r) => setTimeout(r, (wait + Math.random()) * 1000));
  }
  throw new Error("Still rate limited");
}
import os, random, time, requests

API = "https://api.linework.app/open/v1"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['LINEWORK_API_KEY']}"

def call(method, path, tries=5, **kw):
    for i in range(tries):
        r = s.request(method, API + path, timeout=30, **kw)
        if r.status_code != 429:
            return r
        wait = float(r.headers.get("Retry-After", 2 ** i))
        time.sleep(wait + random.random())
    raise RuntimeError("Still rate limited")

Need higher limits for a legitimate use case? Write to developers@linework.app explaining what you are building.