Skip to main content

Browser Agents

Watch the live browser

Get an authenticated WebSocket URL for available browser frames in a run you own.

gethttps://api.pre.dev/browser-agent/{id}/wsTry it

Request the live-view URL using your API key and an existing run ID:

curl --fail-with-body "https://api.pre.dev/browser-agent/$BATCH_ID/ws" \
  -H "Authorization: Bearer $PREDEV_API_KEY"

The response is { "url": "wss://…" }. Connect to that URL exactly as returned; it includes the authorization needed for the live view. Treat it as a credential-bearing URL and keep it out of public logs.

Frames

Where live capture is available, JSON messages with type: "frame" contain:

FieldMeaning
taskIndexZero-based index within the run
b64Base64-encoded JPEG image
w, hCapture metadata dimensions, when available
tsUnix timestamp in milliseconds

Filter for type: "frame" before reading those fields. For a preview image, use data:image/jpeg;base64, followed by b64 as the image source.

Frames are a live visual feed, not a durable recording, task-control channel, or completion signal. Some execution paths do not produce live frames. Use SSE or polling for authoritative task state and includeEvents=true for available screenshot history.

A returned URL does not guarantee that a frame will arrive. Current SDKs and MCP tools do not have a wrapper for this endpoint.

Errors

StatusWhen
400id is not a valid run ID
401Missing or invalid key
404No run with this ID in your account, or no live stream for it

Each status has an example body in the response examples. See errors and retries.

curl -X GET "https://api.pre.dev/browser-agent/string/ws"
fetch("https://api.pre.dev/browser-agent/string/ws", {  method: "GET"})
package mainimport (  "fmt"  "net/http"  "io/ioutil")func main() {  url := "https://api.pre.dev/browser-agent/string/ws"  req, _ := http.NewRequest("GET", url, nil)  res, _ := http.DefaultClient.Do(req)  defer res.Body.Close()  body, _ := ioutil.ReadAll(res.Body)  fmt.Println(res)  fmt.Println(string(body))}
import requestsurl = "https://api.pre.dev/browser-agent/string/ws"response = requests.request("GET", url)print(response.text)
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.net.http.HttpResponse.BodyHandlers;import java.time.Duration;HttpClient client = HttpClient.newBuilder()  .connectTimeout(Duration.ofSeconds(10))  .build();HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()  .uri(URI.create("https://api.pre.dev/browser-agent/string/ws"))  .GET()  .build();try {  HttpResponse<String> response = client.send(requestBuilder.build(), BodyHandlers.ofString());  System.out.println("Status code: " + response.statusCode());  System.out.println("Response body: " + response.body());} catch (Exception e) {  e.printStackTrace();}
using System;using System.Net.Http;using System.Text;var client = new HttpClient();var response = await client.GetAsync("https://api.pre.dev/browser-agent/string/ws");var responseBody = await response.Content.ReadAsStringAsync();
use reqwest::{Result, Client};async fn main() -> Result<()> {  let client = Client::new();  let url = "https://api.pre.dev/browser-agent/string/ws";  let res = client    .get(url)    .send()    .await?    .text()    .await?;  println!("{}", res);  Ok(())}
{  "url": "wss://browser-worker.example/ws/507f1f77bcf86cd799439011?token=3f1c0b9e2d4a7c58"}
GET
/browser-agent/{id}/ws

Authorization

AuthorizationBearer <token>

Your pre.dev workspace API key (pdk_...) from Integrations, Built-in tab: https://pre.dev/projects/integrations?tab=built-in

In: header

Path Parameters

id*string

24-character record ID.

Match^[a-fA-F0-9]{24}$

Response Body

application/json

Connect to the returned WebSocket URL.

TypeScript Definitions

Use the response body type in TypeScript.

application/json

application/json

application/json

Was this page helpful?