openapi: 3.1.0
info:
  title: Omnis Agent API
  version: v1
  description: Agent-first API for Omnis venture intelligence and event subscriptions.
servers:
  - url: https://www.bamboosnow.co
    description: Production
security:
  - ApiKeyAuth: []
paths:
  /api/v1/companies/{id}:
    get:
      summary: Get canonical company profile
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Company profile with freshness and provenance
          headers:
            x-request-id:
              $ref: "#/components/headers/XRequestId"
            x-agent-key-id:
              $ref: "#/components/headers/XAgentKeyId"
            x-ratelimit-limit:
              $ref: "#/components/headers/XRateLimitLimit"
            x-ratelimit-remaining:
              $ref: "#/components/headers/XRateLimitRemaining"
            x-ratelimit-reset:
              $ref: "#/components/headers/XRateLimitReset"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: Company not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
  /api/v1/companies/{id}/score:
    get:
      summary: Get latest or as-of score for company
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: as_of
          in: query
          required: false
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Score card payload
          headers:
            x-request-id:
              $ref: "#/components/headers/XRequestId"
            x-agent-key-id:
              $ref: "#/components/headers/XAgentKeyId"
            x-ratelimit-limit:
              $ref: "#/components/headers/XRateLimitLimit"
            x-ratelimit-remaining:
              $ref: "#/components/headers/XRateLimitRemaining"
            x-ratelimit-reset:
              $ref: "#/components/headers/XRateLimitReset"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyScoreResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: Company not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
  /api/v1/discovery/top:
    get:
      summary: Get top discovery candidates for agent triage
      security:
        - ApiKeyAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - name: min_score
          in: query
          required: false
          schema:
            type: number
            minimum: 0
            default: 0
      responses:
        "200":
          description: Ranked discovery candidates
          headers:
            x-request-id:
              $ref: "#/components/headers/XRequestId"
            x-agent-key-id:
              $ref: "#/components/headers/XAgentKeyId"
            x-ratelimit-limit:
              $ref: "#/components/headers/XRateLimitLimit"
            x-ratelimit-remaining:
              $ref: "#/components/headers/XRateLimitRemaining"
            x-ratelimit-reset:
              $ref: "#/components/headers/XRateLimitReset"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DiscoveryTopResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/model/health:
    get:
      summary: Get model health metrics and freshness
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Model health
          headers:
            x-request-id:
              $ref: "#/components/headers/XRequestId"
            x-agent-key-id:
              $ref: "#/components/headers/XAgentKeyId"
            x-ratelimit-limit:
              $ref: "#/components/headers/XRateLimitLimit"
            x-ratelimit-remaining:
              $ref: "#/components/headers/XRateLimitRemaining"
            x-ratelimit-reset:
              $ref: "#/components/headers/XRateLimitReset"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ModelHealthResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/agents/manifest:
    get:
      summary: Public machine-readable manifest for autonomous agents
      security: []
      responses:
        "200":
          description: Manifest payload
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentManifestResponse"
              examples:
                default:
                  value:
                    version: v1
                    as_of: "2026-03-03T12:00:00.000Z"
                    data:
                      provider: Omnis
                      api_version: v1
                      mode: agent-first
                      openapi_url: https://www.bamboosnow.co/docs/api/openapi.v1.yaml
  /api/v1/mcp:
    get:
      summary: Discover MCP remote JSON-RPC bridge metadata
      security: []
      responses:
        "200":
          description: Bridge metadata and available methods
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
    post:
      summary: Invoke MCP-compatible JSON-RPC methods over HTTP
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [jsonrpc, method]
              properties:
                jsonrpc:
                  type: string
                  enum: ["2.0"]
                id:
                  type: [string, number, "null"]
                method:
                  type: string
                params:
                  type: object
                  additionalProperties: true
      responses:
        "200":
          description: JSON-RPC success or error payload
          content:
            application/json:
              schema:
                type: object
        "400":
          $ref: "#/components/responses/BadRequest"
  /api/v1/agents/capabilities:
    get:
      summary: Public capability probe for agent onboarding
      security: []
      responses:
        "200":
          description: Capability and first-call guidance
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentCapabilitiesResponse"
              examples:
                default:
                  value:
                    version: v1
                    as_of: "2026-03-03T12:00:00.000Z"
                    data:
                      provider: Omnis
                      mode: agent-first
                      auth:
                        header: x-api-key
                        bearer_supported: true
                        required_for_paid_reads: true
                      first_calls:
                        - GET /api/v1/agents/status
                        - GET /api/v1/agents/value-proof
                        - GET /api/v1/agents/quickstart
  /api/v1/agents/errors:
    get:
      summary: Machine-readable error catalog and retry guidance
      security: []
      responses:
        "200":
          description: Error taxonomy and recommended actions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentErrorsResponse"
  /api/v1/agents/status:
    get:
      summary: Service and freshness status for autonomous agents
      security: []
      responses:
        "200":
          description: Current service status and freshness metrics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/value-proof:
    get:
      summary: Public value-proof preview before paid expansion
      security: []
      responses:
        "200":
          description: Discovery and scoring preview bundle
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/quickstart:
    get:
      summary: One-call quickstart bundle with next-step URLs
      security: []
      responses:
        "200":
          description: Quickstart payload
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/signup:
    post:
      summary: Self-serve API key issuance for autonomous agents
      security: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                contact_email:
                  type: string
                  format: email
                agent_name:
                  type: string
                use_case:
                  type: string
      responses:
        "201":
          description: API key issued
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/registry-pack:
    get:
      summary: Registry submission metadata bundle for OpenAI, MCP, and generic hubs
      security: []
      parameters:
        - name: target
          in: query
          required: false
          schema:
            type: string
            enum: [openai, mcp, generic]
      responses:
        "200":
          description: Machine-readable registry pack details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/registry-pack/{target}:
    get:
      summary: Target-specific markdown registry pack
      security: []
      parameters:
        - name: target
          in: path
          required: true
          schema:
            type: string
            enum: [openai, mcp, generic]
      responses:
        "200":
          description: Markdown pack content
          content:
            text/markdown:
              schema:
                type: string
        "404":
          description: Unknown target
  /api/v1/agents/catalog:
    get:
      summary: Credit packs and capability tiers
      security: []
      responses:
        "200":
          description: Active catalog with optional offers
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/recommend-tier:
    get:
      summary: Recommend best pack based on workload assumptions
      security: []
      parameters:
        - name: monthly_calls
          in: query
          required: false
          schema:
            type: number
        - name: concurrency
          in: query
          required: false
          schema:
            type: number
        - name: target_monthly_budget_usd
          in: query
          required: false
          schema:
            type: number
        - name: aggressive
          in: query
          required: false
          schema:
            type: boolean
      responses:
        "200":
          description: Ranked recommendation output
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/pay:
    get:
      summary: Machine payment strategy and direct charge guidance
      security: []
      parameters:
        - name: objective
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Payment strategy and option list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/checkout-link:
    get:
      summary: Redirect to hosted checkout for selected pack
      security: []
      parameters:
        - name: pack_id
          in: query
          required: false
          schema:
            type: string
        - name: objective
          in: query
          required: false
          schema:
            type: string
      responses:
        "302":
          description: Redirect to checkout URL
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
  /api/v1/agents/quote:
    get:
      summary: ROI-weighted recommendation quote
      security: []
      parameters:
        - name: monthly_calls
          in: query
          required: false
          schema:
            type: number
        - name: avg_deal_value_usd
          in: query
          required: false
          schema:
            type: number
        - name: hit_rate_lift_pct
          in: query
          required: false
          schema:
            type: number
      responses:
        "200":
          description: Recommended packs and economics assumptions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/offers:
    get:
      summary: Time-bounded promotional offers by pack
      security: []
      responses:
        "200":
          description: Active offers list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/conversion:
    get:
      summary: Conversion funnel metrics for agent onboarding
      security: []
      parameters:
        - name: days
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 30
      responses:
        "200":
          description: Aggregated conversion counts and rates
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/traffic:
    get:
      summary: Aggregated traffic and source telemetry
      security: []
      parameters:
        - name: days
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 14
      responses:
        "200":
          description: Aggregated traffic metrics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/growth:
    get:
      summary: 24h growth funnel and Stripe checkout status summary
      security: []
      responses:
        "200":
          description: Growth metrics with checkout activity
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/acquisition:
    get:
      summary: Recent acquisition automation runs
      security: []
      responses:
        "200":
          description: Recent run history and aggregate totals
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
    post:
      summary: Trigger acquisition run
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Acquisition run executed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /api/v1/agents/keys:
    post:
      summary: Issue a new API key and optionally revoke current issued key
      security:
        - ApiKeyAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                rotate_current:
                  type: boolean
                contact_email:
                  type: string
                  format: email
                agent_name:
                  type: string
                use_case:
                  type: string
      responses:
        "201":
          description: Replacement API key issued
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/agents/recovery:
    get:
      summary: Recent recovery and failed payment events
      security: []
      responses:
        "200":
          description: Recovery event timeline
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/agents/broadcast:
    get:
      summary: Public broadcast payload for autonomous agent discovery
      security: []
      responses:
        "200":
          description: Broadcast message with onboarding pointers
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
  /api/v1/billing/account:
    get:
      summary: Get current prepaid billing balance for API key
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Billing account summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/billing/topups/checkout:
    post:
      summary: Create Stripe Checkout session to top up prepaid balance
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BillingCheckoutRequest"
      responses:
        "200":
          description: Checkout session created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingCheckoutResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/billing/setup-intent:
    post:
      summary: Create setup intent for off-session payment method
      security:
        - ApiKeyAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                customer_id:
                  type: string
                customer_email:
                  type: string
                  format: email
                topup_key_id:
                  type: string
      responses:
        "200":
          description: Setup intent created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/billing/payment-methods/attach:
    post:
      summary: Attach payment method and configure auto-recharge
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [customer_id, payment_method_id]
              properties:
                customer_id:
                  type: string
                payment_method_id:
                  type: string
                topup_key_id:
                  type: string
                autopay_enabled:
                  type: boolean
                autopay_threshold_usd:
                  type: number
                autopay_pack_id:
                  type: string
      responses:
        "200":
          description: Payment method attached
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/billing/topups/charge:
    post:
      summary: Directly charge card and credit prepaid account
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [payment_method_id]
              properties:
                pack_id:
                  type: string
                payment_method_id:
                  type: string
                customer_id:
                  type: string
                customer_email:
                  type: string
                  format: email
                topup_key_id:
                  type: string
                save_for_autopay:
                  type: boolean
                autopay_threshold_usd:
                  type: number
                autopay_pack_id:
                  type: string
                offer_code:
                  type: string
      responses:
        "200":
          description: Charge succeeded and balance credited
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Envelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/webhooks/subscriptions:
    get:
      summary: List webhook subscriptions
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Webhook subscriptions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
    post:
      summary: Create a webhook subscription
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateWebhookSubscriptionRequest"
      responses:
        "201":
          description: Created subscription
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookCreateResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /api/v1/webhooks/subscriptions/{id}:
    patch:
      summary: Update a webhook subscription
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateWebhookSubscriptionRequest"
      responses:
        "200":
          description: Updated subscription
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookCreateResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: Subscription not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
    delete:
      summary: Delete a webhook subscription
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDeleteResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: Subscription not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
  /api/v1/webhooks/events:
    post:
      summary: Publish an event to matching webhook subscriptions
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PublishEventRequest"
      responses:
        "200":
          description: Dispatch summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDispatchResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
  headers:
    XRequestId:
      description: Request correlation id
      schema:
        type: string
    XAgentKeyId:
      description: Matched agent key id
      schema:
        type: string
    XRateLimitLimit:
      description: Requests allowed in current window
      schema:
        type: integer
    XRateLimitRemaining:
      description: Requests remaining in current window
      schema:
        type: integer
    XRateLimitReset:
      description: UNIX epoch seconds when window resets
      schema:
        type: integer
  responses:
    BadRequest:
      description: Invalid request payload
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            version: v1
            as_of: "2026-03-03T12:00:00.000Z"
            data:
              error:
                code: BAD_REQUEST
                message: payment_method_id is required
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            version: v1
            as_of: "2026-03-03T12:00:00.000Z"
            data:
              error:
                code: UNAUTHORIZED
                message: Missing API key
    Forbidden:
      description: Authenticated but missing required scope
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            version: v1
            as_of: "2026-03-03T12:00:00.000Z"
            data:
              error:
                code: FORBIDDEN
                message: "Missing required scope: read:scores"
    PaymentRequired:
      description: Payment required before accessing endpoint
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            version: v1
            as_of: "2026-03-03T12:00:00.000Z"
            data:
              error:
                code: INSUFFICIENT_PREPAID_BALANCE
                message: Top up required before API access
                details:
                  action: TOP_UP_REQUIRED
                  topup_charge_path: /api/v1/billing/topups/charge
                  suggested_pack_id: pack_25k
    RateLimited:
      description: Too many requests in current window
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
          example:
            version: v1
            as_of: "2026-03-03T12:00:00.000Z"
            data:
              error:
                code: RATE_LIMITED
                message: Rate limit exceeded
    ServiceUnavailable:
      description: Service dependency or config unavailable
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/SimpleErrorPayload"
          example:
            error:
              code: PAYMENT_LINKS_UNAVAILABLE
              message: No payment links are configured.
  schemas:
    Envelope:
      type: object
      required: [version, as_of, data]
      properties:
        version:
          type: string
          enum: [v1]
        as_of:
          type: string
          format: date-time
        data:
          type: object
    ErrorEnvelope:
      type: object
      required: [version, as_of, data]
      properties:
        version:
          type: string
          enum: [v1]
        as_of:
          type: string
          format: date-time
        data:
          type: object
          required: [error]
          properties:
            error:
              type: object
              required: [code, message]
              properties:
                code:
                  type: string
                message:
                  type: string
                details:
                  type: [object, "null"]
                  additionalProperties: true
    SimpleErrorPayload:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message]
          properties:
            code:
              type: string
            message:
              type: string
    Freshness:
      type: object
      required: [stale, stale_threshold_hours, quality]
      properties:
        latest_signal_at:
          type: [string, "null"]
          format: date-time
        latest_score_at:
          type: [string, "null"]
          format: date-time
        latest_metric_at:
          type: [string, "null"]
          format: date-time
        stale:
          type: boolean
        stale_threshold_hours:
          type: integer
        quality:
          type: string
          enum: [observed, interpolated, missing]
    Provenance:
      type: object
      required: [sources, confidence]
      properties:
        sources:
          type: array
          items:
            type: string
        confidence:
          type: number
          minimum: 0
          maximum: 1
    CompanyResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                company:
                  type: object
                freshness:
                  $ref: "#/components/schemas/Freshness"
                provenance:
                  $ref: "#/components/schemas/Provenance"
    CompanyScoreResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                company_id:
                  type: string
                company_name:
                  type: string
                score:
                  type: [object, "null"]
                factor_sheet:
                  type: array
                  items:
                    type: object
                freshness:
                  $ref: "#/components/schemas/Freshness"
                provenance:
                  $ref: "#/components/schemas/Provenance"
    DiscoveryTopResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                candidates:
                  type: array
                  items:
                    type: object
                provenance:
                  $ref: "#/components/schemas/Provenance"
    ModelHealthResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                health:
                  type: object
                freshness:
                  $ref: "#/components/schemas/Freshness"
                provenance:
                  $ref: "#/components/schemas/Provenance"
    WebhookSubscription:
      type: object
      required: [id, url, events, active, createdAt, updatedAt, createdBy]
      properties:
        id:
          type: string
        url:
          type: string
          format: uri
        events:
          type: array
          items:
            type: string
        active:
          type: boolean
        description:
          type: [string, "null"]
        secret:
          type: [string, "null"]
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        createdBy:
          type: string
    CreateWebhookSubscriptionRequest:
      type: object
      required: [url, events]
      properties:
        url:
          type: string
          format: uri
        events:
          type: array
          minItems: 1
          items:
            type: string
        active:
          type: boolean
        description:
          type: string
        secret:
          type: string
    UpdateWebhookSubscriptionRequest:
      type: object
      properties:
        events:
          type: array
          minItems: 1
          items:
            type: string
        active:
          type: boolean
        description:
          type: string
        secret:
          type: string
    PublishEventRequest:
      type: object
      required: [event_type]
      properties:
        event_type:
          type: string
        payload:
          type: object
          additionalProperties: true
    WebhookListResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                subscriptions:
                  type: array
                  items:
                    $ref: "#/components/schemas/WebhookSubscription"
                provenance:
                  $ref: "#/components/schemas/Provenance"
    WebhookCreateResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                subscription:
                  $ref: "#/components/schemas/WebhookSubscription"
                provenance:
                  $ref: "#/components/schemas/Provenance"
    WebhookDeleteResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                deleted:
                  type: boolean
                subscription_id:
                  type: string
    WebhookDispatchResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                dispatch:
                  type: object
                  properties:
                    eventId:
                      type: string
                    attempted:
                      type: integer
                    delivered:
                      type: integer
                    failed:
                      type: integer
                provenance:
                  $ref: "#/components/schemas/Provenance"
    AgentManifestResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                provider:
                  type: string
                api_version:
                  type: string
                mode:
                  type: string
                auth:
                  type: object
                openapi_url:
                  type: string
                endpoints:
                  type: object
                mcp:
                  type: object
                pricing:
                  type: object
                discovery:
                  type: object
                bat_signal:
                  type: object
    AgentErrorCatalogItem:
      type: object
      required: [code, http_status, retryable, category, meaning, next_action]
      properties:
        code:
          type: string
        http_status:
          type: integer
        retryable:
          type: boolean
        category:
          type: string
        meaning:
          type: string
        next_action:
          type: string
    AgentCapabilitiesResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                provider:
                  type: string
                mode:
                  type: string
                auth:
                  type: object
                billing:
                  type: object
                discovery:
                  type: object
                feature_flags:
                  type: object
                capacity:
                  type: object
                first_calls:
                  type: array
                  items:
                    type: string
                first_paid_calls:
                  type: array
                  items:
                    type: string
    AgentErrorsResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                errors:
                  type: array
                  items:
                    $ref: "#/components/schemas/AgentErrorCatalogItem"
                guidance:
                  type: object
    BillingCheckoutRequest:
      type: object
      required: [pack_id]
      properties:
        pack_id:
          type: string
        success_url:
          type: string
          format: uri
        cancel_url:
          type: string
          format: uri
        topup_key_id:
          type: string
        customer_email:
          type: string
          format: email
    BillingCheckoutResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                checkout:
                  type: object
                  properties:
                    session_id:
                      type: string
                    url:
                      type: string
                    pack_id:
                      type: string
                    amount_usd:
                      type: number
                    credits_usd:
                      type: number
                    topup_key_id:
                      type: string
    BillingAccountResponse:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            data:
              type: object
              properties:
                account:
                  type: object
                  properties:
                    key_id:
                      type: string
                    balance_usd:
                      type: number
                    total_debited_usd:
                      type: number
                    total_credited_usd:
                      type: number
                    updated_at:
                      type: string
                      format: date-time
                plan:
                  type: string
                spend_month_usd:
                  type: number
                spend_cap_usd:
                  type: [number, "null"]
