Docs REST API

The local REST API, every route

Everything the Mosaic window does, a script on the same computer can do: make profiles, give them proxies, start them and drive them. This reference is built from the one the app ships, so it lists what your copy answers.

Base URL
http://127.0.0.1:7317/api/v1
Routes
194
MCP tools
168
Plan
Pro

Authentication

Mosaic runs the API inside the app, on 127.0.0.1, so only programs on the same computer can reach it. Make a key on the API screen in Mosaic and send it with every request, in either header:

Authorization: Bearer msc_…
X-API-Key: msc_…

The secret is shown once and stored as a hash, so a lost key cannot be read back: revoke it and make another. GET /health is the one route that needs no key.

Which plan answers

The API is part of Pro. On Free, a request with a valid key gets a 402 with { "error", "feature": "api" }, while a wrong key is still a 401, so a typo never looks like a billing problem. A limit reached inside a route, such as a sixth profile on Free, is also a 402 that names its feature.

Why a web page cannot call it

A request carrying a Sec-Fetch-Site header other than same-origin came from a browser, and it gets a 403 before the route is read. Otherwise any site you visit could ask /health and learn that this computer runs an anti-detect browser. Scripts, curl, Puppeteer and Playwright do not send that header and are not affected.

Conventions

  • Bodies are JSON unless a route says otherwise. Ids are UUIDs, times are ISO 8601 in UTC.
  • PATCH changes the fields you send and leaves the rest alone. An unknown field is refused by name, not dropped.
  • Deleting a profile or a project moves it to the trash. Nothing is destroyed until it is purged, after 30 days or through the trash routes.
  • An error is { "error": "…" } with a 4xx or 5xx status. A 4xx sentence is written for you; a 500 is a bug of ours.

Attaching Playwright or Puppeteer

POST /profiles/:id/start returns a wsEndpoint. Connect to it and use the context that is already there, because a new context starts with none of the profile’s cookies:

const started = await fetch(`${BASE}/profiles/${id}/start`, {
  method: 'POST', headers: { Authorization: `Bearer ${KEY}` }
}).then((r) => r.json())

const browser = await chromium.connectOverCDP(started.wsEndpoint)
const context = browser.contexts()[0]

The port is 7317 on a new install and can be changed in Settings; the API screen in Mosaic shows the address this copy listens on. An assistant that speaks MCP has its own door: the MCP tools.

Profiles

Make profiles, run them, draw and repair their fingerprints, and organise them into projects and tags.

Proxies

Saved proxies, and the provider accounts that mint a fresh exit per profile.

A profile’s data

Everything one profile carries: its cookies, its saved logins and 2FA codes, its bookmarks and its downloads.

Content and transfer

Extensions, presets, and moving whole profiles in and out of Mosaic.

Automation

Drive a live page the way a person would — tabs, clicks, reading the DOM, and typing with human timing.

Preparing and testing

Warm a profile up before it meets the site that matters, and run it past the public detectors.

Housekeeping

The trash, and the library backups.

System

Settings, engines, updates, keys and the health of the running app.

More

Next Try it on your own accounts

Run the API on your own profiles

The REST API and the MCP server are part of Pro: $49 a month, with the first 14 days free. Free has every browser feature and no API key.