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

# REST API

> The same surface that powers the dashboard. One API key, every endpoint.

Onboard clients, run scans, read visibility scores, pull citations, and download client-ready PDF reports. One API key, every endpoint that powers OpenLens.

<Warning>
  **Beta release.** The API runs against production data, but rate limits are conservative and endpoints may evolve before GA. If you need limits raised, email [contact@aibread.com](mailto:contact@aibread.com). We'll give beta users a heads-up before any breaking change.
</Warning>

## What it does

The REST API exposes the same operations as the dashboard:

* **Onboard new clients automatically.** Hand the API a website URL. It researches the brand, proposes competitors and buyer-intent topics, and creates the project with prompts ready to scan.
* **Run AI visibility scans** across ChatGPT, Perplexity, Google AI Overviews, and DeepSeek. (Claude is gated to specific accounts.)
* **Read visibility, share of voice, sentiment, citation sources, and per-attribute breakdowns** programmatically.
* **Download client-ready PDF reports.**
* **Manage projects, topics, prompts, and platforms.**

## Authentication

Every request needs a Clerk API key in the `Authorization` header.

### Get an API key

<Steps>
  <Step title="Sign in to OpenLens">
    [Sign in](https://openlens.com/sign-in). If you don't have an account yet, [sign up here](https://openlens.com/sign-up). The API doesn't provision accounts in beta, so the web sign-up is the only path.
  </Step>

  <Step title="Open your account settings">
    From the dashboard, click your avatar in the **bottom-left** corner and choose **Manage account**.
  </Step>

  <Step title="Add a key">
    Open the **API Keys** tab and click **Add new key**.
  </Step>

  <Step title="Name it and pick an expiry">
    Give the key an optional name (handy if you're running it from multiple machines) and pick an expiration date.
  </Step>

  <Step title="Copy the secret immediately">
    The secret never appears again. If you lose it, you'll need to revoke it and create a new one.
  </Step>
</Steps>

### Send it on every request

```http theme={null}
Authorization: Bearer <your_api_key>
```

## Base URL

```http theme={null}
https://openlens.com/api
```

Responses are JSON unless otherwise noted. The PDF report endpoint returns `application/pdf`.

## End-to-end example

We'll onboard Anthropic from scratch and read back their visibility scores. Five short steps, about 11 minutes end to end. The individual steps run fast. The wait is the AI platforms thinking.

### Setup

Pin the base URL and the auth header so every request below can reuse them.

```python theme={null}
import json
import time
import requests

BASE = "https://openlens.com/api"
auth = {"Authorization": "Bearer YOUR_API_KEY"}
```

<Steps>
  <Step title="Analyze the brand (about 30s)">
    `POST /onboard` with `action: "analyze"` hands the API a website URL. It reads the page, figures out what the brand does, and proposes a starting set of competitors and buyer-intent topics. Nothing is saved yet, so you can edit the result before committing. The endpoint streams progress events as Server-Sent Events. We just wait for the full response and parse the final `data:` line.

    ```python theme={null}
    res = requests.post(
        f"{BASE}/onboard",
        headers=auth,
        json={"action": "analyze", "url": "https://anthropic.com/"},
    )
    analysis = json.loads(res.text.strip().split("data: ")[-1])["data"]
    ```
  </Step>

  <Step title="Confirm and create the project (about 1m)">
    `action: "confirm"` takes the analysis back (with any edits), creates the project, and generates 10 prompts per topic in the background.

    ```python theme={null}
    res = requests.post(f"{BASE}/onboard", headers=auth, json={
        "action": "confirm",
        "brandName": analysis["brandName"],
        "url": "https://anthropic.com/",
        "industryType": analysis["industryType"],
        "location": analysis["location"],
        "languages": analysis["languages"],
        "competitors": analysis["competitors"],
        "topicList": analysis["topics"],
        "activePlatforms": ["chatgpt_app", "perplexity_app", "google_app", "deepseek"],
        "promptsPerTopic": 10,
    })
    project_id = json.loads(res.text.strip().split("data: ")[-1])["data"]["projectId"]
    ```
  </Step>

  <Step title="Kick off a scan">
    `POST /prompts/run` returns immediately with a `runId`. A typical run is 30 prompts × 4 platforms = 120 platform responses.

    ```python theme={null}
    run_id = requests.post(
        f"{BASE}/prompts/run",
        headers=auth,
        json={"projectId": project_id},
    ).json()["runId"]
    ```
  </Step>

  <Step title="Wait for it to finish (5 to 15 min)">
    Poll every 30 seconds. Most fresh projects complete in 5 to 10 minutes. Larger ones can take 30+. If a deploy or crash interrupts a run, calling `POST /prompts/run` again resumes it from where it left off.

    ```python theme={null}
    while (s := requests.get(
        f"{BASE}/prompts/status",
        headers=auth,
        params={"projectId": project_id, "runId": run_id},
    ).json())["status"] not in ("completed", "failed"):
        time.sleep(30)
    ```
  </Step>

  <Step title="Read the results">
    `GET /visibility` returns an array of brand-level scores: visibility (mention rate), share of voice, sentiment, average rank, per-platform breakdown. Same data the dashboard renders.

    ```python theme={null}
    scores = requests.get(
        f"{BASE}/visibility",
        headers=auth,
        params={"projectId": project_id},
    ).json()
    ```
  </Step>
</Steps>

### What you get back

```
Brand: Anthropic
Competitors: ['OpenAI', 'Google DeepMind', 'Meta AI', 'xAI', 'Mistral AI']
Topics: ['best large language model API for enterprise applications',
         'safest most reliable AI model for business',
         'top frontier AI models compared for developers']
  * Anthropic                  49.2%
    OpenAI                     55.8%
    Google DeepMind             5.8%
    Meta AI                     1.7%
    xAI                         5.8%
    Mistral AI                 14.2%
```

## Supported platforms

| Platform ID      | Display name | Notes                                                                       |
| ---------------- | ------------ | --------------------------------------------------------------------------- |
| `chatgpt_app`    | ChatGPT      | All plans                                                                   |
| `perplexity_app` | Perplexity   | All plans                                                                   |
| `google_app`     | Google AI    | All plans                                                                   |
| `deepseek`       | DeepSeek     | Starter and Agency                                                          |
| `gemini_app`     | Gemini       | Agency                                                                      |
| `grok_api`       | Grok         | Agency                                                                      |
| `claude`         | Claude       | Agency · email [contact@aibread.com](mailto:contact@aibread.com) for access |

To see which platforms are active on your account, call `GET /api/settings/platforms`.

## Endpoint families

A quick tour of what's available. Full request and response shapes are in the OpenAPI spec at `/api/openapi.json` (also rendered as the per-endpoint pages in this section).

* **Onboarding.** `POST /api/onboard` (Server-Sent Events) with `action: analyze` or `action: confirm`.
* **Runs.** `POST /api/prompts/run` to start, `GET /api/prompts/status` to poll, `DELETE /api/prompts/run` to cancel, `GET /api/prompts/results` for raw responses.
* **Metrics.** `GET /api/visibility` (overall, per-topic, per-attribute), `GET /api/visibility/trends` for time series, `GET /api/insights/engines` for per-platform source behavior, `GET /api/insights/topic` for an AI-generated insight paragraph.
* **Citations.** `GET /api/brand-mentions-summary` returns top cited URLs per topic. `GET /api/sources` returns top cited domains.
* **Deliverables.** `GET /api/reports/visibility` returns a client-ready PDF. `GET /api/reports/runs` returns run history.
* **Resources.** CRUD endpoints for projects, brands, topics, and prompts.
* **Account.** `GET /api/me/limits`, `GET /api/usage`, `GET /api/settings/platforms`. (Note: `/api/settings/schedule` returns `410 Gone`. Scheduling is per-project now. Use `/api/projects/{id}/schedule`.)

## Common errors

| Status | Meaning                                                                   |
| ------ | ------------------------------------------------------------------------- |
| `400`  | Missing or invalid request parameter (most often `projectId`)             |
| `401`  | API key missing, malformed, or revoked                                    |
| `404`  | Resource not found, or not owned by your account                          |
| `409`  | A run is already in progress for this project                             |
| `429`  | Rate limit, project cap, or daily quota hit. Body includes a `code` field |
| `500`  | Server error. Retry. If persistent, email us with the request ID          |

## Support

Bug reports, rate-limit bumps, integration help: email [contact@aibread.com](mailto:contact@aibread.com).
