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

# Crawl links

> Discover additional web URLs from one or more seed links before ingesting them as sources.

Use this route when you have one or a few seed URLs and want Fini to discover more web pages before you call [Ingest sources](/en/api-reference/ingest-sources).

<Tip>
  This route discovers URLs only. It does not create source records and it does not ingest content. After you pick the URLs you want, send them to [Ingest sources](/en/api-reference/ingest-sources) with `source: "web"`.
</Tip>

## Headers

<ParamField header="Authorization" type="string" required>
  Bearer token containing your Fini workspace API key. Format: `Bearer fini_...` The key needs `write` scope.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `application/json`
</ParamField>

## Body parameters

<ParamField body="links" type="array" required>
  Seed URLs to crawl.
</ParamField>

<ParamField body="limit" type="integer" default="250">
  Maximum number of discovered URLs to return.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api-prod.usefini.com/v2/documents/public/deep-crawl/links' \
    --header 'Authorization: Bearer fini_your_api_key' \
    --header 'Content-Type: application/json' \
    --data '{
      "links": ["https://help.example.com"],
      "limit": 50
    }'
  ```

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

  response = requests.post(
      "https://api-prod.usefini.com/v2/documents/public/deep-crawl/links",
      headers={
          "Authorization": "Bearer fini_your_api_key",
          "Content-Type": "application/json",
      },
      json={
          "links": ["https://help.example.com"],
          "limit": 50,
      },
  )
  data = response.json()
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api-prod.usefini.com/v2/documents/public/deep-crawl/links",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer fini_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        links: ["https://help.example.com"],
        limit: 50,
      }),
    }
  );
  const data = await response.json();
  ```
</RequestExample>

## Response

<ResponseField name="data" type="array">
  Discovered child URLs.
</ResponseField>

<ResponseField name="message" type="string">
  Success message.
</ResponseField>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": [
      "https://help.example.com/articles/returns",
      "https://help.example.com/articles/shipping"
    ],
    "message": "Successfully crawled parent URLs"
  }
  ```
</ResponseExample>

## Next step

Take the URLs you want from `data`, then call [Ingest sources](/en/api-reference/ingest-sources) with `source: "web"` and place those URLs into `documentIdsToAdd`.

## Errors

<AccordionGroup>
  <Accordion title="400 Bad Request" icon="circle-exclamation">
    The request body is malformed, `links` is missing or empty, or one of the inputs is not a valid URL.
  </Accordion>

  <Accordion title="401 Unauthorized" icon="lock">
    The API key is missing, malformed, revoked, or invalid.
  </Accordion>

  <Accordion title="403 Forbidden" icon="shield-halved">
    The API key does not include the `write` scope.
  </Accordion>

  <Accordion title="500 Internal Server Error" icon="triangle-exclamation">
    Fini failed while crawling one or more seed URLs. Retry once, then narrow the input set to isolate the failing URL.
  </Accordion>
</AccordionGroup>
