# Connect an agent to Anteproof

Anteproof answers two questions about a package or repository: will it reach its commit target, and will it publish a release, in the 90 days from the day the question was issued. The commit target is the repository's commit total in the 90 days before the question was issued. Each answer is a probability with the date it comes due. A probability is not advice.

## Get a key

Sign in on /account and create a key. Keys start with `ap_`. A key is shown once. We keep a hash of it and its first 7 characters. One account can hold five active keys. Send the key in either header:

- `Authorization: Bearer ap_YOUR_KEY`
- `X-API-Key: ap_YOUR_KEY`

## REST

The base URL is `https://api.anteproof.com`. Answers are JSON. Times are UTC in ISO 8601, and probabilities run from 0 to 1. The full schema is at `/openapi.json`.

```
curl -s "https://api.anteproof.com/v1/risk?q=express" -H "Authorization: Bearer ap_YOUR_KEY"
```

`POST /v1/risk/batch` takes up to 25 packages, and one batch counts as one call.

## MCP

The endpoint is `https://api.anteproof.com/mcp`, over streamable HTTP. For Claude Code:

```
claude mcp add --transport http anteproof https://api.anteproof.com/mcp --header "Authorization: Bearer ap_YOUR_KEY"
```

There are six read-only tools: `dependency_risk`, `search_entities`, `get_entity`, `get_question`, `list_forecasts` and `get_calibration`. Listing the tools works without a key. Calling one needs a key or an OAuth sign-in.

## Limits

A new account starts on a 14-day Pro trial with 20,000 calls a month. After that, the Free plan covers 1,000 calls a month. Calls are counted across all of an account's keys, and the count resets on the 1st (UTC). One REST request or one MCP tool call is one call. Each metered REST answer carries `X-Api-Calls-Used`, `X-Api-Calls-Limit` and `X-Api-Calls-Reset`; MCP answers do not.

- Past the month's allowance: `429 quota_exceeded`, with the reset date.
- More than 20 calls at once on one key, or more than 5 a second after that: `429 rate_limited`, with a `Retry-After` header. A refused call is not counted.
- Under heavy load, `/v1/risk`, `/v1/risk/batch`, `/v1/proof` and `/v1/coverage-preview` can answer `503 origin_busy` with `Retry-After: 5`, or `504 origin_timeout` after 25 seconds.

## When a figure is withheld

A figure we are not willing to stand behind is `null`, never 0. Beside it, a `withheld` object gives the `reason` (`source_degraded`, `source_collapsed`, `resolutions_untrusted` or `insufficient_data`), the `metrics` affected, and a `detail` sentence written for a person to read. A `null` here means "not published". It does not mean zero.

## What `status` means

Every batch row, and every `/v1/risk` answer that finds the package, carries a `status`, always one of: `covered`, `activity_only`, `below_activity_threshold`, `not_collected`, `forecast_pending`, `data_withheld`, `repository_unresolved`, `not_covered`, `ambiguous`, `service_error`. The last three appear only in batch rows: on `/v1/risk`, an unknown or ambiguous name is a `404` instead. A status describes what we hold and can forecast, and says nothing else about the project.

## Where each value comes from

These fields are in the default `/v1/risk` answer, and in batch rows with `view` set to `detail`.

- `as_of`: when the answer was built.
- `chain_head.head_hash`: the head of our append-only forecast log when the answer was built. `/v1/chain/rows` lets you verify it; `/v1/chain/head` and `/v1/anchor/latest` show the current head and the latest receipt.
- `maintenance.<family>`: `window_start` and `window_end` (the question's window), `resolves_at`, `threshold`, `issued_at` (when the latest forecast was issued), and a `url` to the question's page with its history.
- `activity.data_through`: the last day of activity data behind the answer.
- `activity.source_health.<metric>.status`: `healthy`, `degraded`, `collapsed` or `unknown`, with the dates behind it.

## What this is not

A probability is not advice.
