# First request

> The two ways to call /v1, how to pick the output, and how to read errors and retry safely.

**TL;DR**: `POST /v1` with a JSON body is the main way in. `GET /v1?url=` is
the paste-a-URL way. Read `X-Credits-Charged` and `X-Billing` on every
answer. Retry with the same `Idempotency-Key`.

Set your key first:

```sh
export MEG_API_KEY='meg_sk_your_key_here'
```

## Two ways in

`POST /v1` takes one JSON object. A target URL with its own query string
needs no encoding:

```sh tab="cURL"
: "${MEG_API_KEY:?Set MEG_API_KEY first}"
# export MEG_API_KEY=YOUR_KEY

curl -X POST https://get.megalania.io/v1 \
  -H "Authorization: Bearer $MEG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)" \
  -d '{"url":"https://docs.megalania.io/start/quickstart","response_types":"markdown"}' \
  --fail-with-body -D - -o page.md
```
```python tab="Python"
# export MEG_API_KEY=YOUR_KEY

import os
import uuid

import requests

resp = requests.post(
    "https://get.megalania.io/v1",
    headers={"Authorization": f"Bearer {os.environ['MEG_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
        "url": "https://docs.megalania.io/start/quickstart",
        "response_types": "markdown",
    },
    timeout=90,
)
print(resp.status_code, resp.headers.get("X-Credits-Charged"), resp.headers.get("X-Route"))
print(resp.text[:500])
```
```js tab="Node.js"
// export MEG_API_KEY=YOUR_KEY

const res = await fetch("https://get.megalania.io/v1", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MEG_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "url": "https://docs.megalania.io/start/quickstart",
    "response_types": "markdown"
  }),
});
console.log(res.status, res.headers.get("x-credits-charged"), res.headers.get("x-route"));
console.log((await res.text()).slice(0, 500));
```
```go tab="Go"
// export MEG_API_KEY=YOUR_KEY

package main

import (
	"crypto/rand"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{"url":"https://docs.megalania.io/start/quickstart","response_types":"markdown"}`)
	req, err := http.NewRequest("POST", "https://get.megalania.io/v1", body)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("MEG_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Idempotency-Key", rand.Text())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	page, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.StatusCode, resp.Header.Get("X-Credits-Charged"), len(page))
}
```

[Open in Playground](https://app.megalania.io/#url=https%3A%2F%2Fdocs.megalania.io%2Fstart%2Fquickstart&response_types=markdown)

`GET /v1` takes the same parameters in the query. Put `url` last and paste
it as it is:

```sh
curl -sS -H "Authorization: Bearer $MEG_API_KEY" \
  "https://get.megalania.io/v1?response_types=markdown&url=https://docs.megalania.io/start/quickstart"
```

## Pick the output

`response_types` decides what you get back. One type is the body itself.
Several types come back as `multipart/mixed`, one part each, from one fetch.

| Type | What you get |
| -- | -- |
| `html` | the page, the default |
| `markdown` | the main content as Markdown, for an LLM |
| `text` | the same content without markup |
| `links` | every link on the page, as JSON |
| `metadata` | title, description, canonical, OpenGraph and JSON-LD, as JSON |
| `page_data` | the data the page embeds for its scripts, as JSON |
| `compact_html` | the page's HTML without scripts, styles and noise; selectors still match |
| `inspect` | the page's structure, with ready `extract` rules, as JSON |
| `json` | the fields your `extract` rules read |

[Fetch, extract and lists](/guides/fetch) has every parameter.

## Read the answer

- **`200` with the page.** `X-Credits-Charged` is what it cost.
- **`422` with `error.code` `blocked`.** The site blocked every route we
  tried. `X-Billing: blocked` says you paid nothing, `X-Hops` lists the
  tries, and `X-Untried` names a route left to try. A block never comes as
  a `200`.
- **Anything else.** The body is JSON: `error.code`, `error.message` and,
  on a 400, `error.field`. The message says what to change. You are never
  charged for it. [Troubleshooting](/start/troubleshooting) has the fix by
  symptom, and [Error codes](/reference/errors) lists every code.

## Retry safely

Send `Idempotency-Key` with your own id, such as a UUID. If the answer is
lost, send the same request with the same key. Inside 24 hours a repeat is a
free 409 `replayed`: your first call went through. On a 429 or a 503 `busy`, wait
the seconds in `Retry-After`, then send the same request again.

## Scrape, extract and batch the Lab

Three first calls against the Lab, our test site: one page, rows from a list
page, and a batch of both. Each one runs as pasted once `MEG_API_KEY` is set.
The dashboard's **SDKs & code** page shows the same code.

**One page as Markdown**

```sh
curl -sS -i https://get.megalania.io/v1 \
  -H "Authorization: Bearer $MEG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)" \
  -d '{"url": "https://lab.megalania.io/article", "response_types": "markdown"}'
```

**Rows from a list page**

```sh
curl -sS -i https://get.megalania.io/v1 \
  -H "Authorization: Bearer $MEG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)" \
  -d '{"url": "https://lab.megalania.io/cards", "response_types": "json", "extract": "items:.card{title:h2|price:.price|url:a@href}*"}'
```

**Many pages in one batch**

```sh
curl -sS -i https://api.megalania.io/v1/batches \
  -H "Authorization: Bearer $MEG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)" \
  -d '{"urls": ["https://lab.megalania.io/article", "https://lab.megalania.io/cards"],"response_types": "markdown"}'
```
