Run a Task
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.Overview
- Method:
POST - Path:
/browser-agent - Cost: billed per successful task. Failed tasks are free.
- Max tasks per request:
1000 - Max in-flight tasks per user: varies by plan (5 on the free tier, up to 150 on Enterprise). Check yours with
GET /browser-agent-status
concurrency vs your in-flight cap: concurrency controls parallel workers within one request. Your in-flight cap counts every submitted task (pending, claimed, and running) across your account — so a 200-task submission counts as 200 against the cap immediately, even at concurrency: 5. If a submission would exceed your remaining cap, it’s rejected with 429 QUEUE_FULL; chunk large workloads to your cap using GET /browser-agent-status.- Per-task default timeout:
240000ms
Headers
Request Body
Task object
Response Modes
Sync (default)
Default behavior. The request holds the HTTP connection until every task in the run completes, then returns the fullBatchResult.
Best for: small runs (≤ 50 tasks), interactive scripts, jobs where you want one clean response.
Async (async: true)
Returns immediately with a batchId. Poll GET /browser-agent/:id for progress.
Best for: large runs, long-running tasks, fire-and-forget jobs.
Stream (stream: true)
Returns 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:
:keepalive comments are sent every 10s to stop intermediaries from closing the connection.
503. Fall back to async: true + polling.Response Schemas
BatchResult
TaskResult
Task statuses
Status Codes
Error response shape
Non-2xx responses return a structured JSON body (and the matching SSEerror event when streaming):
code lets clients dispatch typed handlers without parsing strings.
actionUrl, when present, deep-links the user back to pre.dev with the
right modal pre-opened — paste it into window.open and they’ll land
on the credit-purchase or subscription flow ready to go.
code value to a typed exception
class with the actionUrl populated — see the
Node SDK and
Python SDK error-handling
sections.
Code Examples
Multiple tasks with concurrency
Structured extraction with output schema
Python — sync + async + streaming
Node.js — sync + streaming
TypeScript — fully typed client
Error Handling
All non-2xx responses follow the structured shape above. The two billing codes carry anactionUrl that auto-opens the right modal on pre.dev — surface it in your UI and the user is one click from resolving the gate.
402 SUBSCRIPTION_REQUIRED
This API key’s user is on the trial plan and has used their lifetime free task. Send them to actionUrl (subscribe modal) or have them upgrade at pre.dev/projects/key.
402 INSUFFICIENT_CREDITS
Subscription is fine, but the credit balance is below the per-task estimate (0.1 credits/task by default; failed tasks aren’t billed but you need the headroom to start). Send them to actionUrl (credits modal) — or top up at pre.dev/projects/key.
429 RATE_LIMITED / QUEUE_FULL
Per-minute request cap hit, or you’re at your plan’s in-flight task cap. Wait for tasks to drain, lower concurrency, or check GET /browser-agent-status.
503 SSE capacity exceeded
The serving pod is already at its SSE connection cap. Retry the request with "async": true and poll — the underlying work isn’t affected.
400 / invalid task shape
Every task needs a url. If you get 400, check you’re not sending tasks: { ... } (a single object) — it must always be an array, even for one task.
Next: Task Status
Authorizations
API key for authentication. Get your API key from https://pre.dev/projects/key (Solo) or https://pre.dev/enterprise/dashboard?page=api (Enterprise). Use format: Bearer YOUR_API_KEY
Body
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.
Response
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".

