Skip to content

Router.Africa — Public API Surface

Which endpoints exist at OpenRouter, which we will have, and which we make public (documented, therefore supported) at launch. Input to api-docs-scope.md (backlog #10). Built from openrouter-api-comparison.md §1, §3 and §4, checked against the decisions log, build-inventory.md and website-copy.md.

Status: proposed, for confirmation. Rows marked Public are what the docs will cover. Anything not public may still exist internally; documented means supported (see api-docs-scope.md §1).

Legend. Ours = whether we will have it at all: Yes, Verify (depends on Bifrost support, backlog #18), Build (custom code in apps/api), No. Public at launch: Yes, Later, No.


1. Inference endpoints (api.router.africa, API-key auth)

Section titled “1. Inference endpoints (api.router.africa, API-key auth)”
OpenRouter Ours Public at launch Reasoning
POST /chat/completions Yes Yes The core product. Comparison #1
POST /messages (Anthropic format) Verify Yes, once verified website-copy.md already tells developers the Anthropic SDK works with a one-line change, so this is a public promise. Bifrost’s /anthropic prefix should cover it; confirm Anthropic-native bodies work end to end (comparison §5). If it fails verification, the website copy must change instead. Path is ours to define (e.g. /v1/messages)
POST /responses (OpenAI Responses) Verify Later unless verified What Codex and the Agents SDK speak. Bifrost support is unclear (comparison #2). Don’t document until it works; not promised anywhere yet
GET /models Yes (key-scoped: Bifrost’s list is VK-aware) Yes Needed by every SDK and by developers picking a model. Fields and any pricing in it are deferred with the rates decision (section 4)
GET /models/user No No Same job as a key-scoped /models. No separate endpoint
/embeddings Not at launch Later Token-priced, so the easiest addition later, but the model catalog and pricing model are built around chat token types. Add with its own rates
/rerank, /images, /videos, /audio/speech, /audio/transcriptions No No Non-token billing dimensions (images, seconds, characters) with no pricing model behind them (pricing-model.md covers token types)
/api/alpha/decisions No No Alpha at OpenRouter; not relevant
OpenRouter Ours Public at launch Reasoning
GET /key (limit, remaining, usage, expiry) Build Yes Comparison #9: customer-callable balance and usage is table stakes for a prepaid product. Returns the key’s spend cap and usage, expiry, and the workspace’s credit balance, all in credits (wording rule). Exact fields are part of the schema and contract work
GET /generation?id= (cost, latency, attempts) Build Later Serves dispute investigation (comparison #10), but the dashboard’s Log detail drawer already covers it for customers. The response must still carry a request id so support and customers can refer to a request
GET /generation/content?id= No No, by decision Stored prompts and responses are readable only by admins and every read is audited (decisions log → Audit trail & prompt/response retention). An API key is not an admin, so this would break that rule
POST /generation/feedback No No Nice to have; not needed
POST /oauth/token (workload identity) No No Explicit v1 non-goal (comparison #13)

3. Management surface (keys, workspaces, guardrails and so on)

Section titled “3. Management surface (keys, workspaces, guardrails and so on)”

All of OpenRouter’s management endpoints (/keys, /workspaces, /guardrails, /byok, /presets, /organization/members, /scim/*, /observability/destinations, /analytics/*, /activity, /files, /containers) are not public at launch.

Our equivalents are the dashboard’s own routes on app.router.africa (apps/dashboard-api, Better Auth session, CORS scoped to the dashboard). They are not an API-key surface and are not in the build inventory as one. Webhooks are already on the “Later” list.

Likely first additions later, if customers ask: a keys provisioning API (for resellers creating keys per end user), then usage and activity queries. BYOK, SCIM and observability destinations are excluded by earlier decisions (no BYOK; SCIM irrelevant to v1).

4. Request and response extensions to document

Section titled “4. Request and response extensions to document”
Item Ours Documented at launch Notes
Idempotency-Key request header Yes (decided) Yes Router.Africa extension; the decisions log already names the developer docs as where it is explained
Request id on every response Build Yes Needed to refer to a request in support; also enables /generation later
usage with token counts Yes Yes Standard
Cost / remaining balance in the response body (comparison #27) Verify → Build Decide Highest-value addition in the comparison, but not yet decided for our credits model. Whether Bifrost returns cost in the body is a verification item. If added, in credits
models[] as an alias for fallbacks (comparison #16) Build (thin) Later Not needed at launch: fallback chains are configured by staff, not per request
session_id sticky routing (comparison #17) Build Later A cost optimisation, not a launch feature
provider, plugins, route, :nitro / :floor variants, ~alias models, auto / pareto / fusion routers No Listed as unsupported Deliberate divergences (comparison #4, #19–21). The Compatibility notes page says so, so ported code fails predictably
Rate-limit response headers (Retry-After, x-ratelimit-*) Build Yes Contract to define with the apps/api build (decided, section 5)
Error format and error types Build Yes See section 5
  • Error catalogue and rate-limit headers are defined before the apps/api build, as a contract the docs depend on. The main choice inside it (comparison #39, #40): adopt OpenRouter’s error.metadata.error_type vocabulary and {error: {code, message, metadata}} envelope so ported client code keeps working, or publish our own. Still to decide; recommend adopting OpenRouter’s shape and a smaller subset of its 27 types that we can actually emit.
  • Status page at launch: yes. Tooling and where it lives are to be chosen.
  • Public rates page and the pricing fields in /models: deferred. Rates and models need more supporting content than fits now; revisit later.
  1. The launch list: Chat completions, Messages (once verified), models list, key info (GET /key); Responses only if it passes verification.
  2. Whether cost and remaining balance appear in the response body at launch (section 4).
  3. Error format: adopt OpenRouter’s, or our own (section 5).
  4. Whether GET /generation (without content) should be public at launch rather than later, if customers need to look up a request programmatically.
  5. Verification items that gate this list, from backlog #18 and comparison §5: Anthropic-native bodies on /anthropic, Responses support, cost in the response body, Authorization: Bearer reaching the VK layer.