# Keenable search API through Mux: models and pricing

> What the Keenable search API offers through Mux: two models, a flat $4 per 1,000 requests for up to 50 results, native date filters, and no page text.

Canonical: https://getmux.io/guides/keenable-search-api


The Keenable search API is available through Mux as two models, `keenable/pro` and `keenable/realtime`, at a flat $4 per 1,000 requests with no extra charge for results beyond ten, up to 50 per request. You call it with the same request body and get the same response shape as every other Mux model, so it drops into an existing integration or a fallback list without new parsing code. The trade-off is that Keenable returns snippets only; `content` is always `null`.

## What Keenable is

[Keenable](https://keenable.ai) describes itself as independent web search infrastructure for AI, built on its own crawler, index and ranking. Its public pricing page lists an Agent Builder tier at $4 per 1,000 requests, as of October 2026, which is the list price Mux passes through. For anything beyond what this page covers, such as direct API access, a fetch endpoint or enterprise tiers, see [keenable.ai](https://keenable.ai).

Through Mux, Keenable is one of three providers alongside Exa and Parallel. You do not need a Keenable account; your Mux key and credit balance cover it. If you already have a Keenable key, you can connect it with [BYOK](https://getmux.io/docs/byok) and Mux will route Keenable requests through it.

## The two models

| Model | Description | $/1k requests | $/1k extra results | Max results | Typical latency |
|---|---|---|---|---|---|
| `keenable/pro` | Keenable pro index | 4.00 | 0 | 50 | ~700 ms |
| `keenable/realtime` | Keenable realtime index | 4.00 | 0 | 50 | ~700 ms |

Both cost the same and have the same limits. `keenable/pro` is the general index and the one `auto` falls back to. `keenable/realtime` queries the realtime index, which is the one to pick when recency matters more than depth, for example news monitoring or "what happened today" questions. Latency is measured end to end through Mux and is typical, not guaranteed.

The rest of the model catalog, with live prices, is below and on [/docs/models](https://getmux.io/docs/models).

(Live price table: https://getmux.io/models or GET https://api.getmux.io/v1/models)

## How Keenable behaves behind the Mux request shape

Mux translates each request into Keenable's native format and normalizes the answer. The differences from Exa and Parallel that affect how you write requests:

| Feature | Keenable through Mux |
|---|---|
| `max_results` | 1 to 50. Asking for more is capped to 50. |
| Extra results | No charge. 50 results cost the same $0.004 as 10. |
| `include_domains` | One domain is sent natively as Keenable's `site` filter. With more than one, Mux filters the results after they come back. |
| `exclude_domains` | Applied by Mux after the response. |
| `published_after`, `published_before` | Both applied natively. |
| `content: "full"` | Not available. `content` is `null` on every result; `snippet` is still filled. |
| `provider_options` | None allow-listed yet. |

Two consequences worth planning for. First, because the price is flat, request the full 50 results whenever you might use them; on Exa or Parallel the same request would add 40 extra-result charges. Second, because multi-domain and exclude filtering happen after the provider has answered, you can get fewer than `max_results` back and still pay the flat price. If you only need one domain, pass exactly one entry in `include_domains` so it is applied natively.

## When to pick Keenable

- **You want many results at a flat price.** A 50-result `keenable/pro` request is $0.004. The same count on `exa/auto` is $0.007 plus 40 extra results at $0.001 each, or $0.047. For agents that cast a wide net and rank locally, the difference is more than 10x.
- **You need fresh results.** `keenable/realtime` is a dedicated realtime index. Pair it with `published_after` to keep an agent's news or monitoring queries bounded to the last day or week.
- **You want a third, independent provider in a fallback list.** Keenable runs its own index, so it is unlikely to fail at the same moment as Exa or Parallel. It is already the last entry in `auto`.
- **You need `published_before`.** Keenable and Exa apply it natively; Parallel does not.

## When not to pick Keenable

- **You need page text.** `content` is `null` on Keenable. If your agent reads full pages from search results, use `exa/auto` with `content: "full"` for page text, or a Parallel model for joined excerpts. Keenable also offers a separate fetch product directly; Mux does not expose it, so a direct Keenable relationship is the better choice if fetch is what you need.
- **You need more than 50 results.** Exa models go to 100.
- **You rely on provider-specific options.** Nothing is allow-listed for Keenable in `provider_options` yet.

## Calling Keenable through Mux

The same endpoint and key as every other model. Set `model` to `keenable/pro` or `keenable/realtime`.

```bash
curl https://api.getmux.io/v1/search \
  -H "Authorization: Bearer $MUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "lithium battery recycling startups",
    "model": "keenable/pro",
    "max_results": 50,
    "published_after": "2026-01-01"
  }'
```
```ts
import { Mux } from "getmux";

const mux = new Mux();
const res = await mux.search({
  query: "lithium battery recycling startups",
  model: "keenable/pro",
  maxResults: 50,
  publishedAfter: "2026-01-01",
});
for (const r of res.results) console.log(r.title, r.url, r.snippet);
console.log(res.usage.costUsd); // 0.004
```
```python
from getmux import Mux

mux = Mux()
res = mux.search(
    "lithium battery recycling startups",
    model="keenable/pro",
    max_results=50,
    published_after="2026-01-01",
)
for r in res.results:
    print(r.title, r.url, r.snippet)
print(res.cost_usd)  # 0.004
```

A realtime query for the last 24 hours, restricted to one site so the domain filter is applied natively:

```ts
const res = await mux.search({
  query: "federal reserve rate decision",
  model: "keenable/realtime",
  includeDomains: ["reuters.com"],
  publishedAfter: "2026-10-17",
  maxResults: 20,
});
```
```python
res = mux.search(
    "federal reserve rate decision",
    model="keenable/realtime",
    include_domains=["reuters.com"],
    published_after="2026-10-17",
    max_results=20,
)
```

### In a fallback list

Keenable works well as a cheap, independent backstop. This order tries Parallel first, Keenable second, and Exa last; failed attempts are refunded and `attempts` shows which model answered.

```ts
const res = await mux.search({
  query: "kubernetes pod eviction thresholds",
  models: ["parallel/fast", "keenable/pro", "exa/auto"],
});
console.log(res.model, res.attempts);
```
```python
res = mux.search(
    "kubernetes pod eviction thresholds",
    models=["parallel/fast", "keenable/pro", "exa/auto"],
)
print(res.model, res.attempts)
```

If a request needs page text, put Keenable after the models that provide it, or leave it out, since a successful Keenable answer ends the fallback chain with `content` set to `null`.

## FAQ

### How much does a Keenable request cost through Mux?

$0.004 per request at any result count from 1 to 50. That is Keenable's own list price with no per-request markup. Mux's only fee is 5.5% (minimum $0.80) when you buy credits. See [/pricing](https://getmux.io/pricing).

### What is the difference between keenable/pro and keenable/realtime?

They query different indexes at the same price and limits. `pro` is the general index and the default in `auto`; `realtime` is the realtime index, intended for queries where freshness matters most. Both support native date filters.

### Can I get full page content from Keenable?

Not through Mux. `content` is `null` on every Keenable result, even with `content: "full"`. Use an Exa model for full page text or a Parallel model for joined excerpts, or put one of them ahead of Keenable in your `models` list.

### Can I filter to several domains?

Yes. Keenable natively supports one `site` domain, so a single `include_domains` entry is sent upstream. With several, Mux filters the results after they return, which can leave you with fewer than `max_results` at the same flat price.

Run your first `keenable/pro` search in a minute with the [quickstart](https://getmux.io/docs/quickstart).
