v1.0Июнь 2026

TrackMind API

Документация по интеграции с GPS-платформой

Быстрый старт

Три шага, чтобы получить данные о ваших транспортных средствах через API.

01

Создайте API-ключ

Настройки → API → Новый ключ. Выберите область доступа и скопируйте ключ — он показывается один раз.

02

Добавьте заголовок

Передавайте ключ в каждом запросе: Authorization: Bearer tm_...

03

Делайте запросы

GET https://api.trackmind.ru/vehicles — и вы получите список ТС с текущими координатами.

Минимальный рабочий запрос
curl https://api.trackmind.ru/vehicles \
  -H "Authorization: Bearer tm_ваш_ключ_здесь"

Базовый URL и форматы

Базовый URL

https://api.trackmind.ru

Протокол

HTTPS обязателен
  • • Все запросы и ответы — в формате JSON.
  • • Для POST/PUT запросов передавайте заголовок Content-Type: application/json.
  • • Все временны́е метки — в формате ISO 8601 UTC (пример: 2026-06-01T08:30:00.000Z).
  • • Идентификаторы объектов (vehicles, geofences и др.) — UUID v4.
  • • Версионирование API включено в URL при необходимости. Текущая версия: v1 (суффикс не требуется).

Аутентификация

TrackMind API использует API-ключи для аутентификации. Ключи создаются в личном кабинете: Настройки → API → Новый ключ.

Передача ключа

Добавьте заголовок Authorization к каждому запросу:

Authorization: Bearer tm_ваш_ключ_здесь

Области доступа (scopes)

ScopeЧто разрешено
readТолько чтение данных: список ТС, позиции, треки, геозоны, события. Нельзя создавать/изменять/удалять объекты.
fullПолный доступ: чтение + создание, изменение и удаление объектов (вебхуки, геозоны и др.).
Безопасность ключей: API-ключ показывается один раз при создании. Храните его в защищённом месте (переменные окружения, secrets manager). Не передавайте ключ в URL-параметрах или клиентском коде. При компрометации — немедленно отзовите ключ в настройках.
Каждый ключ обновляет поле last_used_at при каждом запросе — вы можете отслеживать активность ключей в личном кабинете.

Коды ошибок

Все ошибки возвращают JSON с полем error и соответствующим HTTP-кодом.

Формат ответа с ошибкой
{
  "error": "Описание ошибки на русском"
}
КодЗначение и действие
400Bad Request — неверные параметры запроса. Проверьте тело запроса.
401Unauthorized — ключ отсутствует, недействителен или отозван. Создайте новый ключ.
403Forbidden — scope ключа недостаточен для данного действия.
404Not Found — объект не найден или не принадлежит вашему аккаунту.
429Too Many Requests — превышен лимит запросов. Уменьшите частоту или используйте вебхуки.
500Internal Server Error — ошибка сервера. Повторите запрос через несколько секунд.

Транспортные средства

Основной ресурс платформы. Каждое ТС имеет уникальный UUID, метаданные и связанный GPS-трекер.

Список транспортных средств

GET/vehicles

Возвращает все ТС аккаунта с последними известными координатами. Данные позиции берутся из кеша Redis и обновляются в реальном времени по мере поступления сигналов от трекеров.

Запрос
GET https://api.trackmind.ru/vehicles
Authorization: Bearer tm_xxxxxxxxxxxxxxxx
Ответ 200 OK
{
  "vehicles": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Газель 001",
      "license_plate": "А123БВ77",
      "make": "ГАЗ",
      "model": "Газель Next",
      "driver_name": "Иванов Иван",
      "driver_phone": "+7 900 123-45-67",
      "speed_limit": 90,
      "fuel_consumption_base": 12.5,
      "marker_type": "van-large",
      "group_id": "uuid-группы",
      "group_name": "Доставка МСК",
      "group_color": "#4F8EF7",
      "device_imei": "123456789012345",
      "position": {
        "lat": 55.7558,
        "lon": 37.6173,
        "speed": 42,
        "heading": 270,
        "satellites": 12,
        "time": "2026-06-01T08:30:00.000Z",
        "ignition": true,
        "sensors": {
          "voltage": 12.4,
          "bat_pct": 87,
          "mileage": 142300,
          "fuel": 65,
          "gsm": 18
        }
      }
    }
  ]
}

Поле position равно null, если трекер ещё не отправил ни одной позиции. Поле sensors содержит данные датчиков — набор ключей зависит от модели трекера (см. ниже).

Одно транспортное средство

GET/vehicles/:id
Запрос
GET https://api.trackmind.ru/vehicles/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer tm_xxxxxxxxxxxxxxxx

Возвращает тот же объект, что и в списке, но с расширенными полями (дополнительные атрибуты устройства).

Последняя позиция

GET/vehicles/:id/last

Только координаты, без метаданных ТС. Удобно для периодического опроса (polling) одного объекта.

Ответ 200 OK
{
  "lat": 55.7558,
  "lon": 37.6173,
  "speed": 42,
  "heading": 270,
  "satellites": 12,
  "time": "2026-06-01T08:30:00.000Z",
  "ignition": true,
  "sensors": {
    "voltage": 12.4,
    "bat_pct": 87,
    "mileage": 142300
  }
}
Для получения позиций в реальном времени рекомендуем использовать вебхуки вместо периодического опроса этого endpoint — это снижает нагрузку и даёт мгновенное обновление.

Поля объекта sensors

Набор ключей зависит от модели трекера — передаются только те поля, которые поддерживает устройство.

КлючТипЕдиницаОписание
voltagenumberВНапряжение бортовой сети
bat_pctnumber%Уровень заряда встроенного аккумулятора
bat_vnumberВНапряжение встроенного аккумулятора
int_bat_vnumberВНапряжение резервного (внутреннего) аккумулятора
mileagenumberмПробег по данным трекера (одометр)
fuelnumber%Уровень топлива
rpmnumberоб/минОбороты двигателя (CAN-шина)
eng_tempnumber°CТемпература охлаждающей жидкости (CAN-шина)
gsmnumberdBmУровень GSM-сигнала
satnumberштКоличество спутников (дубль поля satellites)

История маршрутов

GET/vehicles/:id/track

Возвращает полную историю движения ТС за указанный период: координаты, остановки, статистику пробега и времени в движении.

Query-параметры

ПараметрТипОписание
from*string (ISO 8601)Начало периода. Пример: 2026-06-01T00:00:00Z
to*string (ISO 8601)Конец периода. Максимальный диапазон — 31 день. При превышении API вернёт 400.
min_stopintegerМинимальная длительность остановки в минутах (по умолчанию: 5). Используется для автоматического определения стоянок.
interpolate0 | 1При значении 1 включает автоматическую интерполяцию маршрута в местах пропуска сигнала (через OSRM-маршрутизатор).
Запрос
GET https://api.trackmind.ru/vehicles/550e8400.../track
  ?from=2026-06-01T00:00:00Z
  &to=2026-06-01T23:59:59Z
  &min_stop=5
Authorization: Bearer tm_xxxxxxxxxxxxxxxx
Ответ 200 OK
{
  "points": [
    {
      "lat": 55.7558,
      "lon": 37.6173,
      "speed": 0,
      "heading": 0,
      "time": "2026-06-01T06:00:00.000Z",
      "gps_status": "valid"
    },
    { "lat": 55.7612, "lon": 37.6254, "speed": 54, "heading": 90, "time": "2026-06-01T06:02:00.000Z", "gps_status": "valid" }
  ],
  "stops": [
    {
      "lat": 55.7558,
      "lon": 37.6173,
      "start": "2026-06-01T06:00:00.000Z",
      "end":   "2026-06-01T06:15:00.000Z",
      "duration_minutes": 15
    }
  ],
  "stats": {
    "distance_km": 142.3,
    "moving_minutes": 198,
    "stop_minutes": 42,
    "max_speed": 112,
    "avg_speed": 73,
    "interpolated_distance_km": 0
  },
  "interpolated_segments": []
}

Поля ответа

ПараметрТипОписание
pointsarrayМассив точек маршрута. Уже прошёл фильтрацию антиспуфинга и прореживание до 5 000 точек на запрос для производительности визуализации.
stopsarrayСтоянки дольше min_stop минут с координатами, временем начала/конца и длительностью.
stats.distance_kmfloatПробег по GPS-данным, км.
stats.moving_minutesintegerВремя в движении, мин.
stats.stop_minutesintegerВремя на стоянках, мин.
stats.max_speedintegerМаксимальная скорость за период, км/ч.
stats.avg_speedintegerСредняя скорость в движении, км/ч.
gps_statusstringСтатус точки: valid (достоверная) или invalid (аномалия, отфильтрована).
Нет ограничения на количество точек в БД — запрашивайте любой период до 31 дня. Для периодов больше 31 дня разбивайте на несколько запросов.

Геозоны

Геозоны — это виртуальные периметры на карте. Платформа автоматически фиксирует события въезда и выезда транспортных средств в зону.

Список геозон

GET/geofences
Ответ 200 OK (массив)
[
  {
    "id": "uuid-геозоны",
    "name": "Склад Москва",
    "type": "circle",
    "color": "#22C55E",
    "center_lat": 55.7558,
    "center_lon": 37.6173,
    "radius_m": 500,
    "points": null,
    "is_active": true,
    "notify_enter": true,
    "notify_exit": true,
    "vehicle_ids": ["uuid-тс-1", "uuid-тс-2"],
    "group_ids": [],
    "created_at": "2025-05-15T10:00:00.000Z"
  }
]

Типы геозон

ПараметрТипОписание
circletypeКруговая зона. Поля: center_lat, center_lon, radius_m.
polygontypeПроизвольный многоугольник. Поле: points — массив координат [[lat,lon],...].
presettypeПредустановленная зона (заправки, АЗС, стоянки и др.).

События геозон

GET/geofences/events

История въездов и выездов всех ТС за период с фильтрацией.

Query-параметры

ПараметрТипОписание
fromstring (ISO 8601)Начало периода.
tostring (ISO 8601)Конец периода.
geofence_idUUIDФильтр по конкретной геозоне.
vehicle_idUUIDФильтр по конкретному ТС.
limitintegerМаксимум записей (по умолчанию 200, максимум 1 000).
Ответ 200 OK (массив)
[
  {
    "id": "event-uuid",
    "event_type": "enter",
    "lat": 55.7558,
    "lon": 37.6173,
    "occurred_at": "2026-06-01T09:15:00.000Z",
    "geofence_id": "uuid-геозоны",
    "geofence_name": "Склад Москва",
    "geofence_color": "#22C55E",
    "vehicle_id": "uuid-тс",
    "vehicle_name": "Газель 001",
    "license_plate": "А123БВ77"
  }
]

Управление API-ключами

Управлять ключами можно как через личный кабинет (Настройки → API), так и программно через API. Доступно только для ролей owner и admin. Максимум 10 ключей на аккаунт.

Список ключей

GET/api-keys
Ответ 200 OK
[
  {
    "id": "uuid-ключа",
    "name": "CRM Интеграция",
    "key_prefix": "tm_a1b2c3d4e5f6",
    "scope": "read",
    "last_used_at": "2026-06-01T10:00:00.000Z",
    "created_at": "2025-05-10T12:00:00.000Z"
  }
]
Полное значение ключа в этом ответе не возвращается — только его префикс для идентификации. Полный ключ отображается один раз при создании.

Создать ключ

POST/api-keys
Тело запроса
{
  "name": "CRM Интеграция",
  "scope": "read"
}
Ответ 201 Created
{
  "id": "uuid-ключа",
  "name": "CRM Интеграция",
  "key_prefix": "tm_a1b2c3d4e5f6",
  "scope": "read",
  "created_at": "2026-06-01T12:00:00.000Z",
  "key": "tm_a1b2c3d4e5f6...полный_ключ_48_символов"
}
Поле key присутствует только в этом ответе. После закрытия окна восстановить ключ невозможно — сохраните его немедленно.

Отозвать ключ

DELETE/api-keys/:id

Ключ немедленно деактивируется. Все запросы с этим ключом начнут возвращать 401 Unauthorized.

Ответ 200 OK
{ "ok": true }

Вебхуки

Вебхуки позволяют вашей системе получать уведомления о событиях в реальном времени — без периодического опроса API. TrackMind отправляет HTTP POST-запрос на ваш URL при наступлении события.

Типы событий

СобытиеКогда отправляется
positionНовая GPS-позиция от трекера (каждое обновление)
geofence.enterТранспортное средство въехало в геозону
geofence.exitТранспортное средство выехало из геозоны
speed.exceededСкорость превысила установленный лимит
device.offlineТрекер не выходил на связь более 30 минут
device.onlineТрекер восстановил связь

Формат входящего запроса

Заголовки запроса на ваш сервер
POST https://your-server.com/webhook
Content-Type: application/json
User-Agent: TrackMind-Webhook/1.0
X-TrackMind-Event: position
X-TrackMind-Signature: sha256=abc123...хеш_подписи
Тело запроса (событие position)
{
  "event": "position",
  "timestamp": "2026-06-01T08:30:00.000Z",
  "data": {
    "vehicleId": "uuid-тс",
    "vehicleName": "Газель 001",
    "lat": 55.7558,
    "lon": 37.6173,
    "speed": 42,
    "heading": 270,
    "satellites": 12,
    "time": "2026-06-01T08:30:00.000Z",
    "ignition": true,
    "sensors": {
      "voltage": 12.4,
      "bat_pct": 87,
      "mileage": 142300,
      "fuel": 65,
      "gsm": 18
    }
  }
}

Проверка подписи (HMAC-SHA256)

Если при создании вебхука указан секрет, каждый запрос подписывается. Обязательно проверяйте подпись для защиты от подделки запросов.

Проверка подписи — Node.js
import { createHmac } from 'crypto';

function verifyWebhook(body: string, signature: string, secret: string): boolean {
  const expected = 'sha256=' + createHmac('sha256', secret).update(body).digest('hex');
  // timingSafeEqual защищает от timing-атак
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  if (a.length !== b.length) return false;
  return require('crypto').timingSafeEqual(a, b);
}

// В вашем обработчике Express/Fastify:
app.post('/webhook', (req, res) => {
  const rawBody = req.rawBody; // строка, не объект
  const sig = req.headers['x-trackmind-signature'] as string;
  if (!verifyWebhook(rawBody, sig, process.env.WEBHOOK_SECRET!)) {
    return res.status(401).send('Invalid signature');
  }
  // Обрабатываем событие
  const event = JSON.parse(rawBody);
  console.log('Событие:', event.event, event.data);
  res.send({ ok: true });
});
Проверка подписи — Python
import hmac, hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

# Flask:
from flask import request
@app.route('/webhook', methods=['POST'])
def webhook():
    sig = request.headers.get('X-TrackMind-Signature', '')
    if not verify_webhook(request.data, sig, WEBHOOK_SECRET):
        return 'Invalid signature', 401
    event = request.json
    print(f"Событие: {event['event']}")
    return {'ok': True}
Всегда используйте timingSafeEqual / compare_digest для сравнения подписей. Обычное сравнение строк уязвимо к timing-атакам.

CRUD вебхуков

GET/webhooks

Список всех вебхуков аккаунта.

Ответ 200 OK
{
  "webhooks": [
    {
      "id": "uuid-вебхука",
      "url": "https://your-server.com/webhook",
      "has_secret": true,
      "events": ["position", "geofence.enter", "geofence.exit"],
      "enabled": true,
      "last_triggered_at": "2026-06-01T10:00:00.000Z",
      "last_status": 200,
      "created_at": "2025-05-01T12:00:00.000Z"
    }
  ]
}
POST/webhooks

Создать вебхук. Требуется scope full.

Тело запроса
{
  "url": "https://your-server.com/webhook",
  "secret": "ваш-секретный-ключ-для-подписи",
  "events": ["position", "geofence.enter", "geofence.exit"]
}
PUT/webhooks/:id

Обновить вебхук. Передавайте только изменяемые поля.

Тело запроса
{
  "enabled": false,
  "events": ["geofence.enter"]
}
DELETE/webhooks/:id

Удалить вебхук. Ответ: 204 No Content.

POST/webhooks/:id/test

Отправляет тестовый payload на URL вебхука и возвращает результат. Удобно для проверки доступности вашего сервера.

Ответ 200 OK
{
  "ok": true,
  "status": 200
}
// При ошибке:
{
  "ok": false,
  "status": 0,
  "error": "timeout"
}

Примеры кода

cURL

Получить список ТС с позициями
curl https://api.trackmind.ru/vehicles \
  -H "Authorization: Bearer tm_ваш_ключ"
Трек за день
curl "https://api.trackmind.ru/vehicles/UUID_ТС/track?from=2026-06-01T00:00:00Z&to=2026-06-01T23:59:59Z" \
  -H "Authorization: Bearer tm_ваш_ключ"
Создать вебхук
curl -X POST https://api.trackmind.ru/webhooks \
  -H "Authorization: Bearer tm_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-server.com/hook","events":["position","geofence.enter"]}'

JavaScript / TypeScript

Клиент TrackMind API (fetch)
const API_URL = 'https://api.trackmind.ru';
const API_KEY  = process.env.TRACKMIND_API_KEY;

const headers = {
  'Authorization': `Bearer ${API_KEY}`,
  'Content-Type': 'application/json',
};

// Получить все ТС
async function getVehicles() {
  const res = await fetch(`${API_URL}/vehicles`, { headers });
  if (!res.ok) throw new Error(`API error ${res.status}`);
  const { vehicles } = await res.json();
  return vehicles;
}

// Трек за период
async function getTrack(vehicleId: string, from: Date, to: Date) {
  const params = new URLSearchParams({
    from: from.toISOString(),
    to:   to.toISOString(),
    min_stop: '5',
  });
  const res = await fetch(`${API_URL}/vehicles/${vehicleId}/track?${params}`, { headers });
  if (!res.ok) throw new Error(`API error ${res.status}`);
  return res.json(); // { points, stops, stats }
}

// Использование
const vehicles = await getVehicles();
console.log('ТС:', vehicles.map(v => v.name));

const track = await getTrack(vehicles[0].id, new Date('2026-06-01'), new Date('2026-06-02'));
console.log('Пробег:', track.stats.distance_km, 'км');
console.log('Остановок:', track.stops.length);

Python

Клиент TrackMind API (requests)
import os, requests
from datetime import datetime, timezone

API_URL = 'https://api.trackmind.ru'
API_KEY = os.environ['TRACKMIND_API_KEY']

session = requests.Session()
session.headers.update({
    'Authorization': f'Bearer {API_KEY}',
    'Content-Type': 'application/json',
})

def get_vehicles():
    r = session.get(f'{API_URL}/vehicles')
    r.raise_for_status()
    return r.json()['vehicles']

def get_track(vehicle_id: str, from_dt: datetime, to_dt: datetime):
    r = session.get(f'{API_URL}/vehicles/{vehicle_id}/track', params={
        'from': from_dt.isoformat(),
        'to':   to_dt.isoformat(),
        'min_stop': 5,
    })
    r.raise_for_status()
    return r.json()  # {'points': [...], 'stops': [...], 'stats': {...}}

# Пример использования
vehicles = get_vehicles()
print('Транспортные средства:')
for v in vehicles:
    pos = v.get('position')
    status = f"{pos['lat']:.4f}, {pos['lon']:.4f} @ {pos['speed']} км/ч" if pos else 'нет данных'
    print(f"  {v['name']} ({v.get('license_plate', '-')}): {status}")

# Трек за вчера
from datetime import timedelta
to_dt   = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
from_dt = to_dt - timedelta(days=1)
track = get_track(vehicles[0]['id'], from_dt, to_dt)
stats = track['stats']
print(f"Пробег: {stats['distance_km']} км, остановок: {len(track['stops'])}")

TrackMind

GPS-мониторинг транспорта

API

api.trackmind.ru

Поддержка

support@trackmind.ru

Личный кабинет

app.trackmind.ru

© 2026 TrackMind. Документация актуальна для версии API v1.0.