# Coin & Pike world query API (read-only)

You are talking to the live Coin & Pike world server. This API is read-only: nothing you call here changes the game.
Use it to answer balancing and debugging questions about the production world. Machine-readable schema: `GET /openapi.json`.

## Auth
Every `/v1` route needs `Authorization: Bearer <key>`. Keys look like `cpq_...` and are issued by the owner
(`dotnet TowerDefense.Server.dll query-keys issue <name>` on the server). Missing or bad keys get 401. Each key is
limited to about 120 requests per minute (429 with `Retry-After`). Never paste a key into logs, issues or commits.

## Conventions
- JSON, camelCase. Units are in field names: `...Ticks`, `...Tick` (logical tick), `...Seconds`, `...Bytes`, `...Percent`, `...Gold`.
- Logical time: 10 ticks per second, advancing only while the server runs. Every response carries `elapsedTicks`.
- Lists page with `offset` and `limit`; follow `nextOffset` until it is null.
- Errors: `{"error": "...", "status": 400}`. Unknown query values are rejected with a message listing valid ones.
- `raw` in company detail is the game client's own company view (the domain model), returned as is.

## Endpoints
| Endpoint | Use it for |
|---|---|
| `GET /v1/world` | Clock, content version, counts of companies/accounts/personnel/enemies, primary nation status. Start here. |
| `GET /v1/nations?reports=10` | Every nation: frontier zone, next national battle, collapse/evacuation, the active battle per sector (private), event funding, recent battle reports. |
| `GET /v1/companies` | Paged company table with key stats. Filters: `phase`, `zone`, `minZone`, `nation`, `hasAccount`, `q` (name contains / id prefix). `sort` = zone, wave, kills, losses, desertions, valor, personnel, gold, food, enemies, lastCombat, revision, name; `order` = desc or asc. |
| `GET /v1/companies/{id}?sections=troops,formation&events=25` | One company: summary, personnel by job, depot/exchange stocks, enemies, recent events and the raw client view. `sections` limits `raw` to named top-level keys (`none` drops it); the full view can be large. |
| `GET /v1/events?category=Loss&limit=100` | Recent events across companies, newest first. Filters: `companyId`, `category` (Loss, Territory, Supply, Combat, National, ...), `sinceTick`, `q` (message text). |
| `GET /v1/economy` | Stock distribution per resource (total, mean, median, p90, max) in depots and exchange, open market prices, equipment market, shipments in transit. |
| `GET /v1/combat` | Balancing aggregates: kills/losses/desertions by zone, losses per kill, personnel health and experience by job, active enemies by template, event totals, national battle results. |
| `GET /v1/health` | Process uptime and memory, persistence mode, storage files and free disk, store counters (tick gate waits, commit timings, snapshots). |
| `GET /v1/logs?minLevel=Warning&limit=100` | Recent server warnings and errors (process-local, cleared on restart). |

## Example questions
- "Are players stuck at a zone?" `GET /v1/combat` then compare `byZone[].meanWave`, `lossesPerKill`; drill in with `GET /v1/companies?zone=3&sort=losses`.
- "Why did company X collapse?" `GET /v1/companies?q=X` for the id, then `GET /v1/companies/{id}?sections=troops,depot&events=100` and `GET /v1/events?companyId={id}&category=Loss`.
- "Is food too scarce?" `GET /v1/economy` (`depotByResource.food`, market `openByResource.food`) and `GET /v1/events?category=Supply`.
- "Is the server healthy?" `GET /v1/health` (`status`, `store.advanceGateWaitMaxMs`, `storage.disk.freeBytes`) and `GET /v1/logs`.

## What this exposes
Private company state for every company (personnel, stocks, private combat, national sector participation and
events) plus server metrics. It never returns passwords or their hashes, account emails, session tokens or command
receipts. Treat responses as confidential owner data.

```bash
curl -H "Authorization: Bearer $COIN_AND_PIKE_QUERY_KEY" https://api.coinandpike.com/v1/world
```