15 KiB
TGEX Backend API v2
Аутентификация
JWT Bearer Token в заголовке Authorization: Bearer <token>
Получение токена через Telegram Bot
Логика точно такая же как и раньше
Эндпоинты
| Метод | Эндпоинт | Описание | Auth |
|---|---|---|---|
GET |
/auth/complete |
Обмен временного токена на JWT | ❌ |
GET |
/auth/me |
Получить текущего пользователя | ✅ |
Response /auth/me:
{
"id": "uuid",
"telegram_id": 123456789,
"username": "string | null"
}
Workspaces (Рабочие пространства)
Воркспейсы - изолированные пространства для команд. У пользователя может быть несколько воркспейсов.
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces |
Список воркспейсов пользователя (пагинация) |
POST |
/workspaces |
Создать воркспейс |
PATCH |
/workspaces/{workspace_id} |
Обновить название |
DELETE |
/workspaces/{workspace_id} |
Удалить воркспейс |
Body POST /workspaces:
{
"name": "string"
}
Response:
{
"id": "uuid",
"name": "string"
}
Workspace Members (Участники воркспейса)
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{workspace_id}/members |
Список участников (пагинация) |
PUT |
/workspaces/{workspace_id}/members/{user_id}/permissions |
Обновить права участника |
Права доступа (PermissionKey):
admin_full- полный доступprojects_read- чтение проектовprojects_write- запись проектовplacements_read- чтение размещенийplacements_write- запись размещенийanalytics_read- чтение аналитики
Scope types: project (ограничение прав на конкретный проект)
Body PUT permissions:
{
"permissions": [
{
"key": "admin_full"
},
{
"key": "projects_write",
"scopes": [
{"type": "project", "id": "project-uuid"}
]
}
]
}
Workspace Invites (Приглашения)
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{workspace_id}/invites |
Список приглашений (пагинация) |
POST |
/workspaces/{workspace_id}/invites |
Создать приглашение |
Body POST /invites:
{
"username": "telegram_username" // без @
}
Статусы приглашения: PENDING, ACCEPTED, REJECTED
Projects (Проекты / Целевые каналы)
Проекты = целевые Telegram каналы, которые продвигаются. Создаются через Telegram бота.
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{workspace_id}/projects |
Список проектов (пагинация) |
Response:
{
"id": "uuid",
"telegram_id": -1001234567890,
"title": "string",
"username": "string | null",
"status": "ACTIVE | INACTIVE | ARCHIVED"
}
Управление проектами: через Telegram бота (добавить/удалить канал)
Channels (Каналы для размещений)
Каталог Telegram каналов, где можно размещать рекламу.
| Метод | Эндпоинт | Описание | Фильтры |
|---|---|---|---|
GET |
/channels |
Список каналов (пагинация) | ?username=... |
Response:
{
"id": "uuid",
"telegram_id": -1002345678901,
"title": "string",
"username": "string | null",
"description": "string | null",
"subscribers_count": 15000
}
Purchase Plan (План закупа)
План закупа - список каналов для покупки рекламы в рамках проекта.
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{ws}/projects/{proj}/purchase-plan/channels |
Список каналов плана (пагинация) |
POST |
/workspaces/{ws}/projects/{proj}/purchase-plan/channels |
Добавить канал в план |
PATCH |
/workspaces/{ws}/projects/{proj}/purchase-plan/channels/{id} |
Обновить параметры канала |
DELETE |
/workspaces/{ws}/projects/{proj}/purchase-plan/channels/{id} |
Удалить из плана |
Body POST:
{
"channel_id": "uuid",
"planned_date": "2025-01-15T12:00:00Z", // optional
"price": 5000.50, // optional
"comment": "string" // optional
}
Body PATCH:
{
"planned_date": "2025-01-15T12:00:00Z", // optional
"price": 5000.50, // optional
"comment": "string" // optional
}
Response:
{
"id": "uuid",
"status": "PLANNED | COMPLETED | CANCELLED",
"planned_date": "2025-01-15T12:00:00Z | null",
"price": 5000.50,
"comment": "string | null",
"channel": {
"id": "uuid",
"title": "string",
"username": "string | null",
"subscribers_count": 15000
}
}
Creatives (Креативы)
Креативы = рекламные материалы (текст с пригласительной ссылкой).
| Метод | Эндпоинт | Описание | Фильтры |
|---|---|---|---|
GET |
/workspaces/{ws}/creatives |
Список креативов (пагинация) | ?project_id=...&include_archived=false |
GET |
/workspaces/{ws}/creatives/{id} |
Один креатив | |
POST |
/workspaces/{ws}/creatives?project_id=... |
Создать креатив | |
PATCH |
/workspaces/{ws}/creatives/{id} |
Обновить креатив | |
DELETE |
/workspaces/{ws}/creatives/{id} |
Удалить (архивировать) |
Body POST/PATCH:
{
"name": "string",
"text": "Текст с {invite_link} тегом"
}
Response:
{
"id": "uuid",
"name": "string",
"text": "string",
"status": "ACTIVE | ARCHIVED",
"placements_count": 5
}
Важно: {invite_link} в тексте заменяется на уникальную ссылку при создании размещения.
Placements (Размещения)
Размещения = факт размещения креатива в канале.
| Метод | Эндпоинт | Описание | Фильтры |
|---|---|---|---|
GET |
/workspaces/{ws}/placements |
Список размещений (пагинация) | ?project_id=...&placement_channel_id=...&creative_id=...&include_archived=false |
GET |
/workspaces/{ws}/placements/{id} |
Одно размещение | |
POST |
/workspaces/{ws}/placements |
Создать размещение | |
PATCH |
/workspaces/{ws}/placements/{id} |
Обновить размещение | |
DELETE |
/workspaces/{ws}/placements/{id} |
Удалить (архивировать) |
Body POST:
{
"project_id": "uuid",
"placement_channel_id": "uuid",
"creative_id": "uuid",
"placement_date": "2025-01-15T12:00:00Z",
"cost": 5000.50, // optional
"comment": "string", // optional
"ad_post_url": "https://t.me/channel/123", // optional
"invite_link_type": "PUBLIC | APPROVAL"
}
Body PATCH:
{
"placement_date": "2025-01-15T12:00:00Z", // optional
"cost": 5000.50, // optional
"comment": "string", // optional
"ad_post_url": "https://t.me/channel/123" // optional
}
Response:
{
"id": "uuid",
"placement_date": "2025-01-15T12:00:00Z",
"cost": 5000.50,
"comment": "string | null",
"ad_post_url": "string | null",
"invite_link_type": "PUBLIC | APPROVAL",
"invite_link": "https://t.me/+UniqueCode",
"status": "ACTIVE | ARCHIVED",
"subscriptions_count": 42,
"views_count": 1850,
"views_availability": "UNKNOWN | AVAILABLE | UNAVAILABLE | MANUAL",
"last_views_fetch_at": "2025-01-15T14:30:00Z",
"project": {
"id": "uuid",
"title": "string",
"username": "string | null"
},
"placement_channel": {
"id": "uuid",
"title": "string",
"username": "string | null",
"subscribers_count": 15000
},
"creative": {
"id": "uuid",
"name": "string"
}
}
Типы пригласительных ссылок:
PUBLIC- открытая ссылкаAPPROVAL- с одобрением через бота
Статус просмотров:
UNKNOWN- еще не проверялосьAVAILABLE- просмотры доступны (автообновление)UNAVAILABLE- нет доступа к просмотрамMANUAL- ручной ввод
Views History (История просмотров)
| Метод | Эндпоинт | Описание | Фильтры |
|---|---|---|---|
GET |
/workspaces/{ws}/placements/{id}/views/history |
История просмотров (пагинация) | ?from_date=...&to_date=... |
Response:
{
"id": "uuid",
"views_count": 1850,
"fetched_at": "2025-01-15T14:30:00Z"
}
Analytics (Аналитика)
Все эндпоинты поддерживают фильтр ?project_id=... для конкретного проекта.
Аналитика размещений
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{ws}/analytics/placements |
Аналитика по размещениям (пагинация) |
Response:
{
"placement_id": "uuid",
"placement_channel_title": "string",
"placement_channel_username": "string | null",
"creative_name": "string",
"placement_date": "2025-01-15T12:00:00Z",
"cost": 5000.50,
"subscriptions_count": 42,
"views_count": 1850,
"cps": 119.05, // cost per subscription
"cpm": 2702.70 // cost per mille views
}
Аналитика креативов
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{ws}/analytics/creatives |
Аналитика по креативам (пагинация) |
Response:
{
"creative_id": "uuid",
"creative_name": "string",
"placements_count": 5,
"total_cost": 25000.00,
"total_subscriptions": 210,
"total_views": 9250,
"avg_cps": 119.05,
"avg_cpm": 2702.70
}
Аналитика каналов
| Метод | Эндпоинт | Описание |
|---|---|---|
GET |
/workspaces/{ws}/analytics/channels |
Аналитика по каналам (пагинация) |
Response:
{
"channel_id": "uuid",
"channel_title": "string",
"channel_username": "string | null",
"placements_count": 3,
"total_cost": 15000.00,
"total_subscriptions": 126,
"total_views": 5550,
"avg_cps": 119.05,
"avg_cpm": 2702.70
}
Аналитика расходов
| Метод | Эндпоинт | Описание | Фильтры |
|---|---|---|---|
GET |
/workspaces/{ws}/analytics/spending |
Динамика расходов | ?date_from=...&date_to=...&grouping=DAY|WEEK|MONTH |
Response:
{
"items": [
{
"date": "2025-01-15",
"cost": 5000.50,
"subscriptions": 42,
"views": 1850
}
],
"total_cost": 25000.00,
"total_subscriptions": 210,
"total_views": 9250
}
Группировка (DateGrouping): DAY, WEEK, MONTH
Пагинация
Все эндпоинты с пагинацией возвращают:
{
"items": [...],
"total": 42,
"page": 1,
"size": 50,
"pages": 1
}
Query параметры: ?page=1&size=50
Статусы и Enum
WorkspaceUserStatus
ACTIVE- активный участникINVITED- приглашён, но не принял
WorkspaceInviteStatus
PENDING- ожидает принятияACCEPTED- принятоREJECTED- отклонено
ProjectStatus / ChannelStatus
ACTIVE- активенINACTIVE- неактивенARCHIVED- архивирован
CreativeStatus / PlacementStatus
ACTIVE- активенARCHIVED- архивирован
PurchasePlanStatus
PLANNED- запланированCOMPLETED- завершёнCANCELLED- отменён
InviteLinkType
PUBLIC- открытая ссылкаAPPROVAL- с одобрением бота
PostViewsAvailability
UNKNOWN- неизвестно (ещё не проверялось)AVAILABLE- доступны (автообновление)UNAVAILABLE- недоступныMANUAL- ручной ввод
Коды ошибок HTTP
200- OK201- Created204- No Content (успешное удаление)400- Bad Request (валидация)401- Unauthorized (нет токена)403- Forbidden (нет прав)404- Not Found500- Internal Server Error
Формат ошибки:
{
"detail": "Error message"
}
Особенности
- Все UUID в формате:
xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx - Даты в ISO 8601:
2025-01-15T12:00:00Z(UTC) - Метрики автообновляются: просмотры обновляются воркером каждые 60 секунд (если
views_availability = AVAILABLE) - Подписки отслеживаются: через Telegram бота при присоединении по invite_link
- Права проверяются: все эндпоинты под воркспейсами требуют соответствующих прав
- Soft delete: удаление = архивирование (статус
ARCHIVED)
Telegram Bot Integration
- Создание проектов (добавление целевых каналов)
- Создание креативов через диалог
- Приглашения в воркспейсы
- Отслеживание подписок через invite links
- Начальная аутентификация (
/start→ временный токен)