# Plain text from any web page

> Extract clean plain text from any web page with one API call: no tags, no scripts, no styles. Built for search, classification and AI. $0.001 per page.

Send a URL and get back the readable content of the page as plain text, with every tag, script and style removed. For search indexes, classifiers and anything that only needs the words.

- $1 free credit, no card
- No subscription
- Failed requests are free

[Get API key](https://dashboard.grabber.sh/signup) · [Read the docs](https://grabber.sh/docs/parameters)

## One request, plain text

With unwrap=true the text is the whole response body, with Content-Type: text/plain.

- No markup to strip yourself
- Ask for text and links together
- Same price as every format

### cURL

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

### Python

```python
import os
import requests

response = requests.get(
    "https://api.grabber.sh/fetch",
    params={"url": "https://example.com/news/launch", "formats": "text", "unwrap": "true"},
    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/news/launch', formats: 'text', unwrap: 'true' })

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/news/launch"}, "formats": {"text"}, "unwrap": {"true"}}
	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/news/launch', 'formats' => 'text', 'unwrap' => 'true']);

$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 body

```text
Example Co. launches its new trail shoe

The Trail Runner 2 weighs 240 grams and ships on November 3.

Pre-orders open today on the Example store, with free returns for 60 days.
```

## How it works

1. **Send the URL.** Call `GET /fetch` with `url` and `formats=text`.
2. **Grabber loads the page.** It follows redirects, loads the page and removes the markup, scripts and styles.
3. **Use the text.** Index it, classify it, embed it or compare it with yesterday. Errors cost nothing.

## What people build with it

### Search indexes

Fill a full-text search engine with the words of each page and nothing else.

### Classification

Run topic, language or sentiment models on clean input instead of HTML.

### Embeddings

Embed pages for similarity search when you do not need their headings or tables.

### Change detection

Compare the text of a page over time, without layout changes showing up as edits.

## Pricing

Prepaid credit, taken one request at a time. Ask for several formats in one request at the price of one.

| Request | Price |
| --- | --- |
| A page | **$0.001** |
| A page with `js_render=true` | **$0.005** |
| Any error | $0 |
| Credit when you sign up | $1, about 1,000 pages |

## Questions

### What is the difference between text and markdown?

Both hold the readable content of the page. Markdown keeps its structure, such as headings, lists, tables and links. Text has no markup at all. Use Markdown for language models and text when you only need the words.

### Can I get the text and the links together?

Yes. Ask for formats=text,links and both come back in the JSON envelope, for $0.001.

### Does it work on pages built with JavaScript?

Yes, with js_render=true. The page runs in a headless browser first, for $0.005 a page.

### What happens when a page will not load?

You get an error with a stable code, such as fetch_failed, and nothing is charged.

## Related

- [URL to Markdown](https://grabber.sh/url-to-markdown): Clean Markdown for LLMs and RAG.
- [Link extractor](https://grabber.sh/link-extractor): Every link on a page, as absolute URLs.
- [Metadata extractor](https://grabber.sh/metadata-extractor): Title, Open Graph tags, JSON-LD and more.
- [All parameters](https://grabber.sh/docs/parameters): Every option of GET /fetch.

## Give your agents the web

Sign up in a minute and fetch your first 1,000 pages for free.

[Get API key](https://dashboard.grabber.sh/signup) · [Read the docs](https://grabber.sh/docs)
