---
title: API overview
description: The Qaf API v1 at api.qaf.ai/v1. Endpoints, request and response format, authentication, the OpenAPI document, request IDs and the versioning policy.
sidebar:
  label: Overview
---

The Qaf API lets your own code search and read the Qaf library. It runs the same operations as the [MCP server](/mcp) and returns the same JSON.

```text
https://api.qaf.ai/v1
```

## Endpoints

| Endpoint | Does | MCP tool |
| --- | --- | --- |
| [`POST /v1/search`](/reference/passages/search-passages) | Searches passages, optionally filtered by author, book, genre or death year. | `search` |
| [`GET /v1/passages/{id}`](/reference/passages/get-passage) | Reads a passage, with up to five neighbouring passages on each side. | `fetch` |
| [`GET /v1/catalog/lookup`](/reference/catalog/lookup-catalog) | Resolves an author or book name to IDs for search filters. | `lookup_catalog` |

The [API reference](/reference) lists every field, limit and response. [The Qaf library](/library) explains the passage fields, IDs and genres.

## Requests and responses

- **Format:** requests and responses are JSON in UTF-8. Send `Content-Type: application/json` with a request body.
- **Parameters:** `POST /v1/search` takes a JSON body. The `GET` endpoints take query parameters, and the passage ID goes in the path.
- **`HEAD`:** works wherever `GET` does. It returns the same status and headers without the body, and counts toward the rate limit like a `GET`.
- **Unknown fields:** the search body refuses fields it doesn't define with a `422`, so a misspelled filter fails instead of being ignored.
- **Body size:** a request body over 64 KiB gets a `413`.
- **Names:** fields are camelCase, such as `sequenceNumber`. Set `locale` to `ar` for Arabic book and author names; it defaults to `en`.

## Authentication

Send an API key from qaf.ai **Settings › API keys** as a bearer token:

```http
Authorization: Bearer qaf_sk_…
```

Keep keys on your server. See [Authentication](/api/authentication).

## Limits

Each account can make 60 requests a minute and 1,000 searches a day, across all its keys. See [Rate limits](/api/rate-limits).

## OpenAPI document

The OpenAPI 3.1 document for v1 is at:

```text
https://api.qaf.ai/v1/openapi.json
```

It needs no key. Use it to generate a client or to give an agent the exact schema. It is the same document this site's [API reference](/reference) is built from.

## Request IDs

Every response has an `X-Request-Id` header, including errors. The only exception is the answer to a browser's CORS preflight (`OPTIONS`) request. When you email us at contact@qaf.ai about a response, include it.

## Browsers

The API accepts cross-origin requests from any site, so the reference's **Try it** panel can call it. That doesn't make it safe to put a key in a web page or an app: anyone who loads the page can read the key. Call the API from your server.

## Versioning

v1 changes only in ways that keep existing clients working. Write your client to:

- ignore response fields it doesn't know;
- handle enum values and error codes it doesn't know, such as a new genre slug or a new lookup candidate `type`.

These changes can happen in v1 without notice:

- new endpoints and new optional request fields;
- new response fields, enum values and error codes;
- higher limits.

Renaming or removing a field, tightening a type or a limit, or changing a default needs a new version, `v2`. When part of v1 is deprecated, its responses carry `Deprecation` and `Link` headers that point to a migration guide, and the [changelog](/changelog) says so.
