Короткие ссылки в ваших приложениях

Создавайте ссылки, меняйте назначение и получайте данные через Teeb API. Те же проекты, адреса и лимиты, что в вашем кабинете.

1. Создайте ключ

В кабинете откройте «API-ключи», выберите разрешения и срок действия. Полный ключ показывается один раз. Сохраните его в переменной окружения вашего сервера.

2. Выберите проект

Запросите GET /api/v1/projects. Передайте id нужного проекта в поле project_id при создании ссылки.

3. Создайте ссылку

Отправьте адрес в POST /api/v1/links. В ответе data.short_url — готовая короткая ссылка. Настройте свой slug или оставьте его пустым.

4. Меняйте назначение

PATCH /api/v1/links/{id} обновляет только переданные поля. Короткий адрес сохраняется. Для печатной или популярной ссылки сервер сначала попросит проверить изменения и подтвердить их с причиной.

Первая ссылка через API

Замените PROJECT_ID числом из списка ваших проектов. Переменная TEEB_API_TOKEN должна содержать ваш ключ.

curl -X POST 'https://teeb.ru/api/v1/links' \
  -H "Authorization: Bearer $TEEB_API_TOKEN" \
  -H 'Idempotency-Key: launch-2026-09-09-001' \
  -H 'Content-Type: application/json' \
  --data '{"destination":"https://example.com/launch","project_id":PROJECT_ID,"title":"Запуск"}'

Сохраняйте data.id, чтобы позже управлять ссылкой. Ключ нельзя размещать в публичном JavaScript или передавать в URL.

Доступные методы

ЗапросДействиеРазрешения
GET /api/v1/projectsПроекты по возрастанию id: limit до 100, after для следующей страницыread
POST /api/v1/projectsСоздание проекта по названиюwrite
GET /api/v1/domainsСвои домены и состояние DNS и HTTPSread
POST /api/v1/domainsПодключить домен и получить готовые DNS-записиУправление доменами
POST /api/v1/domains/{id}/checkЗапросить фоновую проверку подключенияУправление доменами
GET /api/v1/linksСписок ссылок: limit от 1 до 100, before для следующей страницыread
POST /api/v1/linksСоздание ссылкиwrite
GET /api/v1/links/{id}Ссылка и общий счётчик переходов, включая ботовread
GET /api/v1/links/{id}/availabilityРезультат фоновой проверки доступности назначенияread
PATCH /api/v1/links/{id}Изменение полей, пауза или возобновлениеwrite
DELETE /api/v1/links/{id}Удаление ссылки без повторного использования адресаwrite
GET · PUT /api/v1/links/{id}/scenariosСвободное расписание, сообщения и распределение по 2–10 вариантамread · write
POST /api/v1/links/{id}/scenarios/previewПроверка сценария на выбранную дату без записи переходаread
GET · PATCH /api/v1/links/{id}/protectionИспользование в печати и защита опубликованных материаловread · управление пространством
POST /api/v1/links/{id}/changes/previewПроверка конкретных изменений перед сохранениемwrite
POST /api/v1/links/{id}/changes/confirmОдно подтверждение подготовленных настроек и причиныwrite
GET /api/v1/links/{id}/changesПолная история настроек, по 20 записей с курсором beforeread
POST /api/v1/links/{id}/changes/restoreПодготовка восстановления выбранной записи историиwrite
GET /api/v1/analytics/scenariosФактические исходы по сценариям, вариантам и версиямread
GET /api/v1/usageЛимиты плана, вычислительный бюджет и текущий расходread
GET /api/v1/analyticsПереходы и ежедневная статистика пространства, проекта или ссылкиread
GET /api/v1/analytics/historyДневные суммы переходов до 365 дней, без показателей уникальностиread

Повторяйте запрос без дубликатов

Передавайте новый Idempotency-Key для каждого создания ссылки или проекта. Если ответ потерялся, повторите тот же JSON с тем же ключом и API-токеном: в течение 24 часов вернётся исходный результат, а вторая запись не появится.

Ключ — от 1 до 128 латинских букв, цифр и символов . _ : -; подойдёт UUID. Порядок полей JSON не важен. Другие значения с прежним ключом дадут 409 idempotency_conflict. Заголовок Idempotency-Replayed: true отмечает повтор.

После 24 часов тот же ключ может создать новую запись. Без этого заголовка каждый POST — отдельное создание. Для актуального состояния уже изменённой ссылки используйте GET: повтор сохраняет первоначальный ответ.

Получайте понятную статистику

GET /api/v1/analytics?days=7 возвращает итоги и ежедневный ряд в UTC. Добавьте link_id или project_id для нужного среза. Максимум — 90 дней, включая сегодняшний; дни без переходов тоже есть в ответе.

period_clicks — все записанные GET-переходы, bot_clicks — распознанные боты, human_clicks — остальные. visitor_days суммирует суточные псевдонимы посетителей: один человек в разные дни может учитываться несколько раз. HEAD не увеличивает статистику.

Для истории за год используйте GET /api/v1/analytics/history?days=365 с теми же фильтрами. Ответ содержит только period_clicks, human_clicks и bot_clicks: дневные суммы сохраняются после удаления подробных событий. Ранее удалённые события восстановить нельзя.

GET /api/v1/usage показывает used, limit и remaining для ссылок, проектов и API-ключей. План и использование всегда читаются заново.

В data.budget доступны действующие ограничения, режим shadow или enforce, расход и остаток бюджета. Он общий для работы кабинета и его API-ключей. Источники индивидуальных лимитов тоже видны здесь.

GET /api/v1/links/{id}/availability — отдельный необязательный запрос. Поле data.state принимает pending, available, unavailable, restricted или unknown. Проверка не задерживает создание ссылки. Ответы перенаправления показываются как unknown с кодом redirect_response: конечная страница не проверена. Успешный HTTP-ответ не является оценкой безопасности сайта.

Поля ссылки

При создании обязательны destination и project_id. Дополнительно: title, slug, domain_id, utm_source, utm_medium, utm_campaign, max_clicks, expires_at.

Для ссылки на своём домене запросите GET /api/v1/domains и передайте его id в domain_id. Домен должен быть подключён, с действующим подтверждением DNS и HTTPS. Отсутствующее поле или null выбирает адрес сервиса. После создания домен сохраняется вместе с коротким адресом.

Срок задаётся в UTC с точностью до минуты: 2027-01-01T12:00:00Z. Значение null снимает срок или лимит переходов. Через PATCH можно также изменить status: active или paused. Чтобы изменить короткий адрес, передайте slug и актуальную version. Прежние адреса и QR-коды продолжат работать. Основной адрес берите из short_url. Администратор сервиса может отключить смену короткого имени: API вернёт 403 short_address_change_disabled. Домен после создания изменить нельзя.

Обычный PATCH принимает плоский JSON до 16 КБ. Сценарии и подтверждения используют вложенный JSON до 72 КиБ; сама конфигурация — до 65 535 байт. Действующая API-политика может установить меньший предел. Неизвестные поля отклоняются.

Задавайте условия перехода

Сценарий может действовать в любые указанные часы, дни недели, даты или диапазоны, с исключениями и выбранным часовым поясом. Например, с 09:13 до 18:47 по будням. Первое совпавшее правило выбирает адрес, распределение или сообщение; в остальных случаях применяется обычное действие.

В распределении доступны 2–10 разных адресов с целыми долями, сумма которых равна 100%. Сохраняйте ID сценариев и вариантов при редактировании, чтобы понимать историю эксперимента. Доля переходов показывает распределение запросов, а не продажи или победителя по конверсиям.

POST /scenarios/preview принимает policy и context: момент at в Unix-секундах, устройство, страну и bucket от 1 до 100. Проверка возвращает выбранное действие и ближайшие переключения; ничего не публикует и не увеличивает статистику.

Для публикации используйте полный маршрут PUT /api/v1/links/{id}/scenarios, передайте policy и expected_version из последнего GET. Наступление времени уже опубликованного сценария происходит автоматически и не запрашивает новое подтверждение.

Доступность будущих адресов можно читать отдельно: GET /api/v1/links/{id}/scenarios/availability. POST с пустым объектом на этот маршрут ставит опубликованные адреса в фоновую очередь. Это необязательная интеграция: результаты проверки не меняют редирект.

Меняйте печатную ссылку осознанно

Отметьте ссылку использованной в печати и укажите место размещения. Для изменения её поведения, защиты или ссылки с большим числом переходов сервер вернёт 428 change_confirmation_required. Рабочая ссылка в этот момент остаётся прежней.

Ответ содержит error.patch и expected_version. Передайте их в POST /api/v1/links/{id}/changes/preview, покажите ответственному пользователю различия before и after, затем отправьте полученный permit и причину в /changes/confirm.

POST /api/v1/links/42/changes/preview
{"expected_version":7,"patch":{"link":{"destination":"https://example.com/new"}}}

POST /api/v1/links/42/changes/confirm
{"permit":"PERMIT_ИЗ_ПРЕДПРОСМОТРА","reason":"Обновление страницы печатного каталога"}

Разрешение действует 10 минут и привязано к конкретной версии, пользователю и API-ключу. Причина — от 3 до 500 символов. Если ответ потерялся, повторите тот же permit и причину: второе изменение не появится. Другая причина или изменившиеся настройки возвращают 409. Не размещайте permit в URL.

Полная история хранит прежние и новые настройки. Восстановление — новое проверяемое изменение. Короткий код и домен остаются прежними; ни подтверждение, ни восстановление не снимают блокировку администрации, реестра или антиспама.

Связывайте ссылки с покупками и заявками

Подключите магазин или CRM в разделе «Покупки и заявки». Сохраните параметр _teeb_click вместе с заказом на своём сервере и передавайте события заявок, оплат и возвратов. Рабочие и тестовые результаты разделены.

ЗапросДействиеКлюч
POST /api/v1/conversions/eventsПодписанное событие до 16 КБ: 202 — в очереди, 200 — повторКлюч подключения + HMAC
GET /api/v1/conversions/events/{event_id}Состояние события своего источникаКлюч подключения
GET /api/v1/conversions/analyticsЗаявки, оплаты и возвраты по ссылкам, кампаниям и сценариямОбычный ключ с доступом к финансовым данным
GET /api/v1/conversions/exportТа же статистика в CSVОбычный ключ с доступом к финансовым данным
Подпись и повторная доставка

POST подписывается HMAC-SHA256 от timestamp + "." + rawBody полным ключом подключения. Заголовки: X-Teeb-Timestamp и X-Teeb-Signature: v1=hex; допуск времени — 5 минут. Для повтора сохраняйте прежний event_id и JSON, обновляя подпись. Idempotency-Key здесь не используется.

Готовый PHP-отправитель скачивается в настройках подключения. Храните события в своей серверной очереди и соблюдайте Retry-After. Передавайте только непрозрачные номера заказов и суммы в минимальных единицах, без имён, телефонов и email.

Выбирайте валюту и способ расчёта: по датам оплат/возвратов или по датам исходных переходов. Поля сумм в ответе — целые десятичные строки. Обычные API-ключи и публичные отчёты не получают финансового доступа автоматически.

Полная схема событий и фильтров

Лимиты и ответы

Начальные минутные пределы — 120 запросов на кабинет, суммарно для всех его ключей, и 300 с одного IP. Администратор может менять их: текущие значения доступны в GET /api/v1/usage. При превышении API возвращает 429 и фактический срок ожидания в Retry-After.

Новые вычислительные бюджеты начинают в режиме наблюдения shadow. В enforce учитываются стоимость операций, расход за сутки, размер страницы и параллельная работа. Пауза API и запрет записи действуют в обоих режимах. Состояние опубликованных коротких ссылок от паузы API не меняется.

Списки возвращают data и pagination. Для проектов используйте pagination.next_after, для ссылок — next_before, пока значение не станет null. В строгом режиме размер страницы может быть ниже 100; явно превышенный предел даёт 422.

Успех: 200, создание: 201, удаление: 204. Ошибки возвращаются в error.code и error.message: 401 — ключ недействителен, 403 — недостаточно разрешений, 404 — ссылка не найдена, 422 — проверьте поля.

После временных 429 и 503 соблюдайте Retry-After, увеличивайте паузу и ограничивайте число попыток. Для создания сохраняйте прежний JSON и Idempotency-Key. Ошибки валидации, конфликты и ручную паузу не исправить частыми повторами. Текущие права проверяются и при выдаче сохранённого результата.