Посилання (API v1, видалено)
Ці ендпоінти більше не працюють
Шість ендпоінтів API v1 нижче замінено на API v2, і тепер вони відповідають 410 Gone із вказаною заміною у відповіді. Перейдіть на API v2. Розділи далі описують старий формат і залишені лише для допомоги з міграцією.
Куди переїхав кожен ендпоінт
API v1 (відповідає 410) | API v2 |
|---|---|
POST /apiv1/link/create | POST https://api.revolink.link/apiv2/links |
PUT /apiv1/link/update | PATCH https://api.revolink.link/apiv2/links/{id} |
DELETE /apiv1/link/delete | DELETE https://api.revolink.link/apiv2/links/{id} |
POST /apiv1/links/bulk-create | POST https://api.revolink.link/apiv2/links/bulk |
GET /apiv1/links/{id}/analytics | GET https://api.revolink.link/apiv2/links/{id}/analytics |
GET /apiv1/links/analytics | GET https://api.revolink.link/apiv2/analytics |
Що змінюється для вас: ключ передається в Authorization: Bearer <key> (або X-Api-Key), робочий простір передається в заголовку X-Workspace-Id і більше не в тілі чи рядку запиту, посилання ідентифікується за id в URL, а відповіді загорнуті в { "data": … }. Дивіться автентифікацію API v2 і Помилки.
Старі ендпоінти (довідка для міграції)
| Метод | Шлях | Опис |
|---|---|---|
POST | /link/create | Створення посилання |
PUT | /link/update | Оновлення посилання |
DELETE | /link/delete | Видалення посилання |
POST | /links/bulk-create | Масове створення посилань |
GET | /links/{id}/analytics | Аналітика посилання |
GET | /links/analytics | Аналітика всіх посилань |
Об'єкт правила
Правила визначають, куди перенаправляє посилання. Кожне посилання має мати щонайменше одне правило з isDefault: true: це резервна адреса, коли умови жодного іншого правила не збігаються.
Правила, що не є правилами за замовчуванням, перевіряються по черзі. Перемагає перше правило, усі умови якого збігаються. Якщо жодне правило не підійшло, використовується правило за замовчуванням.
ID правил генеруються автоматично сервером: не додавайте id у запит.
Обмеження:
- Рівно одне правило на посилання має мати
isDefault: true - Правило за замовчуванням є суто резервним: воно не може мати жодних умов (
country,city,device,os,browser,timeStart,timeEnd,daysOfWeek). Умови дозволені лише для правил, що не є правилами за замовчуванням timeStartіtimeEndпотрібно вказувати разом або пропускати обидва
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
targetUrl | string | ✅ | Цільовий URL. Будь-яка коректна URL-адреса, зокрема deep link (наприклад, youtube://, myapp://) |
isDefault | boolean | ✅ | Рівно одне правило на посилання має мати true |
country | string[] | — | Двобуквені коди країн ISO 3166-1 alpha-2 (наприклад, ["UA", "PL"]). Підходять лише відвідувачі з цих країн |
city | string[] | — | Назви міст (наприклад, ["Kyiv", "Warsaw"]). Потрібно вказати country: використовувати місто без країни не можна |
device | string[] | — | Типи пристроїв. Допустимі значення: "desktop", "mobile", "tablet", "console", "smarttv", "wearable", "embedded" |
os | string[] | — | Операційні системи. Допустимі значення: "Windows", "macOS", "Linux", "iOS", "Android" |
browser | string[] | — | Браузери. Допустимі значення: "Chrome", "Firefox", "Safari", "Edge", "Opera", "Brave" |
timeStart | string | — | Початок активного часового вікна у форматі "HH:MM" (наприклад, "09:00") |
timeEnd | string | — | Кінець активного часового вікна у форматі "HH:MM" (наприклад, "18:00") |
daysOfWeek | number[] | — | Дні, коли правило активне. 0 = неділя … 6 = субота (наприклад, [1,2,3,4,5] для робочих днів) |
Повний приклад правила (усі необов'язкові поля умов):
{
"targetUrl": "https://example.com/ua-mobile",
"isDefault": false,
"country": ["UA", "PL"],
"city": ["Kyiv", "Warsaw"],
"device": ["mobile"],
"os": ["iOS", "Android"],
"browser": ["Chrome", "Safari"],
"timeStart": "09:00",
"timeEnd": "21:00",
"daysOfWeek": [1, 2, 3, 4, 5]
}
Об'єкт A/B-тесту
A/B-тестування випадково ділить трафік між кількома цільовими URL залежно від ваг. Коли abTest.enabled має значення true, правила маршрутизації ігноруються: кожного відвідувача відправляють на один із варіантів.
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
enabled | boolean | ✅ | Встановіть true, щоб активувати A/B-тестування |
variants | Variant[] | ✅ | Список варіантів. Щонайменше 2, коли тест увімкнено |
Поля варіанта:
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
id | string | ✅ | Унікальний ідентифікатор варіанта. Використовуйте будь-який стабільний рядок (наприклад, мітку часу): сервер зберігає його як є для відстеження |
name | string | ✅ | Відображувана назва (наприклад, "Variant A") |
url | string | ✅ | Цільовий URL для цього варіанта |
weight | number | ✅ | Частка трафіку. Ваги всіх варіантів мають у сумі давати рівно 100 |
Приклад:
{
"abTest": {
"enabled": true,
"variants": [
{ "id": "1714000000000", "name": "Variant A", "url": "https://example.com/a", "weight": 60 },
{ "id": "1714000000001", "name": "Variant B", "url": "https://example.com/b", "weight": 40 }
]
}
}
Щоб вимкнути A/B-тестування під час оновлення посилання:
{
"abTest": { "enabled": false, "variants": [] }
}
Об'єкт налаштувань QR
Керує зовнішнім виглядом QR-коду, що генерується для посилання.
| Поле | Тип | Опис |
|---|---|---|
color | string | Колір переднього плану у форматі hex. За замовчуванням: "#000000" |
bgColor | string | Колір фону у форматі hex. За замовчуванням: "#ffffff" |
useLogo | boolean | Чи вбудовувати логотип у центр QR-коду. За замовчуванням: false |
logo | string | Зображення логотипа як data URL (наприклад, "data:image/png;base64,...") або URL. Обов'язкове, коли useLogo має значення true |
Приклад:
{
"qrSettings": {
"color": "#1a1a2e",
"bgColor": "#ffffff",
"useLogo": true,
"logo": "https://example.com/logo.png"
}
}
Створення посилання
POST /link/create
Запит
POST https://api.revolink.link/apiv1/link/create
Content-Type: application/json
X-Api-Key: rvlnk_your_api_key_here
Поля тіла запиту
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
workspaceId | string | ✅ | ObjectId робочого простору |
name | string | ✅ | Відображувана назва посилання |
rules | Rule[] | ✅ | Правила маршрутизації. Потрібне щонайменше одне правило з isDefault: true |
description | string | — | Внутрішній опис (відвідувачам не показується). До 1000 символів |
slug | string | — | Власний slug URL. Якщо не вказано, генерується автоматично. Лише малі літери, цифри та дефіси. До 100 символів |
domain | string | — | Ім'я хоста власного домену (наприклад, "go.mycompany.com"). Має бути підтвердженим доменом у робочому просторі. За замовчуванням rvlnk.link |
active | boolean | — | За замовчуванням: true |
clicksLimit | number | — | Додатне ціле число. Якщо не вказано, обмежень немає |
expirationDate | string | — | Дата й час ISO 8601. Має бути в майбутньому |
tagIds | string[] | — | Масив ObjectId тегів |
abTest | object | — | Конфігурація A/B-тесту. Див. Об'єкт A/B-тесту |
qrSettings | object | — | Зовнішній вигляд QR-коду. Див. Об'єкт налаштувань QR |
Мінімальний приклад
curl -X POST https://api.revolink.link/apiv1/link/create \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"name": "My link",
"rules": [
{
"targetUrl": "https://example.com",
"isDefault": true
}
]
}'
Повний приклад (усі поля)
curl -X POST https://api.revolink.link/apiv1/link/create \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"name": "Summer campaign",
"description": "Main landing for summer 2025 promo",
"slug": "summer-2025",
"domain": "go.mycompany.com",
"active": true,
"clicksLimit": 10000,
"expirationDate": "2025-09-01T00:00:00Z",
"tagIds": ["664abc000000000000000010", "664abc000000000000000011"],
"rules": [
{
"targetUrl": "https://example.com/ua-mobile",
"isDefault": false,
"country": ["UA"],
"device": ["mobile"],
"os": ["iOS", "Android"],
"timeStart": "08:00",
"timeEnd": "22:00",
"daysOfWeek": [1, 2, 3, 4, 5]
},
{
"targetUrl": "https://example.com/de",
"isDefault": false,
"country": ["DE", "AT", "CH"],
"device": ["desktop"],
"browser": ["Chrome", "Firefox"]
},
{
"targetUrl": "https://example.com",
"isDefault": true
}
]
}'
Відповідь 200 OK
{
"message": "Link \"Summer campaign\" successfully created.",
"id": "664abc123def456789000001",
"slug": "summer-2025",
"fullLink": "https://go.mycompany.com/summer-2025"
}
Відповіді з помилками
| Статус | Тіло | Причина |
|---|---|---|
400 | {"error": "Name is required."} | Відсутнє поле name |
400 | {"error": "rules must be a non-empty array."} | rules відсутнє або порожнє |
400 | {"error": "Domain is not available for this workspace."} | Указаний domain не є підтвердженим доменом цього робочого простору |
403 | {"licenseLimitReached": true, ...} | Досягнуто квоти тарифу на посилання або правила |
409 | {"error": "This slug is already taken."} | Указаний slug уже використовується на цьому домені |
Оновлення посилання
PUT /link/update Змінюються лише поля, які ви вкажете, а решта полів лишається без змін.
Запит
PUT https://api.revolink.link/apiv1/link/update
Content-Type: application/json
X-Api-Key: rvlnk_your_api_key_here
Поля тіла запиту
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
workspaceId | string | ✅ | ObjectId робочого простору |
linkId | string | ✅ | ObjectId посилання, яке потрібно оновити |
name | string | — | Нова відображувана назва |
description | string | — | Новий опис |
rules | Rule[] | — | Замінює всі правила маршрутизації |
active | boolean | — | Вмикає або вимикає посилання |
clicksLimit | number | — | Новий ліміт кліків. Передайте null, щоб зняти обмеження |
expirationDate | string | — | Нова дата й час завершення терміну дії. Передайте null, щоб зняти термін дії |
tagIds | string[] | — | Замінює список тегів |
Мінімальний приклад (вимкнути посилання)
curl -X PUT https://api.revolink.link/apiv1/link/update \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"linkId": "664abc123def456789000001",
"active": false
}'
Повний приклад (оновлення всіх полів)
curl -X PUT https://api.revolink.link/apiv1/link/update \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"linkId": "664abc123def456789000001",
"name": "Summer campaign (updated)",
"description": "Updated description",
"active": true,
"clicksLimit": 50000,
"expirationDate": "2025-12-31T23:59:59Z",
"tagIds": ["664abc000000000000000012"],
"rules": [
{
"targetUrl": "https://example.com/ua-mobile-v2",
"isDefault": false,
"country": ["UA", "PL"],
"device": ["mobile"]
},
{
"targetUrl": "https://example.com/v2",
"isDefault": true
}
]
}'
Приклад зі зняттям обмежень
curl -X PUT https://api.revolink.link/apiv1/link/update \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"linkId": "664abc123def456789000001",
"clicksLimit": null,
"expirationDate": null
}'
Відповідь 200 OK
{
"message": "Link updated.",
"id": "664abc123def456789000001"
}
Відповіді з помилками
| Статус | Тіло | Причина |
|---|---|---|
400 | {"error": "Invalid linkId format."} | linkId не є коректним ObjectId |
403 | {"error": "You do not have permission to edit this link."} | Посилання належить іншому робочому простору |
403 | {"licenseLimitReached": true, ...} | Досягнуто ліміту правил на поточному тарифі |
404 | {"error": "Link not found."} | Посилання з таким ID не існує |
Видалення посилання
DELETE /link/delete
Запит
DELETE https://api.revolink.link/apiv1/link/delete
Content-Type: application/json
X-Api-Key: rvlnk_your_api_key_here
Поля тіла запиту
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
workspaceId | string | ✅ | ObjectId робочого простору |
linkId | string | ✅ | ObjectId посилання, яке потрібно видалити |
Приклад
curl -X DELETE https://api.revolink.link/apiv1/link/delete \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"linkId": "664abc123def456789000001"
}'
Відповідь 200 OK
{
"message": "Link deleted."
}
Відповіді з помилками
| Статус | Тіло | Причина |
|---|---|---|
400 | {"error": "Invalid linkId format."} | linkId не є коректним ObjectId |
403 | {"error": "You do not have permission to delete this link."} | Посилання належить іншому робочому простору |
404 | {"error": "Link not found."} | Посилання з таким ID не існує |
Масове створення посилань
POST /links/bulk-create До 100 посилань за один виклик. Кожне посилання обробляється незалежно: якщо одне завершується помилкою, решта все одно обробляються.
Запит
POST https://api.revolink.link/apiv1/links/bulk-create
Content-Type: application/json
X-Api-Key: rvlnk_your_api_key_here
Поля тіла запиту
| Поле | Тип | Обов'язкове | Опис |
|---|---|---|---|
workspaceId | string | ✅ | ObjectId робочого простору |
links | LinkInput[] | ✅ | Масив об'єктів посилань. Максимум 100 елементів |
Кожен елемент links приймає ті самі поля, що й /link/create, крім workspaceId (він передається один раз на верхньому рівні).
Приклад
curl -X POST https://api.revolink.link/apiv1/links/bulk-create \
-H "Content-Type: application/json" \
-H "X-Api-Key: rvlnk_your_api_key_here" \
-d '{
"workspaceId": "664abc000000000000000001",
"links": [
{
"name": "Campaign — Ukraine mobile",
"slug": "ua-mob",
"description": "UA mobile audience",
"active": true,
"clicksLimit": 5000,
"expirationDate": "2025-12-31T23:59:59Z",
"tagIds": ["664abc000000000000000010"],
"rules": [
{
"targetUrl": "https://example.com/ua",
"isDefault": false,
"country": ["UA"],
"device": ["mobile"]
},
{
"targetUrl": "https://example.com",
"isDefault": true
}
]
},
{
"name": "Campaign — Germany",
"rules": [
{
"targetUrl": "https://example.com/de",
"isDefault": false,
"country": ["DE", "AT", "CH"]
},
{
"targetUrl": "https://example.com",
"isDefault": true
}
]
},
{
"name": "Simple redirect",
"rules": [
{
"targetUrl": "https://example.com/simple",
"isDefault": true
}
]
}
]
}'
Відповідь 200 OK
Відповідь завжди має код 200, навіть якщо деякі елементи завершилися помилкою. Помилки окремих елементів дивіться в масиві failed.
{
"message": "Bulk create complete: 3 created, 0 failed.",
"created": [
{
"id": "664abc123def456789000001",
"slug": "ua-mob",
"fullLink": "https://rvlnk.link/ua-mob",
"name": "Campaign — Ukraine mobile"
},
{
"id": "664abc123def456789000002",
"slug": "xk7r2p",
"fullLink": "https://rvlnk.link/xk7r2p",
"name": "Campaign — Germany"
},
{
"id": "664abc123def456789000003",
"slug": "m9qw1z",
"fullLink": "https://rvlnk.link/m9qw1z",
"name": "Simple redirect"
}
],
"failed": []
}
Приклад часткової помилки:
{
"message": "Bulk create complete: 2 created, 1 failed.",
"created": [
{
"id": "664abc123def456789000001",
"slug": "ua-mob",
"fullLink": "https://rvlnk.link/ua-mob",
"name": "Campaign — Ukraine mobile"
}
],
"failed": [
{
"input": {
"description": "Missing name and rules"
},
"error": "Each link must have name and rules."
}
]
}
Відповіді з помилками
| Статус | Тіло | Причина |
|---|---|---|
400 | {"error": "links must be a non-empty array."} | links відсутнє або порожнє |
400 | {"error": "Maximum 100 links per request."} | Передано понад 100 елементів |
403 | {"licenseLimitReached": true, ...} | Буде перевищено квоту тарифу |
Аналітика посилання
GET /links/{id}/analytics
Повертає статистику кліків для одного посилання. Доступно всім учасникам робочого простору.
Запит
GET https://api.revolink.link/apiv1/links/{id}/analytics?workspaceId=...&from=...&to=...
X-Api-Key: rvlnk_your_api_key_here
Параметри запиту
| Параметр | Тип | Обов'язковий | Опис |
|---|---|---|---|
workspaceId | string | ✅ | ObjectId робочого простору |
from | string | — | Початкова дата у форматі YYYY-MM-DD. За замовчуванням початок часів |
to | string | — | Кінцева дата у форматі YYYY-MM-DD. За замовчуванням сьогодні |
Приклад
curl "https://api.revolink.link/apiv1/links/664abc123def456789000001/analytics?workspaceId=664abc000000000000000001&from=2025-01-01&to=2025-04-30" \
-H "X-Api-Key: rvlnk_your_api_key_here"
Відповідь 200 OK
{
"totals": {
"total": 1540,
"periodTotal": 320,
"unique": 210
},
"dailyTraffic": {
"2025-04-28": 45,
"2025-04-29": 61,
"2025-04-30": 38
},
"countries": {
"UA": { "title": "Ukraine", "value": 180, "flag": "UA" },
"DE": { "title": "Germany", "value": 54, "flag": "DE" }
},
"cities": {
"Kyiv": { "title": "Kyiv", "value": 92, "flag": "UA" }
},
"devices": {
"mobile": { "title": "Mobile", "value": 210 },
"desktop": { "title": "Desktop", "value": 110 }
},
"browsers": {
"Chrome": { "title": "Chrome", "value": 198 }
},
"os": {
"Android": { "title": "Android", "value": 140 }
},
"referrers": {
"instagram.com": { "title": "instagram.com", "value": 95 },
"Direct": { "title": "Direct", "value": 225 }
},
"rulesStats": {
"rule-id-1": {
"name": "Ukraine mobile",
"targetUrl": "https://example.com/ua",
"clicks": 140,
"uniqueClicks": 95,
"referrers": {
"Direct": { "title": "Direct", "value": 80 }
}
}
},
"abVariantsStats": {
"1714000000000": {
"name": "Variant A",
"targetUrl": "https://example.com/a",
"clicks": 185,
"uniqueClicks": 122,
"referrers": {}
}
}
}
Опис полів:
| Поле | Опис |
|---|---|
totals.total | Загальна кількість кліків цього посилання за весь час |
totals.periodTotal | Кліки в межах запитаного діапазону дат |
totals.unique | Унікальні відвідувачі в межах діапазону дат (за IP + user agent) |
dailyTraffic | Кліки за день у межах діапазону дат. Присутній кожен день діапазону, навіть якщо значення 0 |
countries / cities / devices / browsers / os | Розподіл за виміром. Кожен ключ відповідає { title, value, flag? } |
referrers | Джерела трафіку. "Direct" означає відсутність заголовка referrer |
rulesStats | Розподіл за правилами. Кожен ключ це ID правила. Містить name, targetUrl, clicks, uniqueClicks та referrers |
abVariantsStats | Розподіл за A/B-варіантами. Кожен ключ це ID варіанта. Містить name, targetUrl, clicks, uniqueClicks та referrers. Порожній об'єкт, якщо A/B-тест не ввімкнено |
Відповіді з помилками
| Статус | Тіло | Причина |
|---|---|---|
400 | {"error": "Invalid link id."} | id не є коректним ObjectId |
404 | {"error": "Link not found in this workspace."} | Посилання не існує або належить іншому робочому простору |
Аналітика всіх посилань
GET /links/analytics
Повертає зведену статистику кліків по всіх посиланнях робочого простору. Доступно лише власнику й менеджерам робочого простору.
Запит
GET https://api.revolink.link/apiv1/links/analytics?workspaceId=...&from=...&to=...
X-Api-Key: rvlnk_your_api_key_here
Параметри запиту
| Параметр | Тип | Обов'язковий | Опис |
|---|---|---|---|
workspaceId | string | ✅ | ObjectId робочого простору |
from | string | — | Початкова дата у форматі YYYY-MM-DD. За замовчуванням початок часів |
to | string | — | Кінцева дата у форматі YYYY-MM-DD. За замовчуванням сьогодні |
Приклад
curl "https://api.revolink.link/apiv1/links/analytics?workspaceId=664abc000000000000000001&from=2025-04-01&to=2025-04-30" \
-H "X-Api-Key: rvlnk_your_api_key_here"
Відповідь 200 OK
{
"totals": {
"total": 8420,
"periodTotal": 1750,
"unique": 1120
},
"dailyTraffic": {
"2025-04-01": 52,
"2025-04-02": 78
},
"links": {
"664abc123def456789000001": { "title": "Summer campaign", "value": 920 },
"664abc123def456789000002": { "title": "Product launch", "value": 830 }
},
"countries": {
"UA": { "title": "Ukraine", "value": 640, "flag": "UA" }
},
"cities": {
"Kyiv": { "title": "Kyiv", "value": 310, "flag": "UA" }
},
"devices": {
"mobile": { "title": "Mobile", "value": 980 },
"desktop": { "title": "Desktop", "value": 770 }
},
"browsers": {
"Chrome": { "title": "Chrome", "value": 1050 }
},
"os": {
"Android": { "title": "Android", "value": 620 },
"iOS": { "title": "iOS", "value": 360 }
}
}
Опис полів:
| Поле | Опис |
|---|---|
totals.total | Загальна кількість кліків по всіх посиланнях робочого простору в межах діапазону дат |
totals.periodTotal | Те саме, що й total: кліки, відфільтровані за запитаним діапазоном дат |
totals.unique | Унікальні відвідувачі в діапазоні дат |
links | Розподіл за посиланнями. Кожен ключ це ObjectId посилання. Значення містить title (назва посилання) і value (кількість кліків) |
dailyTraffic | Кліки за день по всіх посиланнях. Присутній кожен день діапазону |
countries / cities / devices / browsers / os | Зведений розподіл по всіх посиланнях. Кожен ключ відповідає { title, value, flag? } |
Відповіді з помилками
| Статус | Тіло | Причина |
|---|---|---|
403 | {"error": "Only workspace owner or manager can access all links analytics."} | Автентифікований користувач є звичайним учасником, а не власником чи менеджером |
INFO
Тіла відповідей і повідомлення про помилки API завжди англійською, як їх повертає сервер. Переклад стосується лише описів.