ScalebrowserDOCS

Groups, presets & bulk

Turning one profile into fifty: groups as labels, presets as stored templates, bulk endpoints and their partial failures, and leasing a whole fleet at once.

Last updated

Profiles are unlimited; what your plan limits is how many run at the same time. So a fleet of two hundred profiles running five at a time is the normal shape of this product, and this page is the machinery for it.

Groups

A group is a flat label a profile belongs to. Nothing more: no nesting, no inherited settings, no permissions.

CallWhat it does
GET · POST /v1/groupsList, create.
GET · PATCH · DELETE /v1/groups/:idFetch, rename, delete. Deleting a group leaves its profiles alone; their group_id becomes null.

Groups are what a fleet lease narrows by, and what the profile list filters on.

Presets

A preset is a stored template with two halves, and the split is the whole idea:

  • constraints shape the identity that gets generated. Exactly one axis is honest here: country. Profiles & personas explains why the list is that short.
  • config is the operating configuration each profile is stamped with: geo mode, group, proxy handling, and so on.
CallWhat it does
GET · POST /v1/presetsList, create.
GET · PATCH · DELETE /v1/presets/:idFetch, update, delete.

Read the allowed countries from GET /v1/persona/constraints rather than writing your own list.

Making a fleet

POST /v1/bulk/profiles stamps out N profiles from a preset. Each gets its own identity; they share the preset's settings.

bash
$ curl -X POST http://127.0.0.1:8787/v1/bulk/profiles \
    -H "Authorization: Bearer $SCALEBROWSER_BEARER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"preset_id":"ps_31a0","count":50,"name_prefix":"shop-"}'

The ceiling is 1000 per call. Over MCP the same operation is capped at 100, which is a narrower limit for an agent on purpose rather than a different implementation.

All or nothing. A failure part way through rolls back everything the call already created. Fifty half-made profiles are worse than none, because you cannot tell from the outside which of them are complete.

The bulk operations

CallBodyWhat it does
POST /v1/bulk/start{ ids, headless? }Start each, one after another.
POST /v1/bulk/stop{ ids }Stop each.
POST /v1/bulk/delete{ ids }Delete each, with its browser directory.
POST /v1/bulk/assign-proxy{ ids, proxy_id }Set the proxy on each. null clears it.
POST /v1/bulk/assign-extensions{ ids, ext_refs }Replace each profile's extension set. An empty array gives them none.

Every one of them answers with a per-id list of { id, ok, error? }, so one bad id does not fail the batch.

bulk/start adds three fields on top: started (how many browsers came up), remaining (ids never attempted) and stopped_reason when it ended early. headless is one decision for the whole batch.

A bulk start stops at the first capacity refusal. Running out of memory or slots says nothing about the profile that happened to be next, so continuing would report fifty identical failures that read like fifty broken profiles.

Look at remaining: those ids were never tried, and retrying them once capacity frees up is the right move. Any other per-profile error does not stop the run.

From an agent

Two tools cover this, both in the management set:

preset_instantiate is the bulk create, capped at 100.

profile_batch is the other four, plus delete, as one call with an action:

json
{ "action": "assign_proxy", "ids": ["pr_9c21e4", "pr_0f7b12"], "proxy_id": "px_7f3a" }

action is one of start, stop, delete, assign_proxy, assign_extensions, and ids takes at most 100. A profile somebody else is actively leasing is refused rather than acted on.

action: "delete" is real. It stops the browser, drops the profile and reclaims its disk, which takes every login inside it. It is the one destructive tool the Windows desktop client serves out of the box, and there is no confirmation step anywhere in this layer.

Leasing a fleet

lease_fleet is the fleet shape of lease_profile: reserve several profiles at once and get a handle for each. Use it when the work is the same across many identities.

It hands back whatever it managed rather than failing. If the machine fills up or the group runs out, you get the handles it did issue plus the reason it stopped. Release each one separately with release_profile, because how each run went is a different answer per profile.

Order survives the concurrency limit. Twenty profiles with five slots is the normal case, and the thing that says what is still outstanding after a batch is interrupted is the profile's own task list, not the batch call. See Tasks & memory.

Listing at fleet scale

GET /v1/profiles pages: limit (default 100), offset, sort, order, and the filters group, state, q (name substring) and enabled.

GET /v1/profiles/ids takes the same filters, ignores paging and answers { count, ids }. That is what a "select all matches" action needs, and it is why the route exists separately: fetching 2000 full profile objects to collect their ids is a waste on both ends.

GET /v1/profiles/count answers the other question a paged list cannot: how many there are. It takes group and q, and reports { total, stopped, starting, running, crashed }, so "how big is the fleet" and "how many are running right now" cost one request together rather than a walk through every page.

Next

Run it on your own machine

Seven days to try it with your own agents on your own sites. Starting the trial needs a card.

Get started