> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pre.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Four copy-paste examples: curl, TypeScript, Python, MCP.

<Card title="Get your API key" icon="key" href="https://pre.dev/projects/key" horizontal>
  Sign in once at [pre.dev/projects/key](https://pre.dev/projects/key) and copy your key. Set it as `PREDEV_API_KEY` before running any of the examples below.
</Card>

Every example below:

* uses your `PREDEV_API_KEY` env var
* hits the live API at `https://api.pre.dev`
* extracts the H1 from `example.com` as the simplest possible task

## 1. curl

```bash theme={null}
export PREDEV_API_KEY=...   # from pre.dev/projects/key
curl -X POST https://api.pre.dev/browser-agent \
  -H "Authorization: Bearer $PREDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tasks": [{
      "url": "https://example.com",
      "instruction": "Extract the heading.",
      "output": {
        "type": "object",
        "properties": { "heading": { "type": "string" } },
        "required": ["heading"]
      }
    }]
  }'
```

## 2. TypeScript

```ts theme={null}
import { PredevAPI } from 'predev-api';

const client = new PredevAPI({ apiKey: process.env.PREDEV_API_KEY! });

const result = await client.browserAgent([
  {
    url: 'https://example.com',
    instruction: 'Extract the heading.',
    output: {
      type: 'object',
      properties: { heading: { type: 'string' } },
      required: ['heading'],
    },
  },
]);
console.log(result.results[0].data); // { heading: 'Example Domain' }
```

## 3. Python

```python theme={null}
import os
from predev_api import PredevAPI

client = PredevAPI(api_key=os.environ["PREDEV_API_KEY"])

result = client.browser_agent([
    {
        "url": "https://example.com",
        "instruction": "Extract the heading.",
        "output": {
            "type": "object",
            "properties": {"heading": {"type": "string"}},
            "required": ["heading"],
        },
    }
])
print(result["results"][0]["data"])  # {'heading': 'Example Domain'}
```

## 4. MCP (Claude Code, Cursor)

Add pre.dev as an MCP server. For Claude Code:

```bash theme={null}
claude mcp add --transport http predev https://api.pre.dev/mcp
```

For Cursor and other editors, add the HTTP server to your MCP config:

```json theme={null}
{
  "mcpServers": {
    "predev": {
      "url": "https://api.pre.dev/mcp"
    }
  }
}
```

On first use a browser tab opens — sign in to pre.dev to authorize.
Then your agent gets a `browser_agent` tool it can call directly.
Example prompt to the agent:

> Use the `browser_agent` tool to extract the product title and price
> from [https://www.apple.com/iphone-17-pro/](https://www.apple.com/iphone-17-pro/) and return
> the JSON.

Full MCP reference: [MCP Tool](/browser-agents/mcp-tool)

## What happens under the hood

1. Your POST lands and your tasks are queued.
2. Each task is dispatched to an isolated, sandboxed browser.
3. An AI planner drives the browser through navigation, actions, and
   extraction.
4. The result streams back as structured JSON, validated against your
   `output` schema.
5. Billed per successful task. Failed tasks are free.

## Streaming + async modes

The quickstart uses sync mode (one HTTP request, one JSON response).
For long-running task sets, flip to async:

```bash theme={null}
# Async: returns immediately with batchId, poll for progress
curl -X POST https://api.pre.dev/browser-agent \
  -H "Authorization: Bearer $PREDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "async": true, "tasks": [...] }'
# → { "id": "69df...", "status": "processing" }

# Poll for the run
curl https://api.pre.dev/browser-agent/$BATCH_ID \
  -H "Authorization: Bearer $PREDEV_API_KEY"
```

Or Server-Sent Events for live per-step updates:

```bash theme={null}
curl -N -X POST https://api.pre.dev/browser-agent \
  -H "Authorization: Bearer $PREDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "stream": true, "tasks": [...] }'
# → event: task_event ... \n event: task_result ... \n event: done
```

Full wire format: [Run a Task](/browser-agents/api/run-task)
