Applications
GET/POST/PATCH/DELETE /applications + /archive, /notes, /history.
Внутренний контрактный хаб: версии, соглашения, примеры запросов и ответов.
Internal API для сайта, партнерских интеграций, AI-агентов и автоматизаций Motiv. Это не публичный consumer API.
Где это в коде: слой API в репозитории см. MSP → Структура кода; карта экранов админки — Структура проекта.
v1.| Параметр | Значение |
|---|---|
| Base path | /api/v1 |
| Format | JSON UTF-8 |
| Auth | Authorization: Bearer <token> (Laravel Sanctum) |
| Token issue | Админка /admin/api-token или POST /api/v1/auth/token (email/password + abilities) |
| Token revoke | DELETE /api/v1/auth/token (текущий токен) |
| Token lifecycle | GET /api/v1/auth/tokens, DELETE /api/v1/auth/tokens/{id} |
| Abilities/scopes | apps:read, apps:write, analytics:write, admin:full и др. |
| Rate limit | 120 req/min на токен (fallback по IP) |
| API audit | Логируются метод, путь, status code, duration, token/user привязка. |
| Pagination | page, per_page |
| Error envelope | { message, errors? } |
composer install, php artisan migrate --seed.email: test@example.compassword: admin12345 (или из MOTIV_DEV_ADMIN_PASSWORD)/admin/api-token (рекомендуется) или через POST /api/v1/auth/token с нужными abilities.Authorization: Bearer <token> в каждом запросе.GET /applications → POST /applications → POST /analytics/clicks/bulk.| Слой | Что проверяет | Пример отказа |
|---|---|---|
| Token ability middleware | Есть ли нужный scope у токена | apps:write отсутствует → 403 |
| Policy (role-aware) | Разрешена ли операция по роли/статусу user | role=user на create app → 403 |
Итог: для mutating endpoints нужны оба условия: корректная ability + разрешающая policy.
| Endpoint group | Ability | Policy role requirement |
|---|---|---|
| Applications create/update/delete/archive | apps:write | admin или manager (для manager: только owner-owned app) |
| Analytics bulk ingest | analytics:write | admin или manager, status active |
| Token lifecycle (list/revoke own) | auth:sanctum | любой аутентифицированный user, только свои токены |
GET/POST/PATCH/DELETE /applications + /archive, /notes, /history.
GET/POST/PATCH/DELETE /companies + /notes, /history.
GET/POST/PATCH/DELETE /contacts с company/app/strategy связями.
GET/POST/PATCH/DELETE /strategies + /notes, /history.
GET/POST/PATCH/DELETE /keywords с фильтрами по strategy/company/status.
GET /analytics/clicks, POST /analytics/clicks, POST /analytics/clicks/bulk.
/dashboard/summary, /dashboard/attention, /dashboard/focus.
GET /admin/api-logs (read-only, debugging/monitoring). Требует logs:read + admin/manager policy.
# Token issue (рабочий локальный пример)
POST /api/v1/auth/token
{
"email": "test@example.com",
"password": "admin12345",
"token_name": "local-dev",
"abilities": ["apps:read", "apps:write", "analytics:write", "dashboard:read"]
}
201 Created
{
"token_type": "Bearer",
"access_token": "1|********************************",
"abilities": ["apps:read", "apps:write", "analytics:write"]
}
# Applications create (минимальный payload)
POST /api/v1/applications
{
"name": "My Test App",
"platform": "ios",
"status": "active"
}
201 Created
{
"data": {
"id": 123,
"name": "My Test App",
"platform": "ios",
"native_id": "api-...",
"status": "active"
}
}
401 unauthenticated — токен не передан или невалиден.422 validation error — ошибки по полям в errors.404 not found — сущность не найдена.403 forbidden — нет прав.500 internal error — fallback response без утечки stacktrace.# 403 (ability/policy mismatch)
{
"message": "This action is unauthorized."
}
# 422 (validation)
{
"message": "Validation failed.",
"errors": {
"name": ["The name field is required."]
}
}
Логи запросов доступны через админку (/admin/api-request-logs) и read-only endpoint GET /api/v1/admin/api-logs.
Security: в api_request_logs не пишутся access tokens и Authorization header. Логируются только safe-поля: method/path/status/duration/ip/user/token_id/user_agent.
GET /api/v1/applications?status=active&without_owner=1&per_page=20
{
"data": [
{
"id": 41,
"name": "Motiv App",
"status": "active",
"company": {"id": 3, "name": "Farmchel"},
"owner": {"id": 8, "name": "Ops Manager"}
}
]
}
POST /api/v1/analytics/clicks/bulk
{
"rows": [
{
"date": "2026-04-17",
"app_id": 41,
"company_id": 3,
"clicks": 1290,
"status": "ok"
}
]
}
{
"created": 1,
"updated": 0,
"skipped": 0,
"errors": []
}
DELETE /api/v1/auth/token
Authorization: Bearer <token>
GET /api/v1/dashboard/summary
Authorization: Bearer <token>
}