openapi: 3.2.0 info: title: Axonflow Cost Controls API version: 11.1.0 contact: name: AxonFlow Support url: https://getaxonflow.com/support license: name: Business Source License 1.1 url: https://github.com/getaxonflow/axonflow/blob/main/LICENSE description: 'Operations tagged Cost Controls across 2 of this provider''s published API definitions: axonflow-orchestrator-api.yaml, axonflow-orchestrator-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development tags: - name: Cost Controls description: 'Budget management and LLM usage tracking for cost optimization. Supports budgets at organization, team, agent, workflow, and user scopes. Provides usage summaries, breakdowns, and pre-request budget checks.' paths: /api/v1/budgets: post: tags: - Cost Controls summary: Create a budget description: 'Create a new budget with spending limits. Budgets can be scoped to organization, team, agent, workflow, or user level. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: createBudget parameters: - name: X-Org-ID in: header required: true description: Organization ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BudgetCreate' example: id: monthly-budget name: Monthly Production Budget scope: organization limit_usd: 1000.0 period: monthly on_exceed: warn alert_thresholds: - 50 - 80 - 100 responses: '201': description: Budget created content: application/json: schema: $ref: '#/components/schemas/Budget' '400': description: Invalid budget configuration content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Budget with this ID already exists get: tags: - Cost Controls summary: List budgets description: 'List all budgets for the organization. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: listBudgets parameters: - name: X-Org-ID in: header required: true description: Organization ID schema: type: string - name: scope in: query description: Filter by budget scope schema: type: string enum: - organization - team - agent - workflow - user - name: limit in: query description: Maximum number of results schema: type: integer default: 50 - name: offset in: query description: Offset for pagination schema: type: integer default: 0 responses: '200': description: List of budgets content: application/json: schema: $ref: '#/components/schemas/BudgetList' servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/budgets/{id}: get: tags: - Cost Controls summary: Get a budget description: 'Get a specific budget by ID. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: getBudget parameters: - name: id in: path required: true description: Budget ID schema: type: string responses: '200': description: Budget details content: application/json: schema: $ref: '#/components/schemas/Budget' '404': description: Budget not found put: tags: - Cost Controls summary: Update a budget description: 'Update an existing budget configuration. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: updateBudget parameters: - name: id in: path required: true description: Budget ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BudgetUpdate' responses: '200': description: Budget updated content: application/json: schema: $ref: '#/components/schemas/Budget' '404': description: Budget not found '400': description: Invalid budget configuration delete: tags: - Cost Controls summary: Delete a budget description: 'Delete a budget by ID. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: deleteBudget parameters: - name: id in: path required: true description: Budget ID schema: type: string responses: '204': description: Budget deleted '404': description: Budget not found servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/budgets/{id}/status: get: tags: - Cost Controls summary: Get budget status description: 'Get real-time status of a budget including current usage, remaining amount, and whether the budget is exceeded. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: getBudgetStatus parameters: - name: id in: path required: true description: Budget ID schema: type: string responses: '200': description: Budget status content: application/json: schema: $ref: '#/components/schemas/BudgetStatus' example: budget: id: monthly-budget name: Monthly Production Budget scope: organization limit_usd: 1000.0 period: monthly used_usd: 450.25 remaining_usd: 549.75 percentage: 45.025 period_start: '2026-01-01T00:00:00Z' period_end: '2026-02-01T00:00:00Z' is_exceeded: false is_blocked: false '404': description: Budget not found servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/budgets/{id}/alerts: get: tags: - Cost Controls summary: Get budget alerts description: 'Get alerts triggered for a specific budget. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: getBudgetAlerts parameters: - name: id in: path required: true description: Budget ID schema: type: string - name: limit in: query description: Maximum number of alerts to return schema: type: integer default: 50 responses: '200': description: Budget alerts content: application/json: schema: $ref: '#/components/schemas/BudgetAlertList' '404': description: Budget not found servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/budgets/check: post: tags: - Cost Controls summary: Check budget before request description: 'Check if a request should be allowed based on budget constraints. Returns whether the request is allowed and the applicable budget status. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: checkBudget requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BudgetCheckRequest' example: org_id: your-org-id team_id: engineering agent_id: support-bot responses: '200': description: Budget check result content: application/json: schema: $ref: '#/components/schemas/BudgetCheckResponse' examples: allowed: summary: Request allowed value: allowed: true blocked: summary: Request blocked value: allowed: false action: block budget_id: team-budget budget_name: Engineering Team Budget used_usd: 520.0 limit_usd: 500.0 percentage: 104.0 message: Budget 'Engineering Team Budget' exceeded - requests blocked servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/usage: get: tags: - Cost Controls summary: Get usage summary description: 'Get aggregated LLM usage for the current period. Available in both Community and Enterprise editions. Basic usage overview.' operationId: getUsageSummary parameters: - name: X-Org-ID in: header required: true description: Organization ID schema: type: string - name: period in: query description: Time period for aggregation schema: type: string enum: - daily - weekly - monthly - quarterly - yearly default: monthly responses: '200': description: Usage summary content: application/json: schema: $ref: '#/components/schemas/UsageSummary' example: total_cost_usd: 450.25 total_tokens_in: 1250000 total_tokens_out: 375000 total_requests: 5420 average_cost_per_request: 0.083 servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/usage/breakdown: get: tags: - Cost Controls summary: Get usage breakdown description: 'Get usage broken down by a specific dimension. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: getUsageBreakdown parameters: - name: X-Org-ID in: header required: true description: Organization ID schema: type: string - name: group_by in: query required: true description: Dimension to group by schema: type: string enum: - provider - model - agent - team - user - name: period in: query description: Time period for aggregation schema: type: string enum: - daily - weekly - monthly - quarterly - yearly default: monthly responses: '200': description: Usage breakdown content: application/json: schema: $ref: '#/components/schemas/UsageBreakdown' example: group_by: provider total_cost_usd: 450.25 items: - group_by: provider group_value: anthropic cost_usd: 320.5 tokens_in: 890000 tokens_out: 245000 request_count: 3200 percentage: 71.2 - group_by: provider group_value: openai cost_usd: 129.75 tokens_in: 360000 tokens_out: 130000 request_count: 2220 percentage: 28.8 servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/usage/records: get: tags: - Cost Controls summary: List usage records description: 'List individual usage records with filtering. Enterprise only. These routes are not registered in Community edition, which returns 404 Not Found.' operationId: listUsageRecords parameters: - name: X-Org-ID in: header required: true description: Organization ID schema: type: string - name: start_time in: query description: Filter records after this time schema: type: string format: date-time - name: end_time in: query description: Filter records before this time schema: type: string format: date-time - name: provider in: query description: Filter by LLM provider schema: type: string - name: model in: query description: Filter by model name schema: type: string - name: agent_id in: query description: Filter by agent ID schema: type: string - name: limit in: query description: Maximum number of records schema: type: integer default: 100 - name: offset in: query description: Offset for pagination schema: type: integer default: 0 responses: '200': description: Usage records content: application/json: schema: $ref: '#/components/schemas/UsageRecordList' servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development /api/v1/pricing: get: tags: - Cost Controls summary: Get model pricing description: 'Get pricing information for LLM models. Available in both Community and Enterprise editions.' operationId: getPricing parameters: - name: provider in: query description: Filter by provider name schema: type: string - name: model in: query description: Filter by model name schema: type: string responses: '200': description: Pricing information content: application/json: schema: oneOf: - $ref: '#/components/schemas/PricingInfo' - $ref: '#/components/schemas/PricingList' examples: single_model: summary: Single model pricing value: provider: anthropic model: claude-sonnet-4 pricing: input_per_1k: 0.003 output_per_1k: 0.015 all_providers: summary: All providers pricing value: providers: anthropic: claude-sonnet-4: input_per_1k: 0.003 output_per_1k: 0.015 claude-opus-4: input_per_1k: 0.015 output_per_1k: 0.075 openai: gpt-4o: input_per_1k: 0.0025 output_per_1k: 0.01 servers: - url: https://orchestrator.getaxonflow.com description: Production (SaaS) - url: http://localhost:8081 description: Local Development components: schemas: UsageRecordList: type: object properties: records: type: array items: $ref: '#/components/schemas/UsageRecord' count: type: integer total: type: integer BudgetAlertList: type: object properties: alerts: type: array items: $ref: '#/components/schemas/BudgetAlert' count: type: integer PricingInfo: type: object required: - provider - model - pricing properties: provider: type: string model: type: string pricing: $ref: '#/components/schemas/ModelPricing' BudgetCheckResponse: type: object properties: allowed: type: boolean description: Whether the request should be allowed action: type: string enum: - warn - block - downgrade description: Action that was taken (if budget exceeded) budget_id: type: string description: ID of the budget that blocked the request budget_name: type: string used_usd: type: number format: double limit_usd: type: number format: double percentage: type: number format: double message: type: string BudgetUpdate: type: object properties: name: type: string limit_usd: type: number format: double on_exceed: type: string enum: - warn - block - downgrade alert_thresholds: type: array items: type: integer ModelPricing: type: object properties: input_per_1k: type: number format: double description: Cost per 1,000 input tokens in USD output_per_1k: type: number format: double description: Cost per 1,000 output tokens in USD BudgetStatus: type: object properties: budget: $ref: '#/components/schemas/Budget' used_usd: type: number format: double description: Amount spent in current period remaining_usd: type: number format: double description: Remaining budget percentage: type: number format: double description: Percentage of budget used period_start: type: string format: date-time period_end: type: string format: date-time is_exceeded: type: boolean description: Whether budget limit has been exceeded is_blocked: type: boolean description: Whether requests are being blocked Budget: type: object required: - id - name - scope - limit_usd - period properties: id: type: string description: Unique budget identifier name: type: string description: Human-readable budget name enabled: type: boolean default: true description: 'When false the budget is configured but its limit is not enforced — usage is still tracked. Lets operators dry-run a budget before flipping it on. ' scope: type: string enum: - organization - team - agent - workflow - user description: Budget scope level scope_id: type: string description: ID of the scoped entity (team_id, agent_id, etc.) limit_usd: type: number format: double description: Maximum spending limit in USD period: type: string enum: - daily - weekly - monthly - quarterly - yearly description: Budget reset period on_exceed: type: string enum: - warn - block - downgrade default: warn description: Action when budget is exceeded alert_thresholds: type: array items: type: integer description: Percentage thresholds for alerts (e.g., [50, 80, 100]) org_id: type: string description: Organization ID tenant_id: type: string description: Tenant ID (multi-tenant deployments) created_at: type: string format: date-time updated_at: type: string format: date-time UsageBreakdownItem: type: object properties: group_by: type: string description: Dimension name (provider, model, agent, etc.) group_value: type: string description: Value of the dimension cost_usd: type: number format: double tokens_in: type: integer tokens_out: type: integer request_count: type: integer percentage: type: number format: double PricingList: type: object required: - providers properties: providers: type: object additionalProperties: type: object additionalProperties: $ref: '#/components/schemas/ModelPricing' UsageSummary: type: object properties: total_cost_usd: type: number format: double total_tokens_in: type: integer total_tokens_out: type: integer total_requests: type: integer average_cost_per_request: type: number format: double period_start: type: string format: date-time period_end: type: string format: date-time period: type: string description: 'Bucket label for the rolled-up period (e.g. `2026-04`, `2026-W17`, `2026-04-29`). Echoes the request''s bucket granularity so callers can label charts without parsing `period_start` / `period_end`. ' BudgetCreate: type: object required: - id - name - scope - limit_usd - period properties: id: type: string name: type: string scope: type: string enum: - organization - team - agent - workflow - user scope_id: type: string limit_usd: type: number format: double period: type: string enum: - daily - weekly - monthly - quarterly - yearly on_exceed: type: string enum: - warn - block - downgrade default: warn alert_thresholds: type: array items: type: integer BudgetList: type: object properties: budgets: type: array items: $ref: '#/components/schemas/Budget' count: type: integer BudgetAlert: type: object properties: id: type: integer budget_id: type: string threshold: type: integer description: Threshold percentage that triggered alert percentage_reached: type: number format: double amount_usd: type: number format: double alert_type: type: string enum: - threshold_reached - budget_exceeded - budget_blocked message: type: string created_at: type: string format: date-time acknowledged: type: boolean BudgetCheckRequest: type: object required: - org_id properties: org_id: type: string team_id: type: string agent_id: type: string workflow_id: type: string user_id: type: string UsageRecord: type: object properties: id: type: string request_id: type: string org_id: type: string tenant_id: type: string team_id: type: string agent_id: type: string user_id: type: string workflow_id: type: string provider: type: string model: type: string tokens_in: type: integer tokens_out: type: integer cost_usd: type: number format: double latency_ms: type: integer success: type: boolean error_message: type: string created_at: type: string format: date-time timestamp: type: string format: date-time description: 'Wall-clock time the usage event occurred — distinct from `created_at` (when the row was inserted). Some downstream paths emit this as the canonical event time. ' UsageBreakdown: type: object properties: group_by: type: string total_cost_usd: type: number format: double items: type: array items: $ref: '#/components/schemas/UsageBreakdownItem' period: type: string description: 'Bucket label for the rolled-up period (e.g. `2026-04`, `2026-W17`). Same field as `UsageSummary.period`. ' period_start: type: string format: date-time description: Inclusive start of the rolled-up period. period_end: type: string format: date-time description: Exclusive end of the rolled-up period. ErrorResponse: type: object description: 'The FLAT error envelope: `{success, error}`. This is what `sendErrorResponse` emits, which is the orchestrator''s dominant error writer (240 call sites), so it is the shape of every error from the core request, audit, plan, workflow, execution and connector surfaces. It is one of THREE error SHAPES this document describes. See `CodedErrorResponse` and `TripletErrorResponse` for the other two, and the note on `components.responses` for why there is more than one. `LLMProviderAPIError` is a code-constrained refinement of the coded shape, not a fourth shape. This paragraph said "TWO" until issue #3941. `TripletErrorResponse` was added by the #3901 reconciliation and this sentence was not updated with it, so the document undercounted its own families — which is the same defect one level up as the operations that named the wrong one. ' properties: success: type: boolean example: false error: type: string description: Human-readable message. There is no machine-readable code on this envelope. required: - success - error securitySchemes: basicAuth: type: http scheme: basic description: OAuth2-style client credentials (clientId:clientSecret) BearerAuth: type: http scheme: bearer bearerFormat: JWT description: Enterprise JWT token (see /scripts/generate-jwt.sh) x-refined-from: - axonflow-orchestrator-api.yaml - axonflow-orchestrator-openapi.yml