How do I make my first MetaDock API call?
Mint a scoped API key in MetaDock, point your client at the local base URL, and send a request over whichever of the five protocols you already use. Everything runs on your own machine, and all five surfaces are part of MetaDock Pro.
Which automation protocol should I use?
MetaDock provides five ways to automate browsers: REST API, WebSocket API, Selenium WebDriver (W3C), Chrome DevTools Protocol (CDP), and MCP integration. MetaDock shows all browsers running in a visual grid, so you can watch your automation execute in real-time.
REST API
HTTP endpoints for browser control. Works with any language.
MetaDock Pro
WebSocket API
Real-time bidirectional communication and event subscriptions.
MetaDock Pro
Selenium WebDriver
W3C WebDriver protocol. Use existing scripts with minimal changes.
MetaDock Pro
Chrome DevTools Protocol
CDP discovery and WebSocket passthrough. Point Puppeteer or Playwright at a running browser.
MetaDock Pro
MCP Integration
Control browsers with AI assistants using natural language.
MetaDock Pro
Authentication
Create API keys in the MetaDock app under Settings → API, Automation & AI. There is no single shared key: you mint as many as you need and revoke them individually. The API stays off until at least one active key exists.
Each key is a UUID v4 carrying a set of scopes: rest, websocket, mcp, cdp, and selenium. A request is accepted only if the key's scopes cover the surface it targets. Each surface also has its own toggle in the same settings panel, and all of them are off by default: a request to a surface whose toggle is off is rejected no matter which key it carries.
What a key is allowed to do
Beyond the surface scopes, a key carries four independent restrictions. Each is empty by default, which means unrestricted on that axis, and each is enforced in one place rather than per protocol: a capability denied to a key is denied whether the call arrives over REST, WebSocket, MCP, CDP or WebDriver.
- Capabilities. 24 groups spanning browser control, organization, content and user data, such as
browser.read,browser.script,browser.cookiesandhistory. Six are withheld from a new key by default because they read or move data rather than drive a page: cookies, local and session storage, screenshots, layout screenshots, browsing history, and downloads. - Individual tools.A per-key deny list that overrides the capability grant, for the case where a group is right except for one call inside it. One-click presets set the whole tree by risk tier, cumulatively: read-only observes, interact adds navigate, click, type and scroll, submit adds cookies, storage, settings and lifecycle. The tiers come from each tool's own MCP risk hints, so they cannot drift from the catalog.
- Profiles and layouts. An allowlist of the browsers a key may act on. Out-of-scope browsers answer 403, and so do the fleet-wide verbs (navigate-all, execute-all, close-all and their siblings), which carry no single target and therefore cannot be scope-checked per browser.
- Domains. A navigation allowlist. A key holding one can only navigate to, or create a browser at, a host that matches an entry exactly or as a
*.example.comwildcard covering the host and its subdomains. Anything else is 403, including the URL inside a fleet-wide navigate. This is the restriction to reach for when handing a key to an AI agent.
Batched calls are checked the same way. A browser_batch is resolved to the canonical tool name of every sub-action before it runs, so a batch cannot smuggle a denied tool past the gate.
Two limits apply to every surface regardless of the key. Only http:// and https:// URLs are accepted for API-driven navigation, so file:// cannot be used to read local files back through the page-reading tools, and print-to-PDF writes only to a .pdf path with no parent-directory traversal or UNC target.
The plaintext key is never stored. The database keeps a SHA-256 lookup hash plus an HMAC derived from this machine's hardware fingerprint, compared in constant time and failing closed, so a database lifted onto another machine authenticates nothing. The first connection from a new client may also need an in-app approval unless “Allow All” is on, and repeated authentication failures trigger a per-IP lockout.
Authentication Methods
On the HTTP surfaces (REST, Selenium WebDriver, MCP, CDP discovery), send the key in a header. Query-parameter authentication is not supported.
Recommended. Standard Bearer token in Authorization header.
Alternative header-based authentication.
WebSocket Authentication
A WebSocket connection carries no headers, so it authenticates in-band. The first message on the socket must be an auth frame carrying a key with the websocket scope. Include id to have the response echo it back.
{
"type": "auth",
"api_key": "your-uuid-from-metadock-settings",
"id": 1
}import requests
API_KEY = "your-uuid-from-metadock-settings"
BASE_URL = "http://127.0.0.1:8080"
# Method 1: Bearer Token (Recommended)
headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.get(f"{BASE_URL}/api/browsers", headers=headers)
# Method 2: X-Api-Key Header
headers = {"X-Api-Key": API_KEY}
response = requests.get(f"{BASE_URL}/api/browsers", headers=headers)Base URLs
REST API
http://127.0.0.1:8080All REST endpoints are prefixed with /api/
WebSocket API
ws://127.0.0.1:8080/wsSingle WebSocket endpoint for all operations
Selenium WebDriver
http://127.0.0.1:8080/wd/hubW3C WebDriver protocol endpoint
Chrome DevTools Protocol
http://127.0.0.1:8080/jsonCDP discovery; targets hand out /devtools/ WebSocket URLs
Response Formats
REST API Success Response
{
"success": true,
"data": {
"uuid": "browser-abc-123",
"url": "https://example.com",
"title": "Example Domain"
},
"timestamp": "2025-01-04T12:00:00"
}REST API Error Response
{
"success": false,
"error": "Browser not found",
"timestamp": "2025-01-04T12:00:00"
}WebSocket Response
Action responses carry only these three fields, and id is absent when the request omitted one. Pushed events are a different shape and do carry a type and a timestamp.
{
"success": true,
"data": { ... },
"id": 1
}WebDriver Response (W3C)
{
"value": {
"sessionId": "session-xyz-789",
"capabilities": { ... }
}
}