> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrape.st/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Authenticating requests to the Scrapest Service

Most endpoints in the Scrapest Service are protected and require authentication.

## API Key

To authenticate your requests, you must include the `x-api-key` header with a valid API key.

<ParamField header="x-api-key" type="string" required>
  Your unique API key generated via the Dashboard.
</ParamField>

## Generate API Key

To get started, you need to generate an API key via the **Dashboard**.

1. **Log in** to the Scrapest Dashboard at [admin.scrape.st](https://admin.scrape.st)
2. **Navigate to API Keys** in the sidebar
3. **Click "Generate New API Key"**
4. **Name your key** (e.g., "My First Integration")
5. **Copy the key** and store it securely

### API Key Features

* **Dashboard Management**: Create, rename, and delete API keys through the dashboard
* **Usage Tracking**: Monitor API calls and usage statistics
* **Security**: Keys are tied to your user account and permissions
* **Rate Limits**: Each key has its own rate limits and quotas

## Live Demo

You can interact with our live Scrapest instance at:

`https://scrape.st/`

<Note>
  Authentication is required for all state-changing operations and sensitive
  data access on the live instance.
</Note>

### Example Request

<CodeGroup>
  ```bash curl theme={null}
  curl -X GET https://scrape.st/webhook \
    -H "x-api-key: your-api-key"
  ```

  ```javascript fetch theme={null}
  fetch("https://scrape.st/webhook", {
    method: "GET",
    headers: {
      "x-api-key": "your-api-key",
    },
  })
    .then((response) => response.json())
    .then((data) => console.log(data));
  ```

  ```python python theme={null}
  import requests

  url = "https://scrape.st/webhook"
  headers = {
      "x-api-key": "your-api-key"
  }

  response = requests.get(url, headers=headers)
  print(response.json())
  ```

  ```go go theme={null}
  package main

  import (
  	"fmt"
  	"io/ioutil"
  	"net/http"
  )

  func main() {
  	url := "https://scrape.st/webhook"
  	method := "GET"

  	client := &http.Client{}
  	req, err := http.NewRequest(method, url, nil)

  	if err != nil {
  		fmt.Println(err)
  		return
  	}
  	req.Header.Add("x-api-key", "your-api-key")

  	res, err := client.Do(req)
  	if err != nil {
  		fmt.Println(err)
  		return
  	}
  	defer res.Body.Close()

  	body, err := ioutil.ReadAll(res.Body)
  	if err != nil {
  		fmt.Println(err)
  		return
  	}
  	fmt.Println(string(body))
  }
  ```

  ```rust rust theme={null}
  use reqwest::header;

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = reqwest::Client::new();

      let res = client
          .get("https://scrape.st/webhook")
          .header("x-api-key", "your-api-key")
          .send()
          .await?
          .text()
          .await?;

      println!("{}", res);
      Ok(())
  }
  ```
</CodeGroup>

### Error Responses

* **401 Unauthorized**: Missing or invalid authentication headers (`x-api-key` or `x-admin-key`).
* **403 Forbidden**: API key limit reached (when generating keys).
* **429 Too Many Requests**: Standard API key has exceeded the rate limit.

```json 401 Unauthorized theme={null}
{
  "status": "error",
  "error": "Missing or invalid authentication header"
}
```

```json 429 Too Many Requests theme={null}
{
  "status": "error",
  "error": "Too many requests. Please try again later.",
  "retry_after": 60
}
```
