Source: docs/integration/api.openapi.yaml

integration/api.openapi.yaml

openapi: 3.1.0
info:
  title: Forgium Agent — Public API
  description: |
    ✅ FOR INTEGRATOR AGENTS — This is the API you need.

    Public API for the conversational agent backend.

    Authentication: API key via `Authorization: Bearer <key>`.
    Keys are issued by the Forgium administrator.
  version: 2.0.0
  contact:
    name: MVP Team

servers:
  - url: http://localhost:8787
    description: Local development
  - url: https://agent-api.forgium-agent.workers.dev
    description: Production

security:
  - bearerAuth: []

paths:
  /health:
    get:
      summary: Health check
      security: []
      tags: [System]
      responses:
        '200':
          description: Service is active
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  service:
                    type: string
                    example: agent-api

  /v1/channels/http/messages:
    post:
      summary: Send message via HTTP channel
      description: |
        Generic sync endpoint for external apps (mobile, web, backend) to communicate with the agent.
        Returns the agent response synchronously in the same request.
        
        Channel: `provider=native`, `channel=http`
      tags: [HTTP Channel]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HttpChannelRequest'
            example:
              message:
                type: text
                body: "Hola, necesito ayuda"
              user_id: "mobile_user_123"
              metadata:
                platform: ios
                app_version: "1.0.0"
      responses:
        '200':
          description: Agent response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpChannelResponse'
              example:
                conversation_id: "conv_abc123def456"
                message:
                  id: "msg_abc123def456"
                  role: assistant
                  type: text
                  body: "¡Hola! ¿En qué puedo ayudarte?"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '405':
          description: Method not allowed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpChannelErrorResponse'
        '409':
          description: Duplicate event
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpChannelErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpChannelErrorResponse'
        '500':
          description: Agent runtime error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpChannelErrorResponse'
  /v1/capability-credentials/{credentialRef}:
    put:
      summary: Store or rotate an encrypted endpoint credential for the authenticated API key
      description: |
        Encrypts the supplied endpoint token with the platform credential vault.
        The secret is never returned, logged, stored in a manifest, or kept as
        plaintext at rest. Provision this credential before importing a capability
        that references it.
      tags: [Capabilities]
      parameters:
        - name: credentialRef
          in: path
          required: true
          schema:
            type: string
            pattern: '^cred_[a-zA-Z0-9_-]{3,120}$'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [auth_type, secret]
              properties:
                auth_type:
                  type: string
                  enum: [bearer, api_key, basic]
                header_name:
                  type: string
                  enum: [x-api-key, x-api-token]
                secret:
                  type: string
                  minLength: 1
                  maxLength: 4096
      responses:
        '201':
          description: Credential configured; no secret is returned
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '413':
          description: Credential request is too large
        '503':
          description: Credential vault unavailable

  /v1/capabilities:
    get:
      summary: List capabilities available to the authenticated API key
      description: The API key scopes the result; no account identifier is required.
      tags: [Capabilities]
      responses:
        '200':
          description: Capability definitions
        '401':
          $ref: '#/components/responses/Unauthorized'

  /v1/capabilities/import:
    post:
      summary: Import business capabilities for the authenticated API key
      description: |
        Imports one or more capabilities as drafts. The API key scopes the
        import. Include an `Idempotency-Key` header. Import does not activate
        the capability.
      tags: [Capabilities]
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            maxLength: 200
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CapabilityManifest'
      responses:
        '201':
          description: Draft capabilities created
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'

  /v1/capabilities/{capabilityId}:
    get:
      summary: Get one capability for the authenticated API key
      tags: [Capabilities]
      parameters:
        - $ref: '#/components/parameters/CapabilityId'
      responses:
        '200':
          description: Capability definition
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      summary: Revise one capability for the authenticated API key
      description: A revision returns to draft and must pass a new contract test before activation.
      tags: [Capabilities]
      parameters:
        - $ref: '#/components/parameters/CapabilityId'
        - name: If-Match
          in: header
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Draft revision created
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'

  /v1/capabilities/{capabilityId}/test:
    post:
      summary: Run a contract test for a draft read capability
      tags: [Capabilities]
      parameters:
        - $ref: '#/components/parameters/CapabilityId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [arguments]
              properties:
                arguments:
                  type: object
      responses:
        '200':
          description: Contract test result
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'

  /v1/capabilities/{capabilityId}/activate:
    post:
      summary: Activate a tested capability for the authenticated API key
      tags: [Capabilities]
      parameters:
        - $ref: '#/components/parameters/CapabilityId'
      responses:
        '200':
          description: Capability activated
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'

  /v1/capabilities/{capabilityId}/disable:
    post:
      summary: Disable a capability for the authenticated API key
      tags: [Capabilities]
      parameters:
        - $ref: '#/components/parameters/CapabilityId'
      responses:
        '200':
          description: Capability disabled
        '401':
          $ref: '#/components/responses/Unauthorized'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        API key issued by the Forgium administrator.
        Format: mg_<64 hex chars>

  parameters:
    CapabilityId:
      name: capabilityId
      in: path
      required: true
      schema:
        type: string
        pattern: '^cap_[a-z0-9]+$'
      example: cap_xxxxxxxxxxxxxxxx

  schemas:
    CapabilityManifest:
      type: object
      required: [domain, capabilities]
      properties:
        domain:
          type: string
        capabilities:
          type: array
          minItems: 1
          items:
            type: object
      description: See integration/capability-handoff.md for the complete bounded JSON Schema contract.
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        code:

    HttpChannelRequest:
      type: object
      required:
        - message
      properties:
        conversation_id:
          type: string
          description: Conversation ID. If not provided, a new conversation is created.
          example: "conv_abc123def456"
        user_id:
          type: string
          description: External user identifier from the consuming app.
          example: "mobile_user_123"
        message:
          type: object
          required:
            - type
            - body
          properties:
            type:
              type: string
              enum: [text]
              description: Message type. Only 'text' supported in MVP.
            body:
              type: string
              description: Message content.
              example: "Hola, necesito ayuda"
        metadata:
          type: object
          description: Optional metadata from the consuming app.
          example:
            platform: ios
            app_version: "1.0.0"

    HttpChannelResponse:
      type: object
      properties:
        conversation_id:
          type: string
          example: "conv_abc123def456"
        message:
          type: object
          properties:
            id:
              type: string
              example: "msg_abc123def456"
            role:
              type: string
              enum: [assistant]
            type:
              type: string
              enum: [text]
            body:
              type: string
              example: "¡Hola! ¿En qué puedo ayudarte?"

    HttpChannelErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - VALIDATION_ERROR
                - UNAUTHORIZED
                - FORBIDDEN
                - METHOD_NOT_ALLOWED
                - DUPLICATE_EVENT
                - AGENT_RUNTIME_ERROR
                - INTERNAL_ERROR
            message:
              type: string
            details:
              type: object
          type: string

  responses:
    Unauthorized:
      description: Invalid, expired, or revoked API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: Invalid API key
            code: UNAUTHORIZED
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: Not Found
    BadRequest:
      description: Invalid payload
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: "Missing required fields: id, type"
            code: VALIDATION_ERROR
    Conflict:
      description: State conflict
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: Cannot approve action in state 'approved'