openapi: "3.0.3"

info:
  title: SentryAgent.ai — Public Agent Marketplace
  version: 1.0.0
  description: |
    Public Agent Marketplace endpoints for the SentryAgent.ai AgentIdP platform.

    The marketplace enables discovery of AI agents that have been explicitly
    marked as public (`isPublic: true`) by their owners. It is a read-only
    public catalog — no authentication required.

    **Feature flag:** When `MARKETPLACE_ENABLED=false` all routes return `404`.

    **Unauthenticated endpoints:**
    - `GET /marketplace/agents` — Paginated list of public agents with search and filters
    - `GET /marketplace/agents/:agentId` — Detailed public agent with DID Document

servers:
  - url: http://localhost:3000/api/v1
    description: Local development server
  - url: https://api.sentryagent.ai/v1
    description: Production server

tags:
  - name: Marketplace
    description: Public agent discovery endpoints (unauthenticated)

components:
  schemas:
    MinimalDIDDocument:
      type: object
      description: Minimal W3C DID Document returned with marketplace agent detail.
      required:
        - "@context"
        - id
        - controller
        - verificationMethod
        - authentication
      properties:
        "@context":
          type: array
          items:
            type: string
          example:
            - "https://www.w3.org/ns/did/v1"
        id:
          type: string
          example: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        controller:
          type: string
          example: "did:web:api.sentryagent.ai"
        verificationMethod:
          type: array
          items:
            type: object
            additionalProperties: true
          description: Verification methods from the DID Document.
        authentication:
          type: array
          items:
            type: object
            additionalProperties: true

    MarketplaceAgentCard:
      type: object
      description: |
        Public agent card returned by the marketplace. Contains only information
        that the agent owner has explicitly made public.
      required:
        - agentId
        - agentType
        - version
        - capabilities
        - owner
        - deploymentEnv
        - publishedAt
      properties:
        agentId:
          type: string
          format: uuid
          description: Unique identifier of the agent.
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        agentType:
          type: string
          description: Functional classification of the agent.
          enum:
            - screener
            - classifier
            - orchestrator
            - extractor
            - summarizer
            - router
            - monitor
            - custom
          example: "screener"
        version:
          type: string
          description: Semantic version string of the agent.
          example: "1.4.2"
        capabilities:
          type: array
          items:
            type: string
          description: List of capability strings (`resource:action` format).
          example:
            - "resume:read"
            - "email:send"
            - "candidate:score"
        owner:
          type: string
          description: Team or organization that owns this agent.
          example: "talent-acquisition-team"
        deploymentEnv:
          type: string
          enum:
            - development
            - staging
            - production
          example: "production"
        did:
          type: string
          nullable: true
          description: W3C DID identifier for this agent, if one has been generated.
          example: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        didDocument:
          $ref: '#/components/schemas/MinimalDIDDocument'
          nullable: true
          description: Minimal W3C DID Document for this agent, if a DID has been generated.
        publishedAt:
          type: string
          format: date-time
          description: Timestamp when this agent was made public.
          example: "2026-03-01T08:00:00.000Z"

    PaginatedMarketplaceResponse:
      type: object
      description: Paginated marketplace listing response.
      required:
        - data
        - total
        - page
        - limit
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/MarketplaceAgentCard'
        total:
          type: integer
          description: Total number of public agents matching the query.
          example: 58
        page:
          type: integer
          description: Current page number (1-based).
          example: 1
        limit:
          type: integer
          description: Number of results per page.
          example: 20

    ErrorResponse:
      type: object
      description: Standard error response envelope.
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: "AGENT_NOT_FOUND"
        message:
          type: string
          example: "Agent with the specified ID was not found."
        details:
          type: object
          additionalProperties: true

paths:
  /marketplace/agents:
    get:
      operationId: listPublicAgents
      tags:
        - Marketplace
      summary: List public agents
      description: |
        Returns a paginated list of agents that have been marked as public.

        Supports full-text search across `owner`, `capabilities`, and `agentType`
        via the `q` parameter. Results can be filtered by `capability` or `publisher`.

        **Unauthenticated** — no Bearer token required.

        Returns `404` when the `MARKETPLACE_ENABLED` feature flag is set to `false`.
      security: []
      parameters:
        - name: q
          in: query
          required: false
          description: |
            Full-text search query across agent owner, capabilities, and agent type.
          schema:
            type: string
          example: "resume screener"
        - name: capability
          in: query
          required: false
          description: Filter by a specific capability string (exact match).
          schema:
            type: string
          example: "resume:read"
        - name: publisher
          in: query
          required: false
          description: Filter by owner/publisher name (exact match).
          schema:
            type: string
          example: "talent-acquisition-team"
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          example: 1
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          example: 20
      responses:
        '200':
          description: Paginated list of public agents returned successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedMarketplaceResponse'
              example:
                data:
                  - agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                    agentType: "screener"
                    version: "1.4.2"
                    capabilities:
                      - "resume:read"
                      - "email:send"
                      - "candidate:score"
                    owner: "talent-acquisition-team"
                    deploymentEnv: "production"
                    did: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                    didDocument: null
                    publishedAt: "2026-03-01T08:00:00.000Z"
                  - agentId: "b2c3d4e5-f6a7-8901-bcde-f12345678901"
                    agentType: "classifier"
                    version: "2.1.0"
                    capabilities:
                      - "document:classify"
                      - "label:write"
                    owner: "platform-team"
                    deploymentEnv: "staging"
                    did: null
                    didDocument: null
                    publishedAt: "2026-03-10T10:00:00.000Z"
                total: 58
                page: 1
                limit: 20
        '400':
          description: Invalid query parameters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: "VALIDATION_ERROR"
                message: "Invalid query parameter value."
                details:
                  field: "limit"
                  reason: "Must be between 1 and 100."
        '404':
          description: Marketplace is not enabled on this instance.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: "NOT_FOUND"
                message: "The Agent Marketplace is not enabled on this instance."
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: "INTERNAL_SERVER_ERROR"
                message: "An unexpected error occurred. Please try again later."

  /marketplace/agents/{agentId}:
    get:
      operationId: getPublicAgent
      tags:
        - Marketplace
      summary: Get public agent detail
      description: |
        Returns the full public profile for a specific marketplace-listed agent,
        including its DID Document (if a DID has been generated).

        Only agents with `isPublic: true` are accessible via this endpoint.
        Attempting to retrieve a private agent returns `404`.

        **Unauthenticated** — no Bearer token required.

        Returns `404` when the `MARKETPLACE_ENABLED` feature flag is set to `false`.
      security: []
      parameters:
        - name: agentId
          in: path
          required: true
          description: UUID of the public agent.
          schema:
            type: string
            format: uuid
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
      responses:
        '200':
          description: Public agent detail returned successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketplaceAgentCard'
              example:
                agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                agentType: "screener"
                version: "1.4.2"
                capabilities:
                  - "resume:read"
                  - "email:send"
                  - "candidate:score"
                owner: "talent-acquisition-team"
                deploymentEnv: "production"
                did: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                didDocument:
                  "@context":
                    - "https://www.w3.org/ns/did/v1"
                  id: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                  controller: "did:web:api.sentryagent.ai"
                  verificationMethod:
                    - id: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890#key-1"
                      type: "JsonWebKey2020"
                      controller: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                      publicKeyJwk:
                        kty: "EC"
                        crv: "P-256"
                        x: "f83OJ3D..."
                        y: "x_FEzRu..."
                  authentication:
                    - id: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890#key-1"
                publishedAt: "2026-03-01T08:00:00.000Z"
        '404':
          description: Agent not found, not public, or marketplace not enabled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                agentNotFound:
                  summary: Agent not found or not public
                  value:
                    code: "AGENT_NOT_FOUND"
                    message: "Agent with the specified ID was not found."
                marketplaceDisabled:
                  summary: Marketplace feature disabled
                  value:
                    code: "NOT_FOUND"
                    message: "The Agent Marketplace is not enabled on this instance."
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: "INTERNAL_SERVER_ERROR"
                message: "An unexpected error occurred. Please try again later."
