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

# Introduction

> Search cleaned English-language news with familiar query syntax, source and time filters, explicit content states, and stable cursor pagination.

The Clair News API exposes two read-only endpoints over a continuously
maintained news index:

| Method | Path          | Purpose                                                                   |
| ------ | ------------- | ------------------------------------------------------------------------- |
| `GET`  | `/v1/news`    | Search cleaned English-language articles or walk the corpus newest first. |
| `GET`  | `/v1/sources` | List the exact active source names accepted by News filters.              |

Clair collects and cleans publisher material in the background. Public
requests query the prebuilt index only. They never crawl a URL supplied by a
caller, contact a publisher during the request, or invoke an embedding model.

## Base URL and authentication

The News API is distributed through
[RapidAPI](https://rapidapi.com/clairapis-clairapis-default/api/clair-news-api).
Send your key and the News API host on every request:

```sh theme={null}
X-RapidAPI-Key: YOUR_RAPIDAPI_KEY
X-RapidAPI-Host: clair-news-api.p.rapidapi.com
```

RapidAPI owns key issuance, plan quotas, rate limiting, and billing. There is no
separate Clair account.

<Note>
  Use the exact host shown on the RapidAPI listing. The Jobs API is a separate
  listing with a separate host, even when you use the same RapidAPI key.
</Note>

## Search or walk the corpus

`q` is optional:

* With `q`, Clair runs English full-text search across title and cleaned
  content. Title matches receive more weight.
* Without `q`, Clair returns the canonical corpus newest first. This is the
  simplest path for polling or maintaining a local mirror.

The query syntax supports quoted phrases, uppercase `OR`, and minus-prefixed
exclusions:

```text theme={null}
"central bank" OR inflation -sports
```

A query that contains only English stop words returns `empty_query` instead of
quietly returning no results.

## Query parameters

| Parameter         | Default        | Contract                                                                                                                    |
| ----------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `q`               | none           | Search expression, 1–300 characters. Supports quoted phrases, uppercase `OR`, and `-excluded` terms.                        |
| `sources`         | all            | Comma-separated exact names from `GET /v1/sources`, at most 50.                                                             |
| `exclude_sources` | none           | Comma-separated exact names, at most 50. Mutually exclusive with `sources`.                                                 |
| `from`            | none           | Inclusive RFC 3339 publication timestamp.                                                                                   |
| `to`              | none           | Inclusive RFC 3339 publication timestamp. Must not precede `from`.                                                          |
| `sort_by`         | `published_at` | `published_at` or `relevance`. Relevance sorting requires `q`.                                                              |
| `category`        | all            | `general`, `world`, `politics`, `business`, `technology`, `science`, `health`, `sports`, `entertainment`, or `environment`. |
| `include_edits`   | `false`        | Include later revisions that share the same publisher URL.                                                                  |
| `limit`           | `25`           | Page size from 1 to 100.                                                                                                    |
| `cursor`          | none           | Opaque continuation token returned by the preceding page.                                                                   |

See [Search news](/docs/news-api/search) for the generated request playground and
complete schema.

## Response

```json theme={null}
{
  "query": "\"central bank\" OR inflation -sports",
  "language": "en",
  "sort_by": "published_at",
  "count": 1,
  "items": [
    {
      "id": "8cbabdf6-31cc-4677-8cf3-a39f8152aa08",
      "title": "Article title",
      "url": "https://publisher.example/article",
      "source": {
        "name": "Publisher"
      },
      "description": "Publisher summary or normalized short description",
      "image_url": "https://publisher.example/image.jpg",
      "authors": ["Reporter Name"],
      "language": "en",
      "category": "politics",
      "published_at": "2026-07-29T10:15:30.123456Z",
      "collected_at": "2026-07-29T10:16:04.654321Z",
      "content": "Cleaned article text or feed excerpt",
      "content_available": true,
      "content_truncated": false,
      "is_update": false,
      "relevance_score": 0.42
    }
  ],
  "next_cursor": "OPAQUE_CURSOR"
}
```

The sample values are illustrative.

## Content and revision semantics

`content` is a bounded cleaned snippet when extraction succeeded, a feed
excerpt when one was available, or `null` when neither was available. Clair
does not expose a full-article archive.

* `content_available` tells you whether `content` is present.
* `content_truncated` is true when Clair capped the returned snippet at 2,000
  characters.
* `description` is publisher-provided summary metadata when available.
* `image_url` and `authors` are nullable/empty when the publisher did not
  provide reliable values.
* `category` is a deterministic source/section category. Cross-cutting events
  such as elections, crimes, conflicts, and disasters remain keyword queries.
* `is_update` marks a later in-place revision of the same publisher URL.
* `relevance_score` is a query-local value from 0 to 1. It is not a
  probability and is `null` when `q` is absent.

By default, Clair returns only the canonical version of each publisher URL.
Set `include_edits=true` when a revision history matters to your application.

`published_at` is the publisher time. `collected_at` is when Clair ingested that
record. Both preserve microseconds in the response and cursor.

## Cursor pagination

When `next_cursor` is not null, repeat the exact search and pass the cursor
unchanged:

```sh theme={null}
curl -G https://clair-news-api.p.rapidapi.com/v1/news \
  -H "X-RapidAPI-Key: YOUR_RAPIDAPI_KEY" \
  -H "X-RapidAPI-Host: clair-news-api.p.rapidapi.com" \
  --data-urlencode 'q="central bank" OR inflation -sports' \
  --data-urlencode "sort_by=published_at" \
  --data-urlencode "cursor=CURSOR_FROM_PREVIOUS_RESPONSE"
```

The cursor is bound to the query, filters, sort, and revision mode that created
it. Changing any of them while reusing the cursor returns `bad_cursor`. Stop
when `next_cursor` is null.

Exact totals are intentionally absent from the request path. Walk
`next_cursor` for a stable result stream rather than depending on a broad
archive count.

## Sources

`GET /v1/sources` returns active names alphabetically:

```json theme={null}
{
  "count": 2,
  "items": [
    "Al Jazeera English",
    "Deutsche Welle (English)"
  ]
}
```

Pass those strings exactly to `sources` or `exclude_sources`. An unknown name
returns `unknown_source` rather than silently producing an empty page.

## Errors

Product-handler failures use `{ "error": "...", "detail": "..." }`.
Authorization and gateway failures may contain only `error`. Branch on the
stable code; `detail` is human-readable and may change. Validation failures
return an array of details, while typed failures return a string.

| Status | `error`                  | Meaning                                                  |
| ------ | ------------------------ | -------------------------------------------------------- |
| `400`  | `bad_request`            | One or more parameters failed validation.                |
| `400`  | `bad_cursor`             | The cursor is malformed or belongs to different inputs.  |
| `400`  | `empty_query`            | English normalization left no searchable terms.          |
| `400`  | `unknown_source`         | A source name is not in `GET /v1/sources`.               |
| `401`  | `unauthorized`           | The request is missing valid RapidAPI authorization.     |
| `429`  | Gateway-managed          | The RapidAPI plan rate limit was exceeded.               |
| `500`  | `internal`               | An unexpected internal error occurred.                   |
| `503`  | `dependency_unavailable` | The shared API platform is not ready.                    |
| `503`  | `product_unavailable`    | The News product failed its readiness check.             |
| `503`  | `overloaded`             | This endpoint reached its per-machine concurrency limit. |
| `504`  | `timeout`                | Search exceeded its processing deadline.                 |

Origin responses include `X-Request-ID`. Include it when reporting a problem.
Honor `Retry-After` on `503` responses and retry with backoff.
