Adsly.pro
Documentation pages All documentation

Rate limits

How many requests a key can make — separate budgets for reads, writes and incoming conversions — the headers that show your remaining budget, and how to back off.

View as Markdown

Each key has three independent budgets. Using one never eats into another — a dashboard polling stats can’t starve its own pause button, and a burst of conversions from your tracker can’t block either.

BudgetApplies toLimit
Readevery GET60 requests per minute
Writeevery POST, PATCH, DELETE except conversions30 requests per minute
Conversions inPOST /v1/postback, GET /v1/ingest/{token}20 events per second, bursts up to 1,000

The limits are token buckets, not fixed windows: the budget refills continuously, and a short burst up to the full minute’s allowance is fine. A typical sync — campaigns, stats, totals — is 3–4 read requests.

Need more for a specific integration? Ask @adsly_pro — limits can be raised per key.

Headers

Every response says where you stand:

X-RateLimit-Limit: 60          the budget for this kind of request, per minute
X-RateLimit-Remaining: 47      requests you can make right now
X-RateLimit-Reset: 1791364800  unix time when the budget is full again
Retry-After: 23                only on 429 — seconds to wait

Doing more with fewer calls

  • Bulk instead of loops. Pausing 300 campaigns is one POST /v1/campaigns/bulk, not 300 pause calls. See Manage campaigns.
  • Create in batches. POST /v1/campaigns takes up to 100 campaigns.
  • Webhooks instead of polling. Status changes arrive the moment they happen; hourly stats arrive by themselves. See Webhooks.
  • Batch conversions. POST /v1/postback accepts up to 1,000 events per request (each event still counts against the events budget — batching saves round trips, not quota).

Other limits

WhatLimit
Queued or running operations per cabinet5 creates + 5 other operations (copy, bulk). The 6th returns 429 QUEUE_FULL.
Campaigns per create request100
Copies per copy request100
Campaigns per bulk request1,000
Uploaded file10 MB
Page size for GET /v1/campaigns500

Backing off

On 429, wait Retry-After seconds and retry. For anything automated, add jitter so many workers don’t retry at the same instant:

async function call(url, init, attempt = 0) {
  const res = await fetch(url, init);
  if (res.status !== 429 || attempt >= 5) return res;
  const wait = Number(res.headers.get('Retry-After') || 1) * 1000;
  await new Promise(r => setTimeout(r, wait + Math.random() * 500));
  return call(url, init, attempt + 1);
}

Updated 2026-10-08

Discuss your project