openapi: 3.0.3
info:
  title: Agent as a Service
  version: 1.0.0
  description: Run AI agents in hardened Sandy sandboxes through a lightweight API.
servers:
  - url: https://agent-as-a-service.online/api
    description: Production
  - url: http://localhost:3000/api
    description: Local development
paths:
  /health:
    get:
      summary: Health check
      description: Validate upstream API gateway health.
      responses:
        "200":
          description: Health response
        "502":
          description: Gateway unavailable
  /openapi.json:
    get:
      summary: Machine-readable API contract
      responses:
        "200":
          description: OpenAPI JSON
  /openapi.yaml:
    get:
      summary: Machine-readable API contract (YAML)
      responses:
        "200":
          description: OpenAPI YAML
  /sandboxes:
    get:
      summary: List user sandboxes
      security:
        - BearerAuth: []
      responses:
        "200":
          description: List of sandboxes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Sandbox'
        "401":
          description: Missing or invalid API key
    post:
      summary: Create a sandbox
      security:
        - BearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSandboxRequest'
      responses:
        "200":
          description: Sandbox created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Sandbox'
        "400":
          description: Invalid request payload
        "401":
          description: Missing or invalid API key
  /sandboxes/{id}:
    get:
      summary: Get sandbox metadata
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      responses:
        "200":
          description: Sandbox details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Sandbox'
        "401":
          description: Missing or invalid API key
        "404":
          description: Sandbox not found
  /sandboxes/{id}/exec:
    post:
      summary: Execute a shell command
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecRequest'
      responses:
        "200":
          description: Command output
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecResult'
        "401":
          description: Missing or invalid API key
  /sandboxes/{id}/agent/run:
    post:
      summary: Run an AI coding agent
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunRequest'
      responses:
        "200":
          description: Streaming SSE response
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/AgentEventStream'
  /sandboxes/{id}/agent/cancel:
    post:
      summary: Cancel an active agent run
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      responses:
        "200":
          description: Cancellation accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
  /sandboxes/{id}/files/list:
    get:
      summary: List files
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
        - $ref: '#/components/parameters/PathQuery'
      responses:
        "200":
          description: Directory listing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileNode'
  /sandboxes/{id}/files/read:
    get:
      summary: Read file content
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
        - $ref: '#/components/parameters/PathQuery'
      responses:
        "200":
          description: File content
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileReadResult'
            text/plain:
              schema:
                type: string
        "404":
          description: File not found
  /sandboxes/{id}/files/write:
    post:
      summary: Write file content
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WriteRequest'
      responses:
        "200":
          description: Write result
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
  /sandboxes/{id}/vnc:
    get:
      summary: Get VNC preview URL
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      responses:
        "200":
          description: Preview URL
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VncResult'
  /sandboxes/{id}/terminate:
    post:
      summary: Terminate sandbox
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/SandboxId'
      responses:
        "200":
          description: Termination result
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
        "404":
          description: Sandbox not found
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_agnt_...
      description: Send your API key as `Authorization: Bearer YOUR_API_KEY`
  parameters:
    SandboxId:
      name: id
      in: path
      required: true
      schema:
        type: string
      description: Sandbox identifier
    PathQuery:
      name: path
      in: query
      required: false
      schema:
        type: string
        default: /workspace
      description: Absolute path in sandbox workspace
  schemas:
    CreateSandboxRequest:
      type: object
      properties:
        persistent:
          type: boolean
        preemptable:
          type: boolean
        priority:
          type: integer
        runtimePreference:
          type: string
    Sandbox:
      type: object
      properties:
        id:
          type: string
        status:
          type: string
        runtime:
          type: string
        metadata:
          type: object
    ExecRequest:
      type: object
      required:
        - command
      properties:
        command:
          type: string
        workdir:
          type: string
        timeoutMs:
          type: integer
          minimum: 1000
    ExecResult:
      type: object
      properties:
        stdout:
          type: string
        stderr:
          type: string
        exit_code:
          type: integer
    AgentRunRequest:
      type: object
      required:
        - agent
        - prompt
      properties:
        agent:
          type: string
          example: claude-code
        model:
          type: string
          example: auto
        prompt:
          type: string
        maxDuration:
          type: integer
          example: 1200
        rawPrompt:
          type: boolean
    AgentEventStream:
      type: string
      description: SSE stream containing JSON events (`status`, `output`, `complete`).
    WriteRequest:
      type: object
      required:
        - path
        - content
      properties:
        path:
          type: string
        content:
          type: string
    FileNode:
      type: array
      items:
        type: object
        properties:
          name:
            type: string
          type:
            type: string
            enum:
              - file
              - directory
          path:
            type: string
    FileReadResult:
      type: object
      properties:
        path:
          type: string
        content:
          type: string
    VncResult:
      type: object
      properties:
        url:
          type: string
          format: uri
