Adsly.pro
Documentation pages All documentation

Adsly API — overview and quickstart

What the Adsly API does, the base URL, and a five-minute path from a new key to your first campaign created and paused from code.

View as Markdown

The Adsly API gives your code the same control over your Telegram Ads cabinets that you have in the Adsly panel. One key, one base URL, the same calls for Euro, TON and Stars cabinets.

You want to…Use
Pull campaigns and stats into a dashboard or BICampaigns, Stats
Launch campaigns from a script, a bot or your CRMCreate campaigns
Raise bids, pause losers, top up winners automaticallyManage campaigns
Know the moment a campaign is approved, declined or runs out of budgetWebhooks
Count leads and sales from your tracker against each campaignConversions

Base URL

https://app.adsly.pro/api/v1

Every request carries your key in the X-API-Key header. Request and response bodies are JSON. All times are UTC.

Quickstart

1. Create a key

In the panel open API & Webhooks → + New key (Pro and Agency plans). Choose which cabinets the key reaches. To create and change campaigns, tick Allow managing campaigns — without it the key only reads. Copy the key: it is shown once.

export ADSLY_API_KEY="adsly_…"

2. List the cabinets the key sees

curl -s https://app.adsly.pro/api/v1/account/info \
  -H "X-API-Key: $ADSLY_API_KEY"
{
  "success": true,
  "data": [
    {
      "id": 53,
      "name": "Main cabinet",
      "cabinet_type": "euro",
      "is_active": true,
      "access_level": "owner",
      "currency": "EUR",
      "balance": "250.00",
      "balance_updated_at": "2026-10-08T09:40:12.000Z",
      "min_budget": 1,
      "features": { "ad_button": true, "crypto_filters": true }
    }
  ]
}

Keep id — it is the account_id every other call uses. All money in a cabinet is in its currency.

3. Read campaigns

curl -s "https://app.adsly.pro/api/v1/campaigns?account_id=53&status=Active&limit=50" \
  -H "X-API-Key: $ADSLY_API_KEY"

4. Create a campaign (switched off, so nothing is spent)

curl -s -X POST https://app.adsly.pro/api/v1/campaigns \
  -H "X-API-Key: $ADSLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "account_id": 53,
    "title": "API test",
    "text": "Join the channel for daily market notes",
    "promote_url": "https://t.me/yourchannel",
    "cpm": 1.5,
    "budget": 0,
    "active": false,
    "target_type": "channels",
    "channels": ["@durov"]
  }'

Creating talks to Telegram, so it runs in the background. You get 202 Accepted and a task:

{ "success": true, "data": { "id": 81234, "type": "create", "status": "pending", "account_id": 53, "total": 1, "ad_ids": [] } }

5. Wait for the task

curl -s https://app.adsly.pro/api/v1/tasks/81234 -H "X-API-Key: $ADSLY_API_KEY"

When status is completed, ad_ids holds the new campaign’s id. Now you can fund it and switch it on:

curl -s -X POST https://app.adsly.pro/api/v1/campaigns/90412/budget \
  -H "X-API-Key: $ADSLY_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "account_id": 53, "action": "add", "amount": 5 }'

curl -s -X POST "https://app.adsly.pro/api/v1/campaigns/90412/resume?account_id=53" \
  -H "X-API-Key: $ADSLY_API_KEY"

Telegram reviews every new ad before it runs; the campaign’s status shows where it is (see statuses). A webhook tells you the moment it changes.

Five rules every integration follows

  1. ad_id is unique only inside a cabinet. Telegram reuses ad ids across cabinets. Store and look up campaigns by the pair (account_id, ad_id), and pass account_id whenever a key sees more than one cabinet.
  2. Send an Idempotency-Key on create, copy, bulk and budget calls — a fresh UUID per operation, the same one when you retry it. A retry then never creates a second campaign or moves money twice. See Idempotency.
  3. Create, copy and bulk return a task. Poll GET /v1/tasks/{id} until it finishes. See Tasks.
  4. Money fields are strings ("spent": "3.541000") to keep exact decimals. Parse them as decimals before doing arithmetic.
  5. Branch on code, show error. Every error has a stable machine-readable code and a human sentence in error. See Errors.

Response shape

{ "success": true, "data": { … }, "meta": { … } }
{ "success": false, "error": "Human-readable message", "code": "MACHINE_CODE", "request_id": "…" }

Where to go next

Updated 2026-10-08

Discuss your project