> Adsly docs index: https://adsly.pro/docs/llms.txt · every page in one file: https://adsly.pro/docs/llms-full.txt · OpenAPI: https://adsly.pro/docs/api/openapi.yaml

# Conversions (postbacks in)

Send leads, deposits and sales back to Adsly from your backend or tracker (Keitaro, RedTrack, Binom, Voluum) so every campaign shows its real results; read them back with GET /v1/conversions.

Telegram counts views, clicks and joins. Your backend or tracker knows what happened next — a lead, a deposit, a sale. Send those events to Adsly and each campaign shows its conversions and revenue in the panel, in reports and in automation rules.

## Turn it on

On the key's card in the panel, switch on **Receive postbacks**. Without it, sending returns `403 INGEST_DISABLED`. For a tracker, also press **Generate tracker URL** — you get a write-only URL (shown once) that can post conversions but can't read anything.

## How a conversion finds its campaign

Each ad links somewhere with an identifier you control:

- a bot or mini-app: `t.me/yourbot?start=REF` or `?startapp=REF`
- a website: your tracker's click id or sub id in the link, e.g. `https://site.com/?subid=REF`

When you send a conversion, include that `REF` as `ref`. Adsly finds the campaign whose link carries it, in the cabinets the key reaches. If several campaigns of one cabinet share the same `ref`, the conversion counts for each of them.

## From your backend: POST /v1/postback

```bash
curl -s -X POST https://app.adsly.pro/api/v1/postback \
  -H "X-API-Key: $ADSLY_API_KEY" -H "Content-Type: application/json" \
  -d '{ "ref": "promo_oct", "event": "purchase", "amount": 49.90, "currency": "USD", "txid": "order-10087" }'
```

```json
{ "success": true, "data": { "id": 551203, "ad_id": 90412, "account_id": 53, "event_type": "purchase", "deduped": false } }
```

Up to 1,000 events at once: `{ "events": [ {…}, {…} ] }` (or a bare array). The response reports each one — `{ "accepted": 998, "failed": 2, "results": [ … ] }` — so one bad event never sinks the batch.

## From a tracker: GET /v1/ingest/{token}

Paste the tracker URL into your tracker's postback settings, with its macros:

```text
# Keitaro
https://app.adsly.pro/api/v1/ingest/<token>?ref={subid}&event={status}&amount={payout}&currency={currency}&txid={subid}_{status}
# RedTrack
https://app.adsly.pro/api/v1/ingest/<token>?ref={clickid}&event={type}&status={status}&amount={sum}&txid={rdtk_event_id}
# Binom
https://app.adsly.pro/api/v1/ingest/<token>?ref={clickid}&event={status}&amount={payout}&txid={clickid}
# Voluum
https://app.adsly.pro/api/v1/ingest/<token>?ref={clickid}&event={et}&amount={payout}&currency={currency}&txid={txid}
```

Check the macro names against your tracker's own documentation. The answer is plain text: `OK`, `OK (deduped)`, or an error message with its HTTP status (4xx — don't retry, 5xx — retry).

## Fields

| Field | Also accepted as | Required | Meaning |
|---|---|---|---|
| `ref` | `subid`, `sub_id`, `clickid`, `click_id`, `cnv_id`, `cid` | yes¹ | The identifier from the ad's link. Up to 512 characters. |
| `invite_link` | `invitelink`, `link` | yes¹ | For channel ads: the unique invite link Adsly created. |
| `event` | `event_type`, `type`, `goal`, `cnv_status` | yes | Becomes `lead`, `conversion` or `purchase` (words like `signup`, `ftd`, `deposit`, `sale` are understood). Unknown words are refused. |
| `txid` | `tid`, `transaction_id`, `order_id`, `rdtk_event_id`, header `X-Idempotency-Key` | yes | Your id for this event. Sending the same `txid` again updates the event instead of counting it twice. Up to 128 characters. |
| `amount` | `payout`, `sum`, `revenue`, `value` | no | Number; negative for chargebacks. |
| `currency` | `cur`, `cnv_currency` | no | ISO 4217 code. Without one, an amount is recorded as USD. |
| `status` | — | no | Your network's own status word (approved, pending…), stored as is. |
| `event_time` | `timestamp`, `date` | no | ISO or unix time; kept within the last 90 days. |
| `account_id` | `accountId` | sometimes | Needed when the same `ref` exists in several of your cabinets (`409` otherwise). |
| `meta` | — | no | Your own JSON object, up to 4 KB. |

¹ `ref` or `invite_link`.

## Limits and retries

20 events per second per key, with bursts up to 1,000 — separate from the read and write budgets. On `429` wait `Retry-After`; retrying is always safe because `txid` deduplicates.

## GET /v1/conversions

Totals per campaign, counted once per event:

```bash
curl -s "https://app.adsly.pro/api/v1/conversions?days=30" -H "X-API-Key: $ADSLY_API_KEY"
```

```json
{
  "success": true,
  "data": [
    { "account_id": 53, "ad_id": 90412, "leads": 12, "conversions": 3, "purchases": 1, "revenue": { "USD": 49.9 } }
  ]
}
```

| Parameter | Meaning |
|---|---|
| `adId` | One campaign. |
| `days` | Only events received in the last 1–365 days. |

- `revenue` is per currency — amounts are never converted.
- `ad_id` is `null` for events matched by a `ref` that several campaigns share.
- Amounts you send are your own reporting. They are not billed and don't change anything you pay Adsly.

---
Page: https://adsly.pro/docs/api/conversions/ · Updated: 2026-10-08
