# Appendix — Not for client apps

# Appendix — Not for client apps

[← Contents](README.md) · Previous: [Part 6 — Building the screens](6-screens.md)

What the engine has besides the client API, so client developers know what to ignore and what to ask the
Ringmaster owner for.

---

## A. Engine-internal routes

These answer on the engine's host but are **not** part of the client API. They don't take the client app's key, and
in production they are reachable only inside the voice box's network.

| Route | Who calls it | What for |
|---|---|---|
| `POST /internal/calls/inbound` · `POST /internal/calls/{callId}/turn` | The voice worker | Asks the engine "what next?" on each step of a call (worker token) |
| `GET /internal/audio/tts/{hash}` · `GET /internal/audio/media/{id}` · `POST /internal/tts/claim` · `POST /internal/tts/{hash}` | The voice worker | Audio for calls; turning texts into speech |
| `POST /hooks/livekit` | LiveKit | Room and participant events (signed by LiveKit) |
| `POST /hooks/resume/{token}` | A business's own system | The callback of a Send request block in "wait for callback" mode; the token is single-use and in the URL the block sent (see [Part 5, Send request](5-flow-reference.md#request)) |
| `GET /media/{mediaId}/{hash}.mp3?t=…` | A browser | The signed `previewUrl` of an audio file ([Part 2B](2b-flows.md#e2-list-audio)); no key, expires |
| `/sim/*` | Developers, local only | The phone simulator; never enabled next to a real trunk |
| `/actuator/*` | Monitoring | Health and metrics |

---

## B. What the Ringmaster owner sets up

The owner runs `ringmaster-admin` on the voice box. A client app depends on these; ask the owner for them.

### Client app
| Command | Does |
|---|---|
| `client-app create --name <app> [--webhook-url <url>] [--can-call-url <url>] [--features inbound,callouts,otp,ai] [--rate-limit 50]` | Creates the client app; prints the **API key** and the **webhook secret** once |
| `client-app edit <app> [--webhook-url <url\|none>] [--can-call-url <url\|none>] [--features …] [--rate-limit n]` | Changes them; offers a test webhook after a URL change |
| `client-app features <app> --set inbound,callouts,otp,ai,numbers` | Sets the features ([Part 1 §1.2](1-how-it-works.md#12-getting-access)) |
| `client-app rotate-webhook-secret <app>` | New webhook secret, shown once; signatures use it from that moment — switch at once (refused events are retried for 24 h) |
| `client-app test-webhook <app>` | Sends `test.ping` and shows the answer |
| `client-app list` · `client-app show <app>` | Status, features, rate limit, URLs |
| `client-app suspend <app> --reason <text> [--hard]` · `client-app resume <app>` | Suspended: API calls get `403 CLIENT_SUSPENDED` and call-outs pause. With `--hard`, incoming calls are refused too; without it, callers are still answered |
| `client-app export <app> --out <file.zip>` · `client-app remove <app>` · `client-app purge <app>` | Leaving: export everything, remove (grace period), then delete for good |

### API keys
| Command | Does |
|---|---|
| `key rotate <app>` | A new key (shown once); the old one keeps working until revoked, so both can be used during the switch |
| `key revoke <app> <prefix>` | Stops a key at once |
| `key list <app>` | Keys by prefix, created, last used and from which IP |

### Numbers
| Command | Does |
|---|---|
| `numbers register <e164> [--type REGULAR\|TOLL_FREE]` | Adds a number the owner bought to the pool |
| `numbers allocate <e164> --client <app>` | Gives it to a client app (it shows as `ALLOCATED` in `GET /v1/numbers`) |
| `numbers unallocate <e164>` | Takes it back |
| `numbers trunk-setting [--ip <voice box IP>]` | What to set at the carrier so the number reaches the engine |
| `numbers list` | Every number, its status, client app and account |

### Audit
`audit log [--client <app>] [--since 7d]` — who changed what (owner and client app changes to numbers, apps, keys).

---

## C. Versioning of this API

- Paths start with `/v1`. Within `v1`, the engine only **adds**: new endpoints, new optional request fields, new
  response fields, new enum values, new webhook types and new timeline events. Client apps must ignore fields and
  values they don't know.
- Anything that would break a client app (removing or renaming a field, changing a meaning) comes as `/v2`, with time
  to move.
- The script schema has its own `schemaVersion` ([Part 2A, A2](2a-setup.md#a2-script-schema)).