> ## 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.

# API reference

> The HTTP API behind the Keenable CLI, MCP server, and integrations.

Two endpoints sit under everything else Keenable ships — the [CLI](/cli), the [MCP server](/mcp-server), and every [integration](/integrations) call one or both of them. Reach for the HTTP API directly when you are building something none of those cover.

## Base URL

```
https://api.keenable.ai
```

## Authentication

There are three ways in, and the one you pick decides the path you call.

**With an API key**, in the `X-API-Key` header:

```bash theme={"system"}
curl -X POST "https://api.keenable.ai/v1/search" \
  -H "X-API-Key: keen_<your_key>" \
  -H "Content-Type: application/json" \
  -d '{ "query": "typescript best practices" }'
```

`Authorization: Bearer keen_<your_key>` works too, and `X-API-Key` wins if both are present. See [Authentication](/authentication) for obtaining and rotating a key, and for the error responses both endpoints share.

**Without one**, on the `/public` twin of each endpoint:

```bash theme={"system"}
curl -X POST "https://api.keenable.ai/v1/search/public" \
  -H "X-Keenable-Title: My App" \
  -H "Content-Type: application/json" \
  -d '{ "query": "typescript best practices" }'
```

`X-Keenable-Title` names the application making the call. It is **required** on the public endpoints — a request without it is rejected with `400 Missing app identifier` — and it is how keyless traffic is attributed. Values longer than 256 characters are truncated, and `?keenable_title=` carries the same value when a header is not an option.

**Paying per request**, on the `/v1/x402/*` paths, with no key and no account: each call pays \$0.01 in USDC on Base over the x402 protocol. See [Pay per request](/pay-per-request) for the payment flow and a client example.

Parameters and response shapes are identical across all three, so moving between them means changing the path and swapping one header. The keyless tier is what the [CLI](/cli), the [MCP server](/mcp-server), and every [integration](/integrations) fall back to when no key is configured.

## Endpoints

| Endpoint | Method | Path | Keyless path | Pay-per-request path | Returns |
| - | - | - | - | - | - |
| [Search](/api-reference/search) | `POST` | `/v1/search` | `/v1/search/public` | `/v1/x402/search` | Ranked results with URLs, titles, descriptions, and snippets |
| [Fetch](/api-reference/fetch) | `GET` | `/v1/fetch` | `/v1/fetch/public` | `/v1/x402/fetch` | Page content as markdown, with title, description, and author |

Each endpoint page carries the full request and response shape, examples in curl, Python, and TypeScript, and a playground you can call with your own key.

## Limits and billing

Authenticated requests are rate limited per organization rather than per IP — see [Rate limits](/rate-limits) for the numbers — and draw on your [credit](/credits) balance.

Keyless requests are limited per IP instead, on a public pool capped at 1,000 requests per hour and 10 per second, and they consume no credits. Responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`, and a `429` adds `Retry-After`. That pool is shared with everyone else on your egress address, so its headroom is outside your control: use a key for anything past a first look.

Pay-per-request calls consume no credits either: each one is paid for on its own, and has its own [limits](/pay-per-request#limits).


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