# For agents

How an AI agent, or the developer building one, gets HalfPoint's data: fixtures, live scores,
venue mappings, grades and a market-implied consensus probability for MLB, NBA, NFL, college football, NHL, the
Premier League, the Bundesliga, LaLiga and the Champions League. Every page of these docs is also Markdown: add `.md` to its path (this one:
[/agents.md](https://docs.halfpoint.tech/agents.md)); [llms.txt](https://docs.halfpoint.tech/llms.txt)
lists them all.

## 1. Try it without a key

The [sample](endpoints/sample.md) answers without a key: one league, delayed, 10 fixtures.

```bash
curl "https://odds.halfpoint.tech/sample/odds?league=nba"
curl "https://fixtures.halfpoint.tech/sample/fixtures?league=nba"
```

## 2. Describe the API to your agent

Both hosts serve an OpenAPI 3.0 description of every route, its parameters and errors, without
a key:

```
https://odds.halfpoint.tech/openapi.json
https://fixtures.halfpoint.tech/openapi.json
```

## 3. Get a key

A key works on both hosts and gets what its [plan](plans.md) includes: Consensus USD 49 a month,
Realtime 249, Risk 799 (or 490, 2,490 and 7,990 a year). Subscribe with a card in a browser at

```
https://account.halfpoint.tech/checkout?plan=consensus      # or realtime, risk; &interval=year
```

The page names the plan, its price and its trial and asks for your email; its button takes you to
Stripe. Consensus and
Realtime start with a 7-day free trial (card required; one trial per customer and email); Risk has
none. The key is shown once after the checkout; it can be rotated after logging in with your email
at `https://account.halfpoint.tech/login`. See [After you pay](after-you-pay.md).

Send it as the `X-Api-Key` header:

```bash
curl -H "X-Api-Key: $HALFPOINT_KEY" "https://odds.halfpoint.tech/odds?league=nba"
```

## 4. Or connect over MCP

An MCP server (streamable HTTP) offers the same data as tools:

```
https://mcp.halfpoint.tech/
```

| tool | does | key |
|------|------|-----|
| `get_sample` | the sample above: `kind` `odds` or `fixtures`, one `league` | no |
| `get_pass_options` | the plans, prices and checkout links | no |
| `list_leagues` | the leagues served | yes |
| `list_fixtures` | a league's schedule on a date | yes |
| `get_live` | score, period and clock of the games being played | yes |
| `get_consensus` | the consensus, of a league or one fixture | yes |
| `get_bet_stop_status` | the bet stop and widened per market | yes, plan risk |

Set the key as a header in the client's config, e.g.:

```json
{
  "mcpServers": {
    "halfpoint": {
      "type": "http",
      "url": "https://mcp.halfpoint.tech/",
      "headers": {"X-Api-Key": "hp_..."}
    }
  }
}
```

`Authorization: Bearer hp_...` works too. A client that can't set headers (some hosted
connectors) can put the key in the URL instead, `https://mcp.halfpoint.tech/?key=hp_...`; prefer
the header where you can. Without a key only `get_sample` and `get_pass_options` answer; the
others say how to get one.

## 5. Or pay with x402

Agents with a wallet can pay in USDC with [x402](https://www.x402.org), without an account.
Payments settle on **Base** (`eip155:8453`) in USDC.

x402 version 2 only: the payment goes in the `PAYMENT-SIGNATURE` header (a v1 client's
`X-PAYMENT` is not read, and gets `402` again). Paying for a request accepts the
[terms](https://halfpoint.tech/terms).

**Per request.** A request without a key to `/odds`, `/fixtures`, `/live` or `/grades` answers
`402` with the payment requirements in the `PAYMENT-REQUIRED` header (scheme `exact`, USDC,
the amount in its smallest unit, the address paid). Retry with `PAYMENT-SIGNATURE`: the answer
comes once the payment is settled, with `PAYMENT-RESPONSE` (the transaction). An x402 client
library does this for you. On `/odds`, `?plan=x402.risk` adds `stop`, `widened` and `range`.
Only an answer that delivers data (`2xx`) is settled: an error is not charged, and a paid request
always gets the full answer, never `304`.

| route | price (USD) |
|-------|-------------|
| `/odds` | 0.01, or 0.05 with `?plan=x402.risk` |
| `/fixtures`, `/live`, `/grades` | 0.002 |

**A pass.** For many calls or the stream, buy a plan for a period: it comes with a key, shown
once, that works until the period ends. A pass bought without a key has no email login: a lost key
is replaced by signing a message with the paying wallet (`POST /x402/key`, see
[After you pay](after-you-pay.md#with-x402-usdc)).

```
POST https://account.halfpoint.tech/x402/pass?plan=realtime&period=24h
```

| pass | price (USD) |
|------|-------------|
| `realtime`, `24h` | 15 |
| `risk`, `24h` | 49 |
| `realtime`, `7d` | 69 |

A payer whose settlements fail repeatedly is refused for a while (`403`); a payer may have 2
paid requests open at once (`429` beyond), and one payment serves one request (`409` while it is
in use by another). While payments are starting up they answer `503` with `Retry-After: 30`. A
pass settled but not recorded answers `500` with its transaction (`tx`): contact us with it.

## Errors your agent should handle

| status | meaning | what to do |
|--------|---------|------------|
| `400` | invalid parameters | fix the request; the body says what |
| `401` | unknown key | check the key |
| `402` | no key, or the key's subscription has lapsed | get a key, renew, or pay with x402: the body names the options |
| `403` | the plan doesn't include this route, or the x402 payer is blocked | a higher [plan](plans.md) |
| `409` | this x402 payment is in use by another request | wait for that request, or sign a new payment |
| `429` | too many requests, or too many streams open for the key | wait `Retry-After` seconds; for streams (no `Retry-After`), close one |
| `451` | not available in your country | |
| `503` | x402 payments not available yet | retry after `Retry-After` seconds |

Errors answer `{"error": "..."}`. See [Errors](errors.md) and [Polling](polling.md): answers carry
an `ETag`, and polling faster than the data changes returns the same answer.
