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

# Search

> Search returns ranked web pages with their text already extracted, ready for a model to cite. Sample code, cost per call, key parameters and gotchas.

Search returns ranked web pages with their text already extracted, ready for a model to cite.

## Run a search

This sample runs one search with no account or API key and prints the top 3 results as a numbered block you can paste into a prompt:

```python Python theme={"system"}
from keenable import Keenable

client = Keenable()  # keyless: no API key needed to try it
results = client.search("fastest inference providers 2026", max_results=3)
print(results.to_context())
```

```typescript TypeScript theme={"system"}
import { Keenable } from "keenable";

async function main() {
  const client = new Keenable(); // keyless: no API key needed to try it
  const results = await client.search("fastest inference providers 2026", { maxResults: 3 });
  console.log(results.toContext());
}

main();
```

```go Go theme={"system"}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/keenableai/keenable-sdk/go"
)

func main() {
	client, err := keenable.New(nil) // keyless: no API key needed to try it
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	results, err := client.Search(context.Background(), "fastest inference providers 2026",
		&keenable.SearchOptions{MaxResults: 3})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(results.ToContext(nil))
}
```

```bash curl theme={"system"}
curl -X POST https://api.keenable.ai/v1/search/public \
  -H "Content-Type: application/json" \
  -H "X-Keenable-Title: My App" \
  -d '{"query": "fastest inference providers 2026", "max_results": 3}'
```

You see one `[n] Title (url)` header per result, followed by the page text:

```text Example output · results vary theme={"system"}
[1] Hugging Face Inference Providers · Supported Models (https://huggingface.co/inference)
…

[2] Fastest LLM Inference Provider 2026: TTFT, tok/s, p99 (https://openbenchmarks.com/inference/fastest-inference-provider) - published 2026-09-03T00:00:00Z
Baseten recorded the lowest end-to-end p99 latency at 3.23 seconds on this run, with a median of 331 ms…

[3] Best LLM Inference Providers Compared for 2026 - SiliconFlow (https://siliconflow.com/articles/the-best-inference-provider-for-llms)
…
```

Your agent cites sources by number, and you map each number back to its URL.

## Cost

Each search is billed by the mode that served it. Keyless calls cost no credits. [Rate limits](https://docs.keenable.ai/rate-limits.md) cap them instead.

| Mode | What you get | SKU |
| - | - | - |
| `pro` (default) | Deeper retrieval | `search.pro` |
| `realtime` | The fastest results | `search.realtime` |

Prices are per organization. Read what a call cost from the `usage` object in the response. See [Credits](https://docs.keenable.ai/credits.md#what-a-call-costs) for the allowance and how usage is reported.

## Key parameters

This sample limits results to one site and to pages published since 1 January 2026, and returns 5 results:

```python Python theme={"system"}
from keenable import Keenable

client = Keenable()  # keyless: no API key needed to try it
results = client.search(
    "post-training quantization results",
    site="arxiv.org",
    published_after="2026-01-01",
    max_results=5,
)
for result in results:
    print(result.title)
    print(result.url)
```

```typescript TypeScript theme={"system"}
import { Keenable } from "keenable";

async function main() {
  const client = new Keenable(); // keyless: no API key needed to try it
  const results = await client.search("post-training quantization results", {
    site: "arxiv.org",
    publishedAfter: "2026-01-01",
    maxResults: 5,
  });
  for (const result of results.results) {
    console.log(result.title);
    console.log(result.url);
  }
}

main();
```

```go Go theme={"system"}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/keenableai/keenable-sdk/go"
)

func main() {
	client, err := keenable.New(nil) // keyless: no API key needed to try it
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	results, err := client.Search(context.Background(), "post-training quantization results",
		&keenable.SearchOptions{
			Site:           "arxiv.org",
			PublishedAfter: "2026-01-01",
			MaxResults:     5,
		})
	if err != nil {
		log.Fatal(err)
	}
	for _, result := range results.Results {
		fmt.Println(result.Title)
		fmt.Println(result.URL)
	}
}
```

```bash curl theme={"system"}
curl -X POST https://api.keenable.ai/v1/search/public \
  -H "Content-Type: application/json" \
  -H "X-Keenable-Title: My App" \
  -d '{
    "query": "post-training quantization results",
    "site": "arxiv.org",
    "published_after": "2026-01-01",
    "max_results": 5
  }'
```

You see 5 titles and URLs, all on `arxiv.org`.

| Parameter | What it does | Example |
| - | - | - |
| `query` | The search query. Required. | `"post-training quantization results"` |
| `site` | Restricts results to one site. | `"arxiv.org"` |
| `published_after` / `published_before` | Keeps pages published at or after / at or before this point in time. Accepts a date, an ISO 8601 timestamp or a relative delta such as `7d`. | `"2026-01-01"` |
| `acquired_after` / `acquired_before` | Keeps pages Keenable acquired at or after / at or before this point in time. Same formats as above. | `"30d"` |
| `max_results` | Maximum number of results, 1 to 50. Defaults to 10. | `5` |
| `mode` | `pro` for deeper retrieval, `realtime` for the fastest results. Picks the SKU. | `"realtime"` |
| `snippet_max_length` | Maximum length of each result's `snippet`, 180 to 10000 characters. | `500` |
| `disable_cards` | Set to `true` to replace cards (results Keenable writes for prices, exchange rates or company facts) with ordinary web pages. Defaults to `false`. | `true` |

A date on a `_before` bound covers the whole day in UTC. See [Date and time filters](https://docs.keenable.ai/api-reference/search.md#date-and-time-filters) for every accepted format.

In SDK 0.1.x, the Python and TypeScript clients accept only `pro` for `mode`, and no SDK sends `disable_cards`. To use `realtime` from those clients, or `disable_cards` from any SDK, call the HTTP API. See [SDKs](https://docs.keenable.ai/sdks.md#methods).

## Gotchas

> [!WARNING]
>
> Over raw HTTP, `published_at` is an ISO 8601 string on Search but Unix seconds on [Fetch](https://docs.keenable.ai/products/fetch.md). Parse the two differently if your code reads both responses.

Read page text from `snippet`. The `description` field is deprecated and always empty; see [Versioning and deprecation](https://docs.keenable.ai/versioning.md).

## Next steps

* [Search API reference](https://docs.keenable.ai/api-reference/search.md): every request parameter and response field.
* [Fetch](https://docs.keenable.ai/products/fetch.md): read the full text of a page you found.
* [SDKs](https://docs.keenable.ai/sdks.md): install the Python, TypeScript or Go client.
* [Errors](https://docs.keenable.ai/errors.md): what each status code means and how to fix it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.