GitHub Raw JSON API

jo-inc / camofox-browser

8,286 JavaScript

Stealth headless browser for AI agents — bypass Cloudflare, bot detection, and anti-scraping. Drop-in Puppeteer/Playwright replacement.

camofox-browser Specification

Located in docs/openapi.json on branch HEAD

3.0.3 JSON 33 Endpoints 68.8 KB

Operations & Route Endpoints (35)

POST /sessions/{userId}/cookies
Import cookies into a user session
GET /health
Health check
GET /metrics
Prometheus metrics
POST /tabs
Create a new tab
GET /tabs
List open tabs
POST /tabs/{tabId}/navigate
Navigate a tab to a URL or macro
GET /tabs/{tabId}/snapshot
Accessibility snapshot
POST /tabs/{tabId}/wait
Wait for a selector or timeout
POST /tabs/{tabId}/click
Click an element
POST /tabs/{tabId}/type
Type text into an element
POST /tabs/{tabId}/press
Press a keyboard key
POST /tabs/{tabId}/scroll
Scroll the page
POST /tabs/{tabId}/back
Go back
POST /tabs/{tabId}/forward
Go forward
POST /tabs/{tabId}/refresh
Refresh page
GET /tabs/{tabId}/links
Extract page links
GET /tabs/{tabId}/downloads
List tab downloads
GET /tabs/{tabId}/images
Extract page images
GET /tabs/{tabId}/screenshot
Take a screenshot
GET /tabs/{tabId}/stats
Tab statistics
POST /tabs/{tabId}/evaluate
Evaluate JavaScript in tab
POST /tabs/{tabId}/extract
Structured data extraction via JSON Schema
DELETE /tabs/{tabId}
Close a tab
DELETE /tabs/group/{listItemId}
Close all tabs in a group
GET /sessions/{userId}/traces
List trace files
GET /sessions/{userId}/traces/{filename}
Download a trace file
DELETE /sessions/{userId}/traces/{filename}
Delete a trace file
DELETE /sessions/{userId}
Destroy a user session
GET /
Server status
POST /tabs/open
Open tab (OpenClaw format)
POST /start
Start browser
POST /stop
Stop browser
POST /navigate
Navigate (OpenClaw format)
GET /snapshot
Snapshot (OpenClaw format)
POST /act
Combined action (OpenClaw format)
Raw JSON Specification
{
  "openapi": "3.0.3",
  "info": {
    "title": "camofox-browser",
    "version": "1.6.0",
    "description": "Anti-detection browser automation server for AI agents. Accessibility snapshots, element refs, session isolation, cookie import, proxy rotation, and structured logs.",
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    },
    "contact": {
      "name": "Jo Inc",
      "url": "https://askjo.ai",
      "email": "[email protected]"
    }
  },
  "servers": [
    {
      "url": "http://localhost:9377",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "System",
      "description": "Server health, metrics, and status."
    },
    {
      "name": "Tabs",
      "description": "Create, list, inspect, and destroy browser tabs."
    },
    {
      "name": "Navigation",
      "description": "Navigate tabs to URLs or via search macros."
    },
    {
      "name": "Interaction",
      "description": "Click, type, scroll, press keys, evaluate JS."
    },
    {
      "name": "Content",
      "description": "Accessibility snapshots, screenshots, links, images, downloads."
    },
    {
      "name": "Sessions",
      "description": "Per-user session state: cookies, teardown."
    },
    {
      "name": "Browser",
      "description": "Global browser lifecycle (start/stop)."
    },
    {
      "name": "Legacy",
      "description": "OpenClaw-compatible endpoints (deprecated)."
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token matching CAMOFOX_API_KEY."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/sessions/{userId}/cookies": {
      "post": {
        "tags": [
          "Sessions"
        ],
        "summary": "Import cookies into a user session",
        "description": "Import cookies for authenticated browsing. Requires BearerAuth in production.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Session owner identifier."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "cookies"
                ],
                "properties": {
                  "cookies": {
                    "type": "array",
                    "maxItems": 500,
                    "items": {
                      "type": "object",
                      "required": [
                        "name",
                        "value",
                        "domain"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        },
                        "domain": {
                          "type": "string"
                        },
                        "path": {
                          "type": "string"
                        },
                        "expires": {
                          "type": "number"
                        },
                        "httpOnly": {
                          "type": "boolean"
                        },
                        "secure": {
                          "type": "boolean"
                        },
                        "sameSite": {
                          "type": "string",
                          "enum": [
                            "Strict",
                            "Lax",
                            "None"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cookies imported.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "userId": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid cookie data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Health check",
        "description": "Detailed health with tab/session counts and failure tracking.",
        "responses": {
          "200": {
            "description": "Healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "engine": {
                      "type": "string"
                    },
                    "browserConnected": {
                      "type": "boolean"
                    },
                    "browserRunning": {
                      "type": "boolean"
                    },
                    "activeTabs": {
                      "type": "integer"
                    },
                    "activeSessions": {
                      "type": "integer"
                    },
                    "consecutiveFailures": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Unhealthy or recovering.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "recovering": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/metrics": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Prometheus metrics",
        "description": "Returns Prometheus text exposition format. Requires PROMETHEUS_ENABLED=1.",
        "responses": {
          "200": {
            "description": "Prometheus metrics.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Metrics disabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs": {
      "post": {
        "tags": [
          "Tabs"
        ],
        "summary": "Create a new tab",
        "description": "Creates a tab in the given session. Optionally navigates to an initial URL.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "sessionKey"
                ],
                "properties": {
                  "userId": {
                    "type": "string",
                    "description": "Session owner."
                  },
                  "sessionKey": {
                    "type": "string",
                    "description": "Tab group identifier."
                  },
                  "listItemId": {
                    "type": "string",
                    "description": "Legacy alias for sessionKey."
                  },
                  "url": {
                    "type": "string",
                    "description": "Optional initial URL."
                  },
                  "trace": {
                    "type": "boolean",
                    "description": "Enable Playwright tracing for this session (screenshots, DOM snapshots, network). Must be set on first tab creation; cannot be added to an existing session."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tab created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tabId": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing required fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Cannot enable tracing on an existing session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Tab limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Tabs"
        ],
        "summary": "List open tabs",
        "description": "Returns all tabs for a given userId.",
        "parameters": [
          {
            "name": "userId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by session owner."
          }
        ],
        "responses": {
          "200": {
            "description": "Tab list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "running": {
                      "type": "boolean"
                    },
                    "tabs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tabId": {
                            "type": "string"
                          },
                          "targetId": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "listItemId": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/navigate": {
      "post": {
        "tags": [
          "Navigation"
        ],
        "summary": "Navigate a tab to a URL or macro",
        "description": "Navigate to a URL or expand a search macro. Auto-creates tab if not found.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "macro": {
                    "type": "string",
                    "description": "Search macro (e.g. @google_search)."
                  },
                  "query": {
                    "type": "string",
                    "description": "Search query for macro."
                  },
                  "sessionKey": {
                    "type": "string"
                  },
                  "listItemId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Navigation result with snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/snapshot": {
      "get": {
        "tags": [
          "Content"
        ],
        "summary": "Accessibility snapshot",
        "description": "Returns accessibility tree with element refs. Supports pagination via offset.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "text",
                "json"
              ],
              "default": "text"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Character offset for paginated retrieval."
          },
          {
            "name": "includeScreenshot",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "snapshot": {
                      "type": "string"
                    },
                    "refsCount": {
                      "type": "integer"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "totalChars": {
                      "type": "integer"
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextOffset": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/wait": {
      "post": {
        "tags": [
          "Interaction"
        ],
        "summary": "Wait for a selector or timeout",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "selector": {
                    "type": "string"
                  },
                  "timeout": {
                    "type": "integer",
                    "description": "Max wait in ms."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wait completed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/click": {
      "post": {
        "tags": [
          "Interaction"
        ],
        "summary": "Click an element",
        "description": "Click by element ref, CSS selector, or coordinates.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "ref": {
                    "type": "string",
                    "description": "Element ref ID (e.g. \"e3\")."
                  },
                  "selector": {
                    "type": "string",
                    "description": "CSS selector fallback."
                  },
                  "doubleClick": {
                    "type": "boolean"
                  },
                  "coordinates": {
                    "type": "object",
                    "properties": {
                      "x": {
                        "type": "number"
                      },
                      "y": {
                        "type": "number"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Click result with optional post-action snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/type": {
      "post": {
        "tags": [
          "Interaction"
        ],
        "summary": "Type text into an element",
        "description": "Types text into a focused element or a specific ref/selector.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "text"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "ref": {
                    "type": "string"
                  },
                  "selector": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string"
                  },
                  "clear": {
                    "type": "boolean",
                    "description": "Clear field before typing."
                  },
                  "submit": {
                    "type": "boolean",
                    "description": "Press Enter after typing."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Type result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/press": {
      "post": {
        "tags": [
          "Interaction"
        ],
        "summary": "Press a keyboard key",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "key"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "key": {
                    "type": "string",
                    "description": "Key name (e.g. \"Enter\", \"Escape\", \"Tab\")."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Key pressed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/scroll": {
      "post": {
        "tags": [
          "Interaction"
        ],
        "summary": "Scroll the page",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "direction": {
                    "type": "string",
                    "description": "\"up\" or \"down\" (default \"down\")."
                  },
                  "amount": {
                    "type": "integer",
                    "description": "Pixels to scroll."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Scroll result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/back": {
      "post": {
        "tags": [
          "Navigation"
        ],
        "summary": "Go back",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Navigated back.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/forward": {
      "post": {
        "tags": [
          "Navigation"
        ],
        "summary": "Go forward",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Navigated forward.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/refresh": {
      "post": {
        "tags": [
          "Navigation"
        ],
        "summary": "Refresh page",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Page refreshed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/links": {
      "get": {
        "tags": [
          "Content"
        ],
        "summary": "Extract page links",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Links extracted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "links": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "text": {
                            "type": "string"
                          },
                          "href": {
                            "type": "string"
                          },
                          "ref": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/downloads": {
      "get": {
        "tags": [
          "Content"
        ],
        "summary": "List tab downloads",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Downloads list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "downloads": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "filename": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "state": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/images": {
      "get": {
        "tags": [
          "Content"
        ],
        "summary": "Extract page images",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Images extracted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "images": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "src": {
                            "type": "string"
                          },
                          "alt": {
                            "type": "string"
                          },
                          "width": {
                            "type": "integer"
                          },
                          "height": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/screenshot": {
      "get": {
        "tags": [
          "Content"
        ],
        "summary": "Take a screenshot",
        "description": "Returns a base64-encoded PNG screenshot.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Screenshot.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "screenshot": {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "string"
                        },
                        "mimeType": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/stats": {
      "get": {
        "tags": [
          "Tabs"
        ],
        "summary": "Tab statistics",
        "description": "Returns tab metadata including URL, tool call count, visited URLs, download/failure counts.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tab stats.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tabId": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "toolCalls": {
                      "type": "integer"
                    },
                    "visitedUrls": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "downloadCount": {
                      "type": "integer"
                    },
                    "consecutiveFailures": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/evaluate": {
      "post": {
        "tags": [
          "Interaction"
        ],
        "summary": "Evaluate JavaScript in tab",
        "description": "Runs arbitrary JS in the page context and returns the result.",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "expression"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "expression": {
                    "type": "string",
                    "description": "JavaScript expression to evaluate."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evaluation result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}/extract": {
      "post": {
        "tags": [
          "Content"
        ],
        "summary": "Structured data extraction via JSON Schema",
        "description": "Extracts structured data from the current page using a JSON Schema whose properties\ncarry `x-ref` hints pointing at snapshot element refs (e.g. `e1`, `e2`).  \nCall `GET /tabs/{tabId}/snapshot` first to populate the ref table.\n",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "schema"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "schema": {
                    "type": "object",
                    "description": "JSON Schema with `type: \"object\"` and a `properties` map.  \nEach property may include `x-ref` (a snapshot element ref) and an optional\n`type` (`string`, `number`, `integer`, `boolean`).\n",
                    "required": [
                      "type",
                      "properties"
                    ],
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "object"
                        ]
                      },
                      "properties": {
                        "type": "object",
                        "additionalProperties": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "string",
                                "number",
                                "integer",
                                "boolean",
                                "object",
                                "null"
                              ]
                            },
                            "x-ref": {
                              "type": "string",
                              "description": "Snapshot element ref (e.g. `e1`)."
                            }
                          }
                        }
                      },
                      "required": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Property names that must resolve to a non-null value."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extraction succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "description": "Extracted key-value pairs matching the input schema."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing userId, missing schema, or invalid schema.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "No refs available -- call snapshot first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "snapshot": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Extraction failed (e.g. required ref not found).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "error": {
                      "type": "string"
                    },
                    "snapshot": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/{tabId}": {
      "delete": {
        "tags": [
          "Tabs"
        ],
        "summary": "Close a tab",
        "parameters": [
          {
            "name": "tabId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tab closed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tabs/group/{listItemId}": {
      "delete": {
        "tags": [
          "Tabs"
        ],
        "summary": "Close all tabs in a group",
        "parameters": [
          {
            "name": "listItemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Group closed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "closed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Session not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sessions/{userId}/traces": {
      "get": {
        "tags": [
          "Sessions"
        ],
        "summary": "List trace files",
        "description": "Returns all Playwright trace zip files for the given user session, sorted newest first.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Session owner identifier."
          }
        ],
        "responses": {
          "200": {
            "description": "Trace list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "traces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "filename": {
                            "type": "string"
                          },
                          "sizeBytes": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": "number"
                          },
                          "modifiedAt": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sessions/{userId}/traces/{filename}": {
      "get": {
        "tags": [
          "Sessions"
        ],
        "summary": "Download a trace file",
        "description": "Streams a Playwright trace zip for viewing in trace.playwright.dev.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Session owner identifier."
          },
          {
            "name": "filename",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Trace zip filename."
          }
        ],
        "responses": {
          "200": {
            "description": "Trace zip stream.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid filename.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Trace not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sessions"
        ],
        "summary": "Delete a trace file",
        "description": "Removes a specific Playwright trace zip from the server.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Session owner identifier."
          },
          {
            "name": "filename",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Trace zip filename."
          }
        ],
        "responses": {
          "200": {
            "description": "Trace deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid filename.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Trace not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sessions/{userId}": {
      "delete": {
        "tags": [
          "Sessions"
        ],
        "summary": "Destroy a user session",
        "description": "Closes all tabs and cleans up state for the given userId.",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session destroyed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "closed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Session not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Server status",
        "description": "Returns basic server liveness and browser state.",
        "responses": {
          "200": {
            "description": "Server status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "running": {
                      "type": "boolean"
                    },
                    "engine": {
                      "type": "string"
                    },
                    "browserConnected": {
                      "type": "boolean"
                    },
                    "browserRunning": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tabs/open": {
      "post": {
        "tags": [
          "Legacy"
        ],
        "summary": "Open tab (OpenClaw format)",
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "url"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "listItemId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tab opened.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/start": {
      "post": {
        "tags": [
          "Browser"
        ],
        "summary": "Start browser",
        "description": "Ensures the browser process is running. Idempotent.",
        "responses": {
          "200": {
            "description": "Browser started.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "profile": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Launch failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stop": {
      "post": {
        "tags": [
          "Browser"
        ],
        "summary": "Stop browser",
        "description": "Stops the browser and closes all sessions. Requires x-admin-key header.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Browser stopped.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "stopped": {
                      "type": "boolean"
                    },
                    "profile": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/navigate": {
      "post": {
        "tags": [
          "Legacy"
        ],
        "summary": "Navigate (OpenClaw format)",
        "description": "Navigate with targetId in body instead of path param.",
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "url"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "targetId": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Navigation result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/snapshot": {
      "get": {
        "tags": [
          "Legacy"
        ],
        "summary": "Snapshot (OpenClaw format)",
        "description": "Snapshot with targetId/userId as query params.",
        "deprecated": true,
        "parameters": [
          {
            "name": "targetId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "includeScreenshot",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/act": {
      "post": {
        "tags": [
          "Legacy"
        ],
        "summary": "Combined action (OpenClaw format)",
        "description": "Routes to click/type/scroll/press/etc based on \"kind\" parameter.",
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "kind"
                ],
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "description": "Action kind: click, type, scroll, press, key, select_option, drag, hover, screenshot, wait, back, forward."
                  },
                  "targetId": {
                    "type": "string"
                  },
                  "ref": {
                    "type": "string"
                  },
                  "selector": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string"
                  },
                  "key": {
                    "type": "string"
                  },
                  "direction": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Tab not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}