Сокращение ссылок через API: создание и безопасный повтор
Сокращение ссылок через API нужно, когда ваш сервер готовит приглашения, письма или партнёрские адреса без ручной работы в кабинете. Основная трудность возникает после первого успешного запроса: ответ потерялся, задача запустилась ещё раз, а в базе уже две ссылки на один объект. Поэтому интеграцию стоит начинать с создания, чтения результата и проверки повторного запроса.
Разберём этот цикл на REST API RevRoute. Примеры рассчитаны на curl в Bash: macOS, Linux или WSL. Ключ остаётся на вашем сервере, URL и идентификаторы учебные. Для боевого запуска понадобятся собственный доступный адрес, права в рабочем пространстве и сохранение результата в вашей базе.
API-ключ и минимальные права
В кабинете RevRoute откройте «Настройки» → «API-ключи» в блоке «Разработчик». Создайте отдельный ключ для интеграции. Для этого примера нужны создание и чтение ссылок; не выдавайте доступ к аналитике, доменам и остальным ресурсам только ради теста.
В режиме «Ограниченный» выберите запись для ресурса «Ссылки». По документации аутентификации ключ показывается один раз. Сохраните его в менеджере секретов или переменной окружения серверного процесса. Publishable key для клиентской аналитики здесь не подходит.

В командах ниже используется переменная REVROUTE_API_KEY. Заполните её способом, принятым в вашей среде; не вставляйте настоящий секрет в текст статьи, репозиторий и общий журнал терминала. Перед подключением проверьте, что в вашем рабочем пространстве доступен API, а ключу разрешены создание и чтение ссылок. Условия доступа уточняйте для своего workspace.
Для интеграции только с собственным workspace достаточно такого ключа. Если вы делаете приложение для чужих рабочих пространств, используйте OAuth, чтобы пользователь сам выдал доступ, а не присылал вам свой постоянный ключ.
Создать короткую ссылку через API
Базовый адрес — https://api.revroute.ru. Метод создания — POST /links, поле назначения — url. У короткого пути имя key, а не slug; для связи с вашей системой используется externalId.
В примере ссылка ведёт в UTM-конструктор. Метки article_test нужны, чтобы контрольные переходы можно было отделить от настоящего трафика. Замените идентификатор на новый учебный ID, если этот пример уже запускали в своём workspace.
curl --silent --show-error --fail-with-body --max-time 20 -X POST "https://api.revroute.ru/links" -H "Authorization: Bearer $REVROUTE_API_KEY" -H "Content-Type: application/json" --data '{"url":"https://revroute.ru/tools/utm?utm_source=article_test&utm_medium=api&utm_campaign=api-guide-20261024","key":"api-guide-20261024","externalId":"article-api-guide-20261024","comments":"Учебная ссылка для проверки статьи API 24.10.2026"}'В примере domain не передан: проверьте домен, который вернул API. Если нужен свой, передайте domain без протокола и убедитесь, что он принадлежит этому workspace. Занятый key надо разобрать как конфликт, а не заменять случайным значением при каждом повторе.
У успешного ответа проверьте id, shortLink, url, domain, key и externalId. Сохраните id и shortLink вместе с ID вашей операции. Адрес назначения должен совпасть с отправленным, включая UTM. Не считайте любой JSON успехом: сначала проверьте HTTP-статус и наличие ожидаемых полей.

Прочитать результат и проверить переход
Запись есть в ответе сервера. А сохранилась ли она так, как нужно? Прочитайте её отдельно по внешнему идентификатору. В теле создания externalId записывается без служебного префикса; при запросе чтения нужен ext_:
curl --silent --show-error --fail-with-body --max-time 20 "https://api.revroute.ru/links/info?externalId=ext_article-api-guide-20261024" -H "Authorization: Bearer $REVROUTE_API_KEY"Сравните id, key и url с результатом создания. Это полезно и после таймаута: запрос мог завершиться на сервере, даже если клиент не получил ответ.
Затем скопируйте shortLink из фактического ответа в SHORT_LINK и посмотрите первый HTTP-ответ. Команда намеренно не следует по редиректу:
curl --silent --show-error --max-time 20 -D - -o /dev/null "$SHORT_LINK"У простой ссылки проверьте редирект и заголовок Location: нужный адрес, путь и параметры. После этого откройте короткую ссылку в браузере и убедитесь, что страница загружается. Эта проверка создаёт контрольный переход — его нельзя считать привлечённым пользователем или результатом статьи.
Один ответ 200 от API не проверяет всю цепочку. Рабочий результат — запись находится по ID, короткий адрес открывается, конечная страница доступна, параметры дошли, а ваш продукт показывает сохранённый shortLink.
Повтор без дублей и обработка ошибок
Не повторяйте создание с новым случайным ключом после каждого таймаута. Свяжите одну операцию вашего продукта с одним externalId, сохранённым до запроса. Если ответ потерян, сначала запросите существующую ссылку и сравните её назначение с ожидаемым.
Повторный POST с тем же externalId может вернуть 409 conflict. Это не подтверждает, что найденная ссылка подходит: прочитайте её и проверьте url. Если назначение отличается, остановите операцию и разберите конфликт. В этом примере нет обещания поддержки заголовка Idempotency-Key и нет скрытого обновления существующих ссылок.
Для проверки ошибки запроса отправьте заведомо неполный URL. Это отрицательный тест: успешное создание здесь было бы поводом остановить интеграцию и проверить контракт.
curl --silent --show-error --max-time 20 -i -X POST "https://api.revroute.ru/links" -H "Authorization: Bearer $REVROUTE_API_KEY" -H "Content-Type: application/json" --data '{"url":"https://"}'Ожидаемый класс ответа — ошибка входных данных, например 422 unprocessable_entity. Формат ошибок API содержит error.code и error.message. Логируйте статус, код, свой ID операции и время; токен и полный заголовок Authorization исключите из логов.
Разведите действия для разных ответов:
- 400 или 422 — исправить тело запроса; повторы с теми же данными не помогут.
- 401 — проверить секрет и окружение, в котором работает процесс.
- 403 — проверить права ключа, роль и доступные лимиты workspace; не выдавать полный доступ автоматически.
- 409 — прочитать существующую запись и сопоставить её с текущей операцией.
- 429 — приостановить очередь, проверить лимиты и отложить повтор.
- Таймаут или 5xx — считать результат создания неизвестным до отдельного чтения, ограничить число повторов.
Для очереди можно задать собственную политику: не более трёх повторов, паузы 2, 4 и 8 секунд, затем ручной разбор. Это пример клиентской политики, а не лимиты или SLA RevRoute. Документация лимитов перечисляет заголовки ответа; перед автоматическим использованием проверьте их реальные значения и единицы в своём окружении. Нельзя превращать любое число в Retry-After в бесконечный сон процесса.
Подключить к своей задаче
В обработчике отправки письма создавайте ссылку один раз и храните результат. Повторная отправка письма должна брать сохранённый адрес. Для параллельных обработчиков закрепите ID операции уникальным ограничением в своей базе и предусмотрите восстановление после сбоя: HTTP-запрос и запись результата в вашу БД не являются одной транзакцией.
Перед запуском пройдите четыре проверки: успешное создание и чтение, открытие конечной страницы, повтор с прежним externalId, отказ ключу без права записи. Последняя проверка подтверждает, что ограниченные права действительно работают, а не только выбраны в форме.
Если вашему продукту нужны такие адреса из кода, создайте отдельный API-ключ в RevRoute и начните с одной учебной операции. Встраивайте её в рабочую очередь после того, как сохранённая ссылка пережила повторный запуск и открыла нужную страницу. Так первая интеграция проверяет именно тот сценарий, на который будут опираться ваши письма и приглашения.