Skip to content

Latest commit

 

History

History
1342 lines (1112 loc) · 22.9 KB

File metadata and controls

1342 lines (1112 loc) · 22.9 KB

Fuba Browser API Documentation

Base URL

http://localhost:39000

Health Check

GET /health

Returns the health status of the application, not just HTTP process liveness.

Response (healthy):

{
  "status": "ok",
  "version": "0.1.0",
  "application": "ok"
}

Response (unhealthy, HTTP 503):

{
  "status": "unhealthy",
  "version": "0.1.0",
  "application": "unavailable",
  "error": "Browser page is closed"
}

API Discovery

GET /

Returns a service discovery payload with key endpoints and docs hints.

Response (JSON):

{
  "success": true,
  "data": {
    "name": "fuba-browser",
    "version": "0.1.0",
    "endpoints": {
      "health": "/health",
      "api": "/api",
      "llmsTxt": "/llms.txt",
      "docs": {
        "index": "/api/docs",
        "bundle": "/api/docs/llm",
        "single": "/api/docs/{docId}"
      }
    },
    "hints": [
      "Use GET /api/docs to list available documentation IDs."
    ]
  }
}

GET /api

Returns API-level discovery info including docs endpoints and curl examples.

GET /llms.txt

Returns plain-text LLM entrypoint hints including /api/docs and /api/docs/llm?format=markdown.

LLM Documentation

These endpoints fetch markdown docs from the upstream repository and provide them in a format that is easy for LLM ingestion.
Default source base URL: https://raw.githubusercontent.com/fuba/fuba-browser/v<running-version> (derived from DOCS_REF or APP_VERSION or runtime package.json version). You can override with DOCS_BASE_URL.

GET /api/docs

Returns the list of available documents.

Query Parameters:

Parameter Type Required Description
docs string No Comma-separated IDs to filter list (e.g. api,cli,usage)

Response:

{
  "success": true,
  "data": {
    "documents": [
      {
        "id": "api",
        "title": "REST API Reference",
        "path": "doc/API.md",
        "sourceUrl": "https://raw.githubusercontent.com/fuba/fuba-browser/v2.0.1/doc/API.md"
      }
    ],
    "bundleEndpoint": "/api/docs/llm"
  }
}

GET /api/docs/:docId

Returns one markdown document.

Query Parameters:

Parameter Type Required Description
format string No Set markdown to receive text/markdown directly

Response (JSON):

{
  "success": true,
  "data": {
    "id": "api",
    "title": "REST API Reference",
    "path": "doc/API.md",
    "sourceUrl": "https://raw.githubusercontent.com/fuba/fuba-browser/v2.0.1/doc/API.md",
    "markdown": "# Fuba Browser API Documentation...",
    "fetchedAt": "2026-02-13T01:20:00.000Z"
  }
}

GET /api/docs/llm

Returns a concatenated markdown bundle for LLM context input.

Query Parameters:

Parameter Type Required Description
docs string No Comma-separated IDs to include (default: all docs)
format string No Set markdown to receive text/markdown directly

Response (JSON):

{
  "success": true,
  "data": {
    "documents": [
      {
        "id": "api",
        "title": "REST API Reference",
        "path": "doc/API.md",
        "sourceUrl": "https://raw.githubusercontent.com/fuba/fuba-browser/v2.0.1/doc/API.md"
      }
    ],
    "markdown": "# Fuba Browser Documentation Bundle...",
    "format": "markdown",
    "fetchedAt": "2026-02-13T01:20:00.000Z"
  }
}

Web VNC

POST /api/web-vnc/token

Issue a one-time token for noVNC access. The token expires after the configured TTL (default: 5 minutes, configurable via VNC_TOKEN_TTL_SECONDS environment variable).

Each token is issued with a unique dynamic VNC password. This password is automatically added to the x11vnc password file and removed after TTL expiry (default: 10 minutes, configurable via VNC_PASSWORD_TTL_SECONDS). There is no fixed base password — all VNC access requires a dynamic password obtained via this API.

Request Body:

{
  "vncHost": "puma2:39101"
}
Field Type Required Description
vncHost string No The host:port for noVNC redirect. When specified, the redirect will use this host directly instead of auto-detecting from request headers. Useful when accessing from an external hostname.

Response:

{
  "success": true,
  "data": {
    "token": "a1b2c3...hex64chars",
    "expiresAt": "2026-02-08T02:35:28.463Z"
  }
}

Error (503): VNC password manager is not configured (missing VNC_PASSWDFILE).

curl example:

# Without vncHost (uses auto-detected host)
curl -X POST http://localhost:39000/api/web-vnc/token

# With vncHost (for external access)
curl -X POST -H 'Content-Type: application/json' \
  -d '{"vncHost":"puma2:39101"}' \
  http://localhost:39000/api/web-vnc/token

GET /web-vnc

Consume a one-time token and redirect to the noVNC web client with auto-connect parameters.

Query Parameters:

Parameter Type Required Description
token string Yes One-time token from POST /api/web-vnc/token

Response:

  • 302 redirect to http://<host>:<port>/vnc.html#password=...&autoconnect=1
    • The password in the URL fragment is the per-token dynamic password.
    • If the token was issued with vncHost, the redirect uses that host:port directly.
    • Otherwise, the host is auto-detected from request headers and the port is set to the configured Web VNC port (VNC_WEB_PORT, default: 39001).
  • 401 if the token is missing, invalid, or already consumed.
  • 503 if no VNC password is associated with the token.

Usage flow:

# 1. Issue a token
TOKEN=$(curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"vncHost":"puma2:39101"}' \
  http://puma2:39100/api/web-vnc/token | jq -r '.data.token')

# 2. Open in browser (one-time use)
open "http://puma2:39100/web-vnc?token=${TOKEN}"

Browser Control

POST /api/navigate

Navigate to a specified URL.

Request Body:

{
  "url": "https://example.com"
}

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com"
  }
}

POST /api/scroll

Scroll the page to specified coordinates.

Request Body:

{
  "x": 0,
  "y": 100
}

Response:

{
  "success": true,
  "data": {
    "x": 0,
    "y": 100
  }
}

POST /api/click

Click an element matching the selector.

Request Body:

{
  "selector": "#submit-button"
}

Response:

{
  "success": true,
  "data": {
    "selector": "#submit-button"
  }
}

POST /api/type

Type text into an input field.

Request Body:

{
  "selector": "input[name='username']",
  "text": "john_doe"
}

Response:

{
  "success": true,
  "data": {
    "selector": "input[name='username']",
    "text": "john_doe"
  }
}

GET /api/screenshot

Capture a screenshot of the current page.

Response:

  • Content-Type: image/png
  • Binary PNG data

Content Extraction

GET /api/content

Get page content as extended Markdown format.

Response:

{
  "success": true,
  "data": {
    "html": "<html>...</html>",
    "markdown": "# Page Title\n\n...",
    "elements": [
      {
        "tagName": "a",
        "selector": "#link-1",
        "text": "Click here",
        "bbox": {
          "x": 10,
          "y": 20,
          "width": 100,
          "height": 30
        },
        "attributes": {
          "id": "link-1",
          "href": "/page",
          "class": "nav-link"
        },
        "isVisible": true,
        "areaPercentage": 2.5
      }
    ],
    "url": "https://example.com",
    "title": "Example Domain"
  }
}

GET /api/elements

Get all interactive elements on the page.

Response:

{
  "success": true,
  "data": [
    {
      "tagName": "button",
      "selector": "#submit",
      "text": "Submit",
      "bbox": {
        "x": 100,
        "y": 200,
        "width": 80,
        "height": 40
      },
      "attributes": {
        "id": "submit",
        "type": "submit"
      },
      "isVisible": true,
      "areaPercentage": 1.2
    }
  ]
}

GET /api/dom

Get simplified DOM tree information.

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com",
    "title": "Example Domain",
    "elementsCount": 15,
    "elements": [...]
  }
}

Session Management

GET /api/cookies

Get all cookies for the current session.

Response:

{
  "success": true,
  "data": [
    {
      "name": "session_id",
      "value": "abc123",
      "domain": ".example.com",
      "path": "/",
      "expires": 1234567890,
      "size": 16,
      "httpOnly": true,
      "secure": true,
      "sameSite": "Lax"
    }
  ]
}

POST /api/cookies

Set a cookie.

Request Body:

{
  "url": "https://example.com",
  "name": "user_pref",
  "value": "dark_mode"
}

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com",
    "name": "user_pref",
    "value": "dark_mode"
  }
}

DELETE /api/cookies

Clear all cookies.

Response:

{
  "success": true,
  "data": {
    "message": "Cookies cleared"
  }
}

GET /api/session

Get current session information.

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com",
    "title": "Example Domain",
    "cookiesCount": 3
  }
}

Snapshot API

The snapshot API provides accessibility tree-based element identification with ref IDs for fast, deterministic element targeting.

GET /api/snapshot

Get page accessibility snapshot with element refs.

Query Parameters:

  • interactive (boolean): Only include interactive elements
  • compact (boolean): Remove empty nodes
  • depth (number): Maximum tree depth
  • selector (string): Scope to a CSS selector

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com",
    "title": "Example Domain",
    "viewport": { "width": 1200, "height": 2000 },
    "timestamp": "2024-01-01T00:00:00.000Z",
    "tree": [
      {
        "ref": "e1",
        "role": "link",
        "name": "Click here",
        "tag": "a",
        "selector": "#link-1",
        "bbox": { "x": 10, "y": 20, "width": 100, "height": 30 },
        "visible": true,
        "focusable": true,
        "attributes": { "href": "/page" },
        "children": []
      }
    ],
    "refs": {
      "e1": { ... }
    }
  }
}

POST /api/action

Perform action using a ref from snapshot.

Request Body:

{
  "ref": "@e1",
  "action": "click"
}

Available actions:

  • click - Click the element
  • dblclick - Double-click the element
  • hover - Hover over the element
  • focus - Focus the element
  • fill - Clear and type text (requires value)
  • type - Type text (requires value)
  • check - Check a checkbox
  • uncheck - Uncheck a checkbox
  • select - Select an option (requires value)

Response:

{
  "success": true,
  "data": {
    "ref": "@e1",
    "action": "click",
    "selector": "#link-1"
  }
}

DELETE /api/snapshot

Clear stored snapshot.

Response:

{
  "success": true,
  "data": {
    "message": "Snapshot cleared"
  }
}

Extended Interaction API

POST /api/hover

Hover over an element.

Request Body:

{
  "selector": "#menu-item"
}

POST /api/focus

Focus an element.

Request Body:

{
  "selector": "input[name='email']"
}

POST /api/check

Check a checkbox.

Request Body:

{
  "selector": "input[type='checkbox']"
}

POST /api/uncheck

Uncheck a checkbox.

Request Body:

{
  "selector": "input[type='checkbox']"
}

POST /api/select

Select an option in a dropdown.

Request Body:

{
  "selector": "select[name='country']",
  "value": "JP"
}

Wait API

Wait for various conditions before proceeding.

POST /api/wait/selector

Wait for an element to appear.

Request Body:

{
  "selector": "#loading-complete",
  "timeout": 30000
}

Response:

{
  "success": true,
  "data": {
    "selector": "#loading-complete",
    "found": true
  }
}

POST /api/wait/text

Wait for text to appear on the page.

Request Body:

{
  "text": "Success",
  "timeout": 30000
}

POST /api/wait/url

Wait for URL to match a pattern.

Request Body:

{
  "pattern": "**/dashboard",
  "timeout": 30000
}

POST /api/wait/load

Wait for page load state.

Request Body:

{
  "state": "networkidle"
}

Available states:

  • domcontentloaded - DOM content loaded (default)
  • networkidle - No network activity for 500ms

POST /api/wait/timeout

Wait for a specified duration.

Request Body:

{
  "ms": 2000
}

Getter API

Get information about elements and page state.

GET /api/get/title

Get the page title.

Response:

{
  "success": true,
  "data": {
    "title": "Example Domain"
  }
}

GET /api/get/url

Get the current URL.

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com/page"
  }
}

GET /api/get/text/:selector

Get text content of an element.

Response:

{
  "success": true,
  "data": {
    "selector": "#message",
    "text": "Hello World"
  }
}

GET /api/get/html/:selector

Get HTML content of an element.

Response:

{
  "success": true,
  "data": {
    "selector": "#container",
    "html": "<div>...</div>"
  }
}

GET /api/get/value/:selector

Get value of an input element.

Response:

{
  "success": true,
  "data": {
    "selector": "#email",
    "value": "user@example.com"
  }
}

GET /api/get/count/:selector

Get count of matching elements.

Response:

{
  "success": true,
  "data": {
    "selector": ".item",
    "count": 10
  }
}

POST /api/is/visible

Check if an element is visible.

Request Body:

{
  "selector": "#modal"
}

Response:

{
  "success": true,
  "data": {
    "selector": "#modal",
    "visible": true
  }
}

POST /api/is/enabled

Check if an element is enabled.

Request Body:

{
  "selector": "#submit"
}

POST /api/is/checked

Check if a checkbox is checked.

Request Body:

{
  "selector": "#agree"
}

Input API

Keyboard and mouse control.

POST /api/keyboard/press

Press a key or key combination.

Request Body:

{
  "key": "Enter"
}

Examples:

  • "Enter", "Tab", "Escape"
  • "Control+c", "Control+v"
  • "Shift+Tab"

POST /api/keyboard/down

Press and hold a key.

Request Body:

{
  "key": "Shift"
}

POST /api/keyboard/up

Release a key.

Request Body:

{
  "key": "Shift"
}

POST /api/mouse/move

Move the mouse to coordinates.

Request Body:

{
  "x": 100,
  "y": 200
}

POST /api/mouse/down

Press a mouse button.

Request Body:

{
  "button": "left"
}

POST /api/mouse/up

Release a mouse button.

Request Body:

{
  "button": "left"
}

POST /api/mouse/wheel

Scroll using mouse wheel.

Request Body:

{
  "deltaY": 300,
  "deltaX": 0
}

Storage API

Access localStorage and sessionStorage.

GET /api/storage/local

Get all localStorage items.

Response:

{
  "success": true,
  "data": {
    "token": "abc123",
    "theme": "dark"
  }
}

GET /api/storage/local/:key

Get a specific localStorage item.

POST /api/storage/local

Set a localStorage item.

Request Body:

{
  "key": "token",
  "value": "abc123"
}

DELETE /api/storage/local

Clear all localStorage.

DELETE /api/storage/local/:key

Delete a specific localStorage item.

GET /api/storage/session

Get all sessionStorage items.

GET /api/storage/session/:key

Get a specific sessionStorage item.

POST /api/storage/session

Set a sessionStorage item.

DELETE /api/storage/session

Clear all sessionStorage.

DELETE /api/storage/session/:key

Delete a specific sessionStorage item.


Debug API

Debugging and development tools.

GET /api/console

Get console logs.

Response:

{
  "success": true,
  "data": {
    "logs": [
      {
        "type": "log",
        "text": "Page loaded",
        "timestamp": "2024-01-01T00:00:00.000Z"
      }
    ]
  }
}

DELETE /api/console

Clear console logs.

GET /api/errors

Get JavaScript errors.

Response:

{
  "success": true,
  "data": {
    "errors": [
      {
        "message": "Uncaught TypeError",
        "source": "https://example.com/app.js",
        "line": 42,
        "timestamp": "2024-01-01T00:00:00.000Z"
      }
    ]
  }
}

DELETE /api/errors

Clear errors.

POST /api/eval

Execute JavaScript in the page context.

Warning: This is a powerful endpoint by design. It executes arbitrary JavaScript in the currently loaded page context and can access page DOM/state/session data.

Request Body:

{
  "script": "document.title"
}

Response:

{
  "success": true,
  "data": {
    "result": "Example Domain"
  }
}

POST /api/highlight

Highlight an element visually.

Request Body:

{
  "selector": "#target"
}

Network API

Inspect recent network requests and export response bodies (including data: URLs).

GET /api/network

Returns the in-memory network request log for the current browser session.

Response:

{
  "success": true,
  "data": {
    "entries": [
      {
        "id": "req-1",
        "url": "https://example.com/pixel.png",
        "method": "GET",
        "resourceType": "image",
        "timestamp": "2026-02-23T05:00:00.000Z",
        "status": 200,
        "statusText": "OK",
        "ok": true,
        "contentType": "image/png",
        "finishedAt": "2026-02-23T05:00:00.120Z"
      }
    ],
    "count": 1
  }
}

DELETE /api/network

Clear the in-memory network request log and cached response handles.

Response:

{
  "success": true,
  "data": {
    "cleared": 12
  }
}

GET /api/network/body/:id

Returns the response body for a captured request ID.

Query Parameters:

Parameter Type Required Description
type string No binary (default) for raw bytes, or base64 for JSON metadata + base64/data URL

Response (type=base64):

{
  "success": true,
  "data": {
    "id": "req-1",
    "url": "https://example.com/pixel.png",
    "contentType": "image/png",
    "size": 68,
    "base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...",
    "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB..."
  }
}

Response (type=binary):

  • Raw response body bytes with Content-Type set to the captured response content type
  • Includes header X-Network-Request-Id: <id>

Errors:

  • 404 if the request ID is unknown or the response body is no longer available

State Management API

Save and load browser authentication state (cookies, localStorage, sessionStorage).

POST /api/state/save

Save current browser state.

Response:

{
  "success": true,
  "data": {
    "version": "1.0",
    "timestamp": "2024-01-01T00:00:00.000Z",
    "url": "https://example.com/dashboard",
    "cookies": [...],
    "localStorage": { "key1": "value1" },
    "sessionStorage": { "key2": "value2" }
  }
}

POST /api/state/load

Load browser state from saved data.

Request Body:

{
  "state": { ... },
  "navigateToUrl": true
}

Options:

  • navigateToUrl (boolean): Navigate to the saved URL after loading state

Response:

{
  "success": true,
  "data": {
    "message": "State loaded successfully",
    "cookiesCount": 5,
    "localStorageCount": 3,
    "sessionStorageCount": 1,
    "url": "https://example.com/dashboard"
  }
}

GET /api/state/info

Get current state info without full data.

Response:

{
  "success": true,
  "data": {
    "url": "https://example.com/dashboard",
    "cookiesCount": 5,
    "localStorageCount": 3,
    "sessionStorageCount": 1,
    "timestamp": "2024-01-01T00:00:00.000Z"
  }
}

System API

System-level operations for browser management.

POST /api/reset

Restart the browser process. This completely resets the browser state including all pages, cookies, storage, and memory.

Request Body: (none required)

Response:

{
  "success": true,
  "message": "Browser has been reset"
}

Error Response:

{
  "success": false,
  "error": "Reset failed"
}

Use Cases:

  • Browser becomes unresponsive
  • Memory usage grows too high
  • Need a completely clean state
  • After long automation sessions

CLI Usage:

fbb reset

Download API

Intercept, track, and retrieve files downloaded by the browser. Uses a "wait before click" pattern: call POST /api/download/wait before triggering the download action, ensuring no race condition.

POST /api/download/wait

Wait for the next browser download to complete (long-polling).

Request Body:

{
  "timeout": 60000
}
Field Type Required Description
timeout number No Timeout in milliseconds (default: 60000, max: 300000)

Response:

{
  "success": true,
  "data": {
    "id": "dl-1",
    "url": "https://example.com/file.zip",
    "suggestedFilename": "file.zip",
    "status": "completed",
    "startedAt": "2026-03-21T00:00:00.000Z",
    "completedAt": "2026-03-21T00:00:05.000Z"
  }
}

GET /api/download

List all tracked downloads.

Response:

{
  "success": true,
  "data": {
    "entries": [
      {
        "id": "dl-1",
        "url": "https://example.com/file.zip",
        "suggestedFilename": "file.zip",
        "status": "completed",
        "startedAt": "2026-03-21T00:00:00.000Z",
        "completedAt": "2026-03-21T00:00:05.000Z"
      }
    ],
    "count": 1
  }
}

GET /api/download/:id

Get download metadata by ID.

Response:

{
  "success": true,
  "data": {
    "id": "dl-1",
    "url": "https://example.com/file.zip",
    "suggestedFilename": "file.zip",
    "status": "completed",
    "startedAt": "2026-03-21T00:00:00.000Z",
    "completedAt": "2026-03-21T00:00:05.000Z"
  }
}

GET /api/download/:id?type=binary

Get downloaded file content as binary.

Response:

  • Raw file bytes with Content-Type: application/octet-stream
  • Includes headers:
    • X-Download-Id: <id>
    • X-Suggested-Filename: <url-encoded filename>
    • Content-Disposition: attachment; filename="<url-encoded filename>"

Errors:

  • 404 if the download ID is not found
  • 500 if the download is not yet completed

DELETE /api/download

Clear download history and delete temp files.

Response:

{
  "success": true,
  "data": {
    "cleared": 3
  }
}

Error Responses

All endpoints return error responses in the following format:

{
  "success": false,
  "error": "Error message describing what went wrong"
}

Common HTTP status codes:

  • 400: Bad Request (missing required parameters)
  • 500: Internal Server Error