Taxi Watcher — API для B2B-клиентов
Taxi Watcher — API для B2B-клиентов
Руководство по подключению сервиса расчёта стоимости такси к вашему продукту.
Версия документа: 1.0
Базовый URL: https://taxi-watcher.ru
1. Что это и как это работает
Taxi Watcher отдаёт актуальную стоимость и время поездки такси между двумя адресами по вашему запросу. Вы передаёте адреса отправления и назначения, получаете цену, дистанцию, время в пути и ожидания подачи.
Один запрос = одна поездка. Ваш бэкенд вызывает API, сервис считает цену и возвращает готовый результат. Дальше вы используете его как хотите — показываете цену пользователям, сравниваете тарифы, автоматизируете заказы.
Схема работы:
Ваш бэкенд --(адреса)--> Taxi Watcher API --(цена, время)--> Ваш бэкенд
| X-API-Key
2. Быстрый старт
Подключение занимает 3 шага:
- Получите API-ключ. Ключ выпускает администратор сервиса. Он выглядит
как
tw_live_+ 32 символа, напримерtw_live_a1b2c3…. - Передавайте ключ в заголовке каждого запроса:
X-API-Key: tw_live_<ваш ключ>
- Сделайте первый запрос — посчитайте стоимость поездки:
curl -X POST https://taxi-watcher.ru/api/v1/estimate \
-H "X-API-Key: tw_live_<ваш ключ>" \
-H "Content-Type: application/json" \
-d '{"from_address":"Москва, улица Леси Украинки, 4к1","to_address":"Москва, Люсиновская улица, 7/8с1","tariff":"econom"}'
В ответе придёт цена, дистанция и время в пути (подробно — в разделе 4).
3. Аутентификация
Единственный механизм — заголовок X-API-Key с вашим ключом.
| Параметр | Значение |
|---|---|
| Заголовок | X-API-Key: tw_live_<токен> |
| Формат токена | tw_live_ + 32 hex-символа |
| Как передавать | В каждом запросе к /api/v1/* |
| Ключ неактивен / неверен | Ответ 401 Unauthorized |
Ключ выдаётся один раз и показывается полностью только при создании. Храните его в секрете — это ваш доступ к сервису и ваш биллинг. Если ключ утёк — ротируйте его (см. раздел 7), старый перестанет работать.
4. Расчёт стоимости поездки
POST /api/v1/estimate
Заголовки:
| Заголовок | Обязателен | Описание |
|---|---|---|
X-API-Key |
да | Ваш ключ клиента |
Content-Type |
да | application/json |
Тело запроса (JSON):
{
"from_address": "Москва, улица Леси Украинки, 4к1",
"to_address": "Москва, Люсиновская улица, 7/8с1",
"tariff": "econom"
}
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
from_address |
string | да | Адрес отправления (свободный текст) |
to_address |
string | да | Адрес назначения (свободный текст) |
tariff |
string | нет | Класс тарифа (по умолчанию econom) |
Допустимые тарифы:
| Значение | Тариф |
|---|---|
econom |
Эконом |
comfort |
Комфорт |
comfortplus |
Комфорт+ |
business |
Бизнес |
vip |
VIP / Premier |
minivan |
Минивэн |
cargo |
Грузовой |
express_d2d |
Доставка |
Если запрошенный тариф недоступен на маршруте, сервер сам выберет первый доступный — фактический класс придёт в поле
data.tariff.
Пример успешного ответа (200 OK):
{
"status": "success",
"timestamp": 1700000000,
"data": {
"from": "Москва, улица Леси Украинки, 4к1",
"to": "Москва, Люсиновская улица, 7/8с1",
"tariff": "econom",
"tariff_name": "Эконом",
"price": 2050,
"base_price": 1339,
"surge_active": true,
"currency": "RUB",
"distance": "12,45 км",
"duration": "~ 35 мин",
"wait_time": "~ 3 мин",
"cached_at": 1700000000
}
}
Поля data:
| Поле | Тип | Описание |
|---|---|---|
from / to |
string | Адреса, по которым считался маршрут |
tariff |
string | Фактический класс тарифа |
tariff_name |
string | Человекочитаемое имя тарифа |
price |
int | Итоговая цена с учётом спроса (в копейках) |
base_price |
int | Базовая цена без спроса |
surge_active |
bool | Признак повышенного спроса (price > base_price) |
currency |
string | Валюта (обычно RUB) |
distance |
string | Дистанция, например "12,45 км" |
duration |
string | Время в пути, например "~ 35 мин" |
wait_time |
string | Ожидание подачи, например "~ 3 мин" |
cached_at |
int | Unix-время расчёта |
5. Лимиты
На каждый ключ действуют два ограничения:
| Уровень | Лимит | Что происходит при превышении |
|---|---|---|
| В минуту (RPM) | задаётся на ключе (по умолчанию 10/мин) | 429 Too Many Requests |
| За месяц (квота) | задаётся на ключе (по умолчанию 1000/мес) | 429 Too Many Requests |
Текущее использование и остаток видны в личном кабинете. Если упёрлись в лимит — обратитесь к администратору, чтобы увеличить квоту.
Одинаковые запросы (одинаковые адреса и тариф) кэшируются сервером на несколько минут — повторные вызовы отдаются быстро и не тратят квоту Яндекса (но учитываются в вашей статистике).
6. Коды ответов и ошибки
| Код | Что значит | Как реагировать |
|---|---|---|
200 OK |
Успех — вернулась цена | Обрабатывайте data |
400 Bad Request |
Не удалось распознать адрес | Проверьте адреса, попробуйте полнее |
401 Unauthorized |
Ключ неверный или деактивирован | Проверьте ключ, активируйте его |
404 Not Found |
Для маршрута нет доступных тарифов | Сообщите пользователю |
422 Unprocessable Entity |
Не хватает обязательных полей | Проверьте тело запроса |
429 Too Many Requests |
Превышен лимит (в минуту или за месяц) | Подождите / увеличьте квоту |
500 Internal Server Error |
Внутренняя ошибка расчёта | Повторите позже |
502 Bad Gateway |
Сбой сети / партнёра | Повторите позже |
Формат ошибок — всегда строка в поле detail:
{ "detail": "описание ошибки" }
Пример — превышение лимита в минуту:
{ "detail": "Rate limit exceeded: max 10 requests per minute." }
Пример — исчерпана месячная квота:
{ "detail": "Monthly quota exceeded (1000 requests). Please upgrade your plan." }
При ошибках валидации (422) detail — это массив объектов с описанием
конкретных проблем (какое поле, что не так).
7. Ваш личный кабинет
Кабинет B2B-клиента доступен по адресу /b2b. Здесь вы управляете своими
ключами, смотрите статистику и лимиты.
Вход и выход
- Вход —
/b2b/login(email + пароль). - Выход — кнопка в кабинете (
POST /b2b/logout). - После входа открывается дашборд
/b2b/dashboard: ваши ключи, квоты, быстрый старт с готовым cURL-запросом и ссылка на эту документацию.
Возможности кабинета
| Действие | Где | Что даёт |
|---|---|---|
| Список моих ключей | Дашборд /b2b/dashboard |
Превью ключа, лимит, использовано, остаток |
| Показать полный ключ | Кнопка «Показать токен» | Полный токен для копирования |
| Статистика по ключу | Кнопка «Графики» | Всего/сегодня/месяц, ошибки, последние запросы |
| Ротация ключа | по API, см. ниже | Новый токен — старый перестаёт работать |
| Активация/деактивация | по API, см. ниже | Включить/выключить ключ |
JSON-эндпоинты кабинета
Все требуют авторизованной B2B-сессии (вы в кабинете). Доступ — только к своим ключам.
Список моих ключей — GET /b2b/api/keys:
[
{
"id": 1,
"key_preview": "tw_live_abc••••1234",
"client_name": "Demo Logistics Co.",
"is_active": true,
"limit_monthly": 1000,
"rate_limit_per_minute": 10,
"used_this_month": 12,
"quota_percent": 1.2,
"remaining": 988,
"total_requests": 80,
"created_at": "2024-01-01 12:00",
"expires_at": null
}
]
Показать полный ключ — GET /b2b/api/keys/{key_id}/reveal:
{ "id": 1, "key": "tw_live_<токен>" }
Статистика по ключу — GET /b2b/api/keys/{key_id}/stats:
{
"key_id": 1,
"client_name": "Demo Logistics Co.",
"is_active": true,
"limit_monthly": 1000,
"total_requests": 80,
"today_requests": 3,
"month_requests": 40,
"avg_response_ms": 350.5,
"error_count": 5,
"redis_usage": {
"used": 12,
"limit": 1000,
"remaining": 988,
"percent": 1.2,
"month": "2024-01"
},
"recent_logs": [
{ "endpoint": "/api/v1/estimate", "status_code": 200, "response_time_ms": 300 }
]
}
Ротация ключа — POST /b2b/api/keys/{key_id}/rotate:
{ "status": "rotated", "id": 1, "key": "tw_live_<новый токен>" }
Старый токен немедленно перестаёт работать. Используйте, если ключ утёк.
Активация / деактивация — PATCH /b2b/api/keys/{key_id}:
{ "is_active": false }
8. Примеры запросов
Расчёт стоимости (основной сценарий)
curl -X POST https://taxi-watcher.ru/api/v1/estimate \
-H "X-API-Key: tw_live_<токен>" \
-H "Content-Type: application/json" \
-d '{"from_address":"Москва, улица Леси Украинки, 4к1","to_address":"Москва, Люсиновская улица, 7/8с1","tariff":"business"}'
Сравнить тарифы на маршруте
Повторите запрос с разными tariff (econom, comfort, business, …) —
выберите лучшее значение price.
Ротация ключа (если он утёк)
curl -X POST https://taxi-watcher.ru/b2b/api/keys/1/rotate \
-H "Cookie: session=<сессия из кабинета>"
Эндпоинты кабинета (
/b2b/api/*) используют сессию из вашего входа в кабинет. В повседневной работе вы обычно управляете ключами через интерфейс кабинета, а программно вызываете только/api/v1/estimate.
9. Советы
- Повышенный спрос: сравнивайте
priceиbase_price— еслиsurge_active: true, цена выше базовой. Можно подсказать пользователю подождать. - Проверяйте
tariffв ответе — сервер мог подставить доступный класс, если запрошенный не нашёлся на маршруте. - Следите за квотой в кабинете, чтобы не упереться в лимит в самый нужный момент.
- Не храните ключ в коде клиента — держите его на бэкенде и передавайте только в заголовке.
- Используйте кэш: одинаковые маршруты повторно не списывают квоту Яндекса.
Если нужен дополнительный ключ, больший лимит или нестандартный тариф — свяжитесь с владельцем Taxi Watcher в Telegram – @fancycode