# Scrape a URL (/docs/reference/scrape)

Scrapes one URL and returns its content. If it takes longer than timeout, the response is a 202 with a scrape ID and status URL to poll, with or without an API key; once completedAt is set, the scrape status carries the document as data.

`POST /v2/scrape`

An API key is optional; without one the caller is anonymous.

## Example request

```sh
curl -X POST 'https://api.elisebot.dev/v2/scrape' \
  -H "Authorization: Bearer $ELISEBOT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "…"
  }'
```

## Request body

`application/json`, required.

Type: `ScrapeRequest`

- `requestOptions` (RequestOptions): Options for the request sent to the URL.
  - `headers` (array of RequestHeader or null): Headers to send, in this order and exactly as written. Omit to use the defaults. Redirect hops also carry the cookies the site sets. With headers, redirects to another site are not followed.
    - `name` (string, required): The header name. At least 1 characters.
    - `value` (string, required): The header value.
- `responseOptions` (ResponseOptions): Options for the content returned for the URL.
  - `format` (string): The format to return the page in. One of `html`, `markdown`. Default `html`.
  - `onlyMainContent` (boolean): Return only the page's main content, without navigation, headers and footers. Default `false`.
- `timeout` (integer (int64)): Maximum time to wait, in milliseconds. Default `10000`. Minimum 1000. Maximum 20000.
- `url` (string, required): The URL to scrape. At least 1 characters.

## Responses

### 200

OK.

Type: `ScrapeResponse`

- `data` (Document, required)
  - `html` (string): The page HTML, converted to UTF-8; only its main content with responseOptions.onlyMainContent.
  - `markdown` (string): The page as Markdown.
  - `metadata` (DocumentMetadata, required)
    - `contentType` (string): The response content type.
    - `error` (string): Why the scrape failed.
    - `errorCode` (string): A machine-readable error code.
    - `sourceURL` (string, required): The requested URL.
    - `statusCode` (integer (int64)): The HTTP status code.
    - `url` (string, required): The final URL after redirects.
- `success` (boolean, required): Always true. One of `true`.

### 202

The page was not scraped within timeout. The scrape keeps running: poll url, also sent as Location, for the document.

Headers:

- `Location` (string): The scrape status URL, the same as url.

Type: `ScrapeAcceptedResponse`

- `id` (string, required): The scrape ID.
- `success` (boolean, required): Always true. One of `true`.
- `url` (string, required): The URL to check the scrape status.

### 400

MALFORMED_REQUEST: The request body is missing or is not valid JSON.

Type: `MalformedRequestResponse`

- `code` (string, required): A machine-readable error code. One of `MALFORMED_REQUEST`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 401

UNAUTHORIZED: The API key is invalid or revoked; API_KEY_REQUIRED: This endpoint needs an API key; INVALID_ACCESS_TOKEN: The OAuth access token is unknown, expired or revoked, or was sent to an endpoint other than /mcp, the only one it works on.

Type: `UnauthorizedResponse`

- `code` (string, required): A machine-readable error code. One of `UNAUTHORIZED`, `API_KEY_REQUIRED`, `INVALID_ACCESS_TOKEN`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 402

INSUFFICIENT_CREDITS: The credit balance does not cover the request's URLs.

Type: `PaymentRequiredResponse`

- `code` (string, required): A machine-readable error code. One of `INSUFFICIENT_CREDITS`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 408

REQUEST_TIMEOUT: The request body took too long to arrive.

Type: `RequestTimeoutResponse`

- `code` (string, required): A machine-readable error code. One of `REQUEST_TIMEOUT`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 413

PAYLOAD_TOO_LARGE: The request body is too large.

Type: `PayloadTooLargeResponse`

- `code` (string, required): A machine-readable error code. One of `PAYLOAD_TOO_LARGE`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 415

UNSUPPORTED_MEDIA_TYPE: The request body must be JSON.

Type: `UnsupportedMediaTypeResponse`

- `code` (string, required): A machine-readable error code. One of `UNSUPPORTED_MEDIA_TYPE`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 422

VALIDATION_FAILED: One or more fields are invalid; TOO_MANY_URLS: The request has more URLs than your rate limit allows; IDEMPOTENCY_CONFLICT: The Idempotency-Key was already used with a different request.

Type: `ValidationFailedResponse`

- `code` (string, required): A machine-readable error code. One of `VALIDATION_FAILED`, `TOO_MANY_URLS`, `IDEMPOTENCY_CONFLICT`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 429

RATE_LIMITED: Rate limit exceeded, retry after Retry-After seconds.

Headers:

- `Retry-After` (integer): Seconds to wait before retrying. Minimum 1.

Type: `TooManyRequestsResponse`

- `code` (string, required): A machine-readable error code. One of `RATE_LIMITED`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.

### 500

INTERNAL_ERROR: Something went wrong on our side, try again.

Type: `InternalErrorResponse`

- `code` (string, required): A machine-readable error code. One of `INTERNAL_ERROR`.
- `details` (array of ValidationErrorDetail or null): The invalid fields.
  - `location` (string): Where the error occurred, e.g. body.urls[3].
  - `message` (string): What went wrong.
  - `value` (any): The rejected value.
- `error` (string, required): A human-readable message.
- `success` (boolean, required): Always false. One of `false`.
