> ## 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=...   # solo userId or enterprise org API 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 (one-line in `~/.claude.json` or
`~/.cursor/mcp.json`):

```json theme={null}
{
  "mcpServers": {
    "pre.dev": {
      "command": "npx",
      "args": ["-y", "@predotdev/mcp-server"],
      "env": { "PREDEV_API_KEY": "..." }
    }
  }
}
```

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. POST lands, we check credits + enqueue your tasks in Mongo.
2. Scheduler dispatches each task to a sandbox (Daytona → E2B → Modal
   fallback chain, cheapest first).
3. Inside the sandbox, a planner LLM (`gemini-2.5-flash-lite`) drives
   Playwright through navigation + actions + extraction.
4. 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 batches, 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 batch
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)
