# Grabber API docs

> Get started with the Grabber API: one GET request turns any URL into Markdown, HTML, text or links. Quickstart, code samples, parameters and errors.

Grabber loads one web page and returns it as markdown, HTML, text, links, or
the raw body. It is made for AI agents and scripts.

There is one endpoint, `GET /fetch`. Every call needs
`Authorization: Bearer <key>`. Create a key at
https://dashboard.grabber.sh/keys. Keys start with `gsh_`. A key goes in the
header only: `?key=` is refused like any other unknown parameter.

## Quickstart

1. **Create an account.** [Sign up](https://dashboard.grabber.sh/signup) and verify your email. You get $1 of free credit, enough for 1,000 pages, with no card.
2. **Create an API key.** Open [API keys](https://dashboard.grabber.sh/keys) and create one. It starts with `gsh_` and is shown once, so store it as `GRABBER_API_KEY`.
3. **Make a request.** Call `GET /fetch` with the key in the `Authorization` header and the page in `url`. The examples below are ready to run.

## Your first request

Ask for Markdown and get the JSON envelope back: what was loaded, from where, and the content.

### cURL

```bash
curl -G https://api.grabber.sh/fetch \
  -H "Authorization: Bearer $GRABBER_API_KEY" \
  --data-urlencode "url=https://example.com/start" \
  -d "formats=markdown"
```

### Python

```python
import os
import requests

response = requests.get(
    "https://api.grabber.sh/fetch",
    params={"url": "https://example.com/start", "formats": "markdown"},
    headers={"Authorization": f"Bearer {os.environ['GRABBER_API_KEY']}"},
    timeout=130,
)
response.raise_for_status()
print(response.text)
```

### Node.js

```javascript
const params = new URLSearchParams({ url: 'https://example.com/start', formats: 'markdown' })

const response = await fetch(`https://api.grabber.sh/fetch?${params}`, {
  headers: { Authorization: `Bearer ${process.env.GRABBER_API_KEY}` },
  signal: AbortSignal.timeout(130_000),
})
if (!response.ok) throw new Error(`Grabber answered ${response.status}`)
console.log(await response.text())
```

### Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"time"
)

func main() {
	query := url.Values{"url": {"https://example.com/start"}, "formats": {"markdown"}}
	req, _ := http.NewRequest("GET", "https://api.grabber.sh/fetch?"+query.Encode(), nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("GRABBER_API_KEY"))

	client := &http.Client{Timeout: 130 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status)
	fmt.Println(string(body))
}
```

### PHP

```php
<?php
$query = http_build_query(['url' => 'https://example.com/start', 'formats' => 'markdown']);

$ch = curl_init("https://api.grabber.sh/fetch?$query");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('GRABBER_API_KEY')],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 130,
]);
$body = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), "\n", $body;
```

### Response

```json
{
  "status": 200,
  "message": "OK",
  "data": {
    "url": "https://example.com/start",
    "fetch": {
      "loadedUrl": "https://example.com/final",
      "loadedTime": "2026-10-21T16:36:49.840Z",
      "httpStatusCode": 200,
      "contentLengthBytes": 9,
      "contentType": "text/html",
      "encoding": "utf8"
    },
    "markdown": "ok"
  }
}
```

## Just the content

Add `unwrap=true` and the body is the content itself, with its own content type: Markdown here. That is often what you want to hand to a model.

```bash
curl -G https://api.grabber.sh/fetch \
  -H "Authorization: Bearer $GRABBER_API_KEY" \
  --data-urlencode "url=https://example.com/" \
  -d "formats=markdown" \
  -d "unwrap=true"
```

With no envelope, the response headers are the only place the spend is reported: `X-Grabber-Cost` says what the request cost and `X-Grabber-Balance` what is left.

## Reference

- [Authentication](https://grabber.sh/docs/authentication): API keys, the Authorization header and 401s.
- [Parameters](https://grabber.sh/docs/parameters): Every query parameter and every response field.
- [Errors](https://grabber.sh/docs/errors): Each error code, what it means and what to do.
- [Pricing and limits](https://grabber.sh/docs/pricing-and-limits): What is charged, credit, and request limits.
- [MCP server](https://grabber.sh/mcp): Give Claude, Cursor and other agents the same API as a tool.
- [OpenAPI](https://grabber.sh/openapi.json): The full spec, for code generators and agents.
