CRM API — Довідник ендпоінтів
Arc OS — The Orchestration System for AI Teams
Загальна інформація
| Параметр | Значення |
|---|---|
| Base URL | https://arc-os.co/api/crm |
| Авторизація | Authorization: Bearer <JWT> або ?token=<JWT> (для SSE/WebSocket) |
| Content-Type | application/json |
| JWT алгоритм | HMAC-SHA256 |
| JWT TTL | 24 години |
Автентифікація
Всі ендпоінти (окрім /docs/*) вимагають JWT токен у заголовку Authorization: Bearer <token>.
Для SSE та WebSocket з'єднань токен передається через query-параметр ?token=<JWT>.
Помилки авторизації
| Код | Опис |
|---|---|
| 401 | Відсутній або невалідний токен |
| 403 | Немає доступу до проєкту (multi-tenancy) |
Ендпоінти за категоріями
Акаунт та налаштування
| Метод | Шлях | Опис |
|---|---|---|
| GET | /account/settings |
Отримати налаштування акаунту |
| PUT | /account/settings |
Оновити налаштування акаунту |
| GET | /account/usage |
Історія використання токенів для авторизованого користувача (Phase 63, #148). Response: { rows: [ { project_name, worker_id, input_tokens, output_tokens, cache_tokens, total_tokens, created_at } × до 200 ], totals: { total, input, output } }. Читає token_usage_log за owner_id. Відображається в UserDropdown (UsageCard) і BillingPage (секція Token Usage). |
Онбординг + Trial Credits (Phase 50.1)
| Метод | Шлях | Опис |
|---|---|---|
| POST | /onboarding/setup |
Створити перший проєкт. Body multipart: config (JSON) + files. Поле anthropicKey тепер опціональне — якщо empty + у користувача email_verified + раніше не отримував trial, проєкт створюється у trial_mode=1 зі 100K free tokens. Response: { ok, project, trial_activated }. Phase 51: повертає 402 з {error:"plan_limit_reached", reason, current, limit, plan} коли користувач перевищив project limit для плану. |
| GET | /account/trial-status |
Trial-статус для UI banner. Response: { email, email_verified, trial_granted, has_trial_active, total_remaining, total_granted, projects: [...] } |
Beta Invites (Phase 52.1, admin-only)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /admin/invites |
Список усіх invite codes + counts (total_active, total_used). Лише admin. |
| POST | /admin/invites |
Згенерувати N кодів. Body: {count: N, note?: string}. Лише admin. Response: {ok, codes, count}. |
| DELETE | /admin/invites/:code |
Revoke невикористаного invite-коду. |
Auth flow update: POST /api/auth/register тепер вимагає поле invite_code (Phase 52.1 closed beta). Без коду → 403 {error: "invite_required"}. Невалідний/used код → 403 {error: "invalid_invite"}.
Billing (Phase 51)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /billing/status |
Поточний план, ліміти, usage, features. Auto-creates Free row при першому виклику. Response: { plan, status, current_period_end, limits, usage, features, pricing, can_upgrade, stripe_ready } |
| POST | /billing/checkout-session |
Stripe Checkout (Stage 2 — повертає 501 поки Stripe SDK не інтегровано) |
Plan limits (OR-semantic):
- Free: 1 project AND 5 workers
- Min ($4.99/mo): 5 projects OR 25 workers total
- Max ($11.99/mo): 20 projects OR 150 workers total
402 response на POST /onboarding/setup або POST /projects/:name/workers коли ліміт перевищено: { error: "plan_limit_reached", reason: "projects_limit"|"workers_limit", current, limit, plan, message }
Admin-користувачі (
role=admin) обходять plan-limit перевірку повністю — вони оператори, а не платні тенанти.
Beta-тестери (
subscriptions.plan='beta', Phase 52 F&F) також обходять — необмежена кількість проєктів/воркерів плюс усі Max-фічі. Призначається вручну:UPDATE subscriptions SET plan='beta' WHERE user_id=?.
Bugfix (issue #25):
POST /projects/create(Quick Start, Phase 50.2) раніше падав ізownerChatId is not definedчерез typo — виправлено, audit-actor тепер коректно записується.
Bugfix (issue #26): allocatePort() для нових проєктів тепер пробить реальні TCP-bindings (
ss -tln), а не лише registry. Раніше міг видати порт, зайнятий не-registry сервісом (NotebookLM bridge :19213, internal bridges) → workspace bot падав на EADDRINUSE.
Auth flow (Phase 50.1): /api/auth/register і /api/auth/login тепер повертають JWT навіть для unverified email + flag needs_verification: true. Сенситивні дії (trial grant, billing, invites) перевіряють email_verified окремо. Rate limit на signup: 3 / IP / 24h.
Проєкти (9 ендпоінтів)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /projects |
Список проєктів користувача |
| POST | /projects/create |
Створити проєкт |
| GET | /projects/:name |
Деталі проєкту |
| GET | /projects/:name/config |
Конфігурація проєкту |
| PUT | /projects/:name/config |
Оновити конфігурацію |
| GET | /projects/:name/protocol |
Протокол проєкту |
| PUT | /projects/:name/protocol |
Оновити протокол |
| GET | /projects/:name/logs |
Логи проєкту |
| GET | /projects/:name/metrics |
Метрики проєкту |
POST /projects/create — body:
{
"technical_name": "string",
"displayName": "string",
"description": "string",
"icon": "string",
"color": "string"
}
GET /projects/:name/logs — query: category, lines
GET /projects/:name/metrics — query: since, until
Воркери (11 ендпоінтів)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /projects/:name/workers |
Список воркерів |
| POST | /projects/:name/workers |
Створити воркера |
| PUT | /projects/:name/workers/:id |
Оновити воркера |
| DELETE | /projects/:name/workers/:id |
Видалити воркера |
| POST | /projects/:name/workers/generate-prompt |
Згенерувати системний промпт |
| GET | /projects/:name/workers/:id/telegram-token |
Отримати Telegram токен |
| POST | /projects/:name/workers/:id/telegram-token |
Встановити Telegram токен |
| DELETE | /projects/:name/workers/:id/telegram-token |
Видалити Telegram токен |
| POST | /projects/:name/restart |
Перезапустити воркера |
| GET | /projects/:name/active-role |
Поточна активна роль |
| POST | /projects/:name/active-role |
Змінити активну роль |
POST /projects/:name/workers — body:
{
"label": "string",
"icon": "string",
"type": "terminal | telegram",
"model": "string",
"max_turns": 20,
"tools": ["Read", "Write", "Bash"],
"system_prompt": "string",
"focus_dirs": ["src/", "docs/"]
}
max_turnsза замовчуванням20(раніше було5, що спричиняло помилку "Reached max turns" у багатоступеневих діалогах із tool calls).
POST /projects/:name/restart — query: worker_id
Файли та сховище (8 ендпоінтів)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /projects/:name/files |
Дерево файлів |
| POST | /projects/:name/files/upload |
Завантажити файл (multipart, max 100MB) |
| POST | /projects/:name/files/mkdir |
Створити директорію |
| POST | /projects/:name/files/create |
Створити файл |
| GET | /projects/:name/files/read |
Прочитати файл |
| PUT | /projects/:name/files/save |
Зберегти файл |
| DELETE | /projects/:name/files/delete |
Видалити файл |
| POST | /projects/:name/files/clone |
Git clone репозиторію |
GET /projects/:name/files — query: path
GET /projects/:name/files/read — query: path, raw
Навички / Skills (18 ендпоінтів)
Навички проєкту
| Метод | Шлях | Опис |
|---|---|---|
| GET | /projects/:name/skills |
Список навичок проєкту |
| POST | /projects/:name/skills |
Створити навичку |
| PUT | /projects/:name/skills/:id |
Оновити навичку |
| DELETE | /projects/:name/skills/:id |
Видалити навичку |
Глобальний маркетплейс
| Метод | Шлях | Опис |
|---|---|---|
| GET | /skills |
Список глобальних навичок |
| POST | /skills |
Опублікувати навичку |
| GET | /skills/:id |
Деталі навички |
| PUT | /skills/:id |
Оновити навичку |
| DELETE | /skills/:id |
Видалити навичку |
Еволюція та оновлення
| Метод | Шлях | Опис |
|---|---|---|
| GET | /skills/:id/evolution |
Історія еволюції навички |
| GET | /skill-updates |
Список доступних оновлень |
| POST | /skill-updates/:id/approve |
Прийняти оновлення |
| POST | /skill-updates/:id/reject |
Відхилити оновлення |
Форки навичок
| Метод | Шлях | Опис |
|---|---|---|
| GET | /projects/:name/skill-forks |
Список форків |
| POST | /projects/:name/skill-forks |
Створити форк |
| PUT | /projects/:name/skill-forks/:id |
Оновити форк |
| DELETE | /projects/:name/skill-forks/:id |
Видалити форк |
Чат та повідомлення
| Метод | Шлях | Опис |
|---|---|---|
| POST | /projects/:name/chat |
Відправити повідомлення в чат |
| GET | /projects/:name/chat/history |
Історія чату |
| POST | /projects/:name/message |
Надіслати повідомлення воркеру (Phase 48.6: автоматично wake-up idle-killed воркера, ~2-4с cold start; Phase 48.6.1: wake-up тепер працює і в single-mode проєктах, не лише parallel) |
| GET | /projects/:name/pins |
Список нотаток (pins) |
| POST | /projects/:name/pins |
Створити нотатку |
| DELETE | /projects/:name/pins/:id |
Видалити нотатку |
Wiki (4 ендпоінти)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /projects/:name/wiki/tree |
Дерево wiki-сторінок |
| GET | /projects/:name/wiki/file |
Прочитати wiki-сторінку |
| PUT | /projects/:name/wiki/save |
Зберегти wiki-сторінку |
| GET | /projects/:name/wiki/download |
Завантажити wiki як ZIP-архів |
Аналітика (4 ендпоінти)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /analytics/activity |
Стрічка активності |
| GET | /analytics/sidebar |
Дані для бічної панелі |
| GET | /analytics/phases |
Список фаз проєкту |
| POST | /analytics/phases |
Оновити фази проєкту |
Marketplace та Sage (8 ендпоінтів)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /sage/scout/categories |
Категорії маркетплейсу |
| POST | /sage/scout |
Пошук навичок |
| POST | /sage/scout/quick-scan |
Швидке сканування |
| POST | /sage/scout/analyze |
Глибокий аналіз навички |
| POST | /sage/scout/install |
Встановити навичку |
| POST | /sage/analyze |
Sage-аналіз |
| GET | /sage/status |
Статус Sage-сервісу |
| POST | /sage/benchmark |
Запустити бенчмарк |
Пам'ять та Knowledge
| Метод | Шлях | Опис |
|---|---|---|
| POST | /projects/:name/memory/refresh |
Оновити нейронну пам'ять |
| POST | /projects/:name/memory/fetch-artifact |
Завантажити артефакт |
| GET | /projects/:name/learnings |
Список learnings |
| POST | /projects/:name/learnings |
Додати learning |
| GET | /projects/:name/knowledge-graph |
Граф знань проєкту |
Документація (глобальна, без auth)
| Метод | Шлях | Опис |
|---|---|---|
| GET | /docs/tree?lang=<lang> |
Дерево документації; lang опціональний (en/uk), default en |
| GET | /docs/file?path=<p>&lang=<lang> |
Прочитати файл документації з language fallback |
GET /docs/tree — query: lang (опціональний)
- Спочатку шукає
docs/public/<lang>/index.md, fallback наdocs/public/index.md - Response includes:
sections,files,served_lang,is_fallback,requested_lang
GET /docs/file — query: path (обов'язковий), lang (опціональний)
- Resolve order:
docs/public/<lang>/<path>→docs/public/<path>(EN fallback) - Response includes:
path,content,size,modified,served_lang,is_fallback,requested_lang - 403 на path traversal, 404 на missing file
- Phase 52.1.3 — додано
langпараметр для UK перекладу
Система
| Метод | Шлях | Опис |
|---|---|---|
| GET | /system/configs |
Отримати системні конфігурації |
| PUT | /system/configs |
Оновити системні конфігурації |
Коди помилок
| Код | Значення |
|---|---|
| 200 | Успіх |
| 201 | Створено |
| 400 | Невалідний запит |
| 401 | Не авторизовано |
| 403 | Заборонено (multi-tenancy) |
| 404 | Не знайдено |
| 409 | Конфлікт (дублікат) |
| 429 | Занадто багато запитів |
| 500 | Серверна помилка |
GitHub Integration (Phase 49.3)
| Endpoint | Method | Опис |
|---|---|---|
/api/crm/projects/:name/github |
GET | Список GitHub repos, прив'язаних до проєкту |
/api/crm/projects/:name/github |
POST | Прив'язати repo (body: {owner, repo}) — повертає webhook URL + secret + setup instructions |
/api/crm/projects/:name/github/:id |
DELETE | Відв'язати repo |
/api/crm/projects/:name/github/events |
GET | Список останніх GitHub events (Phase 49.3.1, query: ?limit=50) |
/api/webhooks/github |
POST | Public webhook receiver (HMAC-SHA256 validated, rate-limit 100/min) |
Supported events: push, pull_request, workflow_run, issues. Сповіщення йдуть у Telegram власника проєкту.
Account Security (Phase 45.4)
| Endpoint | Method | Опис |
|---|---|---|
/api/crm/account/recovery |
GET | Список активних recovery keys |
/api/crm/account/recovery |
POST | Створити recovery key (body: encryptedKey, keyHint) |
/api/crm/account/recovery |
DELETE | Відкликати recovery key(s) (body: { id } або {} для всіх) |
/api/crm/account/recovery/restore |
GET | Отримати encrypted master key для відновлення |
Безпека
- Multi-tenancy: кожен
:nameendpoint перевіряє ownership черезchatIdз JWT - Project name validation:
^[a-zA-Z0-9][a-zA-Z0-9_-]*$(max 64 символи) - Path traversal protection:
safePath()на всіх user-controlled шляхах - File upload: max 100MB, заблоковані розширення (
.exe,.bat,.sh) - CORS: whitelist origins через
CRM_ALLOWED_ORIGINS - SSRF protection: allowlist на
handleScoutAnalyze— лише HTTPS + дозволені хости - Internal endpoints: відхиляють запити з proxy-заголовками (
X-Forwarded-For,X-Real-IP) - At-rest encryption (Phase 45): API-ключі та chat messages зашифровані AES-256-GCM
- Security headers:
Content-Security-Policy,X-Frame-Options: DENY,X-Content-Type-Options: nosniff - PII sanitization: emails, API-ключі, JWT автоматично редагуються з JSONL логів
Phase 63 — Консолідація UI/UX + відстеження використання токенів (2026-05-21, #148)
Новий endpoint:
POST /api/internal/usage/log(тільки loopback) — записує рядок уtoken_usage_log. Body:{ project_name, owner_id, worker_id?, input_tokens, output_tokens, cache_tokens, total_tokens }. Викликається зchild-bot/bot.tsяк fire-and-forget після кожного виклику Claude (callClaudeOnce+callWorkertext path). Не потребує auth header —/api/internal/*доступний лише з localhost і блокується nginx для зовнішніх запитів.GET /api/crm/account/usage— історія використання токенів для авторизованого користувача (описана в таблиці Onboarding вище).
Зміни в claude-runner.ts:
callClaudeOnce+callWorkertext path: тепер завжди--output-format json(ранішеtextдля non-trial). JSON parse витягуєresultяк output text іusageдля логування. Trial consume flow незмінний.- Новий
logUsage?dep уClaudeRunnerDeps— callback(workerId, { input, output, cache }) => void.
UI зміни (не API):
UserDropdown: компонентUsageCardз total tokens + "Details →" при відкритті; warning dot на avatar коли trial balance < 20%.BillingPage: секція Token Usage з totals bar + таблиця 50 рядків. Plan Enterprise (в розробці). Toggledetailsна кожній картці.OnboardingProgressPill: перероблений як inline header dropdown (більше не modal wizard).WorkerSelector: семантичні CSS-змінні--worker-{role}замість Tailwind chart токенів.