Run one or more browser-automation tasks. Supports sync, async, and SSE streaming modes. Up to 1000 tasks per request.
tasks field is always an array, even for a single task — so one endpoint covers both “run one task” and “run 1000 tasks in parallel”. No separate batch vs. single-task API.POST/api/v1/browser-agents10005000240000 ms| Header | Required | Description |
|---|---|---|
Authorization | ✅ | Bearer YOUR_API_KEY |
Content-Type | ✅ | application/json |
| Field | Type | Required | Description |
|---|---|---|---|
tasks | Task[] | ✅ | Array of tasks. 1 ≤ length ≤ 1000. |
concurrency | integer | ❌ | Parallel workers within this run. 1–20. Default 5. |
async | boolean | ❌ | If true, returns { id, status: "processing" } immediately. Poll GET /:id. Default false. |
stream | boolean | ❌ | If true, returns an SSE stream with per-step events + final results. Default false. Mutually exclusive with async. |
Task object| Field | Type | Required | Description |
|---|---|---|---|
url | string (URI) | ✅ | Starting page URL the agent navigates to. |
instruction | string | ❌ | Natural-language goal. What should the agent accomplish on this page? |
input | Record<string, string> | ❌ | String values the agent should use during the run — form values, credentials, search queries. |
output | JSON Schema | ❌ | Schema describing the shape of data to extract. If omitted, the agent returns unstructured text. |
successCondition | string | ❌ | Natural-language assertion. Task is marked SUCCESS only if this holds at the end. |
timeoutMs | integer | ❌ | Per-task max runtime in milliseconds. Default 240000. |
BatchResult.
Best for: small runs (≤ 50 tasks), interactive scripts, jobs where you want one clean response.
async: true)batchId. Poll GET /api/v1/browser-agents/:id for progress.
Best for: large runs, long-running tasks, fire-and-forget jobs.
stream: true)text/event-stream with per-step events. Each frame has a taskIndex tying it back to a task in the run.
Best for: live UI progress, debugging, watching what the agent is doing in real time.
SSE frames:
| Event | When | Payload |
|---|---|---|
task_event | Agent performs a step (navigation, plan, action, screenshot, validation) | { taskIndex, type, data } |
task_result | A single task finishes | { taskIndex, ...TaskResult } |
done | Entire run finishes | Full BatchResult |
error | Fatal error aborted the run | { error } |
:keepalive comments are sent every 10s to stop intermediaries from closing the connection.
5000 concurrent streams), new stream requests get 503. Fall back to async: true + polling.BatchResult| Field | Type | Description |
|---|---|---|
id | string | Run id (Mongo ObjectId). Use with GET /:id. |
total | integer | Number of tasks in the run. |
completed | integer | Number of tasks finished (any status). |
results | TaskResult[] | Per-task results, aligned by taskIndex. |
totalCreditsUsed | number | Sum of credits billed across the run. 1 credit = $0.10, floor 0.1 per billed task. |
status | "processing" | "completed" | "failed" | Run state. |
createdAt | ISO-8601 | Run creation time. |
completedAt | ISO-8601 | Run completion time. Omitted while processing. |
liveEvents | RunnerEvent[][] | Only when fetching with includeEvents=true — in-flight event streams for tasks that haven’t yet completed. |
error | string | Set only when status === "failed". |
TaskResult| Field | Type | Description |
|---|---|---|
url | string | Starting URL (echoed from the request). |
instruction | string | Task instruction (echoed). |
input | Record<string, string> | Task input (echoed). |
status | TaskStatus | See task statuses. |
data | any | Extracted data, validated against the task’s output schema. null if no output was specified or the task failed. |
creditsUsed | number | Credits billed for this task. Floor 0.1 (= $0.01) for SUCCESS; scales up with task complexity. Zero for non-SUCCESS statuses. |
durationMs | integer | Wall-clock runtime. |
error | string | Failure reason, when status is not SUCCESS. |
events | RunnerEvent[] | Full step timeline. Only returned when fetching with includeEvents=true. |
| Status | Meaning | Billed? |
|---|---|---|
SUCCESS | Task completed; output schema (if any) validated. | ✅ |
PENDING | Task queued, not yet started (async/polling response only). | — |
ERROR | Task errored during execution. | ❌ |
TIMEOUT | Task hit timeoutMs. | ❌ |
BLOCKED | Target site blocked the agent (bot protection, geo-block, etc.). | ❌ |
CAPTCHA_FAILED | CAPTCHA challenge couldn’t be solved. | ❌ |
LOOP | Agent got stuck in a redirect or action loop. | ❌ |
NO_TARGET | Required element wasn’t found on the page. | ❌ |
| Code | Meaning |
|---|---|
200 | Sync result, async stub, or start of SSE stream. |
400 | Missing tasks, task without url, or tasks.length > 1000. |
401 | Missing or invalid bearer token. |
402 | Insufficient credits. Top up. |
429 | User’s in-flight queue depth exceeded. Retry later or reduce concurrency. |
503 | SSE capacity exceeded on this pod. Retry with async: true and poll. |
output schema402 Insufficient creditsSUCCESS tasks are actually billed. Top up at pre.dev/billing.
429 Queue depth exceeded5000 in-flight tasks. Wait for some to drain, or lower concurrency.
503 SSE capacity exceeded"async": true and poll — the underlying work isn’t affected.
400 / invalid task shapeurl. If you get 400, check you’re not sending tasks: { ... } (a single object) — it must always be an array, even for one task.
API key for authentication. Get your API key from https://pre.dev/projects/playground (Solo) or https://pre.dev/enterprise/dashboard?page=api (Enterprise). Use format: Bearer YOUR_API_KEY
1 - 1000 elementsHow many tasks to run in parallel. Default: 5.
1 <= x <= 20If true, returns { id, status: 'processing' } immediately — poll GET /:id for progress.
If true, returns an SSE stream with task_event, task_result, done, and error frames.
Batch result (sync mode) or batch stub (async mode).
Run summary. The schema is named BatchResult for backwards compatibility with older clients.
Run id (24-char Mongo ObjectId).
Total tasks in the run.
Number of tasks that have finished (any status).
Per-task results aligned by taskIndex. In-progress runs return PENDING stubs for tasks that haven't started; the stub has only url, instruction, input, and status: "PENDING".
Sum of credits billed across all tasks in the run.
processing, completed, failed Populated once status !== "processing".
Only present when includeEvents=true on GET /:id. Per-task in-flight event streams for tasks that haven't yet finished. Aligned by index with results; completed tasks get an empty array.
Set only when status === "failed".