REST API для создания коротких ссылок и получения аналитики. Подходит для интеграции из любого языка — нужно лишь передать ваш API-ключ.
Authorization.curl -X POST https://link.tj/api/v1/links \
-H "Authorization: Bearer lnktj_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/a/very/long/link"}'Каждый запрос должен содержать заголовок Authorization: Bearer <key> (либо X-Api-Key: <key>). Базовый URL:
https://link.tj/api/v1Ключи привязаны к вашему аккаунту, поэтому действуют те же лимиты тарифа, что и в интерфейсе. CORS открыт (*), API можно вызывать из браузера.
Условия и требования
Мобильные и нативные приложения получают токен по email и паролю: POST /api/auth/token. В ответ приходит JWT, который передаётся в /api/v1/* так же, как API-ключ: Authorization: Bearer <token>. Если включена 2FA, добавьте поле code; без кода вернётся 401 с error: needs_2fa.
/api/auth/tokenЛогин по email/паролю → JWT для /api/v1/*. Тело: email, password, code? (для 2FA).
Как использовать: Отправьте email и пароль, чтобы получить JWT для приложения.
curl -X POST https://link.tj/api/auth/token \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"••••••••"}'Ответ
{
"token": "eyJhbGciOi...",
"user": { "id": "clx...", "email": "you@example.com", "name": "You", "role": "USER" }
}Условия и требования
/api/v1/meАккаунт, тариф и расход лимитов за месяц.
Как использовать: Запросите профиль, тариф и расход лимитов за текущий месяц.
curl https://link.tj/api/v1/me \
-H "Authorization: Bearer lnktj_API_KEY"Ответ
{
"data": {
"email": "you@example.com",
"plan": { "name": "Free", "linkLimit": 5, "clickLimit": 1000 },
"usage": { "linksUsed": 2, "linksRemaining": 3, "clicksUsed": 87 }
}
}Условия и требования
/api/v1/linksСоздать короткую ссылку. Поля: url (обязательно для kind=url), slug (необязательно), title (необязательно), kind (необязательно: url | wifi | vcard | text), payload (объект для типов кроме url).
Типы wifi/vcard/text доступны на платных тарифах (иначе 403). Такой QR ведёт на отслеживаемую страницу /l/{slug}.
Как использовать: Отправьте JSON с полем url (обычная ссылка) или kind + payload (типизированная).
curl -X POST https://link.tj/api/v1/links \
-H "Authorization: Bearer lnktj_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","slug":"promo","title":"Promo"}'Пример: Wi-Fi (платный тариф)
curl -X POST https://link.tj/api/v1/links \
-H "Authorization: Bearer lnktj_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"wifi","title":"Guest Wi-Fi","payload":{"ssid":"MyNet","encryption":"WPA","password":"secret123"}}'Ответ 201
{
"data": {
"id": "clx...",
"slug": "promo",
"shortUrl": "https://link.tj/promo",
"kind": "url",
"originalUrl": "https://example.com",
"summary": null,
"clicks": 0
},
"usage": { "linksUsed": 3, "linkLimit": 5, "linksRemaining": 2 }
}Ответ 402 — достигнут лимит тарифа
{
"error": "limit_reached",
"code": "limit_reached",
"recommend": { "name": "Core", "priceMonthly": 8, "linkLimit": 100 }
}Условия и требования
/api/v1/linksСписок ваших ссылок. Параметры: limit (1–100), offset.
Как использовать: Получите свои ссылки постранично.
curl "https://link.tj/api/v1/links?limit=20&offset=0" \
-H "Authorization: Bearer lnktj_API_KEY"Ответ — список
{
"total": 42,
"limit": 20,
"offset": 0,
"data": [
{ "id": "clx...", "slug": "promo", "shortUrl": "https://link.tj/promo", "kind": "url",
"originalUrl": "https://example.com", "clicks": 128, "isActive": true }
]
}Условия и требования
/api/v1/links/{id_or_slug}Детали ссылки и аналитика кликов (по странам, устройствам, источникам).
Как использовать: Передайте id или slug ссылки, чтобы получить детали и аналитику кликов.
curl https://link.tj/api/v1/links/promo \
-H "Authorization: Bearer lnktj_API_KEY"Ответ — детали и аналитика
{
"data": {
"id": "clx...", "slug": "promo", "shortUrl": "https://link.tj/promo",
"originalUrl": "https://example.com", "clicks": 128, "isActive": true,
"analytics": {
"byCountry": [ { "name": "TJ", "count": 80 }, { "name": "RU", "count": 48 } ],
"byDevice": [ { "name": "mobile", "count": 95 }, { "name": "desktop", "count": 33 } ],
"byReferrer": [ { "name": "t.me", "count": 60 }, { "name": "Unknown", "count": 68 } ]
}
}
}Условия и требования
/api/v1/links/{id_or_slug}Удалить ссылку и её аналитику.
Как использовать: Передайте id или slug, чтобы удалить ссылку.
curl -X DELETE https://link.tj/api/v1/links/promo \
-H "Authorization: Bearer lnktj_API_KEY"Условия и требования
Подключите URL в разделе «Вебхуки» кабинета — мы будем отправлять POST-запрос на ваш сервер при наступлении события. Тело: { event, data, ts }. Заголовки: X-LinkTJ-Event и X-LinkTJ-Signature.
Как использовать: Добавьте URL и подпишитесь на события в разделе «Вебхуки», затем проверяйте подпись на своём сервере.
link.created — link.created — создана короткая ссылка. data: { id, slug, url }.subscription.created — subscription.created — оформлена или продлена подписка. data: { plan, amount, interval }.POST https://your-server.example/webhook
X-LinkTJ-Event: link.created
X-LinkTJ-Signature: <hmac-sha256-hex>
Content-Type: application/json
{ "event": "link.created", "data": { "id": "clx...", "slug": "promo", "url": "https://example.com" }, "ts": "2026-01-01T12:00:00.000Z" }Заголовок X-LinkTJ-Signature — это HMAC-SHA256 от тела запроса, подписанный секретом вебхука (whsec_…). Сравните его, чтобы убедиться, что запрос пришёл от link.tj.
Условия и требования
Внешний планировщик может запускать продление подписок и еженедельные отчёты, передав секрет: ?secret=<CRON_SECRET>. Параметр task: renew, weekly или all (по умолчанию all).
Как использовать: Настройте внешний планировщик на вызов эндпоинта с секретом.
/api/cron?secret=&task=renew|weekly|allcurl -X POST "https://link.tj/api/cron?secret=CRON_SECRET&task=renew"Условия и требования
| 200 / 201 | Успешно |
| 400 | Некорректный запрос (например, неверный URL или slug) |
| 401 | Отсутствует или неверный API-ключ |
| 402 | Достигнут лимит тарифа — нужно повысить тариф |
| 403 | Доступ запрещён (например, типы wifi/vcard/text на бесплатном тарифе) |
| 404 | Ссылка не найдена |
| 409 | Slug уже занят |
| 429 | Слишком много запросов — сработал лимит частоты |