Admin API: conversions and postback
Admin API methods for conversion types, importing conversions from CSV and working with the event delivery queue: list, search and resend.
The API offers the same actions as the panel: conversion types, importing conversions from CSV and the event delivery log. Authorization is described on the Admin API: overview and authorization page, and the request, response and error format on the Request, response and error format page.
Methods in this group
| Method and address | Purpose | Token scope |
|---|---|---|
GET /api/v1/conversion-types | List conversion types | full or reports:read |
POST /api/v1/conversion-types | Create a type | full |
PUT /api/v1/conversion-types/{id} | Edit a type | full |
DELETE /api/v1/conversion-types/{id} | Delete a type | full |
POST /api/v1/conversion-import/preview | Check a CSV | full |
POST /api/v1/conversion-import/apply | Import a CSV | full |
GET /api/v1/deliveries | The last 200 delivery tasks | full |
GET /api/v1/deliveries/search | Search delivery tasks | full |
POST /api/v1/deliveries/{id}/retry | Retry a delivery | full |
If {id} in the address is not a UUID, the response is 400 with the bad_request code. With an inactive license, all methods in the group respond with 402 — see Expired license.
A campaign's log of accepted conversions is returned by GET /api/v1/campaigns/{id}/conversions — see Admin API: campaigns.
Receiving postbacks and leads
The /api/v1/postback, /api/v1/lead and /api/v1/lead-file addresses accept data without a token; they do not need the Api-Key header. Postback parameters, statuses, payout, txid and the source secret are described on the Incoming postback page, repeats and corrections on the Transaction ID, duplicates and corrections page, and receiving data from forms on the Receiving leads from forms page.
Conversion types
A type maps the status value from an affiliate network's postback to a tracker status. The mapping rules are on the Conversion types page.
Type object:
| Field | Type | Description |
|---|---|---|
id | string, UUID | Type ID |
name | string | Name |
status | string | The status the tracker records: lead, sale, rejected or hold |
params | string | Comma-separated status values from the network, for example deposit,ftd |
count_conv | boolean | Count in report conversions |
count_revenue | boolean | Count the payout in revenue |
send_postback | boolean | Send outgoing S2S postbacks for such conversions |
color | string | Color |
List types
GET /api/v1/conversion-typesReturns all of the team's types in order of creation. Token scope: full or reports:read. No parameters.
Response — code 200 and an array of type objects. If there are no types, an empty array [].
Create a type
POST /api/v1/conversion-typesCreates a conversion type. Token scope: full.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Name |
status | string | no | lead, sale, rejected or hold. Default lead |
params | string | no | Comma-separated status values from the network. A type without values matches nothing |
count_conv | boolean | no | Default true |
count_revenue | boolean | no | Default true |
send_postback | boolean | no | Default false. Pass true to send postbacks to the source |
color | string | no | Default is an empty string |
Response — code 201 and the created type object.
curl -X POST https://panel.example.com/api/v1/conversion-types \
-H "Api-Key: <token>" \
-H "Content-Type: application/json" \
-d '{"name":"Deposit","status":"sale","params":"deposit,ftd","send_postback":true}'Errors: 422, code validation, message name is required — there is no name field or the body is not a JSON object.
Edit a type
PUT /api/v1/conversion-types/{id}Replaces the type's settings. Token scope: full.
The body fields are the same as on creation; name is required. Pass the whole object:
- omitted
count_conv,count_revenueandsend_postbackbecomefalse; - omitted
paramsandcolorbecome an empty string; - an omitted or empty
statusdoes not change.
Response — code 200 and the type object after the change.
Errors:
| Code | code | When |
|---|---|---|
404 | not_found | There is no type with this ID |
422 | validation | There is no name field or the body is not a JSON object |
Delete a type
DELETE /api/v1/conversion-types/{id}Deletes a type. Token scope: full. No request body.
Response — code 204 with no body. If there is no type with this ID — 404, code not_found. What happens to already accepted conversions is described in the Deleting and changing section.
Importing conversions from CSV
The import takes two requests: the check returns a token, and the import accepts the same data together with this token. The file format and the rules for each column are on the Conversion import from CSV page.
Body of both requests:
| Field | Type | Required | Description |
|---|---|---|---|
csv | string | yes | CSV text with the sub_id,payout,tid,status header. Up to 256 KB and up to 200 data rows |
currency | string | no | Currency of the amounts in the file, three Latin letters. Default USD |
notify | boolean | no | true — send outgoing S2S and CAPI for the imported conversions. Default false |
token | string | import only | The token value from the check response |
Response of both requests — code 200:
| Field | Type | Description |
|---|---|---|
rows | array | One object per file row |
rows[].line | number | Row number in the file. The header is row 1 |
rows[].click_id, rows[].payout, rows[].status | string | Values of the sub_id, payout and status columns. The status is in lower case |
rows[].tid | string | Transaction ID. For an empty column — import: and the sub_id value |
rows[].error | string | The reason the row was not accepted. The field is absent if there is no error |
rows[].result | string | The row's import result. Present only in the import response |
valid | boolean | true — all rows passed the check |
token | string | Filled only in the check response with valid: true, otherwise an empty string |
applied | boolean | true — the import was performed |
notify | boolean | The notify value from the request |
Check a CSV
POST /api/v1/conversion-import/previewChecks the file and writes nothing. Token scope: full.
If valid is false, fix the rows with the error field and repeat the check. Row error messages are covered in the If something went wrong section.
curl -X POST https://panel.example.com/api/v1/conversion-import/preview \
-H "Api-Key: <token>" \
-H "Content-Type: application/json" \
-d '{"csv":"sub_id,payout,tid,status\n1a2b3c4d5e6f,25.5,order-1001,sale\n","currency":"USD","notify":false}'{
"rows": [
{"line": 2, "click_id": "1a2b3c4d5e6f", "payout": "25.5", "tid": "order-1001", "status": "sale"}
],
"valid": true,
"token": "1791021600.9f2c…",
"applied": false,
"notify": false
}Errors:
| Code | code | message |
|---|---|---|
400 | bad_request | Некорректный запрос (invalid request) — the body is not a JSON object |
422 | validation | Некорректная валюта (invalid currency), Файл больше 256 КБ (file larger than 256 KB), Не больше 200 строк за импорт (no more than 200 rows per import), В CSV нет данных (no data in the CSV) |
422 | validation | Нужен CSV с заголовком sub_id,payout,tid,status (a CSV with the sub_id,payout,tid,status header is required), Нужны ровно 4 колонки: sub_id,payout,tid,status (exactly 4 columns are required: sub_id,payout,tid,status), Заголовок: sub_id,payout,tid,status (header: sub_id,payout,tid,status) |
503 | unavailable | temporary error, retry later — repeat the request later |
Import a CSV
POST /api/v1/conversion-import/applyWrites conversions from the checked file. Token scope: full.
Send the same csv, currency and notify as in the check, and add the token. It is valid for 15 minutes and fits only this data and only the user whose API token ran the check. If you changed even one field, check the file again.
Rows are processed by the same rules as an incoming postback. With applied: true, each row has a result:
resultwith the valueПринято (точный повтор не создаёт дубль)(accepted; an exact repeat does not create a duplicate) — the conversion was accepted;errorwith the valueНе принято: HTTP <код>. Проверьте журнал postback; строку можно повторить с тем же tid.(not accepted: HTTP code; check the postback log; the row can be repeated with the same tid) — the row was not written; the other rows are not affected.
If valid is false during import, nothing is written: applied is false.
Errors — the same as for the check, plus two more:
| Code | code | message |
|---|---|---|
428 | preview_required | Сначала выполните предварительную проверку (run the preliminary check first) — there is no token field or it has the wrong form |
409 | preview_expired | Данные изменились или проверка устарела. Повторите проверку. (the data has changed or the check has expired; repeat the check) |
Deliveries
A delivery task is writing an accepted conversion to the statistics, an outgoing S2S postback or a Facebook Conversions API event. What the states and results mean and when a retry is safe is described on the Event delivery log page.
Task object:
| Field | Type | Description |
|---|---|---|
id | string, UUID | Task ID |
campaign_id | string, UUID | Campaign |
click_id | string | The click's subid |
kind | string | conversion — writing a conversion, s2s — S2S postback, capi — Facebook event |
destination | string | S2S recipient: source — the source, campaign — the campaign address, source_and_campaign — the addresses matched, one request. If there is no recipient, the field is absent |
state | string | pending — waiting, running — being processed, sent — done, failed — needs checking |
attempts | number | How many times the tracker has run the task |
result_code | string | The result of the last attempt, see result values |
held_for_license | boolean | Sending is held until the license is renewed. Filled only in GET /api/v1/deliveries; always false in the search response |
created_at, updated_at | string, RFC 3339 date | Creation time and time of the last change |
next_attempt_at | string, RFC 3339 date | Time of the next attempt |
Latest deliveries
GET /api/v1/deliveriesReturns the team's last 200 tasks, newest first. Token scope: full. No parameters.
Response — code 200 and an array of task objects.
Search deliveries
GET /api/v1/deliveries/searchSearches tasks by click, period and filters. Token scope: full.
| Parameter | Type | Required | Description |
|---|---|---|---|
click_id | string | no | The full click subid: from 1 to 64 characters, Latin letters, digits, _, - and dots (not at the start or end, and not two in a row) |
from | string, RFC 3339 date | no | Start of the period by task creation time. Default — 24 hours ago |
to | string, RFC 3339 date | no | End of the period. Default — the current time |
campaign_id | string, UUID | no | Campaign |
state | string | no | pending, running, sent or failed |
kind | string | no | conversion, s2s or capi |
destination | string | no | source, campaign or source_and_campaign |
limit | number | no | Page size from 1 to 200. Default 100 |
cursor | string | no | The next_cursor value from the previous response |
The period is no longer than 93 days. If click_id is passed without from and to, the search covers all time.
Response — code 200:
| Field | Type | Description |
|---|---|---|
items | array | Task objects, newest first |
next_cursor | string | Pass it in cursor to get the next page. An empty string means this is the last page |
curl "https://panel.example.com/api/v1/deliveries/search?state=failed&kind=s2s&from=2026-10-01T00:00:00Z&to=2026-10-04T00:00:00Z&limit=50" \
-H "Api-Key: <token>"{
"items": [
{
"held_for_license": false,
"id": "0b7e4c19-6a2d-4f85-b3c1-8d9e0f1a2b3c",
"campaign_id": "c41a9e07-52bd-4f13-8a60-9d7e6f5a4b3c",
"click_id": "1a2b3c4d5e6f",
"kind": "s2s",
"destination": "source",
"state": "failed",
"attempts": 1,
"result_code": "http_404",
"created_at": "2026-10-03T14:22:05.418332Z",
"updated_at": "2026-10-03T14:22:06.102778Z",
"next_attempt_at": "2026-10-03T14:22:05.418332Z"
}
],
"next_cursor": ""
}Errors — code 400, code is validation.
Search error messages
Некорректный subid(invalid subid) —click_iddoes not match the format.Некорректное начало периода(invalid period start),Некорректный конец периода(invalid period end) — the date is not in RFC 3339 format.Выберите период до 93 дней(choose a period of up to 93 days) — the period is longer than 93 days ortois earlier thanfrom.Размер страницы: от 1 до 200(page size: from 1 to 200) —limitis out of range or not a number.Некорректная страница(invalid page) —cursoris not from this method's response.Некорректная кампания(invalid campaign) —campaign_idis not a UUID.Некорректный фильтр(invalid filter) — an unknownstate,kindordestinationvalue.
Retry a delivery
POST /api/v1/deliveries/{id}/retryPuts the task back in the queue: state becomes pending, and sending happens immediately and in the same form. Token scope: full. The address contains the task id; there is no request body.
Only a task in the failed state can be retried. Tasks with result_code equal to invalid_url, blocked_address, invalid_payload or invalid_kind are not retried.
Response — code 200:
{"ok": true}Errors: 404, code not_found — there is no task with this ID, it is not in the failed state, or it cannot be retried.
If the recipient has already accepted the event, a retry may create a duplicate on its side. Check tasks with result_code equal to unknown_delivery with the recipient first — see Receipt not confirmed.