openapi: 3.1.0 info: title: AI Gateway Customer API version: 1.0.0 description: 客户控制面契约。身份认证和具体业务授权由运行时服务执行。 servers: - url: https://api.example.invalid security: - customerBearer: [] paths: /v1/public/lead-challenge: get: operationId: createPublicLeadChallenge summary: 获取一次性试用申请挑战 security: [] responses: '200': description: 带最短提交时间和失效时间的签名挑战 content: application/json: schema: {$ref: '#/components/schemas/PublicLeadChallenge'} '429': {description: 请求频率超限} /v1/public/leads: post: operationId: submitPublicSalesLead summary: 提交企业试用或销售申请 security: [] requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/PublicLeadRequest'} responses: '201': description: 线索已进入内部受理流程,不会自动创建生产资源 content: application/json: schema: {$ref: '#/components/schemas/PublicLeadCreated'} '400': {description: 校验、隐私同意或反自动化检查失败} '409': {description: 挑战已使用} '429': {description: 提交频率超限} /v1/me: get: operationId: getCurrentCustomerContext summary: 获取当前客户上下文 responses: '200': description: 客户主账号和当前结算归属 content: application/json: schema: $ref: '#/components/schemas/CustomerContext' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' /v1/workspaces: get: operationId: listWorkspaces summary: 查询授权 workspace responses: '200': description: workspace 列表 content: application/json: schema: type: array items: $ref: '#/components/schemas/Workspace' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createWorkspace summary: 创建 workspace 并绑定模型授权 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateWorkspaceRequest' responses: '201': description: workspace 已创建 content: application/json: schema: $ref: '#/components/schemas/Workspace' /v1/workspaces/{workspace_id}/disable: post: operationId: disableWorkspace parameters: - $ref: '#/components/parameters/WorkspaceId' responses: '204': {description: workspace 已停用} /v1/workspaces/{workspace_id}/restore: post: operationId: restoreWorkspace parameters: - $ref: '#/components/parameters/WorkspaceId' responses: '204': {description: workspace 已恢复} /v1/workspaces/{workspace_id}/model-grants: get: operationId: listWorkspaceModelGrants parameters: [{ $ref: '#/components/parameters/WorkspaceId' }] responses: '200': description: 模型授权列表 content: application/json: schema: type: array items: { $ref: '#/components/schemas/ModelGrant' } post: operationId: addWorkspaceModelGrant parameters: [{ $ref: '#/components/parameters/WorkspaceId' }] requestBody: required: true content: application/json: schema: type: object required: [declared_model] properties: declared_model: { type: string } responses: '201': { description: 模型授权已添加 } /v1/model-grants/{grant_id}/revoke: post: operationId: revokeWorkspaceModelGrant parameters: - name: grant_id in: path required: true schema: { type: string, format: uuid } responses: '204': { description: 模型授权已撤销 } /v1/model-grants/{grant_id}/restore: post: operationId: restoreWorkspaceModelGrant parameters: - name: grant_id in: path required: true schema: { type: string, format: uuid } responses: '204': { description: 模型授权已恢复 } /v1/sub-accounts: get: operationId: listSubAccounts responses: '200': description: 子账号列表 content: application/json: schema: type: array items: {$ref: '#/components/schemas/SubAccount'} post: operationId: createSubAccount requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreateSubAccountRequest'} responses: '201': description: 子账号已创建 content: application/json: schema: {$ref: '#/components/schemas/SubAccount'} /v1/sub-accounts/{sub_account_id}/disable: post: operationId: disableSubAccount parameters: - $ref: '#/components/parameters/SubAccountId' responses: '204': {description: 子账号已停用} /v1/sub-accounts/{sub_account_id}/restore: post: operationId: restoreSubAccount parameters: - $ref: '#/components/parameters/SubAccountId' responses: '204': {description: 子账号已恢复} /v1/members: get: operationId: listMembers responses: '200': description: 成员列表 content: application/json: schema: type: array items: {$ref: '#/components/schemas/Member'} post: operationId: createMember requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreateMemberRequest'} responses: '201': description: 成员与登录身份已创建,临时密码只在本次响应返回 content: application/json: schema: {$ref: '#/components/schemas/CreatedMember'} /v1/members/{member_id}/disable: post: operationId: disableMember parameters: - $ref: '#/components/parameters/MemberId' responses: '204': {description: 成员已停用} /v1/members/{member_id}/restore: post: operationId: restoreMember parameters: - $ref: '#/components/parameters/MemberId' responses: '204': {description: 成员已恢复} /v1/members/{member_id}/roles: post: operationId: grantMemberRole parameters: - $ref: '#/components/parameters/MemberId' requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/GrantRoleRequest'} responses: '201': description: 角色已授予 content: application/json: schema: {$ref: '#/components/schemas/RoleBinding'} /v1/role-bindings: get: operationId: listRoleBindings responses: '200': description: 角色绑定列表 content: application/json: schema: type: array items: {$ref: '#/components/schemas/RoleBinding'} /v1/role-bindings/{binding_id}/revoke: post: operationId: revokeMemberRole parameters: - name: binding_id in: path required: true schema: {type: string, format: uuid} responses: '204': {description: 角色已撤销} /v1/api-keys: get: operationId: listApiKeys summary: 查询授权 API key 元数据 responses: '200': description: API key 列表,不返回完整 Secret content: application/json: schema: type: array items: $ref: '#/components/schemas/ApiKeyMetadata' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createApiKey summary: 创建 API key requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateApiKeyRequest' responses: '201': description: Secret 只在本次响应完整返回 content: application/json: schema: $ref: '#/components/schemas/CreatedApiKey' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' /v1/api-keys/{api_key_id}/disable: post: operationId: disableApiKey parameters: - $ref: '#/components/parameters/ApiKeyId' responses: '204': {description: API key 已停用} /v1/api-keys/{api_key_id}/restore: post: operationId: restoreApiKey parameters: - $ref: '#/components/parameters/ApiKeyId' responses: '204': {description: API key 已恢复} /v1/api-keys/{api_key_id}/revoke: post: operationId: revokeApiKey parameters: - $ref: '#/components/parameters/ApiKeyId' responses: '204': {description: API key 已撤销} /v1/billing/statements: get: operationId: listBillingStatements summary: 查询客户账单 parameters: - $ref: '#/components/parameters/Cursor' responses: '200': description: 账单摘要 content: application/json: schema: $ref: '#/components/schemas/PagedBillingStatements' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' /v1/billing/statements/{statement_id}: get: operationId: getBillingStatement summary: 查询账单行、请求级费用和历史商业快照 parameters: [{$ref: '#/components/parameters/StatementId'}] responses: '200': {description: 账单详情, content: {application/json: {schema: {$ref: '#/components/schemas/BillingStatementDetail'}}}} '403': {$ref: '#/components/responses/Forbidden'} '404': {description: 账单不存在} /v1/billing/statements/{statement_id}/export: get: operationId: exportBillingStatement summary: 导出 JSON 或 CSV 账单明细 parameters: - $ref: '#/components/parameters/StatementId' - name: format in: query schema: {type: string, enum: [json, csv], default: json} responses: '200': description: 结构化账单明细 content: application/json: {schema: {$ref: '#/components/schemas/BillingStatementDetail'}} text/csv: {schema: {type: string}} '403': {$ref: '#/components/responses/Forbidden'} /v1/billing/transactions: get: operationId: listFundTransactions summary: 查询预付款、消费、调账和退款流水 responses: '200': description: 资金流水 content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/FundTransaction'}}}} '403': {$ref: '#/components/responses/Forbidden'} /v1/billing/invoices: get: operationId: listInvoices summary: 查询发票及红字/更正出口 responses: '200': {description: 发票出口, content: {application/json: {schema: {$ref: '#/components/schemas/InvoiceExports'}}}} '403': {$ref: '#/components/responses/Forbidden'} /v1/console/overview: get: operationId: getConsoleOverview summary: 查询服务端过滤后的客户概览与预付余额 responses: '200': {description: 客户概览, content: {application/json: {schema: {$ref: '#/components/schemas/ConsoleOverview'}}}} /v1/models: get: operationId: listAuthorizedModels summary: 查询当前身份可访问的模型目录 responses: '200': {description: 模型目录, content: {application/json: {schema: {$ref: '#/components/schemas/ModelCatalog'}}}} /v1/requests: get: operationId: listAuthorizedRequests summary: 查询当前身份和 workspace 范围内的调用日志 parameters: - {name: workspace_id, in: query, schema: {type: string, format: uuid}} - {name: limit, in: query, schema: {type: integer, minimum: 1, maximum: 200, default: 50}} responses: '200': {description: 调用日志, content: {application/json: {schema: {$ref: '#/components/schemas/RequestFactPage'}}}} '403': {$ref: '#/components/responses/Forbidden'} '404': {description: workspace 不存在或属于其他主账户} /v1/usage: get: operationId: summarizeAuthorizedUsage summary: 汇总当前身份和 workspace 范围内的用量 parameters: - {name: workspace_id, in: query, schema: {type: string, format: uuid}} - {name: from, in: query, schema: {type: string, format: date-time}} - {name: to, in: query, schema: {type: string, format: date-time}} responses: '200': {description: 用量汇总, content: {application/json: {schema: {$ref: '#/components/schemas/UsageResult'}}}} '403': {$ref: '#/components/responses/Forbidden'} '404': {description: workspace 不存在或属于其他主账户} /v1/audit-events: get: operationId: listCustomerAuditEvents summary: 查询客户授权范围内的操作审计 parameters: - $ref: '#/components/parameters/Cursor' responses: '200': description: 审计事件摘要 content: application/json: schema: type: object required: [items] properties: items: {type: array, items: {$ref: '#/components/schemas/AuditEvent'}} '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' components: securitySchemes: customerBearer: type: http scheme: bearer bearerFormat: JWT parameters: Cursor: name: cursor in: query required: false schema: type: string maxLength: 512 WorkspaceId: name: workspace_id in: path required: true schema: {type: string, format: uuid} SubAccountId: name: sub_account_id in: path required: true schema: {type: string, format: uuid} MemberId: name: member_id in: path required: true schema: {type: string, format: uuid} ApiKeyId: name: api_key_id in: path required: true schema: {type: string, format: uuid} StatementId: name: statement_id in: path required: true schema: {type: string, format: uuid} responses: Unauthorized: description: 未认证或会话已失效 content: application/json: schema: $ref: '#/components/schemas/Error' Forbidden: description: 无权访问资源 content: application/json: schema: $ref: '#/components/schemas/Error' BadRequest: description: 请求参数无效 content: application/json: schema: $ref: '#/components/schemas/Error' schemas: ConsoleOverview: type: object required: [main_account_id, display_name, account_status, balance_visible, cash_available, service_credit_available, reserved_amount, currency, workspace_count, api_key_count] properties: main_account_id: {type: string, format: uuid} display_name: {type: string} account_status: {type: string} billing_account_id: {type: string, format: uuid} billing_account_status: {type: string} balance_visible: {type: boolean} cash_available: {type: string} service_credit_available: {type: string} reserved_amount: {type: string} currency: {type: string, enum: [CNY]} workspace_count: {type: integer} api_key_count: {type: integer} ModelCatalog: type: object required: [items] properties: items: type: array items: type: object required: [declared_model, protocols, workspace_ids, status] properties: declared_model: {type: string} protocols: {type: array, items: {type: string}} workspace_ids: {type: array, items: {type: string, format: uuid}} status: {type: string} RequestFactPage: type: object required: [items, next_cursor] properties: items: {type: array, items: {$ref: '#/components/schemas/RequestFact'}} next_cursor: {type: string} RequestFact: type: object required: [gateway_request_id, api_key_id, billing_account_id, model, input_tokens, output_tokens, amount, billing_status, status, created_at] properties: gateway_request_id: {type: string} api_key_id: {type: string, format: uuid} billing_account_id: {type: string, format: uuid} model: {type: string} stream: {type: boolean} input_tokens: {type: integer, format: int64} output_tokens: {type: integer, format: int64} amount: {type: string} unbilled_amount: {type: string} billing_status: {type: string} status: {type: string} created_at: {type: string, format: date-time} UsageResult: type: object required: [from, to, currency, summary] properties: from: {type: string, format: date-time} to: {type: string, format: date-time} currency: {type: string, enum: [CNY]} summary: type: object required: [request_count, input_tokens, output_tokens, amount, unbilled_amount, error_count] properties: request_count: {type: integer, format: int64} input_tokens: {type: integer, format: int64} output_tokens: {type: integer, format: int64} amount: {type: string} unbilled_amount: {type: string} error_count: {type: integer, format: int64} PublicLeadChallenge: type: object required: [token, min_submit_at, expires_at] properties: token: {type: string} min_submit_at: {type: string, format: date-time} expires_at: {type: string, format: date-time} PublicLeadRequest: type: object additionalProperties: false required: [challenge_token, company_name, contact_name, work_email, scenario, intended_models, estimated_monthly_tokens, data_region, requirements, privacy_consent] properties: challenge_token: {type: string} website: {type: string, description: 反自动化蜜罐字段,正常访客必须留空} company_name: {type: string, minLength: 2, maxLength: 240} contact_name: {type: string, minLength: 2, maxLength: 120} work_email: {type: string, format: email, maxLength: 320} phone: {type: string, maxLength: 40} scenario: {type: string, enum: [agent, coding, agent_coding, other]} intended_models: type: array minItems: 1 maxItems: 4 uniqueItems: true items: {type: string, enum: [deepseek-v4-flash, needs_assessment]} estimated_monthly_tokens: {type: string, enum: [under_100m, 100m_1b, 1b_10b, over_10b, unknown]} data_region: {type: string, enum: [mainland_china, overseas, mixed, undecided]} requirements: {type: string, minLength: 10, maxLength: 2000} privacy_consent: {type: boolean, const: true} PublicLeadCreated: type: object required: [lead_number, status] properties: lead_number: {type: string} status: {type: string, enum: [submitted]} ModelGrant: type: object required: [id, workspace_id, declared_model, status] properties: id: { type: string, format: uuid } workspace_id: { type: string, format: uuid } declared_model: { type: string } status: { type: string, enum: [active, revoked] } Error: type: object required: [code, message, request_id] properties: code: type: string message: type: string request_id: type: string CustomerContext: type: object required: [main_account_id, status, currency] properties: main_account_id: type: string format: uuid status: type: string enum: [active, suspended, terminated] currency: type: string enum: [CNY] Workspace: type: object required: [id, name, environment, status] properties: id: type: string format: uuid name: type: string environment: type: string enum: [development, test, staging, production] status: type: string enum: [active, disabled] models: type: array items: {type: string} SubAccount: type: object required: [id, name, status] properties: id: {type: string, format: uuid} name: {type: string} status: {type: string, enum: [active, disabled]} Member: type: object required: [id, identity_subject, email, display_name, status] properties: id: {type: string, format: uuid} identity_subject: {type: string} email: {type: string, format: email} display_name: {type: string} status: {type: string, enum: [active, disabled]} CreatedMember: allOf: - $ref: '#/components/schemas/Member' - type: object required: [temporary_password] properties: temporary_password: {type: string, readOnly: true} CreateSubAccountRequest: type: object required: [name] properties: {name: {type: string}} CreateWorkspaceRequest: type: object required: [name, environment, models] properties: sub_account_id: {type: string, format: uuid} name: {type: string} environment: type: string enum: [development, test, staging, production] models: type: array minItems: 1 items: {type: string} CreateMemberRequest: type: object required: [email, display_name] properties: email: {type: string, format: email} display_name: {type: string} GrantRoleRequest: type: object required: [role, scope_type] properties: role: {type: string, enum: [main_account_admin, sub_account_admin, developer, customer_finance, api_key_manager, auditor]} scope_type: {type: string, enum: [main_account, sub_account, workspace]} scope_id: {type: string, format: uuid} RoleBinding: type: object required: [id, member_id, role, scope_type, status] properties: id: {type: string, format: uuid} member_id: {type: string, format: uuid} role: {type: string, enum: [main_account_admin, sub_account_admin, developer, customer_finance, api_key_manager, auditor]} scope_type: {type: string, enum: [main_account, sub_account, workspace]} scope_id: {type: string, format: uuid} status: {type: string, enum: [active, revoked]} ApiKeyMetadata: type: object required: [id, secret_prefix, workspace_id, status, rpm_limit, tpm_limit, concurrent_limit, streaming_concurrent_limit, allowed_cidrs] properties: id: type: string format: uuid secret_prefix: type: string workspace_id: type: string format: uuid status: type: string enum: [active, disabled, revoked] rpm_limit: {type: integer, minimum: 1} tpm_limit: {type: integer, minimum: 1} concurrent_limit: {type: integer, minimum: 1} streaming_concurrent_limit: {type: integer, minimum: 1} spend_limit: {type: string, pattern: '^[0-9]+(\.[0-9]{1,2})?$'} allowed_cidrs: type: array items: {type: string} purpose_tag: {type: string} expires_at: type: string format: date-time CreateApiKeyRequest: type: object required: [workspace_id] properties: workspace_id: type: string format: uuid rpm_limit: {type: integer, minimum: 1, default: 300} tpm_limit: {type: integer, minimum: 1, default: 150000} concurrent_limit: {type: integer, minimum: 1, default: 20} streaming_concurrent_limit: {type: integer, minimum: 1, default: 30} spend_limit: {type: string, pattern: '^[0-9]+(\.[0-9]{1,2})?$'} allowed_cidrs: type: array items: {type: string} purpose_tag: {type: string, maxLength: 120} expires_at: type: string format: date-time CreatedApiKey: allOf: - $ref: '#/components/schemas/ApiKeyMetadata' - type: object required: [secret] properties: secret: type: string description: 仅在创建响应中返回一次的完整 Secret PagedBillingStatements: type: object required: [items, next_cursor] properties: items: type: array items: $ref: '#/components/schemas/BillingStatement' next_cursor: type: string BillingStatement: type: object required: [id, statement_number, version, billing_account_id, period_start, period_end, currency, subtotal_amount, tax_amount, total_amount, status] properties: id: {type: string, format: uuid} statement_number: type: string version: {type: integer, format: int32, minimum: 1} billing_account_id: {type: string, format: uuid} period_start: type: string format: date period_end: type: string format: date currency: type: string enum: [CNY] total_amount: type: string pattern: '^[0-9]+(\\.[0-9]{1,2})?$' subtotal_amount: {type: string} tax_amount: {type: string} status: type: string enum: [draft, reconciling, ready, superseded, finalized, disputed, corrected] BillingStatementLine: type: object required: [id, declared_model, price_rule_version, price_rule_snapshot, workspace_id, api_key_id, tax_rate, raw_amount, rounded_amount, tax_amount, total_amount, request_count] properties: id: {type: string, format: uuid} declared_model: {type: string} price_rule_version: {type: string} price_rule_snapshot: {type: object, additionalProperties: true} workspace_id: {type: string, format: uuid} api_key_id: {type: string, format: uuid} tax_rate: {type: string} raw_amount: {type: string} rounded_amount: {type: string, description: 含税金额按分 ROUND_HALF_UP 后的结果} tax_amount: {type: string} total_amount: {type: string} request_count: {type: integer, format: int64} StatementCharge: type: object required: [id, line_id, gateway_request_id, business_billing_key, input_tokens, output_tokens, amount, occurred_at] properties: id: {type: string, format: uuid} line_id: {type: string, format: uuid} gateway_request_id: {type: string} business_billing_key: {type: string} input_tokens: {type: integer, format: int64} output_tokens: {type: integer, format: int64} amount: {type: string} occurred_at: {type: string, format: date-time, description: 结算准备时固化的计费发生时间} BillingStatementDetail: allOf: - $ref: '#/components/schemas/BillingStatement' - type: object required: [legal_entity_snapshot, contract_snapshot, platform_operator_snapshot, collection_account_snapshot, lines, charges] properties: legal_entity_snapshot: {type: object, additionalProperties: true} contract_snapshot: {type: object, additionalProperties: true} platform_operator_snapshot: {type: object, additionalProperties: true} collection_account_snapshot: {type: object, additionalProperties: true} lines: {type: array, items: {$ref: '#/components/schemas/BillingStatementLine'}} charges: {type: array, items: {$ref: '#/components/schemas/StatementCharge'}} FundTransaction: type: object required: [id, billing_account_id, transaction_type, amount, direction, status, occurred_at] properties: id: {type: string, format: uuid} billing_account_id: {type: string, format: uuid} transaction_type: {type: string, enum: [top_up, charge, adjustment, refund]} business_billing_key: {type: string} amount: {type: string} direction: {type: string, enum: [credit, debit]} status: {type: string} occurred_at: {type: string, format: date-time} Invoice: type: object required: [id, invoice_request_number, billing_statement_id, invoice_type, currency, status, subtotal_amount, tax_amount, total_amount, legal_entity_snapshot, contract_snapshot, platform_operator_snapshot, collection_account_snapshot, price_rule_snapshots, tax_rates] properties: id: {type: string, format: uuid} invoice_request_number: {type: string} billing_statement_id: {type: string, format: uuid} invoice_type: {type: string, enum: [vat_special, vat_general]} currency: {type: string, enum: [CNY]} status: {type: string, enum: [requested, issued, red_letter, voided]} subtotal_amount: {type: string} tax_amount: {type: string} total_amount: {type: string} invoice_code: {type: string} issued_at: {type: string, format: date-time} legal_entity_snapshot: {type: object, additionalProperties: true} contract_snapshot: {type: object, additionalProperties: true} platform_operator_snapshot: {type: object, additionalProperties: true} collection_account_snapshot: {type: object, additionalProperties: true} price_rule_snapshots: {type: array, items: {type: object, additionalProperties: true}} tax_rates: {type: array, items: {type: string}} InvoiceCorrectionExport: type: object required: [id, original_invoice_id, billing_statement_id, correction_type, invoice_type, currency, subtotal_amount, tax_amount, total_amount, reason, status, legal_entity_snapshot, contract_snapshot, platform_operator_snapshot, collection_account_snapshot, price_rule_snapshots, tax_rates] properties: id: {type: string, format: uuid} original_invoice_id: {type: string, format: uuid} billing_statement_id: {type: string, format: uuid} billing_statement_line_id: {type: string, format: uuid} correction_type: {type: string, enum: [red_letter, supplemental]} invoice_type: {type: string, enum: [vat_special, vat_general]} currency: {type: string, enum: [CNY]} subtotal_amount: {type: string} tax_amount: {type: string} total_amount: {type: string} reason: {type: string} status: {type: string, enum: [export_ready]} legal_entity_snapshot: {type: object, additionalProperties: true} contract_snapshot: {type: object, additionalProperties: true} platform_operator_snapshot: {type: object, additionalProperties: true} collection_account_snapshot: {type: object, additionalProperties: true} price_rule_snapshots: {type: array, items: {type: object, additionalProperties: true}} tax_rates: {type: array, items: {type: string}} InvoiceExports: type: object required: [invoices, corrections] properties: invoices: {type: array, items: {$ref: '#/components/schemas/Invoice'}} corrections: {type: array, items: {$ref: '#/components/schemas/InvoiceCorrectionExport'}} AuditEvent: type: object required: [id, event_type, aggregate_type, aggregate_id, action, occurred_at] properties: id: type: string format: uuid event_type: type: string aggregate_type: type: string aggregate_id: type: string action: type: string enum: [insert, update, delete] occurred_at: type: string format: date-time