{"openapi":"3.1.0","info":{"title":"Agentpay API","description":"API для подключения AI-агентов к биллингу Agentpay. Отправляйте события агента,\nпроверяйте баланс, смотрите usage и управляйте агентами.\n\n## Авторизация\nВсе запросы к `/api/v1/*` авторизуются API-ключом в заголовке:\n\n```\nAuthorization: Bearer agb_test_xxxxxxxxxxxxxxxxxxxx\n```\n\nКлюч выдаётся один раз при создании (поле `key`) — храните его в секрете и не\nпубликуйте на клиенте/в браузере. Ключ используется только для `/api/v1/*`.\n\n## Первое событие\n```bash\ncurl -X POST \"$APP_URL/api/v1/events\" \\\n  -H \"Authorization: Bearer agb_test_xxxxxxxxxxxxxxxxxxxx\" \\\n  -H \"Idempotency-Key: ticket_123_resolved\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"agent_id\":\"agent_support_123\",\"event_name\":\"support_ticket_resolved\",\"success\":true}'\n```\n\nПовтор с тем же `Idempotency-Key` вернёт `200` с `idempotent_replay: true` и не\nспишет деньги повторно.","version":"1.0.0"},"servers":[{"url":"https://agent-pay.lamagate.com","description":"Текущее окружение (APP_URL)"},{"url":"http://localhost:3000","description":"Локальная разработка"}],"security":[{"BearerAuth":[]}],"tags":[{"name":"Events","description":"Отправка событий агента для тарификации."},{"name":"Billing","description":"Баланс и история списаний."},{"name":"Agents","description":"Список и создание агентов."},{"name":"API keys","description":"Создание API-ключей."}],"paths":{"/api/v1/events":{"post":{"tags":["Events"],"summary":"Отправить событие агента","description":"Тарифицирует событие по активным правилам агента и атомарно списывает стоимость с баланса организации. Идемпотентно по заголовку `Idempotency-Key` (или `external_event_id` как fallback).","operationId":"createUsageEvent","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Уникальный ключ для дедупликации. Если не задан — используется `external_event_id` из тела. Повтор не спишет деньги дважды.","schema":{"type":"string","example":"ticket_123_resolved"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageEventCreateRequest"},"examples":{"support_ticket_resolved":{"summary":"Решённый тикет поддержки","value":{"agent_id":"agent_support_123","event_name":"support_ticket_resolved","external_event_id":"ticket_123_resolved","units":1,"success":true,"input_tokens":1200,"output_tokens":500,"duration_ms":18000,"payload":{"ticket_id":"123"}}},"lead_qualified":{"summary":"Квалифицированный лид","value":{"agent_id":"agent_sales_123","event_name":"lead_qualified","units":1,"success":true,"payload":{"lead_id":"lead_456","lead_score":87}}},"tokens":{"summary":"Списание за токены LLM","value":{"agent_id":"agent_content_123","event_name":"tokens","input_tokens":3000,"output_tokens":1500,"success":true}}}}}},"responses":{"200":{"description":"Событие принято (или идемпотентный повтор).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageEventCreateResponse"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"402":{"description":"Недостаточно средств на балансе (`insufficient_balance`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Ключ привязан к другому агенту (`forbidden`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Агент не найден в организации (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Агент на паузе (`agent_paused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"description":"Превышен rate limit (`rate_limited`) или дневной лимит организации (`limit_exceeded`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/balance":{"get":{"tags":["Billing"],"summary":"Текущий баланс","description":"Возвращает текущий баланс организации, к которой привязан API-ключ.","operationId":"getBalance","responses":{"200":{"description":"Текущий баланс.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/usage":{"get":{"tags":["Billing"],"summary":"История событий (usage)","description":"Возвращает последние события (по убыванию даты). Пагинации по курсору нет: используйте `limit` (по умолчанию 50, максимум 200). Если ключ привязан к агенту, выдаются только его события.","operationId":"listUsage","parameters":[{"name":"agent_id","in":"query","required":false,"description":"Фильтр по агенту. Игнорируется, если ключ уже привязан к агенту.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Сколько событий вернуть (по умолчанию 50, максимум 200).","schema":{"type":"integer","default":50,"maximum":200,"minimum":1}}],"responses":{"200":{"description":"Список событий.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageListResponse"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/agents":{"get":{"tags":["Agents"],"summary":"Список агентов","description":"Возвращает агентов организации с агрегатами (правила, события, суммарные списания).","operationId":"listAgents","responses":{"200":{"description":"Список агентов.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListResponse"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Agents"],"summary":"Создать агента","description":"Создаёт нового агента. `project_id` опционален: если не указан, используется проект, к которому привязан ключ.","operationId":"createAgent","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateRequest"},"example":{"name":"Support Ticket Resolver","description":"AI-агент поддержки"}}}},"responses":{"201":{"description":"Агент создан.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateResponse"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"404":{"description":"Проект не найден (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/api-keys":{"post":{"tags":["API keys"],"summary":"Создать API-ключ","description":"Создаёт новый API-ключ в организации текущего ключа. Полный ключ возвращается ОДИН раз в поле `key` — сохраните его сразу, повторно его получить нельзя (в базе хранится только хеш).","operationId":"createApiKey","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"},"example":{"name":"Production key","agent_id":"agent_support_123"}}}},"responses":{"201":{"description":"Ключ создан. `key` показывается единственный раз.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"401":{"$ref":"#/components/responses/InvalidApiKey"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API-ключ Agentpay: `Authorization: Bearer agb_test_xxxxxxxxxxxxxxxxxxxx`."}},"responses":{"InvalidApiKey":{"description":"Отсутствует, неверный или отозванный API-ключ (`invalid_api_key`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ValidationError":{"description":"Ошибка валидации тела/параметров (`validation_error`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"RateLimited":{"description":"Превышен rate limit (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"MoneyAmount":{"type":"object","required":["amount","currency","minor_units"],"properties":{"amount":{"type":"number","example":35,"description":"Сумма в основных единицах (рубли)."},"currency":{"type":"string","example":"RUB"},"minor_units":{"type":"integer","example":3500,"description":"Сумма в копейках (целое, без float)."}}},"UsageEventCreateRequest":{"type":"object","required":["event_name"],"description":"`agent_id` обязателен, если API-ключ не привязан к конкретному агенту. Если ключ привязан к агенту — `agent_id` можно не передавать.","properties":{"agent_id":{"type":"string","description":"ID агента.","example":"agent_support_123"},"event_name":{"type":"string","maxLength":200,"example":"support_ticket_resolved"},"external_event_id":{"type":["string","null"],"maxLength":200,"description":"Внешний ID события (fallback для идемпотентности)."},"units":{"type":"integer","minimum":0,"maximum":1000000,"default":1,"description":"Количество единиц (по умолчанию 1)."},"success":{"type":["boolean","null"],"description":"Успех (для тарифов per_successful_run)."},"input_tokens":{"type":["integer","null"],"minimum":0},"output_tokens":{"type":["integer","null"],"minimum":0},"duration_ms":{"type":["integer","null"],"minimum":0,"description":"Длительность в миллисекундах."},"payload":{"type":["object","null"],"additionalProperties":true,"description":"Произвольные метаданные."}}},"UsageEventCreateResponse":{"type":"object","required":["accepted","idempotent_replay","usage_event_id","cost","balance_after"],"properties":{"accepted":{"type":"boolean","example":true},"idempotent_replay":{"type":"boolean","example":false,"description":"true, если событие с этим ключом уже было обработано (деньги не списаны повторно)."},"usage_event_id":{"type":"string"},"cost":{"$ref":"#/components/schemas/MoneyAmount"},"balance_after":{"$ref":"#/components/schemas/MoneyAmount"}}},"BalanceResponse":{"type":"object","required":["balance"],"properties":{"balance":{"$ref":"#/components/schemas/MoneyAmount"}}},"UsageEvent":{"type":"object","properties":{"id":{"type":"string"},"agent_id":{"type":"string"},"agent_name":{"type":"string"},"event_name":{"type":"string"},"external_event_id":{"type":["string","null"]},"status":{"type":"string","example":"processed"},"units":{"type":"integer"},"input_tokens":{"type":["integer","null"]},"output_tokens":{"type":["integer","null"]},"duration_ms":{"type":["integer","null"]},"success":{"type":["boolean","null"]},"cost":{"$ref":"#/components/schemas/MoneyAmount"},"created_at":{"type":"string","format":"date-time"}}},"UsageListResponse":{"type":"object","required":["usage"],"description":"Поле `usage` — массив событий (не `events`). Пагинации по курсору нет.","properties":{"usage":{"type":"array","items":{"$ref":"#/components/schemas/UsageEvent"}}}},"Agent":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","example":"active"},"project_id":{"type":["string","null"]},"project_name":{"type":["string","null"]},"rule_count":{"type":"integer"},"event_count":{"type":"integer"},"total_spend":{"$ref":"#/components/schemas/MoneyAmount"},"created_at":{"type":"string","format":"date-time"}}},"AgentListResponse":{"type":"object","required":["agents"],"properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/Agent"}}}},"AgentCreateRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":120},"description":{"type":"string","maxLength":2000,"default":""},"project_id":{"type":"string","description":"Если не указан — берётся проект ключа."}}},"AgentCreateResponse":{"type":"object","required":["agent"],"properties":{"agent":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","example":"active"},"project_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}}}},"ApiKeyCreateRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"project_id":{"type":["string","null"],"description":"Ограничить ключ проектом."},"agent_id":{"type":["string","null"],"description":"Привязать ключ к агенту."}}},"ApiKeyCreateResponse":{"type":"object","required":["api_key","key"],"properties":{"api_key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"prefix":{"type":"string","example":"agb_a1B2c3D4","description":"Несекретный префикс для отображения."},"status":{"type":"string","example":"active"},"created_at":{"type":"string","format":"date-time"}}},"key":{"type":"string","example":"agb_test_xxxxxxxxxxxxxxxxxxxx","description":"Полный API-ключ. Показывается ТОЛЬКО ОДИН РАЗ — сохраните его сразу."}}},"ErrorResponse":{"type":"object","required":["error"],"description":"Единый конверт ошибок. Идемпотентный повтор события НЕ ошибка — он возвращается с кодом 200 и `idempotent_replay: true`.","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Машиночитаемый код: invalid_api_key, validation_error, insufficient_balance, limit_exceeded, rate_limited, agent_paused, forbidden, not_found, internal_error.","example":"invalid_api_key"},"message":{"type":"string","example":"Неверный или отозванный API-ключ"},"details":{"description":"Опциональные детали валидации."}}},"requestId":{"type":["string","null"],"description":"ID запроса для поиска в логах сервера (также в заголовке x-request-id)."}}}}}}