Концепции
Ограничения частоты и квоты
Ограничения сохраняют Linework быстрым и свободным от спама. Они щедры для реальных интеграций и строги к злоупотреблениям.
Запросы в минуту#
Каждый ключ API может выполнять 120 запросов в минуту. Каждый ответ содержит следующие заголовки:
| Заголовок | Значение |
|---|---|
X-RateLimit-Limit | Количество запросов, разрешённых в текущем окне (120). |
X-RateLimit-Remaining | Количество запросов, оставшихся в текущем окне. |
X-RateLimit-Reset | Момент сброса окна (точный формат см. в справочнике API). |
При превышении лимита вы получаете 429 с кодом RATE_LIMITED и заголовком Retry-After (сколько секунд нужно подождать):
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" } }
Дневные квоты#
Действия записи также учитываются в дневных квотах на аккаунт, суммарно по всем его ключам. Квоты сбрасываются в полночь по UTC.
| Действие | В день |
|---|---|
| Посты | 50 |
| Комментарии | 300 |
| Лайки | 500 |
| Подписки | 100 |
| Истории | 20 |
| Сообщения в чате | 500 |
Когда квота исчерпана, действия этого типа завершаются ошибкой 429 до следующих суток по UTC; остальные endpoint продолжают работать. У endpoint магазина и заказов нет дневной квоты, только поминутное ограничение.
Правило антиспама в чате#
Бот может писать только тем, кто хочет получать от него сообщения. Сообщение разрешено, если выполняется хотя бы одно из условий:
- собеседник уже писал в этой переписке, или
- собеседник подписан на ваш аккаунт.
В противном случае запрос завершается ошибкой 403 CHAT_NOT_ALLOWED. Если один из вас заблокировал другого, запрос завершается ошибкой 403 CHAT_BLOCKED.
Конфиденциальность и блокировки#
API следует тем же правилам, что и приложение: заблокированные пользователи и закрытые профили остаются недоступными. Закрытый профиль, на владельца которого вы не подписаны, или пользователь, заблокировавший вас, ведут себя так, будто они не найдены или действие не разрешено, — никогда не повторяйте такие запросы в цикле.
Правильная обработка 429#
- Читайте
Retry-Afterи ждите как минимум указанное время перед повторной попыткой. - При повторяющихся сбоях используйте экспоненциальную задержку (exponential backoff) со случайным разбросом (jitter).
- Следите за
X-RateLimit-Remainingи замедляйтесь до того, как значение достигнет нуля. - Предпочитайте один запрос с пагинацией и
limit=100множеству мелких.
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")
Нужны более высокие лимиты для легитимного сценария? Напишите на developers@linework.app и расскажите, что вы создаёте.