Preparing and testing REST API
Warm-up
The cookie robot: browse the web as a profile so it stops looking brand new. An empty cookie jar and no history is scored as risk on its own, however good the fingerprint is.
List warm-up presets
GET/api/v1/warmup/presets
The built-in site lists — general browsing, social, shopping, technology — with the sites each contains, plus the default options a run uses when you pass none.
Returns
{ total, presets: Array<{ id, label, description, siteCount, sites }>, defaults: WarmupOptions }
Preview the site list
POST/api/v1/profiles/:id/warmup/plan
Returns the sites a run with these options would visit, in order, without visiting anything. The sample is random, so calling it twice gives two different plans.
Path parameters
| Field | Type | What it is |
|---|---|---|
idrequired | string | The record’s id. |
Body
Partial<WarmupOptions>. Same options as a run.
Returns
{ sites: string[] }
Warm a profile up
POST/api/v1/profiles/:id/warmup
Opens the profile’s own browser — its fingerprint, its proxy — visits the planned sites, dwells for a sampled time on each, scrolls the way a wheel does, optionally dismisses consent banners and follows same-origin links, then closes the browser cleanly so everything collected is flushed to disk. Long-running by design: a default run takes minutes. The profile must not already be running, because the robot needs its own session. A site that fails to load is recorded and skipped rather than ending the run.
Path parameters
| Field | Type | What it is |
|---|---|---|
idrequired | string | The record’s id. |
Body
| Field | Type | What it is |
|---|---|---|
preset | "general" | "social" | "shopping" | "tech" | Which built-in list to sample from. |
sites | string[] | Your own sites. Anything here replaces the preset entirely. |
siteCount | number | How many sites to visit from the pool. Default 8. |
minSecondsPerSite | number | Lower bound of the dwell time. Default 12. |
maxSecondsPerSite | number | Upper bound. Sampled per page, because a constant dwell is itself a pattern. Default 35. |
scroll | boolean | Stepped, eased scrolling with occasional corrections. Default true. |
followLinks | boolean | Follow same-origin links so the history has depth. Default true. |
maxLinksPerSite | number | How many, per site. Default 2. |
acceptCookieBanners | boolean | Click through consent dialogs, which gate most of the cookies worth having. Default true. |
headless | boolean | Default false, and best left that way. --headless=new renames the product token to HeadlessChrome and drops the real GPU, so every site whose cookies you are collecting is told it is talking to an automated browser with a different fingerprint from the one that will later use them. Set only if you have a reason; the launcher forces a --user-agent override when it is on so the token does not leak. |
watch | boolean | Default false. Off runs the real, headed browser parked off-screen — invisible, but with the profile’s own renderer. On shows the window so you can watch the run. |
Returns
A WarmupReport — { visited, cookies, seconds, cancelled, sites: WarmupSiteResult[] }.
Errors
- 400 — the profile is already running, or already warming up.
curl -X POST -H "Authorization: Bearer $KEY" -H 'content-type: application/json' \
-d '{"preset":"shopping","siteCount":12}' \
"$BASE/profiles/$ID/warmup"
Stop a warm-up
POST/api/v1/profiles/:id/warmup/cancel
Asks the run to stop. It finishes the page it is on and closes the browser cleanly, so the cookies collected so far are kept rather than thrown away.
Path parameters
| Field | Type | What it is |
|---|---|---|
idrequired | string | The record’s id. |
Returns
{ cancelled: true }
List warm-ups in progress
GET/api/v1/warmup/running
Profile ids currently being warmed up.
Returns
{ profileIds: string[] }
List saved plans
GET/api/v1/warmup/plans
A plan is a named, reusable warm-up: a list of sites plus how to behave on them. It exists because the four built-in presets are a list somebody else wrote, and the sites that matter to an operator are the ones their accounts live on. Every plan carries a whole WarmupOptions rather than a subset, so a plan is the body POST /profiles/:id/warmup would be sent — a saved copy and a run cannot describe two different things.
Query parameters
| Field | Type | What it is |
|---|---|---|
deleted | boolean | true lists the plan trash instead: the same rows, in the same shape, with deletedAt set. The trash is a filter over one collection, not a second collection. |
Returns
{ total, plans: WarmupPlan[] }
Read one plan
GET/api/v1/warmup/plans/:id
The whole plan, including every run option.
Path parameters
| Field | Type | What it is |
|---|---|---|
id | string | Plan id. |
Returns
A WarmupPlan.
Errors
- 404 — no plan with that id.
Create a plan
POST/api/v1/warmup/plans
The options are checked now rather than at run time. A dwell range the wrong way round, a siteCount of zero or a sites entry that is not a place a browser can go is refused here — the alternative is discovering it forty profiles into a batch nobody is watching. Nothing is silently repaired: clamping a reversed range would leave the author believing something untrue about a plan that will be used on hundreds of profiles.
Body
| Field | Type | What it is |
|---|---|---|
namerequired | string | What the plan is called. |
description | string | What it is for. |
options | Partial<WarmupOptions> | Anything omitted takes the default. sites replaces the preset entirely. |
Returns
The created WarmupPlan.
Errors
- 400 — an unknown field. The run settings go inside
options. - 400 — an option is present and wrong; the message names it.
Change a plan
PATCH/api/v1/warmup/plans/:id
Only what you pass changes, including inside options — so one field can be sent without restating the rest.
Path parameters
| Field | Type | What it is |
|---|---|---|
id | string | Plan id. |
Body
Partial<WarmupPlan>. name, description, options.
Returns
The updated WarmupPlan.
Errors
- 404 — no plan with that id.
Delete a plan
DELETE/api/v1/warmup/plans/:id
The plan goes and no profile is touched — a plan is a list of places, not a record of anything.
Path parameters
| Field | Type | What it is |
|---|---|---|
id | string | Plan id. |
Returns
{ deleted: true }
Errors
- 404 — no plan with that id.
Warm many profiles with one plan
POST/api/v1/warmup/run
Runs the profiles one after another, and that is a correctness point rather than politeness: each run launches that profile’s own browser, so a parallel fan-out is a check-then-act race against maxConcurrentProfiles — every call reads the count before any of them registers, all of them pass, and the cap is silently exceeded. Blocks for the whole batch, which at eight sites and a 12–35s dwell is roughly three minutes per profile. Every profile gets a row whether or not it worked; a dead proxy on one does not cost the rest. Send planId or the options inline, never both — a plan run with fields on top matches neither the plan you can see nor the body you sent.
Body
| Field | Type | What it is |
|---|---|---|
profileIdsrequired | string[] | Which profiles to warm. ids is accepted as well. |
planId | string | A saved plan. Omit to send options inline. |
… | Partial<WarmupOptions> | Inline options, when no planId is given. |
Returns
{ total, results: WarmupBatchResult[] } — one row per profile with ok, error, sitesVisited, cookies and seconds.
Errors
- 400 —
profileIdsis missing or is not an array. - 400 —
planIdsent together with options. - 404 — no plan with that id.
Stop a batch
POST/api/v1/warmup/cancel
Stops the profile that is warming up and every one still queued behind it. The profile in flight finishes its page and closes cleanly, so the cookies it collected are kept.
Returns
{ cancelled: true }
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.
Mosaic is a desktop app
Email yourself the link and open it on your computer.