Skip to content

Синхронизация планов

API синхронизации позволяет загружать планы адаптации из внешних систем — 1С, HRM и других. При каждом вызове план обновляется целиком: блоки и материалы приводятся в соответствие с переданными данными.

Получение токена

Токен синхронизации выдаётся на портал. Найти его можно в настройках приложения в разделе «Синхронизация». Там же доступна кнопка перегенерации токена — после перегенерации старый токен перестаёт работать.

Базовый URL

Все запросы отправляются на:

https://api.adaptation.neuroteam.pro

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

Все запросы к API синхронизации требуют заголовок:

X-Sync-Token: <ваш токен>

При неверном или отсутствующем токене API вернёт 401 Unauthorized.


POST /sync/files

Загрузка файла на сервер. Используйте этот эндпоинт перед /sync/plan, если хотите прикрепить файлы к материалам блоков.

Запрос: multipart/form-data, поле file. Максимальный размер — 200 МБ.

bash
curl -X POST https://api.adaptation.neuroteam.pro/sync/files \
  -H "X-Sync-Token: your_token" \
  -F "file=@/path/to/document.pdf"
python
import requests

with open("/path/to/document.pdf", "rb") as f:
    resp = requests.post(
        "https://api.adaptation.neuroteam.pro/sync/files",
        headers={"X-Sync-Token": "your_token"},
        files={"file": f},
    )
print(resp.json())  # {"file_id": 123, "created": true}
php
$ch = curl_init("https://api.adaptation.neuroteam.pro/sync/files");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["X-Sync-Token: your_token"],
    CURLOPT_POSTFIELDS => ["file" => new CURLFile("/path/to/document.pdf")],
    CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
// ["file_id" => 123, "created" => true]

Ответ:

json
{
  "file_id": 123,
  "created": true
}
ПолеОписание
file_idID файла — передаётся в /sync/plan в материале типа file
createdtrue — файл загружен впервые; false — файл уже существует, вернули существующий ID

POST /sync/plan

Upsert шаблонного плана. Идентификация — по полю external_id. Если план с таким ID уже существует — он обновляется, иначе создаётся новый.

bash
curl -X POST https://api.adaptation.neuroteam.pro/sync/plan \
  -H "X-Sync-Token: your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "plan-001",
    "name": "Адаптация менеджера",
    "blocks": [...]
  }'
python
import requests

resp = requests.post(
    "https://api.adaptation.neuroteam.pro/sync/plan",
    headers={"X-Sync-Token": "your_token"},
    json={
        "external_id": "plan-001",
        "name": "Адаптация менеджера",
        "blocks": [...],
    },
)
print(resp.json())  # {"plan_id": 42, "created": true}
php
$payload = json_encode([
    "external_id" => "plan-001",
    "name" => "Адаптация менеджера",
    "blocks" => [...],
]);
$ch = curl_init("https://api.adaptation.neuroteam.pro/sync/plan");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "X-Sync-Token: your_token",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
// ["plan_id" => 42, "created" => true]

Ответ:

json
{
  "plan_id": 42,
  "created": true
}

Структура запроса

json
{
  "external_id": "plan-001",
  "name": "Адаптация менеджера",
  "blocks": [
    {
      "external_id": "block-001",
      "title": "Знакомство с командой",
      "sort_order": 1,
      "difficulty": 3,
      "description": "Необязательное описание блока",
      "materials": [
        {
          "external_id": "mat-001",
          "type": "text",
          "title": "Регламент работы",
          "sort_order": 1,
          "content": "[B]Добро пожаловать![/B]\n\nТекст материала в BBCode."
        },
        {
          "external_id": "mat-002",
          "type": "file",
          "title": "Презентация компании",
          "sort_order": 2,
          "file_id": 123
        }
      ]
    }
  ]
}

Описание полей

План:

ПолеТипОбязательноеОписание
external_idstringдаУникальный ID плана в вашей системе
namestringдаНазвание плана
blocksarrayдаСписок блоков

Блок:

ПолеТипОбязательноеОписание
external_idstringдаУникальный ID блока в вашей системе
titlestringдаНазвание блока
sort_orderintдаПорядок блока в плане
difficultyintнет (default: 1)Сложность 1–10, влияет на расчёт дедлайнов
descriptionstringнетОписание блока
materialsarrayнетМатериалы блока

Материал:

ПолеТипОбязательноеОписание
external_idstringдаУникальный ID материала в вашей системе
type"text" / "file"даТип материала
titlestringдаНазвание материала
sort_orderintдаПорядок материала внутри блока
contentstringдля type=textТекст в формате BBCode
file_idintдля type=fileID файла из /sync/files

Поведение при повторной синхронизации

При каждом вызове /sync/plan блоки и материалы полностью пересинхронизируются:

  • Блоки, которых нет в запросе — удаляются вместе со своими материалами
  • Существующие блоки (по external_id) — обновляются название, порядок, сложность, описание и материалы
  • Новые блоки — добавляются

Каскад на планы вакансий. Если из этого шаблонного плана были созданы планы вакансий — они тоже обновятся: блоки, связанные с шаблоном, получат актуальные данные. Блоки, добавленные в план вакансии вручную, затронуты не будут.

Внимание

Синхронизация не затрагивает планы кандидатов — они являются независимыми копиями и не обновляются автоматически.


Полный пример

Сценарий: загрузить файл и создать план с двумя блоками — текстовым и файловым материалом.

bash
# Шаг 1. Загрузить файл
curl -X POST https://api.adaptation.neuroteam.pro/sync/files \
  -H "X-Sync-Token: your_token" \
  -F "file=@presentation.pdf"
# → { "file_id": 55, "created": true }

# Шаг 2. Создать план
curl -X POST https://api.adaptation.neuroteam.pro/sync/plan \
  -H "X-Sync-Token: your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "plan-manager-2025",
    "name": "Адаптация менеджера",
    "blocks": [
      {
        "external_id": "block-intro",
        "title": "Знакомство с компанией",
        "sort_order": 1,
        "difficulty": 2,
        "materials": [
          {
            "external_id": "mat-intro-text",
            "type": "text",
            "title": "О компании",
            "sort_order": 1,
            "content": "[B]Добро пожаловать![/B]\n\nМы рады видеть тебя в нашей команде."
          }
        ]
      },
      {
        "external_id": "block-regulations",
        "title": "Регламенты",
        "sort_order": 2,
        "difficulty": 5,
        "materials": [
          {
            "external_id": "mat-reg-file",
            "type": "file",
            "title": "Презентация компании",
            "sort_order": 1,
            "file_id": 55
          }
        ]
      }
    ]
  }'
# → { "plan_id": 42, "created": true }
python
import requests

BASE = "https://api.adaptation.neuroteam.pro"
HEADERS = {"X-Sync-Token": "your_token"}

# Шаг 1. Загрузить файл
with open("presentation.pdf", "rb") as f:
    file_id = requests.post(
        f"{BASE}/sync/files", headers=HEADERS, files={"file": f}
    ).json()["file_id"]

# Шаг 2. Создать план
resp = requests.post(
    f"{BASE}/sync/plan",
    headers=HEADERS,
    json={
        "external_id": "plan-manager-2025",
        "name": "Адаптация менеджера",
        "blocks": [
            {
                "external_id": "block-intro",
                "title": "Знакомство с компанией",
                "sort_order": 1,
                "difficulty": 2,
                "materials": [
                    {
                        "external_id": "mat-intro-text",
                        "type": "text",
                        "title": "О компании",
                        "sort_order": 1,
                        "content": "[B]Добро пожаловать![/B]\n\nМы рады видеть тебя в нашей команде.",
                    }
                ],
            },
            {
                "external_id": "block-regulations",
                "title": "Регламенты",
                "sort_order": 2,
                "difficulty": 5,
                "materials": [
                    {
                        "external_id": "mat-reg-file",
                        "type": "file",
                        "title": "Презентация компании",
                        "sort_order": 1,
                        "file_id": file_id,
                    }
                ],
            },
        ],
    },
)
print(resp.json())  # {"plan_id": 42, "created": true}
php
$base = "https://api.adaptation.neuroteam.pro";
$token = "your_token";

// Шаг 1. Загрузить файл
$ch = curl_init("$base/sync/files");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["X-Sync-Token: $token"],
    CURLOPT_POSTFIELDS => ["file" => new CURLFile("presentation.pdf")],
    CURLOPT_RETURNTRANSFER => true,
]);
$fileId = json_decode(curl_exec($ch), true)["file_id"];

// Шаг 2. Создать план
$payload = json_encode([
    "external_id" => "plan-manager-2025",
    "name" => "Адаптация менеджера",
    "blocks" => [
        [
            "external_id" => "block-intro",
            "title" => "Знакомство с компанией",
            "sort_order" => 1,
            "difficulty" => 2,
            "materials" => [[
                "external_id" => "mat-intro-text",
                "type" => "text",
                "title" => "О компании",
                "sort_order" => 1,
                "content" => "[B]Добро пожаловать![/B]\n\nМы рады видеть тебя в нашей команде.",
            ]],
        ],
        [
            "external_id" => "block-regulations",
            "title" => "Регламенты",
            "sort_order" => 2,
            "difficulty" => 5,
            "materials" => [[
                "external_id" => "mat-reg-file",
                "type" => "file",
                "title" => "Презентация компании",
                "sort_order" => 1,
                "file_id" => $fileId,
            ]],
        ],
    ],
]);
$ch = curl_init("$base/sync/plan");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["X-Sync-Token: $token", "Content-Type: application/json"],
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
// ["plan_id" => 42, "created" => true]