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

# Zoek-API

> Doorzoek het web met natuurlijke taal en krijg gestructureerde links — de AI-zoek-API van Olostep.

Het Olostep `/v1/searches` eindpunt stelt je in staat om het web te doorzoeken met een natuurlijke taalvraag en een gededupliceerde lijst van relevante links met titels en beschrijvingen terug te krijgen.

* Verstuur een vraag in gewoon Engels
* Krijg gestructureerde links van over het hele web terug
* Optioneel elke geretourneerde URL in één keer scrapen en `markdown_content` / `html_content` direct in de respons opnemen
* Filter op domein, beheer het aantal resultaten, en begrens de scraping tijd

Het zal semantisch naar de query zoeken over het web en resultaten teruggeven.

Voor API-details, zie de [Zoek Eindpunt API Referentie](/api-reference/searches/create).

## Installatie

<CodeGroup>
  ```python Python theme={null}
  pip install olostep
  ```

  ```javascript Node theme={null}
  npm install olostep
  ```

  ```bash cURL theme={null}
  # curl is standaard beschikbaar op macOS, Linux en Windows
  ```

  ```javascript Node (API) theme={null}
  npm install node-fetch
  ```

  ```bash Python (API) theme={null}
  pip install requests
  ```
</CodeGroup>

## Basisgebruik

Stuur een natuurlijke taalvraag en ontvang een lijst van relevante links.

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  search = client.searches.create("Best Answer Engine Optimization startups")

  print(search.id, len(search.links))
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const search = await client.searches.create('Best Answer Engine Optimization startups')

  console.log(search.id, search.links.length)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/searches" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Best Answer Engine Optimization startups"
    }'
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/searches', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      query: 'Best Answer Engine Optimization startups'
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/searches"
  payload = {
    "query": "Best Answer Engine Optimization startups"
  }
  headers = {"Authorization": "Bearer <YOUR_API_KEY>", "Content-Type": "application/json"}

  response = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(response.json(), indent=2))
  ```
</CodeGroup>

## Verzoekparameters

| Veld              | Type      | Vereist | Standaard | Beschrijving                                                                                                                                            |
| ----------------- | --------- | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`           | string    | ja      | —         | De zoekvraag in natuurlijke taal.                                                                                                                       |
| `limit`           | integer   | nee     | `12`      | Maximum aantal links om te retourneren na deduplicatie. Moet tussen `1` en `25` zijn.                                                                   |
| `include_domains` | string\[] | nee     | `[]`      | Beperk resultaten tot deze domeinen. Alleen kale hosts — voorloop `http(s)://` en afsluitende slashes worden automatisch verwijderd.                    |
| `exclude_domains` | string\[] | nee     | `[]`      | Sluit resultaten van deze domeinen uit. Alleen kale hosts — voorloop `http(s)://` en afsluitende slashes worden automatisch verwijderd.                 |
| `scrape_options`  | object    | nee     | —         | Wanneer opgegeven, wordt elke geretourneerde link ook gescrapet en de inhoud in de respons opgenomen. Zie [scrape\_options](#scrape-options) hieronder. |

### Het aantal resultaten beperken

```json theme={null}
{
  "query": "What's going on with OpenAI's Sora shutting down?",
  "limit": 5
}
```

### Filteren op domein

`include_domains` beperkt resultaten tot een whitelist; `exclude_domains` filtert ongewenste bronnen uit. Ze kunnen gecombineerd worden.

```json theme={null}
{
  "query": "OpenAI Sora shutdown analysis",
  "include_domains": ["nytimes.com", "wsj.com", "bbc.com"],
  "exclude_domains": ["pinterest.com"]
}
```

## scrape\_options

Geef `scrape_options` door om elke geretourneerde URL parallel te scrapen en de gerenderde inhoud direct op elke link in te bedden. Dit bespaart een round-trip per resultaat in vergelijking met het afzonderlijk aanroepen van `/v1/searches` en `/v1/scrapes`.

```json theme={null}
{
  "query": "What's going on with OpenAI's Sora shutting down?",
  "limit": 10,
  "scrape_options": {
    "formats": ["markdown"],
    "remove_css_selectors": "default",
    "timeout": 25
  }
}
```

| Veld                   | Type      | Standaard      | Beschrijving                                                                                                                                                                                                             |
| ---------------------- | --------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `formats`              | string\[] | `["markdown"]` | Uitvoerformaten om aan elke link toe te voegen. Voor `/v1/searches` worden alleen `"html"` en `"markdown"` ondersteund. Geef `["html", "markdown"]` door om beide te ontvangen.                                          |
| `remove_css_selectors` | string    | `"default"`    | Doorgestuurd naar `/v1/scrapes`. `"default"` verwijdert nav/footer/script/style/svg/dialog ruis. Gebruik `"none"` om uit te schakelen, of geef een JSON-geformatteerde array van selectors om te verwijderen.            |
| `timeout`              | integer   | `25`           | Tijdslimiet in **seconden** voor de gehele scrape-fase. Moet tussen `1` en `60` zijn. Zodra deze verstreken is, retourneert de zoekopdracht onmiddellijk — inhoudsvelden zijn `null` voor links die niet voltooid waren. |

### Gedrag

* Alle links worden **parallel** gescrapet. De `timeout` begrenst de hele batch, niet elke individuele link.
* Per-link scrape-fouten (netwerkfouten, individuele pagina time-outs) laten de `markdown_content` / `html_content` van die link als `null` terwijl andere links normaal terugkomen.
* Als de globale `timeout` verstrijkt voordat alle scrapes voltooid zijn, reageert de zoekopdracht onmiddellijk met de links die het heeft — al voltooide scrapes behouden hun inhoud; in-behandeling zijnde komen terug met `null` inhoud.
* Voor `reddit.com/.../comments/...` URL's wordt het verzoek automatisch gerouteerd via de `@olostep/reddit-post` parser en de gestructureerde JSON wordt gerenderd in schone markdown + basis HTML
* Als de gecombineerde inline-inhoud meer dan 9MB overschrijdt, worden inhoudsvelden genuld, `result.size_exceeded` wordt ingesteld op `true`, en je kunt de volledige payload ophalen van `result.json_hosted_url`.

### Voorbeeld met scraping

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  search = client.searches.create(
      query="What's going on with OpenAI's Sora shutting down?",
      limit=5,
      scrape_options={"formats": ["markdown"], "timeout": 25},
  )

  for link in search.links:
      print(link["url"], "—", len(link.get("markdown_content") or ""), "chars")
  ```

  ```js Node theme={null}
  import Olostep, { Format } from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const search = await client.searches.create({
    query: "What's going on with OpenAI's Sora shutting down?",
    limit: 5,
    scrapeOptions: {
      formats: [Format.MARKDOWN],
      timeout: 25
    }
  })

  for (const link of search.links) {
    console.log(link.url, '—', (link.markdown_content || '').length, 'chars')
  }
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/searches" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "What'"'"'s going on with OpenAI'"'"'s Sora shutting down?",
      "limit": 5,
      "scrape_options": {
        "formats": ["markdown"],
        "timeout": 25
      }
    }'
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/searches', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      query: "What's going on with OpenAI's Sora shutting down?",
      limit: 5,
      scrape_options: {
        formats: ['markdown'],
        timeout: 25
      }
    })
  })
  const data = await res.json()
  for (const link of data.result.links) {
    console.log(link.url, '—', (link.markdown_content || '').length, 'chars')
  }
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/searches"
  payload = {
    "query": "What's going on with OpenAI's Sora shutting down?",
    "limit": 5,
    "scrape_options": {
      "formats": ["markdown"],
      "timeout": 25
    }
  }
  headers = {"Authorization": "Bearer <YOUR_API_KEY>", "Content-Type": "application/json"}

  response = requests.post(endpoint, json=payload, headers=headers)
  data = response.json()
  for link in data["result"]["links"]:
    print(link["url"], "—", len(link.get("markdown_content") or ""), "chars")
  ```
</CodeGroup>

## Respons

Je ontvangt een `search` object als antwoord. Het `search` object bevat een `id`, je originele `query`, `credits_consumed`, en een `result` met een lijst van `links`.

```json theme={null}
{
  "id": "search_9bi0sbj9xa",
  "object": "search",
  "created": 1760327323,
  "metadata": {},
  "query": "What's going on with OpenAI's Sora shutting down?",
  "credits_consumed": 10,
  "result": {
    "json_content": "...",
    "json_hosted_url": "https://olostep-storage.s3.us-east-1.amazonaws.com/search_9bi0sbj9xa.json",
    "size_exceeded": false,
    "credits_consumed": 10,
    "links": [
      {
        "url": "https://www.bbc.com/news/articles/c3w3e467ewqo",
        "title": "OpenAI to shut down Sora video platform",
        "description": "OpenAI says it will discontinue its Sora app...",
        "markdown_content": "# OpenAI to shut down Sora video platform\n\nOpenAI says it will discontinue..."
      },
      {
        "url": "https://www.reddit.com/r/OutOfTheLoop/comments/1s2u847/whats_going_on_with_openais_sora_shutting_down/",
        "title": "What's going on with OpenAI's Sora shutting down?",
        "description": "Reddit thread discussing the shutdown.",
        "markdown_content": "# What's going on with OpenAI's Sora shutting down?\n\n*r/OutOfTheLoop · u/rm-minus-r · 1mo ago*\n\n..."
      }
    ]
  }
}
```

Elke link in `result.links` bevat:

| Veld               | Type   | Beschrijving                                                                                                                                                                        |
| ------------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`              | string | De URL van het zoekresultaat.                                                                                                                                                       |
| `title`            | string | De titel van de resultaatpagina.                                                                                                                                                    |
| `description`      | string | Een korte snippet die het resultaat beschrijft.                                                                                                                                     |
| `markdown_content` | string | Markdown-inhoud van de pagina. Alleen aanwezig wanneer `scrape_options.formats` `"markdown"` bevat. `null` als de scrape is mislukt, leeg was, of de globale timeout heeft bereikt. |
| `html_content`     | string | HTML-inhoud van de pagina. Alleen aanwezig wanneer `scrape_options.formats` `"html"` bevat. `null` bij mislukking/timeout.                                                          |

Het volledige resultaat is ook beschikbaar als een gehost JSON-bestand op `result.json_hosted_url` — handig wanneer `result.size_exceeded` `true` is.

## Een eerdere zoekopdracht ophalen

`GET /v1/searches/{search_id}` retourneert wat er op het moment van zoeken is opgeslagen, inclusief eventuele gescrapete inhoud. Het is een pure idempotente read — geen her-scraping, geen her-facturering. Oudere zoekopdrachten zonder `scrape_options` hebben simpelweg geen per-link inhoudsvelden.

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  search = client.searches.get(search_id="search_9bi0sbj9xa")
  print(search.id, len(search.links))
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const search = await client.searches.get('search_9bi0sbj9xa')
  console.log(search.id, search.links.length)
  ```

  ```bash cURL theme={null}
  curl -s "https://api.olostep.com/v1/searches/search_9bi0sbj9xa" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

Zie [Get Search](/api-reference/searches/get) voor volledige details.

## Prijzen

Elke zoekopdracht kost **5 credits** voor de zoekopdracht zelf.

Wanneer `scrape_options` is opgegeven, wordt elke gescrapete pagina gefactureerd tegen het standaard `/v1/scrapes` tarief (meestal 1 credit per pagina; sommige parsers kosten meer). Het totaal wordt geretourneerd in `credits_consumed`.

Voorbeelden:

| Verzoek                                       | `credits_consumed` |
| --------------------------------------------- | ------------------ |
| Alleen zoeken                                 | `5`                |
| Zoeken + 5 gescrapete pagina's (1 credit elk) | `10`               |
