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

# API reference

> The Canvas HTTP endpoints and how to authenticate to them.

The Canvas agent server exposes a small HTTP surface: a health check, wallet-authenticated read endpoints that power the dashboards, and the deposit endpoints used by the Base Pay Mini App. There is no separate SDK today — the read endpoints are plain signed `GET`s.

Base URL: the agent server origin (Railway in production).

## Authentication

Read endpoints require a **wallet signature** proving you control the address you're querying. Sign the exact message:

```
Canvas auth: <timestampMs>
```

where `<timestampMs>` is the current Unix time in **milliseconds**. Then send:

| Parameter | Where                                        | Value                               |
| --------- | -------------------------------------------- | ----------------------------------- |
| `wallet`  | query                                        | The address being queried           |
| timestamp | `x-canvas-timestamp` header (or `ts` query)  | The same `<timestampMs>` you signed |
| signature | `x-canvas-signature` header (or `sig` query) | Signature of the message above      |

The server verifies the signature on-chain, so both EOAs and smart-contract wallets (ERC-1271/6492) work. Signatures more than **5 minutes** from the server clock are rejected to limit replay.

## Endpoints

### `GET /health`

Liveness check. No auth. Bound before the database connects so platform health checks succeed during cold start.

### `GET /api/groups`

Auth required. Registered-group listing for the advertiser "available groups" view (marketplace data — any valid signature may browse).

```json theme={null}
[
  { "tg_group_id": 123, "group_title": "Base DeFi Traders", "topic": null, "member_count": 2800, "top_bid": 0.12 }
]
```

### `GET /api/advertiser?wallet=<address>`

Auth required. Campaigns and totals for the authenticated advertiser wallet. Returns `404` if no advertiser account is linked to the wallet.

```json theme={null}
{
  "wallet": "0x…",
  "campaigns": [ /* … */ ],
  "totals": { "campaigns": 3, "verificationsCompleted": 214, "totalSpend": 32.10 }
}
```

### `GET /api/group-owner?wallet=<address>`

Auth required. Groups, earnings, and totals for the authenticated group-owner wallet. Returns `404` if no groups are registered to the wallet.

```json theme={null}
{
  "wallet": "0x…",
  "groups": [ /* … */ ],
  "totals": { "groups": 2, "totalVerifications": 480, "totalPendingEarnings": 43.20 }
}
```

### `GET /api/deposit/config`

No auth. Returns the escrow address and chain for the deposit Mini App.

```json theme={null}
{ "escrowAddress": "0xf808…101E", "chainId": 8453, "chainName": "Base" }
```

### `POST /api/deposit/confirm`

Confirms a Base Pay deposit against a campaign. Called by the deposit Mini App with a signed payload:

```json theme={null}
{ "paymentId": "…", "campaignId": 42, "amountMicro": "1000000", "exp": 1750000000000, "sig": "0x…", "topup": null }
```

Returns `{ "ok": true, … }` on success, or a `400`/`500` with an `error` on failure.

### `POST /telegram/webhook`

Internal — Telegram delivers bot updates here, validated by the webhook secret header. Not for third-party use.

## Errors

| Status | Meaning                                                          |
| ------ | ---------------------------------------------------------------- |
| `400`  | Missing/invalid wallet or request fields                         |
| `401`  | Missing, malformed, expired, or non-matching signature           |
| `404`  | No account/groups for the wallet                                 |
| `503`  | Signature verification RPC unavailable, or escrow not configured |
