Keys and access
How API keys work — read-only and campaign-managing keys, which cabinets a key reaches, how agency owners and team members use the API, and how to keep keys safe.
Send the key
Every request carries the key in a header:
X-API-Key: adsly_0f3c… (54 characters, starts with adsly_)
There is no OAuth flow and no token exchange — the key is the credential. Keep it on your server; never ship it to a browser or a mobile app.
Get a key
In the panel: API & Webhooks → + New key. Keys are part of the Pro and Agency plans; each person can hold up to 5 active keys. A key is shown once, right after you create it — we store only its SHA-256 hash and cannot show it again. Lost it? Revoke it and create a new one.
What a key can do
| Permission | How you get it | What it allows |
|---|---|---|
| Read | every key | campaigns, stats, conversions, tasks, targeting codes, webhooks, sending conversions to us |
| Manage campaigns | tick Allow managing campaigns when you create the key, or switch it on later on the key’s card | everything in Read, plus create, edit, pause/resume, budget, copy, bulk actions, delete, media upload |
A read-only key that calls a write endpoint gets 403 READ_ONLY_KEY. Give dashboards and reporting tools a read-only key; give a manage key only to code you trust to change campaigns. No key — read or manage — can take money out of a cabinet: budget moves only between the cabinet balance and its campaigns.
Writes also need an active Pro or Agency plan at the moment of the call (403 FEATURE_NOT_AVAILABLE otherwise) and the same per-feature plan rights the panel checks.
Which cabinets a key reaches
When you create a key you choose its scope:
| Scope | The key reaches |
|---|---|
| All my cabinets (default) | every cabinet you can open in the panel, including ones added later |
| Several | the cabinets you ticked |
| One cabinet | that cabinet only |
The scope only ever narrows what you can open in the panel — it never widens it. It is re-checked on every request: when you lose access to a cabinet, your keys lose it in the same moment. GET /v1/account/info always lists exactly what the key reaches right now.
If a key reaches several cabinets, pass account_id on calls that act on one of them (400 ACCOUNT_ID_REQUIRED tells you when it’s missing).
Agencies and team members
API access follows the access you have in the panel, cabinet by cabinet:
| Who you are | Cabinets your key reaches | Can manage campaigns in |
|---|---|---|
| Account owner (regular user) | your own cabinets | all of them |
| Agency owner | your personal and agency cabinets | all of them |
| Agency team member | the cabinets the agency shared with you | cabinets shared with Manager access; Viewer cabinets stay read-only |
- Team members create their own keys on their own API & Webhooks page. The agency’s plan covers them.
- The agency owner sees every key the team created under API & Webhooks → Team keys — whose it is, whether it can manage campaigns, how many cabinets it reaches, when it was last used — and can revoke any of them.
GET /v1/account/inforeturnsaccess_levelfor each cabinet:owner,managerorviewer. A write to aviewercabinet returns403 VIEW_ONLY_ACCESS.- If the owner removes a member, lowers them to Viewer, or the agency plan ends, the member’s keys follow immediately — nothing to revoke by hand.
What the roles mean in the panel: Manager — full campaign management in that cabinet; Viewer — campaigns and stats only. The owner can also let a member add cabinets, invite teammates or share their own cabinets (never above their own level).
Revoke and rotate
- Revoke a key on its card in the panel. It stops working immediately.
- Rotate = create a new key, deploy it, then revoke the old one. Two keys can be active at once, so there is no downtime.
- The webhook secret (for verifying webhooks) is separate from the key and can be rotated on its own.
Keep keys safe
- One key per integration, so you can revoke one without breaking the others.
- Store keys in environment variables or a secret manager. Never commit them, never paste them into chats or tickets.
- Prefer read-only keys; add Manage campaigns only where the code changes campaigns.
- Narrow the scope to the cabinets an integration needs.
- If a key may have leaked, revoke it first and investigate second. Every change made through the API appears in the campaign’s history in the panel marked 🔌 API.
Errors you can get here
| HTTP | code | Meaning |
|---|---|---|
| 401 | API_KEY_MISSING | no X-API-Key header |
| 401 | API_KEY_INVALID | wrong, revoked or expired key |
| 401 | NO_ACCOUNTS | the key reaches no active cabinet right now |
| 403 | READ_ONLY_KEY | a write with a key that doesn’t have Manage campaigns |
| 403 | VIEW_ONLY_ACCESS | a write to a cabinet shared with you as Viewer |
| 403 | FEATURE_NOT_AVAILABLE | the plan doesn’t include this action |
| 403 | WRITE_NOT_ALLOWED | this kind of key (issued by Adsly for partners) can’t write |
Full list: Errors.
Updated 2026-10-08