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

# API Keys & Authentication

> One project API key lets the Checksum CLI, your CI pipelines, the REST API, and (optionally) MCP clients act on your project. Checksum's public REST API lets you trigger test runs, poll for results, manage test health, and start auto-healing from your own scripts, CI pipelines, or internal tools. This page explains where the key lives, how to call the API, and the order most integrations follow. Each endpoint is documented on the page for the capability it triggers.

## At a glance

| Using | How you authenticate | Learn more |
| - | - | - |
| REST API | Send your key in an `Authorization: Bearer` header | [Making requests](#making-requests) |
| CLI and CI | Store the key as `CHECKSUM_API_KEY` | [Your API key](#your-api-key) |
| Coding agents (MCP) | Sign in through your browser, or use the key | [MCP clients](#authenticating-mcp-clients) |

<div className="ai-ref">
  <Accordion title="Reference for AI: authentication at a glance" icon="robot">
    | Interface | How it authenticates |
    | - | - |
    | REST API | `Authorization: Bearer $CHECKSUM_API_KEY` on every request |
    | CLI | `npx checksumai dotenv --download --api-key=$CHECKSUM_API_KEY`, plus `apiKey: process.env.CHECKSUM_API_KEY` in `checksum.config.ts` |
    | CI | CI secret named `CHECKSUM_API_KEY` |
    | GitHub Action | `api-key: ${{ secrets.CHECKSUM_API_KEY }}` |
    | MCP | Browser sign-in (recommended) or `Authorization: Bearer $CHECKSUM_API_KEY` |
    | Key check | `GET https://api.checksum.ai/public-api/v1/me` |

    * Where the key lives: web app → **Settings → Project Settings**. One key per project, created by Checksum during onboarding.
    * Base URLs: `https://api.checksum.ai/public-api/v1/` for almost everything; `https://api.checksum.ai/public-api/v2/` for `POST /execution/grep` and `GET /execution/status/{jobName}`.
    * Async: execution returns a `runId` (poll until `isTerminal` is `true`); generation and healing return a `batchId` (poll until `allTerminal` is `true`).
    * Validation: invalid bodies return `400`; a missing or invalid key returns `401`.
    * No cancel: API-triggered runs can't be cancelled through the API.
  </Accordion>
</div>

<div className="part dev"><span className="part-icon">{"</>"}</span><div><div className="part-title">Developer guide</div><div className="part-sub">Your API key, making requests, checking a key, and the typical integration flow</div></div></div>

## Your API key

Your project's API key is in the web app under **Settings → Project Settings**. Checksum creates it with your project during [onboarding](/docs/onboarding), so you don't need to generate one. Store it as the environment variable `CHECKSUM_API_KEY` wherever you use it: your shell, your CI secrets, or your coding agent's config.

```bash theme={null}
# Local shell: export the key once per session
export CHECKSUM_API_KEY="<your project API key>"

# CLI: download the project's environment variables into .env
npx checksumai dotenv --download --api-key="$CHECKSUM_API_KEY"
```

In CI, add it as a secret named `CHECKSUM_API_KEY` (see [CI/CD Integration](/docs/ci-integration)). The GitHub Action takes it as `api-key: ${{ secrets.CHECKSUM_API_KEY }}`, and your tests read it through `apiKey: process.env.CHECKSUM_API_KEY` in [`checksum.config.ts`](/docs/test-repository#configure-checksum-config-ts).

<Warning>
  **Keep it secret**

  The key is unique to your project. Anyone who has it can run tests, start billable agent sessions, open pull requests, and read results for the project. Keep it in a secrets manager or CI secret, and never commit it. A key is always tied to exactly one project.
</Warning>

<div className="ai-ref">
  <Accordion title="Reference for AI: where the API key is used" icon="robot">
    | Used by | How |
    | - | - |
    | CLI | `npx checksumai dotenv --download --api-key=<KEY>`, and `apiKey: process.env.CHECKSUM_API_KEY` in [`checksum.config.ts`](/docs/test-repository#configure-checksum-config-ts) |
    | CI | Stored as a CI secret named `CHECKSUM_API_KEY` |
    | GitHub Action | `api-key: ${{ secrets.CHECKSUM_API_KEY }}` |
    | REST API | `Authorization: Bearer <KEY>` header |
    | MCP (optional) | As a bearer header for clients that can't do browser sign-in (see [MCP clients](#authenticating-mcp-clients)) |

    Scope: one key per project. Location: **Settings → Project Settings**. Environment variable name: `CHECKSUM_API_KEY`.
  </Accordion>
</div>

## Making requests

Every call to the REST API sends your key in an `Authorization: Bearer` header, and requests with a body send JSON. Calls that start agent work (runs, generation, healing) return right away with an ID, and you poll for the result. The examples in these docs poll every 10–30 seconds.

```bash theme={null}
# Template for every Checksum REST call
curl -X POST https://api.checksum.ai/public-api/v1/<endpoint> \
  -H "Authorization: Bearer $CHECKSUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
```

### Base URL and versions

Almost everything lives under the **v1** base URL. Two endpoints also have a **v2** with more options. For running tests by name pattern, use v2.

```text v1 base URL theme={null}
https://api.checksum.ai/public-api/v1/
```

```text v2 base URL theme={null}
https://api.checksum.ai/public-api/v2/
```

<div className="ai-ref">
  <Accordion title="Reference for AI: request conventions and API versions" icon="robot">
    | Convention | Rule |
    | - | - |
    | Auth | Every request includes `Authorization: Bearer <YOUR_API_KEY>`. |
    | Bodies | JSON, with `Content-Type: application/json`. |
    | Async work | Endpoints that start agent work return right away with an ID to poll. Execution returns a `runId`. Generation (`202 Accepted`) and healing return a `batchId`. |
    | Polling | Poll runs until `isTerminal` is `true`, and poll batches until `allTerminal` is `true`. Recommended interval 10–30 seconds. |
    | Validation errors | Invalid bodies return `400`. For example, reserved `envOverrides` keys, or a `shardCount` above 40 (rejected, not capped). |

    | Capability | v1 | v2 | Use |
    | - | - | - | - |
    | Run tests by name pattern | `POST /v1/execution/grep`, legacy (`grep` only) | `POST /v2/execution/grep` with `branch`, `envOverrides`, `shardCount`, `autoHeal` | v2 |
    | Status by job name | `GET /v1/execution/status/:jobName` | `GET /v2/execution/status/:jobName` adds `testRunId` when terminal | Prefer [`/v1/execution/status/run/:runId`](/docs/running-tests#check-whether-a-run-passed) for everything new |
    | Everything else | `/v1/…` | n/a | v1 |
  </Accordion>
</div>

## Check that your key works

Before wiring up runs, call `GET /me`. It's a lightweight check that returns the project your key belongs to, and whether a tests repository is connected.

<div className="endpoint"><span className="method get">GET</span><code>[https://api.checksum.ai/public-api/v1/me](https://api.checksum.ai/public-api/v1/me)</code></div>

```bash theme={null}
curl https://api.checksum.ai/public-api/v1/me \
  -H "Authorization: Bearer $CHECKSUM_API_KEY"
```

```json theme={null}
{
  "id": "project-abc-123",
  "name": "My Project",
  "hasTestsRepo": true
}
```

If you get `401`, the key is missing, malformed, or has been rotated. Once this call works, you're ready to [start a run](/docs/running-tests#start-a-cloud-run-from-the-rest-api).

<div className="ai-ref">
  <Accordion title="Reference for AI: GET /me" icon="robot">
    #### GET [https://api.checksum.ai/public-api/v1/me](https://api.checksum.ai/public-api/v1/me)

    Returns basic information about the project the API key belongs to. Use it as a lightweight auth check before triggering runs.

    | Header | Value |
    | - | - |
    | `Authorization` | `Bearer $CHECKSUM_API_KEY` |

    | Response field (200) | Type | Description |
    | - | - | - |
    | `id` | string | Project ID |
    | `name` | string | Project name |
    | `hasTestsRepo` | boolean | Whether a tests repository is connected. Generation and healing PRs require one. |

    | Error | Cause | Fix |
    | - | - | - |
    | `401` | Missing, malformed, or rotated key | Send exactly `Authorization: Bearer $CHECKSUM_API_KEY`, with no stray whitespace or quotes from your secret store |

    Next: trigger a run with an execution endpoint ([Running Tests → execution endpoints](/docs/running-tests#start-a-cloud-run-from-the-rest-api)).
  </Accordion>
</div>

## A typical integration

Most integrations follow the same path: check the key, pick tests, start a run, wait for the verdict, read the details, and heal what broke.

<Steps>
  <Step title="Confirm the key">
    Call [`GET /public-api/v1/me`](#check-that-your-key-works).
  </Step>

  <Step title="Choose tests (optional)">
    `POST /public-api/v1/affected-tests` with your changed files returns the test IDs most likely affected. See [Selecting tests](/docs/running-tests#pick-which-tests-to-run).
  </Step>

  <Step title="Trigger a run">
    Run the suite, a collection, specific tests, or a grep pattern. Add `autoHeal` to heal failures automatically. See [Execution endpoints](/docs/running-tests#start-a-cloud-run-from-the-rest-api).
  </Step>

  <Step title="Poll the run">
    `GET /public-api/v1/execution/status/run/{runId}` until `isTerminal`, then gate on `verdict`. See [Run status](/docs/running-tests#check-whether-a-run-passed).
  </Step>

  <Step title="Read the details">
    Per-test results, HTML report, and attachments. See [Results API](/docs/results-and-reports#get-results-with-the-rest-api).
  </Step>

  <Step title="Heal">
    Include `autoHeal` at step 3, or call `POST /public-api/v1/auto-heal` afterward with the run's UUID. See [Trigger healing](/docs/auto-healing#choose-how-to-start-healing).
  </Step>
</Steps>

<Tip>
  **On GitHub Actions?**

  [`checksum-ai/test-run-action`](/docs/ci-integration#run-checksum-with-the-github-action) wraps steps 2–6 in a single step, including verdict gating and auto-heal.
</Tip>

### Which ID goes where

The most common mistake is passing the wrong ID. Use the run's UUID (`runId`) for status, results, and healing. The job name only works with the legacy status endpoint.

<div className="ai-ref">
  <Accordion title="Reference for AI: which ID goes where" icon="robot">
    | You have | Pass it to |
    | - | - |
    | `runId` (UUID) from an execution call | `/execution/status/run/:runId`, `/test-runs/:id/*`, and `POST /auto-heal` as `testRunId` |
    | `name` (job name, non-sharded runs only) | Legacy `/execution/status/:jobName` only, never to `/auto-heal` |
    | `batchId` from generate or heal | `/auto-generate/batch/:batchId` or `/auto-heal/batch/:batchId` |
    | `checksumTestId` | `POST /execution/tests` (`testIds`), attachments, verdicts |

    The full table, with where each ID comes from, is in [Key Concepts → IDs you'll meet](/docs/concepts#ids-you’ll-meet).
  </Accordion>
</div>

## Current limitations

<Warning>
  **Runs can't be cancelled via the API**

  Cancelling your CI job only stops your workflow from polling. The Checksum run keeps going until it finishes. Plan concurrency settings with this in mind: GitHub Actions' `cancel-in-progress`, for example, cancels your workflow, not the run on Checksum.
</Warning>

A few other things to know: `envOverrides` rejects reserved variable names, the API can read bug entities but not change their status, and sharded runs need a recent `checksumai`.

<div className="ai-ref">
  <Accordion title="Reference for AI: API limitations" icon="robot">
    | Limitation | Details |
    | - | - |
    | No cancel | API-triggered runs can't be cancelled through the public API. Cancelling the CI job stops polling only. |
    | Reserved variables | `envOverrides` rejects `CI` and any key starting with `CHECKSUM_` with `400`. |
    | Bug state is read-only | The API can list bug entities but not change their status. Use the [Feature Health Dashboard](/docs/health-dashboard), or submit per-run [verdicts](/docs/results-and-reports#record-a-verdict-from-your-own-tooling). |
    | Sharding | 2–40 shards per run. Requires `checksumai` 4.4.0 or later on the tests branch (see [Sharding limits](/docs/sharding#current-limits)). |
  </Accordion>
</div>

## Authenticating MCP clients

The [Checksum MCP server](/docs/coding-agents#mcp-server-connect-and-use) (`https://api.checksum.ai/public-api/mcp`) supports two sign-in methods. On your own machine, use **browser sign-in**: you approve the connection while logged in to app.checksum.ai, choose which projects the client may use, and no key is stored. For CI, containers, or clients that only accept a static token, send your **API key** as a bearer header instead.

Browser-sign-in connections belong to *you*, not the project. Review or revoke them from the **MCP connections** card on **My Profile**. An API key is always scoped to one project. Setup per client is on [Coding Agents & MCP](/docs/coding-agents#mcp-server-connect-and-use).

<div className="ai-ref">
  <Accordion title="Reference for AI: MCP authentication" icon="robot">
    | Method | How | Use when |
    | - | - | - |
    | Browser sign-in (recommended) | OAuth approval in your browser while logged in to app.checksum.ai. You choose which projects the client may use. No key is stored. | Claude Code, Cursor, VS Code, and Claude web/desktop on your own machine |
    | API key | `Authorization: Bearer <YOUR_API_KEY>` header in the client config | CI, containers, or clients that only support static tokens |

    Server URL: `https://api.checksum.ai/public-api/mcp`. Browser connections are per user and revocable from **My Profile → MCP connections**. API keys are per project.
  </Accordion>
</div>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Every call returns 401 Unauthorized">
    Check that the header is exactly `Authorization: Bearer <key>`, that there is no stray whitespace or quoting from your secret store, and that the key hasn't been rotated. Call `GET /me` to test the key on its own.
  </Accordion>

  <Accordion title="GET /me returns hasTestsRepo: false">
    No tests repository is connected, so generation and healing can't open PRs. See [Git Integration](/docs/git-integration) or contact your Checksum team.
  </Accordion>

  <Accordion title="My grep run ignores branch or envOverrides">
    Those fields are only supported on the **v2** grep endpoint. Check that you're calling `/public-api/v2/execution/grep`.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Running Tests" icon="play" href="/docs/running-tests">
    Execution and status endpoints.
  </Card>

  <Card title="Key Concepts" icon="book" href="/docs/concepts">
    Outcomes, verdicts, and IDs.
  </Card>
</CardGroup>
