Популярні категорії
Регіони
Нічого не знайдено
Популярні запити
Зміст

AliBord API v1

Публічна REST API для інтеграції вашого бізнесу з AliBord. Створюйте оголошення, отримуйте статистику, керуйте каталогом.

Вступ

AliBord API — це REST-інтерфейс. Базовий URL: https://www.alibord.com

Усі запити та відповіді у форматі JSON у кодуванні UTF-8.

Усі дати — в часовому поясі Europe/Kyiv у форматі ISO 8601.

API версії v1. Версія є частиною шляху URL. Ми зобов’язуємося не ламати зворотну сумісність у межах однієї версії — нові поля можуть додаватися, існуючі не змінюються.

Як отримати API-ключ

  1. Зайдіть у свій особистий кабінет AliBord.
  2. Відкрийте розділ «Налаштування» → «API та інтеграції».
  3. Натисніть «Створити ключ», виберіть потрібні scopes та додайте whitelist.
  4. Скопіюйте ключ одразу — після закриття вікна він більше не показується.

Автентифікація

Кожен запит має містити заголовок Authorization з Bearer-токеном:

Authorization: Bearer sk_live_abcdef1234567890abcdef1234567890abcdef1234567890
Ніколи не розкривайте ключ у фронтенд-коді. Користуйтеся серверним проксі або бекендом. Ключ можна деактивувати в кабінеті у будь-який момент.

Whitelist (IP / домени)

Для безпеки кожен API-ключ повинен мати whitelist. Доступ до API можливий лише з вказаних IP-адрес і доменів.

ПолеРольПриклад
allowed_ipsБілий список IP — обов'язковий, перевіряється сервером192.0.2.10, 203.0.113.5
allowed_domainsДозволені домени — використовуються для CORS (браузерні запити)my-shop.com, api.my-shop.com
IP — єдиний надійний захист. Заголовки Origin / Referer легко підробити з curl/сервера, тому домен не є замком — лише CORS-налаштуванням для браузерних запитів.

Сервер-сайд: якщо IP клієнта не у whitelist — одразу 403 ip_not_whitelisted. Якщо whitelist порожній — 403 whitelist_incomplete.

Для браузера: додайте ваш домен (наприклад, my-shop.com) у whitelist — інакше браузер заблокує запит через CORS.

Scopes (права доступу)

Scopes — це «дозволи», які обмежують, що саме може ключ. Призначайте лише потрібні — за принципом мінімальних прав.

ScopeДозволяє
listings:readЧитати свої оголошення, категорії, атрибути, міста
listings:writeСтворювати і редагувати оголошення, завантажувати медіа

Якщо ключу бракує scope — API повертає 403 scope_required з назвою необхідного scope у полі hint.

Ліміти запитів

Залежно від типу акаунта ключ має різні ліміти на хвилину і на добу.

ЛімітОсобистий акаунтБізнес-акаунт
Запитів на хвилину60600
Запитів на добу5 000100 000

При перевищенні — 429 rate_limit_exceeded або 429 daily_limit_exceeded. Поточний стан можна дивитися у /api/v1/ping.

HTTP-методи

API використовує стандартні HTTP-методи.

МетодПризначенняТілоІдемпотентний
GETОтримання даних (read-only)так
POSTСтворення сутності / виконання діїJSONні
PUT / PATCHПовне / часткове оновленняJSONтак
DELETEВидаленнятак

Заголовки запиту

ЗаголовокОбов'язковийПриклад
AuthorizationтакBearer sk_live_...
Acceptрекомендованоapplication/json
Content-Typeдля POST/PUT/PATCHapplication/json; charset=utf-8
Origin / Refererавтоматично (браузер)використовується для перевірки whitelist
User-Agentопціональнодля діагностики в логах

Тіло запиту

Для POST/PUT/PATCH тіло передається у форматі JSON із заголовком Content-Type: application/json.

Для GET параметри передаються у query-рядку.

Приклад:

POST /api/v1/listings
Authorization: Bearer sk_live_...
Content-Type: application/json

{
  "title": "iPhone 17 Pro Max 256Gb",
  "price": 55000,
  "currency": "UAH",
  "condition": "new",
  "city_ref": "db5c88d0-391c-11dd-90d9-001a92567626",
  "photos": ["https://cdn.example.com/1.jpg", "https://cdn.example.com/2.jpg"]
}

Формат відповіді

Усі відповіді — JSON з полем ok. true — успіх, false — помилка.

Успіх

{
  "ok": true,
  ...
}

Помилка

{
  "ok": false,
  "error": "error_code",
  "hint": "...",
  ...
}

Для колекцій використовується поле count і масив з назвою сутності:

{
  "ok": true,
  "count": 2,
  "listings": [ { ... }, { ... } ]
}

HTTP-коди відповіді

КодЗначення
200 OKУспішний запит
201 CreatedСутність створено
204 No ContentУспіх без тіла відповіді
400 Bad RequestПомилка у форматі запиту (невалідний JSON, відсутні поля)
401 UnauthorizedНевалідний / відсутній токен
402 Payment RequiredНедостатньо коштів на балансі (для платних дій)
403 ForbiddenДоступ заборонено (whitelist / scope / статус ключа)
404 Not FoundРесурс не знайдено
405 Method Not AllowedМетод не дозволений для цього endpoint
413 Payload Too LargeРозмір тіла перевищує ліміт
415 Unsupported Media TypeНевалідний Content-Type
422 Unprocessable EntityДані пройшли валідацію формату, але не пройшли бізнес-правила
429 Too Many RequestsПеревищено ліміт запитів
500 Internal Server ErrorВнутрішня помилка сервера

Коди помилок

При помилці тіло містить поле error з машинним кодом і hint з людським поясненням.

{ "ok": false, "error": "error_code", ... }
HTTPCodeОпис
401missing_bearer_tokenЗаголовок Authorization відсутній або не містить Bearer-токен
401invalid_keyКлюч не знайдено, деактивовано або має невірний формат
403key_suspended / key_revokedКлюч тимчасово призупинено або видалено власником
403whitelist_incompleteУ ключа не заданий whitelist — доступ заборонено
403ip_not_whitelistedIP запиту не в whitelist ключа
403scope_requiredУ ключа немає необхідного scope — див. hint
429rate_limit_exceededПеревищено ліміт запитів за хвилину
429daily_limit_exceededПеревищено добовий ліміт запитів

GET /api/v1/ping

Перевірка ключа і швидкий погляд на ліміти / scopes / IP клієнта.

Відповідь

{
  "ok": true,
  "message": "pong",
  "key_id": 1,
  "key_prefix": "sk_live_abcdef12",
  "user_id": 36,
  "account_type": "personal",
  "scopes":         ["listings:read", "listings:write"],
  "scopes_granted": ["listings:read", "listings:write"],
  "rate_limit_per_minute": 60,
  "daily_limit": 5000,
  "total_requests": 42,
  "server_time": "2026-04-20T12:34:56+03:00",
  "your_ip": "203.0.113.5"
}

GET /api/v1/my/listings

Список власних оголошень з пагінацією по курсору. Scope: listings:read.

Query-параметри

ПараметрDefaultОпис
langukМова відповіді: uk, ru, en
statusactiveactive, sold, archived, inactive, all
limit20Розмір сторінки, 1–100
cursorID останнього оголошення попередньої сторінки
fieldsусі поляСписок полів через кому — щоб отримати тільки потрібні (економія трафіку)

Відповідь

{
  "ok": true,
  "lang": "uk",
  "count": 2,
  "next_cursor": 118,
  "listings": [
    {
      "id": 123,
      "slug": "iphone-17-pro-max-256gb",
      "title": "iPhone 17 Pro Max 256Gb",
      "price": 55000,
      "currency": "UAH",
      "condition": "new",
      "city": "Київ",
      "status": "active",
      "views": 248,
      "vip": true,
      "top": false,
      "vip_until": "2026-05-20 00:00:00",
      "top_until": null,
      "photo":  "https://cdn.alibord.com/listings/3/abc.webp",
      "photos": [
        "https://cdn.alibord.com/listings/3/abc.webp",
        "https://cdn.alibord.com/listings/3/def.webp"
      ],
      "url": "https://alibord.com/uk/board/iphone-17-pro-max-256gb",
      "created_at": "2026-04-15 10:22:01"
    }
  ]
}

Значення next_cursor передавайте у параметр cursor наступного запиту. Якщо сторінка не повна — next_cursor відсутній.

Поля

ПолеТипОпис
idintID оголошення
slugstringSEO-адреса
titlestringЗаголовок вибраною мовою
pricenumberЦіна, може бути дробовою
currencystringUAH, USD, EUR
conditionstring \| nullnew, used
citystring \| nullНазва міста вибраною мовою
statusstringactive, sold, archived, inactive
viewsintКількість переглядів
vip, topboolЧи активне VIP / TOP просування
vip_until, top_untildatetime \| nullДо якої дати діє просування
photostring \| nullГоловне фото (перше з масиву)
photosarrayУсі фото оголошення
urlstringПряме посилання на сторінку оголошення
created_atdatetimeДата створення
Оптимізація: для списків використовуйте fields і limit — відповідь буде меншою, і ліміти витрачаються економніше.

GET /api/v1/my/listings/{id}

Повні дані одного оголошення, включно з описом, атрибутами, контактами та статусом модерації. Scope: listings:read.

Відповідь

{
  "ok": true,
  "lang": "uk",
  "listing": {
    "id": 123,
    "slug": "iphone-17-pro-max-256gb",
    "title": "iPhone 17 Pro Max 256Gb",
    "description": "...",
    "price": 55000,
    "currency": "UAH",
    "condition": "new",
    "city": "Київ",
    "city_ref": "e71f8bb8-4b33-11e4-ab6d-005056801329",
    "category_id": 42,
    "status": "pending",
    ...
  },
  "moderation": {
    "decision":    "pending",
    "reason":      null,
    "reviewed_at": null
  }
}

Блок moderation повертається лише для оголошень у стані pending або blocked. У reason буде причина блокування, якщо модератор її залишив.

POST /api/v1/my/listings

Створення нового оголошення. Scope: listings:write.

Модерація: оголошення від API проходять перевірку так само, як оголошення з сайту. Після створення статус = pending, публікація — після схвалення модератором.

Тіло запиту (JSON)

ПолеТипОбов'язковеОпис
titlestringтакЗаголовок, 5–120 символів
descriptionstringтакОпис, 20–5000 символів
pricenumberтак*Ціна. Необов'язкове якщо price_type = exchange / free
price_typestringніsell, exchange, free
currencystringніUAH, USD, EUR
category_idintтакID категорії (див. /categories)
conditionstringніnew / used
city_refstringтак*UUID міста з /cities/search
photosarray<string>ніURL фото (до 12). Отримати можна через /upload/photo
photos_wmarray<string>ніURL фото з водяним знаком, у тому ж порядку що і photos
photos_3darray<string>ніURL кадрів 3D-огляду (див. 3D-віджет)
video_url / video_thumbnailstringніURL відео і його прев'ю (див. /upload/video)
attributesobjectніОб'єкт з атрибутами категорії (див. /categories/{id}/attributes)
contact_name / contact_phonestringніІм'я і телефон (якщо не вказати — беруться з профілю)
hide_phoneboolніПриховати телефон у оголошенні

Відповідь

HTTP/1.1 201 Created

{
  "ok":         true,
  "listing_id": 2468,
  "slug":       "iphone-17-pro-max-256gb",
  "status":     "active",
  "url":        "https://alibord.com/uk/board/iphone-17-pro-max-256gb"
}
Захист від дублів: одразу після створення система перевіряє, чи не було такого ж оголошення за останні 24 години. Якщо було — повертається 422 duplicate.

PUT PATCH /api/v1/my/listings/{id}

Часткове редагування оголошення. Передавайте лише ті поля які треба оновити — решта залишаються як були. Scope: listings:write.

Тіло (JSON, усі поля опційні)

{
  "title":         "iPhone 17 Pro Max 256Gb",
  "description":   "...",
  "price":         52000,
  "currency":      "UAH",
  "condition":     "new",
  "category_id":   42,
  "city_ref":      "e71f8bb8-...",
  "contact_name":  "...",
  "contact_phone": "+380...",
  "hide_phone":    false,
  "delivery":      { ... },
  "photos":        ["https://...", "..."],
  "photos_wm":     ["https://...", "..."],
  "photos_3d":     ["https://...", "..."],
  "video_url":     "https://...",
  "video_thumbnail": "https://...",
  "attributes":    { "brand": "apple", "memory_gb": 256 }
}
Медіа: якщо передаєте photos, photos_3d або video_url — це повна заміна відповідного набору. Щоб залишити попереднє — не передавайте поле взагалі.
Модерація: якщо оголошення перед редагуванням було active, після оновлення воно автоматично переводиться у pending і проходить перевірку заново — як на сайті.
{ "ok": true, "listing_id": 2468, "status": "pending" }

POST /api/v1/my/listings/{id}/status

Зміна статусу оголошення — активувати або деактивувати. Scope: listings:write. Дії «продано» і «видалити» через API свідомо недоступні — виконуйте їх з сайту або адмінки.

Тіло (JSON)

{ "status": "inactive" }

Можливі значення

ЗначенняЩо робить
activeПовернути в публікацію (дозволено лише з inactive/sold)
inactiveДеактивувати — оголошення приховується з каталогу
Перехід у active дозволений лише зі стану inactive. З pending / blocked / sold активувати через API не можна — це робить модератор/адмін на сайті.

GET /api/v1/categories

Дерево категорій для створення оголошення. Назви — вибраною мовою (?lang=uk|ru|en). Scope: listings:read.

{
  "ok": true,
  "lang": "uk",
  "categories": [
    {
      "id": 1,
      "slug": "electronics",
      "name": "Електроніка",
      "children": [
        { "id": 11, "slug": "phones", "name": "Телефони", "children": [...] }
      ]
    }
  ]
}

GET /api/v1/categories/{id}/attributes

Атрибути конкретної категорії — потрібні у полі attributes при створенні оголошення. Scope: listings:read.

{
  "ok": true,
  "category_id": 11,
  "attributes": [
    {
      "code": "brand",
      "name": "Виробник",
      "type": "select",
      "required": true,
      "options": [
        { "value": "apple", "label": "Apple" },
        { "value": "samsung", "label": "Samsung" }
      ]
    },
    { "code": "memory_gb", "name": "Пам'ять, ГБ", "type": "number" }
  ]
}

Типи: text, number, select, boolean, range. Для select значення передається як value з масиву options.

GET /api/v1/cities/search

Пошук міст для поля city_ref. Повертає ref Нової Пошти. Scope: listings:read.

Query-параметри

ПараметрDefaultОпис
qРядок пошуку (min 2 символи)
langukМова назви: uk, ru, en
limit10Максимум результатів (1–50)
{
  "ok": true,
  "cities": [
    {
      "ref":   "e71f8bb8-4b33-11e4-ab6d-005056801329",
      "name":  "Київ",
      "type":  "м.",
      "region": "Київська",
      "label": "м. Київ, Київська",
      "warehouses": 1823
    }
  ]
}

POST /api/v1/ai/suggest-category

AI-підказка категорії за заголовком і описом. Зручно для автоматичного заповнення форми. Scope: listings:write.

{
  "title": "iPhone 17 Pro Max 256Gb",
  "description": "...",
  "lang": "uk"
}

Успіх

{
  "ok":            true,
  "category_id":   117,
  "category_path": "Електроніка › Телефони › Apple",
  "category_slug": "apple"
}

POST /api/v1/upload/photo

Завантаження фото на CDN — отримати URL для поля photos при створенні оголошення. Scope: listings:write.

Формат: multipart/form-data, поле file. Ліміт — 12 MB. Підтримуються JPG, PNG, WebP, HEIC. Автоматично конвертується у WebP і зменшується до 1600px.

curl -X POST "https://www.alibord.com/api/v1/upload/photo" \
  -H "Authorization: Bearer sk_live_..." \
  -F "file=@/path/to/image.jpg"
HTTP/1.1 201 Created

{
  "ok": true,
  "url":    "https://pub-...r2.dev/listings/36/1776203001_123.webp",
  "url_wm": "https://pub-...r2.dev/pub/36/abc123...webp",
  "width":  1200,
  "height": 1600
}
Повертається пара URL: url — оригінал, url_wm — із водяним знаком. При створенні оголошення використовуйте обидва набори відповідно у photos / photos_wm.

POST /api/v1/upload/video

Завантаження короткого відео (до 60 сек) для оголошення. Scope: listings:write.

  • Формати: MP4, MOV, WebM (H.264 або H.265)
  • Макс. розмір: 50 MB, макс. тривалість: 60 сек
  • На оголошення — одне відео
HTTP/1.1 201 Created

{
  "ok": true,
  "url":       "https://pub-...r2.dev/listings/36/1776213111_456.mp4",
  "thumbnail": "https://pub-...r2.dev/listings/36/1776213111_456_thumb.webp"
}

3D-віджет

Готовий віджет для захоплення 3D-огляду товару через камеру пристрою. Вбудовується одним рядком, завантажує фото через ваш серверний проксі (щоб не розкривати API-ключ).

Вбудовування

<script src="https://www.alibord.com/widget/capture3d.js"></script>

<button onclick="startCapture()">3D</button>

<script>
function startCapture() {
  AliBord.capture3d({
    uploadEndpoint: '/my-proxy/upload-photo',
    lang: 'uk',
    onComplete: (urls) => console.log(urls.length),
    onCancel:   () => {},
    onError:    (err) => console.error(err),
  });
}
</script>

Як працює

  • Користувач натискає кнопку «3D»
  • Віджет просить доступ до камери і відкриває fullscreen
  • Знімається серія кадрів (автоматично або по натисканню)
  • Кадри відправляються POST-запитами на ваш uploadEndpoint
  • Ваш сервер пересилає їх на /api/v1/upload/photo з API-ключем
  • У колбек onComplete(urls) повертається масив URL — передавайте його у полі photos_3d при створенні оголошення
Безпека: ніколи не викликайте /api/v1/upload/photo напряму з браузера — це розкриває API-ключ. Завжди використовуйте серверний проксі.

Приклад серверного проксі (PHP)

<?php
$API_KEY = getenv('ALIBORD_API_KEY');

if (empty($_FILES['file'])) {
    http_response_code(400);
    echo json_encode(['ok'=>false, 'error'=>'no_file']); exit;
}

$ch = curl_init('https://www.alibord.com/api/v1/upload/photo');
$cfile = new CURLFile($_FILES['file']['tmp_name'], $_FILES['file']['type'], $_FILES['file']['name']);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $API_KEY],
    CURLOPT_POSTFIELDS     => ['file' => $cfile],
    CURLOPT_TIMEOUT        => 60,
]);
$resp = curl_exec($ch);
http_response_code((int)curl_getinfo($ch, CURLINFO_HTTP_CODE));
header('Content-Type: application/json; charset=utf-8');
echo $resp;

Модерація

Усі оголошення, створені через API, проходять ту саму модерацію, що й оголошення з сайту.

  • Оголошення із безпечних категорій зазвичай публікуються автоматично — відразу active.
  • Решта переходять у pending і перевіряються модератором (~15 хв у робочий час).
StatusЩо робить
pendingЧекає перевірки модератором
activeОпубліковано і видно в каталозі
blockedВідхилено модератором — див. moderation.reason
soldПозначено проданим
archivedПеренесено в архів за терміном
inactiveДеактивовано власником

Щоб слідкувати за станом, запитуйте GET /my/listings/{id} — у блоці moderation буде рішення і причина (якщо є).

Приклад: cURL

# Список своїх оголошень (англійською)
curl -H "Authorization: Bearer sk_live_..." \
     "https://www.alibord.com/api/v1/my/listings?lang=en&limit=20"

# Тільки потрібні поля — економимо трафік
curl -H "Authorization: Bearer sk_live_..." \
     "https://www.alibord.com/api/v1/my/listings?fields=id,title,price,currency,photo&limit=50"

# Створення нового оголошення
curl -X POST "https://www.alibord.com/api/v1/my/listings" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "iPhone 17 Pro Max 256Gb",
    "description": "...",
    "price": 55000,
    "currency": "UAH",
    "category_id": 42,
    "condition": "new",
    "city_ref": "e71f8bb8-4b33-11e4-ab6d-005056801329",
    "photos": ["https://my-shop.com/images/iphone-1.jpg"],
    "contact_phone": "+380501234567"
  }'

Приклад: PHP

<?php
$API_BASE = 'https://www.alibord.com';
$API_KEY  = 'sk_live_...';

$ch = curl_init($API_BASE . '/api/v1/my/listings?lang=en&limit=10&fields=id,title,price,currency,city,photo');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $API_KEY,
        'Accept: application/json',
    ],
]);
$body = curl_exec($ch);
$data = json_decode($body, true);
curl_close($ch);

if (!empty($data['ok'])) {
    foreach ($data['listings'] as $l) {
        echo $l['title'] . ' — ' . $l['price'] . ' ' . $l['currency'] . "\n";
    }
} else {
    echo 'Error: ' . ($data['error'] ?? 'unknown');
}

Приклад: JavaScript (fetch)

// УВАГА: у браузері напряму — тільки через ваш серверний проксі! Ключ не має потрапити у фронтенд.
const params = new URLSearchParams({
  lang: 'uk', limit: '20',
  fields: 'id,title,price,currency,city,photo,url'
});
const r = await fetch('https://www.alibord.com/api/v1/my/listings?' + params, {
  headers: { 'Authorization': 'Bearer sk_live_...' }
});
const data = await r.json();
if (data.ok) {
  data.listings.forEach(l => console.log(l.title, l.price, l.currency, l.city));
} else {
  console.error(data.error);
}
CORS: для браузерних запитів домен, з якого йде fetch, має бути в allowed_domains ключа. Інакше браузер заблокує відповідь.
Профіль
Тема оформлення
Світла
Світла
Темна
Системна
Мова
Українська