> ## Documentation index
> Fetch the complete documentation index at: https://context7.com/docs/llms.txt
> Ask it with GET https://context7.com/docs/ask?q=<keywords or question>. Short keywords rank best.
> Use these to discover all available pages before exploring further.
> Feature requests: https://context7.com/docs/resources/feature-requests.md lists what users asked for and how to vote for a request or add one.
> Page rating: `GET https://context7.com/docs/feedback?path=/docs/api-guide&helpful=true` (or `false`) records whether this page helped. An optional `comment` (URL-encoded, at most 500 characters) says what was missing or wrong. It is anonymous and needs no key. Comments hold no code, secrets or personal data.

# API Guide

> Authentication, rate limits, best practices, and integration guides for the Context7 API

## Authentication

All API requests require authentication using an API key. Include your API key in the `Authorization` header:

```bash
Authorization: Bearer CONTEXT7_API_KEY
```

Get your API key at [context7.com/dashboard](https://context7.com/dashboard). Learn more about [creating and managing API keys](/howto/api-keys).

## API Methods

| Method | Endpoint | Description |
|--------|----------|-------------|
| [Search Documentation](/api-reference/search/search-documentation-in-one-request) | `GET /api/v3/search` | Find relevant documentation without resolving a library first |
| [Fetch Page](/api-reference/search/read-one-web-page-optionally-narrowed-to-a-question) | `GET /api/v3/fetch` | Read one web page by URL, optionally narrowed to a question |
| [Search Library](/api-reference/search/search-for-libraries) | `GET /api/v2/libs/search` | Find libraries by name |
| [Get Context](/api-reference/context/get-documentation-context) | `GET /api/v2/context` | Retrieve documentation snippets for a library |
| [Refresh Library](/api-reference/refresh/refresh-a-library) | `POST /api/v1/refresh` | Refresh a library's documentation |
| [Get Policies](/api-reference/policies/get-teamspace-policies) | `GET /api/v2/policies` | Retrieve teamspace policy configuration |
| [Update Policies](/api-reference/policies/update-teamspace-policies) | `PATCH /api/v2/policies` | Update teamspace policies |
| [Get Metrics](/api-reference/metrics/get-library-usage-metrics) | `GET /api/v2/libs/metrics` | Retrieve usage metrics for libraries |
| [Add GitHub Repo](/api-reference/add-library/add-a-github-repository) | `POST /api/v2/add/repo/github` | Submit a GitHub repository for processing |
| [Add GitLab Repo](/api-reference/add-library/add-a-gitlab-repository) | `POST /api/v2/add/repo/gitlab` | Submit a GitLab repository for processing |
| [Add Bitbucket Repo](/api-reference/add-library/add-a-bitbucket-repository) | `POST /api/v2/add/repo/bitbucket` | Submit a Bitbucket repository for processing |
| [Add Other Git Repo](/api-reference/add-library/add-from-other-git-providers) | `POST /api/v2/add/repo/git` | Submit a repository from any other Git provider |
| [Add OpenAPI](/api-reference/add-library/add-an-openapi-specification-by-url) | `POST /api/v2/add/openapi` | Submit an OpenAPI spec |
| [Upload OpenAPI](/api-reference/add-library/upload-an-openapi-specification-file) | `POST /api/v2/add/openapi-upload` | Upload an OpenAPI spec file |
| [Add LLMs.txt](/api-reference/add-library/add-an-llmstxt-file) | `POST /api/v2/add/llmstxt` | Submit an llms.txt file |
| [Add Website](/api-reference/add-library/add-a-website) | `POST /api/v2/add/website` | Submit a website for crawling |
| [Add Confluence](/api-reference/add-library/add-a-confluence-space) | `POST /api/v2/add/confluence` | Submit a Confluence space |
| [Add Notion](/api-reference/add-library/add-notion-pages) | `POST /api/v2/add/notion` | Submit Notion pages |

## Library ID format

A **library ID** is the URL path of the library on context7.com. If the library page is at `https://context7.com/websites/uploadcare`, its ID is `/websites/uploadcare`. The same ID works for every endpoint that accepts a `libraryId` or `libraryName` — including [Get Context](/api-reference/context/get-documentation-context) and [Refresh Library](/api-reference/refresh/refresh-a-library).

Use `/owner/repo` for GitHub repositories, or `/<source>/<id>` for other sources:

| Source | Example library ID |
|--------|--------------------|
| GitHub repository | `/vercel/next.js` |
| GitLab / Bitbucket / generic Git repo | `/<owner>/<repo>` (same shape as GitHub) |
| Website | `/websites/uploadcare` |
| llms.txt source | `/llmstxt/<source>` |
| npm / package source | `/packages/<name>` or `/npm/<name>` |
| Uploaded docs | `/docs/<name>` |

You can pin a specific version with either `/owner/repo/<version>` or `/owner/repo@<version>`:

```
/vercel/next.js/v16.2.9
/vercel/next.js@v16.2.9
```

<Tip>
  Don't know the ID for a library? Find it on [context7.com](https://context7.com) — the URL path of the library page **is** the ID. Or call [Search Library](/api-reference/search/search-for-libraries) and use the `id` from the response.
</Tip>

### Search Context7 documentation

The Search API is the simplest way to retrieve documentation. You provide a question, and Context7 selects relevant libraries before searching and reranking their snippets.

If no documentation matches, Search returns `404 no_documentation_found`; treat it as an empty result. A temporary search failure returns `503 search_failed` and can be retried.

```python
import os
import requests

headers = {"Authorization": f"Bearer {os.environ['CONTEXT7_API_KEY']}"}

# Context7 selects the library and returns the best snippets
response = requests.get(
    "https://context7.com/api/v3/search",
    headers=headers,
    params={
        "query": "How do I stream an OpenAI response from a Next.js route?",
        "library": ["Next.js", "OpenAI"],
        "language": "TypeScript",
        "type": "json",
    },
)
response.raise_for_status()
docs = response.json()

for snippet in docs["codeSnippets"]:
    print(f"Library: {snippet['libraryId']}")
    print(f"Title: {snippet['codeTitle']}")
    for code in snippet["codeList"]:
        print(f"Code: {code['code'][:200]}...")

for info in docs["infoSnippets"]:
    print(f"Content: {info['content'][:200]}...")
```

Library hints are optional and do not need to be exact. You can provide up to four names or exact Context7 library IDs. Use `version` with at least one library hint, and use `language` when you want language-specific examples to rank higher.

### Choose a library yourself

Use Search Library followed by Get Context when your application needs to inspect or choose a specific documentation source.

```python
import os
import requests

headers = {"Authorization": f"Bearer {os.environ['CONTEXT7_API_KEY']}"}

# Find libraries that match the task
search_response = requests.get(
    "https://context7.com/api/v2/libs/search",
    headers=headers,
    params={"libraryName": "react", "query": "I need to manage state"},
)
search_response.raise_for_status()
best_match = search_response.json()["results"][0]
print(f"Found: {best_match['title']} ({best_match['id']})")

# Request documentation from the selected library
context_response = requests.get(
    "https://context7.com/api/v2/context",
    headers=headers,
    params={"libraryId": best_match["id"], "query": "How do I use useState?", "type": "json"},
)
context_response.raise_for_status()
docs = context_response.json()

for snippet in docs["codeSnippets"]:
    print(f"Title: {snippet['codeTitle']}")
    for code in snippet["codeList"]:
        print(f"Code: {code['code'][:200]}...")

for info in docs["infoSnippets"]:
    print(f"Content: {info['content'][:200]}...")
```

<Info>
  Each Search API call counts as one request. The two-step flow makes two API calls when it searches for a library and then retrieves its documentation.
</Info>

<Info>
  For TypeScript SDK usage, see [Search](/sdks/ts/commands/search), [Search Library](/sdks/ts/commands/search-library), and [Get Context](/sdks/ts/commands/get-context).
</Info>

## MCP Tools

The [Context7 MCP server](/resources/all-clients) exposes the same lookups as agent tools. Each tool maps to one REST endpoint, with the same parameters as the query fields:

| MCP tool | Endpoint | Parameters |
|----------|----------|------------|
| `resolve-library-id` | [Search Library](/api-reference/search/search-for-libraries) — `GET /api/v2/libs/search` | `libraryName`, `query` |
| `query-docs` | [Get Context](/api-reference/context/get-documentation-context) — `GET /api/v2/context` | `libraryId`, `query`, `language` |

Call the REST API directly to control requests from your own code, or use the MCP tools when you want an agent to fetch documentation automatically during inference. Both use the same [API key](#authentication).

## Rate Limits

- **Without API key**: Low rate limits and no custom configuration
- **With API key**: Higher limits based on your plan
- View current usage and reset windows in the [dashboard](https://context7.com/dashboard).

When you exceed rate limits, the API returns a `429` status code with these headers:

| Header | Description |
|--------|-------------|
| `Retry-After` | Seconds until rate limit resets |
| `RateLimit-Limit` | Total request limit |
| `RateLimit-Remaining` | Remaining requests in window |
| `RateLimit-Reset` | Unix timestamp when limit resets |

## Best Practices

### Be Specific with Queries

Use detailed, natural language queries for better results:

```bash
# Good - specific question
curl "https://context7.com/api/v2/context?libraryId=/vercel/next.js&query=How%20to%20implement%20authentication%20with%20a%20proxy" \
  -H "Authorization: Bearer CONTEXT7_API_KEY"

# Less optimal - vague query
curl "https://context7.com/api/v2/context?libraryId=/vercel/next.js&query=auth" \
  -H "Authorization: Bearer CONTEXT7_API_KEY"

# Non-GitHub source (website) - same endpoint, same shape
curl "https://context7.com/api/v2/context?libraryId=/websites/uploadcare&query=image%20transformations" \
  -H "Authorization: Bearer CONTEXT7_API_KEY"
```

### Add hints only when they provide useful context

Start with only the question when the relevant library is clear from the task. Add library hints when a name is ambiguous or when the answer needs documentation from more than one product.

```bash
curl -G "https://context7.com/api/v3/search" \
  -H "Authorization: Bearer CONTEXT7_API_KEY" \
  --data-urlencode "query=How do I stream an OpenAI response from a Next.js route?" \
  --data-urlencode "library=Next.js" \
  --data-urlencode "library=OpenAI" \
  --data-urlencode "language=TypeScript"
```

### Cache Responses

Documentation updates are relatively infrequent, so caching responses for several hours or days reduces API calls and improves performance.

### Handle Rate Limits

Implement exponential backoff for rate limit errors:

```python
import time
import requests

def fetch_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
            time.sleep(retry_after)
            continue

        return response

    raise Exception("Max retries exceeded")
```

### Use Specific Versions

Pin to a specific version for consistent results. Both `/` and `@` syntax are supported:

```bash
curl "https://context7.com/api/v2/context?libraryId=/vercel/next.js/v16.2.9&query=app%20router" \
  -H "Authorization: Bearer CONTEXT7_API_KEY"

curl "https://context7.com/api/v2/context?libraryId=/vercel/next.js@v16.2.9&query=app%20router" \
  -H "Authorization: Bearer CONTEXT7_API_KEY"
```

If that version is not indexed, the request still succeeds and serves the closest documentation Context7 has: a tag matching the requested numbers, a newer release of the same line, or the library's current documentation. JSON responses include a `version` object that says which version was served. A text response starts with a version note when it serves another release or the current documentation. A branch or channel name that is not indexed, such as `/vercel/next.js/canary`, still returns `404 version_not_found`.

## Error Handling

The Context7 API uses standard HTTP status codes:

| Code | Description                               | Action                                       |
| ---- | ----------------------------------------- | -------------------------------------------- |
| 200  | Success                                   | Process the response normally                |
| 202  | Accepted - Library not finalized          | Wait and retry later                         |
| 301  | Moved - Library redirected                | Use the new library ID from `redirectUrl`    |
| 400  | Bad Request - Invalid parameters          | Check query parameters                       |
| 401  | Unauthorized - Invalid API key            | Check your API key format (starts with `ctx7sk`) |
| 403  | Forbidden - Access denied                 | Check library access permissions or plan     |
| 404  | Not Found - Library doesn't exist         | Verify the library ID                        |
| 409  | Conflict - Resource already exists        | The library has already been added           |
| 422  | Unprocessable - Library too large/no code | Try a different library                      |
| 429  | Too Many Requests - Rate limit exceeded   | Wait for `Retry-After` header, then retry    |
| 500  | Internal Server Error                     | Retry with backoff                           |
| 503  | Service Unavailable - Search failed       | Retry later                                  |
| 504  | Gateway Timeout - Processing timed out    | Retry later                                  |

All errors return a JSON object with `error` and `message` fields:

```json
{
  "error": "library_not_found",
  "message": "Library \"/owner/repo\" not found. Please check the library ID or your access permissions."
}
```

For `301` redirects, the response also includes a `redirectUrl` field pointing to the new library ID.

## SDK and Libraries

For TypeScript SDK installation and usage, see the [Getting Started guide](/sdks/ts/getting-started).
