API для разработчиков

Документация API

Создавайте защищённые ссылки, получайте аналитику с уважением к приватности и фиксируйте конверсии из своего продукта.

01

Выполните первый запрос

API предназначен для связи сервер-сервер. Никогда не помещайте токен в браузерный JavaScript или публичную сборку мобильного приложения.

  1. 1Подключите Pro или BusinessAPI доступен на поддерживаемых платных тарифах и во время пробного периода Pro.
  2. 2Создайте токен с нужными правамиВ консоли разработчика выберите только те права, которые нужны интеграции.
  3. 3Передавайте по HTTPSAuthorization: Bearer 4ul_live_…
  4. 4Храните как парольПолный токен показывается один раз. Немедленно отзовите его при возможной утечке.
curl "https://4ul.ink/api/v1/links?per_page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
02

Справочник endpoints

Доступ к любому объекту ограничен workspace, к которому привязан токен.

МетодПутьПравоРезультат
GET/api/v1/linkslinks:readСписок ссылок с пагинацией
POST/api/v1/linkslinks:writeСоздаёт защищённую ссылку
PATCH/api/v1/links/{id}links:writeОбновляет переданные поля
DELETE/api/v1/links/{id}links:writeОтключает без удаления аналитики
GET/api/v1/links/{id}/analyticsanalytics:readАгрегированная аналитика
POST/api/v1/conversionslinks:writeЗаписывает атрибутированное событие
GET/api/v1/domainsdomains:readПользовательские домены
POST/api/v1/domainsdomains:writeПодключить домен
POST/api/v1/domains/{id}/verifydomains:writeПроверить DNS
DELETE/api/v1/domains/{id}domains:writeУдалить
GET/api/v1/webhookswebhooks:readWebhook-адреса
POST/api/v1/webhookswebhooks:writeДобавить endpoint
PATCH/api/v1/webhooks/{id}webhooks:writeОбновляет переданные поля
POST/api/v1/webhooks/{id}/testwebhooks:writeОтправить тест
POST/api/v1/webhooks/{id}/rotate-secretwebhooks:writeСменить секрет
DELETE/api/v1/webhooks/{id}webhooks:writeУдалить
03

Запросы и ответы

Названия полей ниже точно соответствуют работающему API v1.

POST

Создать ссылку

links:write
{
    "destination_url": "https://example.com",
    "slug": "launch",
    "title": "Launch article"
}
destination_url
Обязательный публичный URL с HTTP или HTTPS.
title
Необязательно, до 190 символов.
slug
Необязательный alias, от 3 до 80 символов.
201

Ответ со ссылкой

application/json
{
  "data": {
    "id": 123,
    "slug": "launch",
    "short_url": "https://4ul.ink/launch",
    "destination_url": "https://example.com/article",
    "title": "Launch article",
    "click_count": 0,
    "is_active": true,
    "created_at": "2026-07-25 12:00:00"
  }
}
GET

Получить ссылки

?page=1&per_page=25
{
  "data": [{ "id": 123, "slug": "launch", "is_active": true }],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
  }
}

per_page принимает значения от 1 до 100. Объекты ссылок используют полную структуру ответа, показанную выше.

GET

Получить аналитику

analytics:read
/api/v1/links/123/analytics?period=custom
  &from=2026-07-01
  &to=2026-07-20

Периоды: 7, 30, 90 или custom. Ответ содержит обзор, сравнения, качество трафика, конверсии, данные по дням, аудитории и часам — но никогда исходные IP посетителей.

PATCH

Обновить ссылку

/api/v1/links/123
{
  "destination_url": "https://example.com/new",
  "title": "New title",
  "slug": "new-alias",
  "is_active": true
}

Меняются только переданные поля. Изменение назначения автоматически ставит новую проверку Nova Shield в очередь.

POST

Записать конверсию

/api/v1/conversions
{
  "click_token": "4ul_click_…",
  "event": "sale",
  "external_id": "order_1042",
  "amount": 49.00,
  "currency": "USD"
}

События: lead, sale или refund. Дубликат внешнего события возвращает HTTP 409 и никогда не учитывается дважды.

Права токена

links:read
получает список ссылок.
links:write
создаёт, обновляет и отключает ссылки, записывает конверсии.
analytics:read
получает аналитику ссылок.
domains:read / domains:write
Пользовательские домены
webhooks:read / webhooks:write
Подписанные webhooks

Лимиты запросов

Токен допускает 120 запросов в минуту и ограничен месячным лимитом workspace. Для аналитики действует дополнительный лимит 60 запросов в минуту. HTTP 429 содержит Retry-After и RateLimit. Обычные редиректы продолжают работать.

Идемпотентность

При создании ссылки передавайте Idempotency-Key длиной 8–128 печатных символов. Ключ действует в workspace 24 часа. Одинаковый повтор возвращает сохранённый ответ, а другие данные с тем же ключом — HTTP 409.

HTTP

Ошибки

Ошибки имеют единый JSON-формат. Основные статусы: 400 неверный JSON, 401 неверный токен, 403 нет права или тарифа, 404 объект не найден в workspace, 409 конфликт, 413 слишком большое тело, 415 неверный тип, 422 ошибка данных и 429 превышение лимита.

{
  "error": "destination_url must be a valid public HTTP or HTTPS URL.",
  "code": "invalid_destination",
  "field": "destination_url",
  "request_id": "req_7fd9c0c8d821e84b3d69d171",
  "error_details": {
    "code": "invalid_destination",
    "message": "destination_url must be a valid public HTTP or HTTPS URL.",
    "field": "destination_url",
    "request_id": "req_7fd9c0c8d821e84b3d69d171"
  }
}
HMAC

Проверяйте каждый webhook

События: link.created, link.updated, link.disabled, link.clicked, conversion.created, shield.status_changed и endpoint.test. Автодоставка выполняет до пяти попыток.

Webhook доступности shield.availability_changed содержит переходы состояния и ограниченную HTTP-диагностику без URL назначения.

Заголовки доставки

X-4ulink-Event: conversion.created
X-4ulink-Delivery: EVENT_UUID
X-4ulink-Timestamp: UNIX_TIMESTAMP
X-4ulink-Signature: sha256=HEX_HMAC

Проверка на PHP

$raw = file_get_contents('php://input');
$signed = $timestamp . '.' . $raw;
$expected = 'sha256=' . hash_hmac('sha256', $signed, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}

Используйте исходное тело запроса, сравнивайте подписи за постоянное время, отклоняйте timestamp старше пяти минут и храните X-4ulink-Delivery для идемпотентности повторов. Webhook должен использовать публичный HTTPS на порту 443.