# **Открытый программный интерфейс (Open API v2.0)**

Система спутникового мониторинга транспорта SKIF.PRO имеет открытое API для интеграции телематических данных и аналитики в любые сторонние корпоративные системы: 1С:Предприятие (УАТ, ERP), TMS/WMS логистические платформы, BI-системы и мобильные приложения.

Интерактивное описание API и документация доступны по адресу: [https://api.skif.pro](https://api.skif.pro) (Swagger UI: [https://api.skif.pro/docs](https://api.skif.pro/docs)).

Для выполнения интеграционных запросов и работы фоновых служб рекомендуется явно использовать выделенный рабочий сервер: **[https://app1.skif.pro/api_v1](https://app1.skif.pro/api_v1)**.
## **Быстрые ссылки для разработчиков**

| Ресурс | Описание | Ссылка |
|:---|:---|:---|
| **Портал API** | Официальный портал открытого программного интерфейса | [api.skif.pro](https://api.skif.pro) |
| **Swagger UI** | Интерактивная веб-песочница с описанием методов и возможностью тестирования | [api.skif.pro/docs](https://api.skif.pro/docs) |
| **Рабочий сервер API** | Рекомендуемый выделенный/резервный контур для интеграций и фоновых задач | `https://app1.skif.pro/api_v1` |
| **Postman-коллекция** | Готовая коллекция эндпоинтов со схемой переменных и примерами запросов | [Скачать коллекцию Postman v2.1](https://api.skif.pro/postman/SKIF_Platform_API_v2.json) |
| **OpenAPI 3.0 JSON** | Машиночитаемая спецификация для генерации клиентских библиотек (SDK) | [api.skif.pro/openapi.json](https://api.skif.pro/openapi.json) |

---

## **Быстрый старт: первые данные за 3 шага**

Для отправки запросов используется базовый адрес: `https://app1.skif.pro/api_v1`.

### **Шаг 1. Авторизация и получение токена**

Аутентификация в API выполняется запросом `POST /api_v1/login`:

```bash
curl -i -X POST "https://app1.skif.pro/api_v1/login" \
  -H "Content-Type: application/json" \
  -d '{
    "userProviderId": "your_login@company.ru",
    "provider_key": "EMAIL",
    "password": "your_password"
  }'
```

> **Важно**: При успешной авторизации (`HTTP 200`) тело ответа пустое, а токен авторизации возвращается **в HTTP-заголовке ответа**:  
> `Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...`

---

### **Шаг 2. Первый запрос: Список объектов компании**

Для всех последующих запросов передавайте полученный токен в заголовке `Authorization: Bearer <токен>`. **Использование сессионных cookies не требуется — API работает автономно по Bearer-токену.**

```bash
curl -X POST "https://app1.skif.pro/api_v1/units/list" \
  -H "Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": 0,
    "count": 10
  }'
```

**Пример ответа сервера:**
```json
{
  "max": 42,
  "list": [
    {
      "id": "3efbec79-a0b2-41aa-a859-cacd80323d2f",
      "name": "Газель Next А102ВВ",
      "device_type": "Navtelecom SMART S-2420",
      "imei": "866795031900671"
    }
  ]
}
```

---

### **Шаг 3. Запрос телеметрии и текущего состояния ТС**

Получение актуальных параметров объекта (координаты, скорость, зажигание, датчики уровня топлива):

```bash
curl -X GET "https://app1.skif.pro/api_v1/units?ids=3efbec79-a0b2-41aa-a859-cacd80323d2f" \
  -H "Authorization: Bearer <токен>"
```

---

## **Постоянный API-ключ компании (Static API Key)**

Если вашей интеграции (например, серверу 1С или регулярному фоновому скрипту) неудобно регулярно вызывать логин и хранить динамические JWT-токены, администратор компании может выпустить постоянный токен доступа.

1. **Создание постоянного ключа** (выполняет администратор через API или веб-кабинет):
   ```bash
   POST https://app1.skif.pro/api_v1/users/:user_id/create_token
   {
     "valid_to": "2028-12-31 23:59:59"
   }
   ```
   В ответе возвращается ключ: `{"user_company_api_key": "YOUR_COMPANY_API_KEY"}`.

2. **Использование ключа**:  
   Передавайте данный ключ в любом запросе в заголовке `user_company_api_key`:
   ```bash
   curl -X POST "https://app1.skif.pro/api_v1/units/list" \
     -H "user_company_api_key: YOUR_COMPANY_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"from": 0, "count": 10}'
   ```
## **Основные функциональные модули API**

| Модуль | Ключевые методы | Возможности и типовые задачи |
|:---|:---|:---|
| **Объекты и датчики** | `POST /units/list`<br>`GET /units?ids=...`<br>`GET /unit_sensors/:id` | Реестр транспортных средств компании, установленные терминалы, счетчики пробега/моточасов, тарировочные таблицы баков. |
| **Пользователи и водители** | `POST /users/query`<br>`POST /users`<br>`POST /drivers/import_csv`<br>`POST /users/import_csv`<br>`PATCH /users/roles/bulk` | Справочник пользователей и водителей компании: фильтр по признаку водителя и ролям, быстрое создание водителя по ФИО, пакетный импорт водителей и пользователей из CSV, массовая смена роли. Водители используются для автоназначения на объекты по коду (RFID). |
| **Телеметрия и треки** | `POST /fasttracks`<br>`POST /fasttracks/bulk`<br>`GET /box_tracks` | Получение детализированных треков за интервал дат, сглаживание выбросов GPS, чтение сырых пакетов телеметрии. |
| **Поездки и стоянки** | `POST /report` (Шаблон «Поездки»)<br>`POST /chronology_report` | Детектор движения: расчет поездок, пробега, остановок и стоянок с определением адресов стоянок. |
| **Контроль топлива** | `POST /report` (Шаблон «Топливо»)<br>`GET /units/fuel_level` | Расход топлива по ДУТ и CAN-шине, детекция сливов и заправок с точным объемом в литрах. |
| **Геозоны и маршруты** | `GET /geozones`<br>`POST /geozones`<br>`POST /races/list` | Контроль входа/выхода из полигонов и окружностей, плановые маршруты и контроль соблюдения графика. |
| **События и тревоги** | `POST /events/list`<br>`POST /notifications` | Тревоги по превышению скорости, кнопке SOS, эвакуации, отключению питания трекера. Доставка через Webhooks / Telegram. |
| **Аналитические отчеты** | `POST /report`<br>`POST /report_excel` | Сводные ведомости по парку за период, экспорт готовых отчетов в Excel (`.xlsx`) и PDF. |
| **Интеграция с 1С** | `POST /units/list`<br>`POST /report` | Заполнение путевых листов 1С фактическим пробегом, расходом ГСМ и отработанными моточасами. |
## **Стандарты взаимодействия, ограничения и производительность**

### **Выбор сервера**
- **Рабочий контур для интеграций (рекомендуется)**: `https://app1.skif.pro/api_v1`.  
  Использование сервера `app1.skif.pro` обеспечивает прямое и стабильное обслуживание API-интеграций и фоновых задач без конкуренции за пул сетевых соединений основного клиентского интерфейса.
- **Интерактивная документация**: `https://api.skif.pro` (Swagger: `https://api.skif.pro/docs`).
- **Тестовый контур**: `https://release.skif.pro/api_v1`.

### **Лимиты частоты запросов (Rate Limits)**
В сервисе авторизации платформы (`skif_auth`) действует автоматическая защита от перегрузки:
- **Базовый лимит**: **40 запросов в минуту** на учетную запись (по скользящему окну 60 секунд на каждый шаблон маршрута).
- **Лимит на метод `/login`**: до **40 запросов в минуту** с одного IP-адреса.
- **Код ответа при превышении лимита**: сервер возвращает `HTTP 429 Too Many Requests` со структурой:
  ```json
  {
    "code": 4029,
    "field": "",
    "message": "Превышено количество отправленных запросов в минуту, подождите немного."
  }
  ```

### **Рекомендации по паузам между запросами (Throttling)**
1. **Интервал 300–600 мс**: После выполнения каждого запроса в цикле рекомендуется выдерживать паузу **300–600 мс** перед отправкой следующего вызова (особенно для ресурсоемких операций: выгрузка треков `POST /fasttracks`, расчет отчетов `POST /report`, построение хронологии `POST /chronology_report` или опрос расширенных данных по ТС). Это предотвращает случайное исчерпание лимита в 40 запросов в минуту и исключает взаимные блокировки при параллельной обработке.
2. **Пакетная обработка (`bulk`)**: Вместо последовательного опроса каждого транспортного средства по отдельности используйте пакетные методы (например, `POST /fasttracks` поддерживает массив идентификаторов `units: [{"id": "..."}, ...]`).
3. **Обработка ошибки 429**: При получении ответа `429` скрипт интеграции должен сделать экспоненциальную паузу (backoff) на 2–5 секунд перед повтором запроса.

---

## **Примеры кода**

### **Python: Получение списка ТС с обработкой пауз**

```python
import time
import requests

# Рекомендуемый сервер для API интеграций
BASE_URL = "https://app1.skif.pro/api_v1"

# 1. Авторизация
auth_resp = requests.post(
    f"{BASE_URL}/login",
    json={
        "userProviderId": "your_login@company.ru",
        "provider_key": "EMAIL",
        "password": "your_password"
    },
    headers={"Content-Type": "application/json"}
)
auth_resp.raise_for_status()

# 2. Извлечение токена из заголовка ответа
token = auth_resp.headers.get("Authorization")
headers = {
    "Authorization": token,
    "Content-Type": "application/json",
    "Accept": "application/json"
}

# 3. Запрос списка транспортных средств
resp = requests.post(
    f"{BASE_URL}/units/list",
    headers=headers,
    json={"from": 0, "count": 20}
)
resp.raise_for_status()

data = resp.json()
print(f"Всего объектов в парке: {data.get('max')}")

for unit in data.get("list", []):
    unit_id = unit["id"]
    unit_name = unit["name"]
    print(f"• ТС: {unit_name} (ID: {unit_id})")

    # Пауза 400-500 мс перед следующим тяжелым запросом телеметрии
    time.sleep(0.5)

    telemetry_resp = requests.get(
        f"{BASE_URL}/units?ids={unit_id}",
        headers=headers
    )
    if telemetry_resp.status_code == 200:
        telemetry = telemetry_resp.json()
        print("  Данные получены успешно.")
    elif telemetry_resp.status_code == 429:
        print("  Внимание: сработал лимит частоты, пауза 3 сек...")
        time.sleep(3)
```

### **Node.js / JavaScript (Fetch API с паузой)**

```javascript
// Рекомендуемый сервер для API интеграций
const BASE_URL = 'https://app1.skif.pro/api_v1';

// Функция задержки между вызовами (300-600 мс)
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function runIntegration() {
  // 1. Авторизация
  const loginRes = await fetch(`${BASE_URL}/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      userProviderId: 'your_login@company.ru',
      provider_key: 'EMAIL',
      password: 'your_password'
    })
  });

  if (!loginRes.ok) throw new Error(`Login failed with status: ${loginRes.status}`);

  // Токен передается в HTTP-заголовке Authorization
  const token = loginRes.headers.get('authorization');

  // 2. Получение списка ТС
  const listRes = await fetch(`${BASE_URL}/units/list`, {
    method: 'POST',
    headers: {
      'Authorization': token,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ from: 0, count: 10 })
  });

  const listData = await listRes.json();
  console.log(`Всего объектов: ${listData.max}`);

  for (const unit of listData.list) {
    console.log(`Объект: ${unit.name} (ID: ${unit.id})`);

    // Пауза 500 мс перед следующим запросом
    await sleep(500);

    const unitRes = await fetch(`${BASE_URL}/units?ids=${unit.id}`, {
      headers: { 'Authorization': token }
    });

    if (unitRes.status === 429) {
      console.warn('Превышен лимит запросов, пауза 3 сек...');
      await sleep(3000);
    }
  }
}

runIntegration().catch(console.error);
```
## **Безопасность и лучшие практики**

1. **Защита учетных данных**: Не храните логин и пароль в открытом виде в исходном коде. Используйте переменные окружения или постоянный ключ `user_company_api_key`.
2. **Кэширование токена**: Полученный JWT-токен действителен длительное время. Не вызывайте метод `/login` перед каждым отдельным запросом — сохраняйте полученный токен и обновляйте его только при ответе сервера `401 Unauthorized`.
3. **Учет лимитов и таймаутов**: При интеграции с 1С настраивайте таймаут ожидания HTTP-соединения не менее 30–60 секунд для тяжелых аналитических отчетов и используйте интервалы 300–600 мс между последовательными запросами.
## **Техническая поддержка интеграторов и обратная связь**

Если вы обнаружили ошибку в работе методов, расхождение с документацией или у вас возник технический вопрос по интеграции:

1. **Форма обратной связи на портале API**: Нажмите кнопку **«Сообщить об ошибке»** в шапке документации [https://api.skif.pro](https://api.skif.pro). Заполните контур проблемы (боевой `app1.skif.pro` или стенд документации `api.skif.pro`), метод и ваш API-ключ компании. Обращение сразу поступит в очередь разработки.
2. **Email техподдержки**: [support@skif.pro](mailto:support@skif.pro) (обязательно укажите тему вида `[API Issue] {Метод} - {Компания}`, ваш `company_id` и cURL вызова).
3. **Персональный менеджер**: Обратитесь к вашему персональному менеджеру SKIF.PRO для согласования индивидуальных лимитов или выделенных вычислительных очередей.
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9