Тема
Синхронизация планов
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_id | ID файла — передаётся в /sync/plan в материале типа file |
created | true — файл загружен впервые; 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_id | string | да | Уникальный ID плана в вашей системе |
name | string | да | Название плана |
blocks | array | да | Список блоков |
Блок:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
external_id | string | да | Уникальный ID блока в вашей системе |
title | string | да | Название блока |
sort_order | int | да | Порядок блока в плане |
difficulty | int | нет (default: 1) | Сложность 1–10, влияет на расчёт дедлайнов |
description | string | нет | Описание блока |
materials | array | нет | Материалы блока |
Материал:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
external_id | string | да | Уникальный ID материала в вашей системе |
type | "text" / "file" | да | Тип материала |
title | string | да | Название материала |
sort_order | int | да | Порядок материала внутри блока |
content | string | для type=text | Текст в формате BBCode |
file_id | int | для type=file | ID файла из /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]