Router.Africa — Developer API Docs Scope
Backlog item #10. What the customer-facing API documentation must cover, where it lives, and what it depends on. This is the scope of the docs, not the docs themselves. Everything here restates decisions from ../architecture/decisions-log.md; where they disagree, the decisions log wins.
Audience: a developer who already uses the OpenAI or Anthropic SDK and wants to move over in minutes. The website promises “change one line” (website-copy.md), so the docs have to make that true and be honest about where we differ.
Surface documented: api.router.africa, the external API served by apps/api. Not the dashboard API, not the admin API.
1. Principles
Section titled “1. Principles”- One line to switch. The first page a developer sees shows the base URL and key change for the OpenAI SDK, the Anthropic SDK and plain curl. Working example before any explanation.
- Document differences, not the whole OpenAI spec. Link to the upstream reference for request fields we pass through unchanged. Spend our own pages on what is ours: auth, credits, errors, extensions, models and rates.
- Credits wording rule applies. Credits are never money in the docs: no “wallet”, “cash”, currency symbols or refund language on balances (build inventory → Wording rule). Currency appears only where the top-up payment is described.
- Accurate over complete. A behaviour is documented only once it is built and verified. Items still marked “Verify” in
openrouter-api-comparison.md(Responses format,finish_reasonnormalisation) are documented as supported only after they are confirmed. - Written by hand, fully curated. No generated reference, no spec-driven pages. The API can expose far more endpoints than we choose to show, so what is documented is a deliberate editorial decision, page by page. Documented means supported: an endpoint or parameter that has no page is not part of the public contract, even if it works. Adding one to the docs is an explicit act, not a side effect of shipping a route.
2. Content scope
Section titled “2. Content scope”| Section | Covers | Source of truth |
|---|---|---|
| Quickstart | Sign up, get a key, first request in curl, OpenAI SDK (Python, TypeScript) and Anthropic SDK. Streaming example | dashboard-scope.md onboarding flow; the same curl as the dashboard Overview |
| Authentication | Authorization: Bearer key, key format and prefix, shown once, HTTPS only, never put keys in client-side code. Other header forms only if confirmed to reach Bifrost’s VK layer (comparison #6) |
Decisions log → API key security model |
| Endpoints | Chat completions (streaming and not), models list, plus whichever of Responses, Anthropic Messages, and the customer-callable key-info and generation-lookup endpoints we commit to build (comparison #2, #9, #10) | Hand-written reference pages, checked against the built route |
| Models and rates | How to list models, what “model” strings look like, that a model needs an enabled key and a published rate, deprecation policy. Deferred: rates and models docs, and any public rates page, come back later | pricing-model.md → Model availability; decisions log → v1 model list |
| Credits and billing | What a credit is, how a request is charged (Bifrost-reported tokens × the published rate, locked at hold time), holds and what a customer sees when a hold is placed and released, low-balance behaviour, top-up with fee shown before payment. No refunds or cash language | Decisions log → Charge basis, Credit balance & non-refundability, Top-up fee; design-doc.md §5 |
| Errors | Full table: status, error code, meaning, whether to retry. Must include insufficient credits, key revoked/expired/over its spend cap, model not allowed or not enabled, 409 for an in-flight duplicate, 429 rate limited, upstream failure and timeout. Error body shape |
backend-scope.md §3 and §6; comparison 3.4 |
| Rate limits | That limits exist per key, the 429 behaviour and Retry-After if we send it, backoff guidance. Limits are set per org in Admin and not shown to customers, so the docs describe behaviour, not numbers |
Decisions log → Rate limiting; build inventory → Rate limits |
| Idempotency and retries | Automatic short-window duplicate protection, the optional Idempotency-Key header as a Router.Africa extension (with an extra_headers example for the OpenAI SDK), safe retry rules |
Decisions log → Idempotency key design (names this docs item explicitly) |
| Streaming | SSE format, final usage chunk, what is charged if the client disconnects mid-stream (settled on Bifrost-reported partial usage) | Decisions log → Mid-stream client disconnect policy |
| Spend caps and key scoping | Per-key model allowlist, spend cap in credits with reset period, expiry; what error a capped key returns | Build inventory → Features |
| Data and privacy | Prompts and responses are saved by default with per-workspace opt-out, who can read them, that headers and keys are never stored. Must match the terms and privacy policy wording | Decisions log → Audit trail & prompt/response retention; backlog #17 |
| Compatibility notes | What differs from OpenAI and Anthropic: unsupported parameters, no batch endpoint, no :free/:nitro-style variants, no model aliases, no session-sticky routing until built |
Comparison 3.1, 3.2 (Diverge rows); decisions log → Batch/async endpoint |
| Changelog and status | Dated API changes, deprecation notices. Link to the status page (at launch, decided) | New |
Which endpoints appear is a curated list, kept as its own short table in the docs repo (endpoint, status: public / hidden, notes). The proposed launch list and reasoning are in api-surface.md.
Out of scope for the docs: dashboard usage help (a separate help surface, if any), admin app, internal architecture, Niobi payment mechanics beyond what a customer sees, provider names and per-provider behaviour.
3. Dependencies
Section titled “3. Dependencies”The docs can’t be finished before these are settled. Drafting can start on the parts marked ready.
| Needs | Status | Affects |
|---|---|---|
| Backend scope (#4) | Done | Errors, request flow, streaming, idempotency: ready to draft |
| OpenRouter comparison (#1) | Done | Compatibility notes: ready to draft |
| Pricing model (#11) | Done | Credits, models and rates: ready to draft |
| Error catalogue: exact status codes, error codes, body shape | Not defined; to be defined before the apps/api build (decided) |
Errors page. Treat as a contract |
| Which extra endpoints are public at launch (Responses, Messages, key-info, generation lookup) | Proposed in api-surface.md, to confirm |
Endpoints section, compatibility notes |
Rate-limit response contract (Retry-After, x-ratelimit-*) |
Not defined; before the build (decided) | Rate limits page |
| Schema (#6) | Next up | Field names in any endpoint that returns ledger or key data |
| Bifrost verifications in backlog #18 | Open | Auth header forms, models list |
4. Home and approach
Section titled “4. Home and approach”Decided (2026-09-20):
- Hand-written and curated, hosted at
router.africa/docs. No new origin: the four-origin split in the decisions log is unchanged, and the docs are static with no auth and no CORS. - Source lives in the website repo (
router.africa-website, Astro), not the monorepo. The docs are site content and deploy with the site. - Tooling: Astro Starlight, added to the existing website project. It provides the sidebar, search (Pagefind), per-page table of contents, code blocks with copy button, and tabs for curl / Python / TypeScript (tabs need MDX, which Starlight brings in). Docs pages are written as Markdown or MDX under Starlight’s
docscontent collection, so they sit alongside the blog collection insrc/content.config.ts. Starlight’s own layout serves/docs, so it needs theming to match the site (colours, fonts, logo) rather than reusingBaseLayout. - Things to check in a short spike before building the docs:
- Path: Starlight serves from the root of its collection, so files go under
src/content/docs/docs/(or the equivalent) to land atrouter.africa/docs. - i18n clash: the site has Astro i18n set up for en / fr / sw. Starlight has its own locale settings. Confirm the two coexist, with docs English only and the site’s other routes unchanged.
- Sitemap: the site already uses
@astrojs/sitemap. Confirm no duplicate integration or double entries, and keep/internal/filtered. - Adapter: confirm Starlight builds and serves correctly with
@astrojs/cloudflare.
- Path: Starlight serves from the root of its collection, so files go under
- Drift between
apps/apiand the docs: no process for now. Revisit later if it becomes a problem.
| Question | Approach |
|---|---|
| Code samples | curl, Python and TypeScript for every documented endpoint, written by hand |
| Versioning | The API is /v1. Breaking changes need a new version; the changelog records everything else |
| Languages | The site is en / fr / sw. Docs are English only at launch unless decided otherwise (section 6). Starlight has its own i18n, so translating later is possible |
5. Where this touches other docs and work
Section titled “5. Where this touches other docs and work”- Dashboard: the Overview quickstart curl (screen 8) and the key reveal sample curl (screen 6) should be the same snippet as the docs quickstart. A “Docs” link in the dashboard shell and an API reference link on the Rates screen. Small additions to
build-inventory.md. - Website: this is website-repo work: adding Starlight, theming it to match the site, a nav link, and a link from the “change one line” section once the docs exist. Any claim in
website-copy.mdabout compatibility must be matched by a page here. - Backend (
apps/api): the error catalogue and rate-limit headers are build work, not just docs work: define them as a contract with the build. Add to the execution plan (#9). - CI/CD (#13): nothing new; the docs deploy with the website.
- Content logging (#17): the Data and privacy page is a fourth place the default-on disclosure must appear, next to signup, terms and privacy.
6. Decisions and open items
Section titled “6. Decisions and open items”Decided (2026-09-20):
- The error catalogue and rate-limit response headers are defined before the
apps/apibuild. - A status page ships at launch (tooling and location to be chosen).
- The public rates page and the models/rates docs are deferred; they need more supporting content and come back later.
In progress: the launch endpoint list is analysed in api-surface.md (proposed, for confirmation).
Open:
- Confirm the launch endpoint list in
api-surface.md. - Docs language: English only at launch is assumed (the site is en / fr / sw). Say if fr and sw are needed.
- Error format: adopt OpenRouter’s or publish our own (
api-surface.md§5).