openapi: 3.1.0
info:
  title: Vancam Visual Verification API
  version: "1.0.0"
  description: >
    Discover live visual feeds and fetch frames for AI agent workflows.
    Backed by a PostGIS spatial database (~4k live assets).

    Production endpoints:
    - Search: `https://api.vancam.ai/cameras/cameras`
    - Image: `https://api.vancam.ai/api?asset_id={id}`

    All requests require an `x-api-key` header. Get a free personal key from
    https://vancam.ai/account, or use the shared anonymous key documented at
    https://vancam.ai/docs.

servers:
  - url: https://api.vancam.ai
    description: Vancam API

security:
  - ApiKeyAuth: []

paths:
  /cameras/cameras:
    get:
      operationId: findCameras
      summary: Search visual feeds by radius, route, bounds, or nearest mode.
      description: |
        One endpoint, four search modes selected by which query parameters
        you pass, plus direct lookup by asset_id:

        **Radius** — lat, lon, radius (km)
        **Nearest** — lat, lon, nearest=true, limit
        **Route** — origin_lat, origin_lon, dest_lat, dest_lon, buffer (m)
        **Bounds** — min_lat, min_lon, max_lat, max_lon
        **By ID** — asset_id
      parameters:
        - in: query
          name: lat
          schema:
            type: number
        - in: query
          name: lon
          schema:
            type: number
        - in: query
          name: radius
          schema:
            type: number
          description: Radius in km, 0-50 (default 1.0)
        - in: query
          name: origin_lat
          schema:
            type: number
        - in: query
          name: origin_lon
          schema:
            type: number
        - in: query
          name: dest_lat
          schema:
            type: number
        - in: query
          name: dest_lon
          schema:
            type: number
        - in: query
          name: buffer
          schema:
            type: number
          description: Corridor width in meters (default 100)
        - in: query
          name: min_lat
          schema:
            type: number
        - in: query
          name: min_lon
          schema:
            type: number
        - in: query
          name: max_lat
          schema:
            type: number
        - in: query
          name: max_lon
          schema:
            type: number
        - in: query
          name: nearest
          schema:
            type: boolean
        - in: query
          name: asset_id
          schema:
            type: string
          description: Look up a single camera by ID
        - in: query
          name: limit
          schema:
            type: integer
      responses:
        "200":
          description: Search results with cameras array and image_url per asset
        "403":
          description: Missing or invalid x-api-key header
        "429":
          description: Rate limit exceeded for your plan

  /api:
    get:
      operationId: cameraImage
      summary: Get the latest live frame for an asset
      parameters:
        - in: query
          name: asset_id
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Binary image (JPEG)
          content:
            image/jpeg:
              schema:
                type: string
                format: binary
        "403":
          description: Missing or invalid x-api-key header

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
  schemas: {}
