Submit one or more browser tasks and get the results back.
result = predev.browser_agent( tasks, concurrency=None, # parallel workers, 1–20, default 5 stream=False, # set True to get an SSE iterator run_async=False, # set True to return immediately with a batch id)
Parameters:
tasks(required): List[Dict] — see Task shape below
concurrency(optional): int — parallel workers within this batch (1–20, default 5)
stream(optional): bool — when True, returns an iterator yielding SSE events instead of a final result
run_async(optional): bool — when True, returns immediately with { id, status: "processing" }; poll with get_browser_agent(id)
Returns:
Default: Dict with id, total, completed, results, totalCreditsUsed, status
Fetch the status and results of a task submission by id. Works for in-progress and completed submissions.
result = predev.get_browser_agent(batch_id, include_events=False)
Parameters:
batch_id(required): str — id returned from browser_agent(..., run_async=True) or from streaming
include_events(optional): bool — when True, includes the full per-step event timeline (navigation, plan, screenshot, action, validation) for each task. Payloads can be large.
Returns:Dict with the same shape as browser_agent() sync response, plus events[] on each task (or liveEvents[] for tasks still in flight) when include_events=True.
result = predev.browser_agent([ { "url": "https://news.ycombinator.com", "instruction": "Extract the top 5 story titles." }, { "url": "https://www.reddit.com/r/programming", "instruction": "Extract the top 5 post titles." },], concurrency=2)for r in result["results"]: print(r["status"], r.get("data"))
import timebatch = predev.browser_agent(tasks, run_async=True)batch_id = batch["id"]while True: status = predev.get_browser_agent(batch_id) if status["status"] in ("completed", "failed"): break print(f"{status['completed']}/{status['total']} done") time.sleep(5)for r in status["results"]: print(r["status"], r.get("data"))
result = predev.get_browser_agent(batch_id, include_events=True)for task in result["results"]: print(task["status"], task["url"]) for event in task.get("events", []): print(" -", event["type"])
The SDK raises typed exceptions for the most common gating cases. The two
billing-gate exceptions carry an action_url — a deep link back to pre.dev
that auto-opens the right modal (subscribe / buy credits) when the user
lands there. Same exceptions fire on REST and SSE error paths.
import webbrowserfrom predev_api import ( PredevAPIError, AuthenticationError, RateLimitError, SubscriptionRequiredError, InsufficientCreditsError, QueueFullError, BatchTooLargeError,)try: result = predev.browser_agent(tasks)except InsufficientCreditsError as e: # Subscription is fine, balance is too low — send the user to the credits modal. if e.action_url: webbrowser.open(e.action_url)except SubscriptionRequiredError as e: # Trial limit hit — send the user to the subscribe modal. if e.action_url: webbrowser.open(e.action_url)except AuthenticationError: # 401 — invalid or missing API key ...except RateLimitError: # 429 RATE_LIMITED — back off and retry ...except QueueFullError: # 429 QUEUE_FULL — wait for in-flight tasks to drain ...except BatchTooLargeError: # 400 — split into smaller batches ...except PredevAPIError as e: print(e)
Exception
HTTP
code
SubscriptionRequiredError
402
SUBSCRIPTION_REQUIRED
InsufficientCreditsError
402
INSUFFICIENT_CREDITS
RateLimitError
429
RATE_LIMITED
QueueFullError
429
QUEUE_FULL
BatchTooLargeError
400
BATCH_TOO_LARGE
AuthenticationError
401
—
PredevAPIError
other
—
Mid-stream errors on the SSE stream raise the same typed exceptions — a
for msg in client.browser_agent(..., stream=True): loop wrapped in
try/except is enough.