openapi: 3.1.0
info:
  title: Nitrograph API
  version: "0.1.0"
  description: Discovery, service detail, and outcome reporting API for agent commerce.
servers:
  - url: https://api.nitrograph.com
paths:
  /v1/discover:
    post:
      summary: Rank services against a natural-language intent
      operationId: discoverServices
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DiscoverRequest"
            examples:
              broad:
                summary: Broad discovery
                value:
                  query: "lead generation"
                  limit: 10
                  filters:
                    rail: "any"
                    max_cost: "any"
                    min_trust: "any"
                    category: "any"
              x402Only:
                summary: x402-only discovery
                value:
                  query: "image generation"
                  limit: 5
                  filters:
                    rail: "x402"
                    max_cost: "any"
                    min_trust: 70
                    category: "any"
      responses:
        "200":
          description: Ranked service results
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DiscoverResponse"
        "400":
          $ref: "#/components/responses/InvalidInput"
        "402":
          $ref: "#/components/responses/PaymentRequired"
        "429":
          $ref: "#/components/responses/RateLimited"
  /v1/service/{slug}:
    get:
      summary: Load the service map and call card for a selected service
      operationId: getServiceDetail
      parameters:
        - $ref: "#/components/parameters/Slug"
        - name: task
          in: query
          required: false
          schema:
            type: string
          description: Optional current task context for call-card selection.
      responses:
        "200":
          description: Service map
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServiceDetail"
        "404":
          $ref: "#/components/responses/NotFound"
        "402":
          $ref: "#/components/responses/PaymentRequired"
  /v1/service/{slug}/report-outcome:
    post:
      summary: Report generalized outcome after a provider call actually ran
      operationId: reportOutcome
      parameters:
        - $ref: "#/components/parameters/Slug"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OutcomeReport"
      responses:
        "200":
          description: Outcome accepted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReportAccepted"
        "400":
          $ref: "#/components/responses/InvalidInput"
        "404":
          $ref: "#/components/responses/NotFound"
  /v1/service/{slug}/report-pattern:
    post:
      summary: Report a reusable workflow after it succeeds end-to-end
      operationId: reportPattern
      parameters:
        - $ref: "#/components/parameters/Slug"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PatternReport"
      responses:
        "200":
          description: Pattern accepted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReportAccepted"
        "400":
          $ref: "#/components/responses/InvalidInput"
        "404":
          $ref: "#/components/responses/NotFound"
components:
  parameters:
    Slug:
      name: slug
      in: path
      required: true
      schema:
        type: string
  responses:
    InvalidInput:
      description: Missing or malformed input
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    NotFound:
      description: Unknown service slug
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    RateLimited:
      description: Free tier rate limit hit
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    PaymentRequired:
      description: x402 payment challenge. This is not automatically a provider failure.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/PaymentChallenge"
  schemas:
    DiscoverRequest:
      type: object
      required: [query]
      properties:
        query:
          type: string
        limit:
          type: integer
          minimum: 1
          maximum: 50
          default: 10
        filters:
          $ref: "#/components/schemas/DiscoverFilters"
    DiscoverFilters:
      type: object
      properties:
        rail:
          oneOf:
            - type: string
              enum: [any, x402, mpp]
        max_cost:
          oneOf:
            - type: string
              enum: [any]
            - type: number
        min_trust:
          oneOf:
            - type: string
              enum: [any]
            - type: number
              minimum: 0
              maximum: 100
        category:
          type: string
          description: Use "any" for no category filter.
    DiscoverResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: "#/components/schemas/ServiceResult"
        total_results:
          type: integer
        filters_applied:
          $ref: "#/components/schemas/DiscoverFilters"
    ServiceResult:
      type: object
      properties:
        slug:
          type: string
        name:
          type: string
        rail:
          type: string
        ranking_score:
          type: number
        legitimacy_score:
          type: number
        rankability_score:
          type: number
        cost:
          $ref: "#/components/schemas/Cost"
        map_signals:
          type: integer
    ServiceDetail:
      type: object
      properties:
        slug:
          type: string
        name:
          type: string
        rail:
          type: string
        cost:
          $ref: "#/components/schemas/Cost"
        call_card:
          type: object
        endpoints:
          type: array
          items:
            type: object
        auth:
          type: object
        gotchas:
          type: array
          items:
            type: object
        patterns:
          type: array
          items:
            type: object
    Cost:
      type: object
      properties:
        amount:
          type: string
        currency:
          type: string
    OutcomeReport:
      type: object
      required: [success]
      properties:
        success:
          type: boolean
        endpoint:
          type: string
        latency_ms:
          type: integer
        error_code:
          type: string
        diagnosis:
          type: string
          description: Generalized diagnosis. Do not include secrets or raw payloads.
        suggested_fix:
          type: string
    PatternReport:
      type: object
      required: [task, steps, success]
      properties:
        task:
          type: string
        steps:
          type: array
          items:
            type: object
        success:
          type: boolean
        cost_usdc:
          type: number
        latency_ms:
          type: integer
    ReportAccepted:
      type: object
      properties:
        ok:
          type: boolean
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
    PaymentChallenge:
      type: object
      properties:
        error:
          type: object
        accepts:
          type: array
          items:
            type: object
        x402:
          type: object
          description: Payment challenge metadata, if returned by the facilitator or service.
