# Search the web by date with Keenable's search API

Keenable's Web Search can answer one query three ways: what the web says now, what it published in the last month, and what it said before a date, with each result carrying its publish and index dates. Each search is one request at $4 per thousand requests, whatever the filters.

## At a glance

- **Endpoint:** `POST https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/v1/zeroclick/search`. The same parameters also work as a GET query string.
- **Body:** `query` (required). Optional fields: `published_after`, `published_before`, `acquired_after`, `acquired_before`, `query_time`, `site`, `max_results` (1 to 50, default 10) and `snippet_max_length` (180 to 10000).
- **Price:** $4 per thousand requests. Each search is one request, with or without filters.
- **Payment:** the cost is drawn from Credits, a prepaid balance (minimum purchase $0.50) held by your bearer credential. There is no per-call payment.
- **Auth:** `Authorization: Bearer <token>`, using the agent credential the storefront issues.
- **Response:** `query`, `mode` and `results`. Each result has `title`, `url`, `snippet`, `published_at` and `acquired_at`.
- **Charge:** the `zc-billing` response header gives `chargedUsd` and `remainingCreditUsd`.
- **Full purchase flow:** [the buyer skill](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/SKILL.md)

## Pick the filter for the question

| You want | Set | Example value |
| --- | --- | --- |
| What the web says now | no date field | |
| Recent pages | `published_after` | `"30d"` |
| Pages published before a date | `published_before` | `"2024-06-01"` |
| Pages indexed in a window | `acquired_after`, `acquired_before` | `"7d"`, `"2024-06-01"` |
| The web as it stood at a moment | `query_time` | `"2024-06-01"` |
| Results from one domain | `site` | `"keenable.ai"` |

`query_time` is not a recency filter. It is an upper bound that excludes every page acquired after that moment, and it sets no lower bound. An offset such as `"7d"` on `query_time` means as of seven days ago, not the last seven days. For recent results, use `published_after`.

## Search one question now, this month and before a date

1. Hold a credential with Credits: [the buyer skill](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/SKILL.md) has the steps for registering the agent credential and buying Credits.

2. Search with no filter:

   ```bash
   curl -s -X POST https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/v1/zeroclick/search \
     -H "Authorization: Bearer $ACCESS_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"query": "HTTP 402 Payment Required status code", "max_results": 5}'
   ```

   The response is a JSON object with `query`, `mode` and `results`. Each result carries the fields in this example, the first of five from the current index:

   ```json
   {"title": "402 Payment Required", "url": "https://developer.mozilla.org/…", "description": "", "snippet": "# 402 Payment Required\nThe HTTP **`402 Payment Required`** [client error respons…", "published_at": "2026-07-15T11:43:47Z", "acquired_at": "2026-10-11T12:45:02Z"}
   ```

   This search drew $0.004 from credit.

3. Limit the results to the last 30 days with `published_after`:

   ```json
   {"query": "HTTP 402 Payment Required", "published_after": "30d", "max_results": 5}
   ```

   The first of the example's five results was published inside that window:

   ```json
   {"title": "What is x402?", "url": "https://developers.circle.com/…", "description": "", "snippet": "x402 is an open, neutral standard for internet-native payments built on the HTTP…", "published_at": "2026-10-13T22:26:17Z", "acquired_at": "2026-10-25T19:03:47Z"}
   ```

   This search drew $0.004 from credit.

4. Search the index as it stood on a date with `query_time`:

   ```json
   {"query": "HTTP 402 Payment Required", "query_time": "2024-06-01", "max_results": 5}
   ```

   The example's first result is a copy indexed before that date. It carries `acquired_at` and no `published_at`:

   ```json
   {"title": "402 Payment Required", "url": "https://developer.mozilla.org/…", "description": "", "snippet": "# 402 Payment Required\nThe HTTP **`402 Payment Required`** is a nonstandard clie…", "acquired_at": "2019-10-22T00:08:16Z"}
   ```

   This search drew $0.004 from credit.

5. Keep the results to one domain with `site`:

   ```json
   {"query": "web index", "site": "keenable.ai", "max_results": 5}
   ```

   The example's first result comes from `keenable.ai`:

   ```json
   {"title": "Web index: definition and examples | Keenable", "url": "https://keenable.ai/…", "description": "", "snippet": "A web index is a searchable copy of web pages that a search engine builds by cra…", "published_at": "2026-10-27T00:00:00Z", "acquired_at": "2026-10-30T00:23:02Z"}
   ```

   This search drew $0.004 from credit.

## Date formats

| Value | On an `_after` field | On a `_before` field |
| --- | --- | --- |
| `2024-06-01` | `2024-06-01T00:00:00Z` | `2024-06-01T23:59:59.999Z`, so the whole day is kept |
| `2024-06-01T12:00:00Z` | that instant | that instant |
| `2024-06-01T12:00:00` | that instant in UTC | that instant in UTC |
| `30d`, `12h`, `6mo`, `1y` | the request time minus the offset, to the minute | the same |

When `query_time` is set, offsets on the other date fields count back from `query_time` instead of from now. `query_time` itself takes an ISO 8601 datetime, a `YYYY-MM-DD` date (read as `00:00:00` UTC), a Unix epoch or an offset.

## Limits and charges

- One request runs one `query`. There is no batch field.
- `mode` takes only `pro`, which is the default.
- `published_at` is the page's publish date. `acquired_at` is when Keenable indexed the page. Both are ISO 8601 in UTC, and each appears only when it is available.
- Every search draws on Credits, and a filter does not change the price.
- A `503` from the storefront means nothing was charged.

## Errors

| Status or code | Meaning | Action |
| --- | --- | --- |
| `401 bearer_required` | No agent credential on the call | Register at [auth.md](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/auth.md), then retry with the bearer |
| `403 plan_required` | The credential holds no Credits (`reason`: `access_not_found`) | Buy Credits with `POST /plans/{planId}/purchase`, then retry |
| `403 plan_required`, `reason`: `usage_exhausted` | The Credits balance is used up | Top up with `POST https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/extend` and `{"amountUsd": "..."}`, or buy again |
| `400` | Invalid parameter, such as `max_results` above 50 | Fix the body using the ranges above |
| `429` | Rate limit exceeded | Slow down, then retry |
| `503`, `529` | Allowance not confirmed, or search overloaded | Retry after `Retry-After` |

## Frequently asked questions

### Is query_time the same as a recency filter?

No. `query_time` returns the web as it stood at a moment and excludes pages acquired after it. It sets no lower bound. To get recent pages, set `published_after`, for example `"30d"`.

### What is the difference between published_at and acquired_at?

`published_at` is when the page was published. `acquired_at` is when Keenable indexed it. A page can be published long before it is indexed, and a result carries `published_at` only when it is available. To filter on when a page entered the index, use `acquired_after` and `acquired_before`.

### Do date or site filters cost extra?

No. Every search is one request at $4 per thousand requests, whatever fields it sets, so 500 searches cost $2. The `zc-billing` header on each response gives the amount drawn and the remaining balance.

### Can a search be paid for without Credits?

No. Every call draws on Credits held by your bearer credential. A call without a credential answers `401 bearer_required`, and a credential without Credits answers `403 plan_required`.

### How many results can one search return?

Up to 50. Set `max_results` between 1 and 50. When you omit it, the search returns 10. `snippet_max_length` sets each snippet's length, from 180 to 10000 characters.

## Keep reading

- [Buyer skill](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/SKILL.md): the full purchase flow
- [Identity](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/auth.md): register the agent credential
- [How to pay](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/payment.md): buying and topping up Credits
- [Error reference](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/errors.md): every error code
- [Machine catalog](https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/manifest.json): live plans and prices

---

Updated 2026-11-04. All Keenable guides: https://zeroclick.keenable.ai/guides.md. Storefront: https://zeroclick.keenable.ai/zcj/e1tlts6v8eqe/llms.txt.
