openapi: 3.1.0
info:
  title: ActionGate API
  version: 1.0.0
  summary: Pre-execution risk, simulation, and policy decisions for autonomous agents.
  description: >
    ActionGate provides deterministic decision endpoints for autonomous systems.
    Version 1 includes risk scoring, action simulation, and policy gate checks.
servers:
  - url: https://api.actiongate.xyz
    description: Production
  - url: https://sandbox.api.actiongate.xyz
    description: Sandbox
tags:
  - name: Decisions
    description: Core decision endpoints
security:
  - apiKeyAuth: []
  - x402PaymentSignature: []
paths:
  /.well-known/agent.json:
    get:
      tags: [Decisions]
      operationId: agentDiscovery
      summary: Discovery metadata for agentic clients.
      description: Returns machine-readable metadata, capabilities, and x402 payment hints.
      security: []
      responses:
        '200':
          description: Discovery metadata.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
  /v1/risk-score:
    post:
      tags: [Decisions]
      operationId: riskScore
      summary: Score action risk before execution.
      description: Returns deterministic risk score, severity, and reason codes.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RiskScoreRequest'
            examples:
              transfer:
                value:
                  request_id: rq_01JY1A8MEXAMPLE
                  actor:
                    actor_id: agent_treasury_bot_01
                    wallet_address: "0x1111111111111111111111111111111111111111"
                  action:
                    action_type: transfer
                    network: base
                    target: "0x2222222222222222222222222222222222222222"
                    asset_symbol: USDC
                    amount: "2500.00"
                  context:
                    ip_country: US
                    session_risk: low
      responses:
        '200':
          description: Risk score generated.
          headers:
            PAYMENT-RESPONSE:
              schema:
                type: string
              description: Base64-encoded x402 settlement response for paid calls.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RiskScoreResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/PaymentSettlementError'
        '500':
          $ref: '#/components/responses/InternalError'
  /v1/simulate:
    post:
      tags: [Decisions]
      operationId: simulateAction
      summary: Simulate expected cost and failure likelihood.
      description: Returns bounded simulation output for a proposed action.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimulateRequest'
            examples:
              swap:
                value:
                  request_id: rq_01JY1B0MEXAMPLE
                  actor:
                    actor_id: agent_trader_07
                    wallet_address: "0x3333333333333333333333333333333333333333"
                  action:
                    action_type: swap
                    network: base
                    route: uniswap_v3
                    input_asset: ETH
                    output_asset: USDC
                    input_amount: "1.2"
                  context:
                    slippage_bps: 100
                    block_number: 24510001
      responses:
        '200':
          description: Simulation completed.
          headers:
            PAYMENT-RESPONSE:
              schema:
                type: string
              description: Base64-encoded x402 settlement response for paid calls.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimulateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/PaymentSettlementError'
        '500':
          $ref: '#/components/responses/InternalError'
  /v1/policy-gate:
    post:
      tags: [Decisions]
      operationId: policyGate
      summary: Enforce policy and return allow or deny decision.
      description: Checks proposed action against policy rules and limits.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PolicyGateRequest'
            examples:
              treasury_policy:
                value:
                  request_id: rq_01JY1B8MEXAMPLE
                  actor:
                    actor_id: agent_ops_02
                    wallet_address: "0x4444444444444444444444444444444444444444"
                  action:
                    action_type: transfer
                    network: base
                    target: "0x5555555555555555555555555555555555555555"
                    asset_symbol: USDC
                    amount: "150000"
                  policy:
                    policy_id: treasury_default_v1
                    overrides:
                      max_single_transfer_usd: "100000"
      responses:
        '200':
          description: Policy decision generated.
          headers:
            PAYMENT-RESPONSE:
              schema:
                type: string
              description: Base64-encoded x402 settlement response for paid calls.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyGateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/PaymentSettlementError'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    x402PaymentSignature:
      type: apiKey
      in: header
      name: PAYMENT-SIGNATURE
      description: Base64-encoded x402 payment payload used for paid requests.
  schemas:
    Actor:
      type: object
      additionalProperties: false
      required: [actor_id]
      properties:
        actor_id:
          type: string
          maxLength: 128
        wallet_address:
          type: string
          maxLength: 128
    Action:
      type: object
      additionalProperties: true
      required: [action_type]
      properties:
        action_type:
          type: string
          minLength: 1
        network:
          type: string
        target:
          type: string
    PolicySpec:
      type: object
      additionalProperties: true
      properties:
        policy_id:
          type: string
        overrides:
          type: object
          additionalProperties: true
    UsageReceipt:
      type: object
      additionalProperties: false
      required:
        - request_id
        - units_billed
        - price_per_unit_usd
        - currency
        - payment_reference
        - signature
      properties:
        request_id:
          type: string
        units_billed:
          type: integer
          minimum: 1
        price_per_unit_usd:
          type: string
          pattern: '^\d+(\.\d{1,6})?$'
        currency:
          type: string
          enum: [USD]
        payment_reference:
          type: string
        signature:
          type: string
    ReasonCode:
      type: object
      additionalProperties: false
      required: [code, message]
      properties:
        code:
          type: string
        message:
          type: string
    Error:
      type: object
      additionalProperties: false
      required: [error]
      properties:
        error:
          type: object
          additionalProperties: false
          required: [code, message]
          properties:
            code:
              type: string
            message:
              type: string
            request_id:
              type: string
            details:
              type: object
              additionalProperties: true
    RiskScoreRequest:
      type: object
      additionalProperties: false
      required: [actor, action]
      properties:
        request_id:
          type: string
          description: Optional idempotency-friendly caller-generated request id.
        actor:
          $ref: '#/components/schemas/Actor'
        action:
          allOf:
            - $ref: '#/components/schemas/Action'
            - type: object
              additionalProperties: true
              required: [action_type]
              properties:
                amount:
                  type: string
                asset_symbol:
                  type: string
        context:
          type: object
          additionalProperties: true
    RiskScoreResponse:
      type: object
      additionalProperties: false
      required:
        - request_id
        - score
        - severity
        - reason_codes
        - confidence
        - latency_ms
        - usage_receipt
      properties:
        request_id:
          type: string
        score:
          type: integer
          minimum: 0
          maximum: 100
        severity:
          type: string
          enum: [low, medium, high, critical]
        reason_codes:
          type: array
          items:
            $ref: '#/components/schemas/ReasonCode'
        confidence:
          type: number
          minimum: 0
          maximum: 1
        latency_ms:
          type: integer
          minimum: 0
        usage_receipt:
          $ref: '#/components/schemas/UsageReceipt'
    SimulateRequest:
      type: object
      additionalProperties: false
      required: [actor, action]
      properties:
        request_id:
          type: string
        actor:
          $ref: '#/components/schemas/Actor'
        action:
          type: object
          additionalProperties: true
          required: [action_type]
          properties:
            action_type:
              type: string
        context:
          type: object
          additionalProperties: true
    SimulateResponse:
      type: object
      additionalProperties: false
      required:
        - request_id
        - expected_cost_usd
        - failure_probability
        - expected_outcome
        - notes
        - latency_ms
        - usage_receipt
      properties:
        request_id:
          type: string
        expected_cost_usd:
          type: string
          pattern: '^\d+(\.\d{1,6})?$'
        failure_probability:
          type: number
          minimum: 0
          maximum: 1
        expected_outcome:
          type: string
        notes:
          type: array
          items:
            type: string
        latency_ms:
          type: integer
          minimum: 0
        usage_receipt:
          $ref: '#/components/schemas/UsageReceipt'
    PolicyGateRequest:
      type: object
      additionalProperties: false
      required: [actor, action, policy]
      properties:
        request_id:
          type: string
        actor:
          $ref: '#/components/schemas/Actor'
        action:
          $ref: '#/components/schemas/Action'
        policy:
          $ref: '#/components/schemas/PolicySpec'
        context:
          type: object
          additionalProperties: true
    ViolatedRule:
      type: object
      additionalProperties: false
      required: [rule_id, description]
      properties:
        rule_id:
          type: string
        description:
          type: string
        severity:
          type: string
          enum: [info, warning, blocking]
    SafeAlternative:
      type: object
      additionalProperties: true
      properties:
        action:
          type: object
          additionalProperties: true
        rationale:
          type: string
    PolicyGateResponse:
      type: object
      additionalProperties: false
      required:
        - request_id
        - decision
        - violated_rules
        - latency_ms
        - usage_receipt
      properties:
        request_id:
          type: string
        decision:
          type: string
          enum: [allow, deny, allow_with_limits]
        violated_rules:
          type: array
          items:
            $ref: '#/components/schemas/ViolatedRule'
        safe_alternative:
          $ref: '#/components/schemas/SafeAlternative'
        latency_ms:
          type: integer
          minimum: 0
        usage_receipt:
          $ref: '#/components/schemas/UsageReceipt'
  responses:
    BadRequest:
      description: Invalid request payload.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Invalid API credentials.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    PaymentRequired:
      description: Missing or invalid x402 payment signature.
      headers:
        PAYMENT-REQUIRED:
          schema:
            type: string
          description: Base64-encoded x402 payment requirements.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Rate limit exceeded.
      headers:
        Retry-After:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    PaymentSettlementError:
      description: Payment verification or settlement failed at facilitator.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
