# API overview

REST, JSON in and out, versioned under `/v1`. The interactive OpenAPI reference ships with the hosted API at `/api-reference`.

## Base URL

```text
https://api.routergrowth.com/v1
```

## Authentication

Every authenticated endpoint takes a bearer key:

```text
Authorization: Bearer rg_live_...
```

Two environments, chosen by the key, not by a different host:

| Prefix | Environment | Behavior |
| --- | --- | --- |
| `rg_test_` | sandbox | full loop (quote, reserve, settle) against mock providers; simulated data is clearly labeled |
| `rg_live_` | production | live provider routing; a paid call is never served simulated data |

Keys are hashed at rest and shown once at creation. Manage them via [`/v1/api-keys`](/docs/api/keys) or the [dashboard](/dashboard). `POST /v1/discover` is the one public endpoint: it needs no key.

## The endpoints

| Endpoint | What it does |
| --- | --- |
| `POST /v1/discover` | [Search the catalog](/docs/api/discover) by job description. Free, public. |
| `POST /v1/inspect` | [Schema, providers, price, billing conditions](/docs/api/inspect) for one capability. Free. |
| `POST /v1/run` | [Execute a capability](/docs/api/run) with routing and cost caps. Billable. |
| `GET /v1/runs`, `GET /v1/runs/{id}`, `POST /v1/runs/{id}/cancel` | [Run history and control](/docs/api/runs). |
| `GET /v1/wallet`, `/v1/wallet/transactions`, `/v1/wallet/topups/checkout`, `/v1/wallet/auto-topup`, `/v1/referrals` | [Wallet, ledger, top-ups, referrals](/docs/api/wallet). |
| `GET/POST/DELETE /v1/api-keys` | [Key management](/docs/api/keys). |
| `GET/POST/DELETE /v1/connections` | [Bring-your-own-key connections](/docs/api/connections). |

The dashboard's sign-in endpoints (`/v1/auth/*`) issue browser sessions for the [dashboard](/dashboard); API integrations use bearer keys and never need them.

## The error envelope

Every error, from any endpoint, has the same shape:

```json
{
  "error": {
    "code": "insufficient_balance",
    "message": "Top up your wallet to run this call.",
    "request_id": "req_1f2e..."
  }
}
```

Codes are stable and enumerable: see [Errors](/docs/api/errors). Include the `request_id` when writing to support.

## Idempotency

Send an `Idempotency-Key` header on `POST /v1/run` to make it safe to retry. A replayed key returns the original run unchanged, marked with an `Idempotent-Replay: true` response header, and never bills twice.

## Money

All amounts are strings in USD (`"0.05"`), accounted internally in integer microdollars on an immutable ledger. Prices are shown before any call executes; nothing bills without a reserved quote.

## Spend guard

`GET /v1/spend-guard` returns the organization's daily cap (a UTC day), today's spend (settled charges plus open holds) and when it resets. `POST /v1/spend-guard` with `{"enabled": true, "daily_limit": "25"}` switches it on. Once a run would push the day past the cap, it ends as `status: blocked` with error `budget_exceeded` and nothing is charged; raise or disable the cap, or wait for the reset.
