Skip to content

Router.Africa — OpenRouter Dashboard Analysis

Working document. Synthesis of the competitor dashboard screenshots against the scope in dashboard-scope.md, with the org/multi-user decision treated as made.

Source: 39 screenshots in ~/Desktop/OpenRouter Screenshots (taken 2026-09-19, one brand-new empty org, so almost every data screen is an empty state). Shots are cited by timestamp, e.g. (1.57.50).

What the screenshots don’t show (so nothing below claims to know it): sign-in / password reset; onboarding steps 3–5 (the progress dots show 5); the API key reveal-once screen; a populated key list, key edit, rotate or revoke; any populated logs, analytics, or transactions; log row detail; the top-up amount / payment / pending / failed states; member invite, role change, and remove flows (only an Admin role is visible); the workspace-create modal; loading skeletons; any error or rate-limit state; the pages behind Files, BYOK, Presets, Classifiers, Management Keys. Items 4 and 5 below flag where this limits the answer.


Screen Notes Shot
Sign-up modal GitHub / Google / MetaMask as icon-only buttons above the form; first/last name optional; email; password with show toggle and a live “meets all requirements” success line; one consent checkbox covering ToS + Privacy + Model Terms 1.53.40, 1.55.34
Verify-your-email modal Address shown with an edit pencil; “Resend (52)” countdown 1.55.51
Sign-up email Link expires in 10 min; states the requesting IP, city, and UTC time; “safe to ignore” 1.56.04
Onboarding 1/5 — Welcome Three value-prop cards, then Individual vs Organization radio, “You can change this later” 1.56.14
Onboarding 2/5 — Set up org (org path only) Org name prefilled <Name>'s Org; invite-by-email with “Add another”; Back / Continue 1.56.36
Post-onboarding landing Drops the user on the public marketing homepage, logged in, with a “Get API Key” CTA 1.57.05
Screen Notes Shot
Workspace Overview Dismissible feature banner; “No API keys yet → Create API Key” callout; “This Week’s Usage” as three tiles (spend / requests / tokens); 3×3 grid of link cards to every sidebar page 1.57.50
Profile Doubles as a personal dashboard: usage summary with Tokens/Spend/Requests toggle, GitHub-style activity heatmap, key counts, workspace table, “Available Models” by policy level 2.04.47, 2.04.54
Screen Notes Shot
Activity → Overview Tabs: Overview / Trends / Explore / Guardrails. Timezone picker, filter, range picker. KPI tiles: total spend, requests, token volume, cache hit rate, blended $/1M. Panels: Top Users, Top Apps, Usage by model, Usage type, Request volume by model. Every panel has an “Explore ›” drill-in link. 2.05.00

Trends, Explore, and Guardrails tabs were not opened.

Screen Notes Shot
Logs → Generations Tabs: Generations / Upstream Requests / Sessions / Videos / Batches. Refresh, filter, range picker (“1d Past 24 Hours”), kebab. Columns: Date, Model, Provider, App, Input, Output, Cost, Usage Type, plus a column-chooser gear. Empty: “No transactions found — try adjusting the date range or filters” 2.03.16, 2.05.05

Status and latency are not in the default columns. They may be in the column chooser; I can’t tell.

Screen Notes Shot
Key list (empty) Search “by name or paste a key”; filters Owner, Expiration; “New Key” 1.58.20
Create-key modal Owner segmented control (Me / Teammate / Workspace); Name*; Expiration* (1h, 1d, 7d, 30d, 90d, 180d, 1y, none); Credit limit* ($50, $250, $1,000, Custom, No limit); “Reset limit every…” (N/A, daily, weekly, monthly); ⓘ tooltip on every label; Create stays disabled until valid 1.58.24, .36, .41, .55
Teammate picker Search box; empty state “No users found in your organization.” 1.58.29

No per-key model picker exists here. Model restriction lives in Guardrails (below).

Screen Notes Shot
Organization Credits Big “TOTAL AVAILABLE” figure with ⓘ; Buy Credits card (crypto toggle, Add Credits, View Usage, Redeem Promo Code); Auto Top-Up card; Recent Transactions with “0 transactions” footer; “Contact sales” for enterprise billing 2.05.12
Add a Billing Address modal Gate before purchase. Name, country, address line 1. Explains why: “required to verify your identity and help prevent fraud.” Disabled CTA reads “Complete address details to continue” 2.05.20
Account Type (inside Preferences) Tier “Standard”; “Top-up platform fee 5.5%” is stated openly 2.05.58
Screen Notes Shot
Preferences Manage rows for User (credentials, security, delete account), Organization (shows Org ID), Account Type; date format; analytics cookies; browser notifications; 18+ attestations, per user and “on behalf of org” 2.05.58
Notifications Low-balance alert (threshold + email target), model-deprecation and price-drop alerts (to org admins); Slack/webhook delivery is an Enterprise upsell card 2.05.48
Screen Notes Shot
Org menu (top-right) “Hassan’s Org ▾”. Contents not captured all
Workspaces list Name, description, spend vs limit bar, key count, member count. Auto-created “Default Workspace” (“all org members are part of it by default”) 1.57.13
Workspace switcher Sidebar dropdown: workspaces with ✓, “Create Workspace +” 1.57.32
Workspace Settings Created-at/by and copyable ID; name; workspace budget (daily/weekly/monthly/lifetime); “Include BYOK spend” toggle disabled until a budget exists; webhook + signing secret; Save; Delete workspace danger zone, disabled with the reason “You can’t delete your organization’s only workspace” 2.04.28, 2.04.35
Organization Members Search, Role filter; columns Member, Role badge, API Keys, Spend (sortable); kebab; “Manage” button. URL is /settings/organization-members 2.05.39
Guardrails list Named policy bundles with Status, Policies, Members, API Keys. Banner: “Org-level policies are inherited by this workspace” 1.59.55
Guardrail detail Members chips, API keys, four policy rows: Budget, Model & Provider Access, Prompt Injection, Sensitive Info Detection (all “Not configured”) 2.00.57
Organization Privacy Org-wide: per-provider zero-data-retention toggles, data-training toggles, max API-key lifetime, regional routing (Business upsell), allowed/ignored providers, Eligibility Preview (“576 available / 3 unavailable”), prompt-injection allowlist, IP allowlist (Enterprise upsell) 2.00.09, .20, .27
Available Models by level Table of Account / Workspace / Member showing available / partial / unavailable model counts 2.04.54
Screen Notes Shot
Routing Auto Router (cost tier, allow/exclude model lists with wildcards, “prevent overrides”), default provider sort, default/fallback model 2.01.13, .14, .18
Tools ~13 server-tool toggles across five categories 2.02.06, 2.02.12
Observability Grafana Cloud destination form: masked key, test connection, send trace, region checkboxes, metadata opt-ins 2.03.40
Sidebar-only (not opened) Files (Beta), BYOK, Presets, Classifiers (Beta), Management Keys
Top-nav-only (not opened) Models, Benchmarks, Chat, Rankings, Apps, Ori, Docs, ⌘K search

Measured by how much UI the competitor gives it and where it sits in their flow, against your seven areas.

Missing from your scope and needed because of the org decision

Section titled “Missing from your scope and needed because of the org decision”
Gap Why it’s there
Members / invites / roles page Their whole ACCOUNT nav hangs off it. Includes per-member key count and spend
Org switcher and org onboarding fork Individual vs Organization is step 1 of their onboarding
Key ownership (Me / Teammate / Workspace) Their most visible org-driven change to the key form. Answers “whose key is this and what happens when they leave”
Spend attribution by member and by key Top Users panel, Members table columns
Inherited limits, shown as inherited “Org-level policies are inherited by this workspace”; effective-access preview by level

Missing from your scope and worth adding, regardless of orgs

Section titled “Missing from your scope and worth adding, regardless of orgs”
Gap Recommendation
Key expiration A required field on their form and an org-wide “max key lifetime” policy. Cheap, security-relevant, sits naturally beside your spend cap
Notification settings Your Overview promises “alerts (e.g. low balance)” but nothing configures them. They have a dedicated page. Low-balance email is the only one you need at launch
Model/rate browser Your onboarding and per-key pickers need a list of models, and your billing scope needs published rates. It’s one component used three times; give it a home (proposed under Billing, section 6)
Email deliverability and transactional templates Verification, invites, low balance, receipts. Their sign-up email (expiry, IP/location, “ignore if not you”) is a good template
Billing identity capture before first purchase They require a billing address to “prevent fraud”. You’ll likely want name, country, and a business tax ID for receipts in several African jurisdictions. Decide when, not whether
A quickstart on Overview Their Overview has no “here’s your first curl”. Your scope already lands users on “Overview/quickstart”, so this is a place you’ll beat them
Global search (⌘K) Nice-to-have. Skip v1

Present in theirs, deliberately absent from yours

Section titled “Present in theirs, deliberately absent from yours”

Guardrails, Routing, Tools, Presets, Files, BYOK, Classifiers, Observability, Management Keys, Chat/Benchmarks/Rankings. See section 5.


3. Organization / workspace / multi-user assessment

Section titled “3. Organization / workspace / multi-user assessment”

Taking the decision as made. This is what building it from day one entails, and where the cost really sits.

It is not a feature; it’s a tenancy model, and it touches all seven areas. The good news: your request path already speaks account_id (idempotency hash, holds, ledger). If you define account = org and keep API keys carrying that account_id, apps/api doesn’t need to learn about users at all. The work lands in apps/dashboard-api, the schema, and the dashboard. The hot path only changes if you let it.

My gut estimate (not measured): roughly 2–4 extra weeks for a minimal, correct version on top of the single-user dashboard. Most of it is permission checks, invitation edge cases, and tests. Very little is CRUD.

Data model

  • organization (owns the ledger, balance, currency), membership(user, org, role), invitation. Every signup creates an org silently; “Individual” is just an org of one with team UI hidden. This avoids a migration later and removes the competitor’s Individual/Organization fork from your onboarding.
  • Keys gain created_by and an owner (user or org). Their Me / Teammate / Workspace control is the reference.
  • Snapshot the owner on the key, don’t join to membership at read time, so spend attribution survives a member being removed.
  • Better Auth has an organization plugin (orgs, members, invitations, roles). I haven’t verified it fits your Hono-on-Workers setup or your schema, but check it before hand-rolling. It changes the estimate.

Roles (minimum)

Action Owner Admin Member
Top up / view balance view only (decide)
Create keys own keys
Revoke others’ keys
See all members’ usage and logs own only (decide)
Invite / remove / change roles
Delete org, transfer ownership

Their role filter implies more than Admin, but only Admin is visible, so I can’t confirm their set.

Hot path and money

  • Balance contention. If a hold is a row update on one balance row, an org with many keys funnels far more concurrent writes at that row than a solo account. Check how your hold transaction is built before load-testing single-account assumptions.
  • Currency is a property of the org, not the user. One currency per org, chosen at creation, effectively immutable. A wrong default here is expensive to reverse. Members in different countries are an edge case to decide on now.
  • Caps at two levels. Per-key caps (already decided) plus an org-level cap or alert. Their hierarchy is org balance → workspace budget → key limit. The Bifrost-in-USD vs ledger-in-local-currency question you already logged gets harder with a second level.
  • Bifrost’s governance model may have levels above virtual keys. I haven’t checked whether they map to org/team; worth a look before mirroring org limits yourself.

Dashboard

  • Org switcher, members page, invite flow (send, accept, expire, resend, revoke), role-aware nav, org settings.
  • Every existing screen gains a “whose?” dimension: logs show who made the call, usage filters by member and key, billing shows who topped up.
  • Invite edge cases bite: invitee has no account; invitee already has a personal org; invite email differs from the social-login email; expired link.

Ops and compliance

  • Removing a member. Default I’d suggest: revoke their user-owned keys, with an admin option to reassign. Without a rule, someone leaves and production breaks, or worse, keeps working.
  • Audit events from day one even if there is no UI: key created/revoked, top-up, member added/removed, role change. Retrofitting is painful.
  • Retention opt-in interacts with roles. If prompts are saved, who can read them? Org-level opt-in plus admin-visible logs means admins can read members’ prompts. Decide and disclose.

What you can sequence (still without a migration)

Section titled “What you can sequence (still without a migration)”
Day one Later
Org tenancy, memberships, invitations Workspaces (sub-tenancy)
Owner / Admin / Member Custom roles, a billing-only role
Key ownership, revoke-on-removal Guardrail policy bundles
Attribution in logs and usage SSO / SAML, SCIM
Audit event capture Audit log UI, IP allowlist
Org-level low-balance alert Per-member budgets, notification routing

On workspaces specifically: in the screenshots they read as environments within an org (“separate keys, configurations, budgets, and rules”), and they look retrofitted. The Default Workspace copy says “We created this workspace for you with all your existing API keys…”, and there’s an “Introducing Workspaces!” banner. That suggests they layered workspaces on top of orgs by backfilling a default, which you can do too. The only prerequisite is that keys, allowed models, and caps are cleanly keyed to the org. This is the one place I’d sequence rather than build first.

  1. Scope creep through “whose?” Every screen needs an answer. Budget for it up front.
  2. Permission checks scattered in handlers. Centralize authorization in one layer; a missed check is a cross-tenant data leak.
  3. Tenant isolation in analytics. The async pipeline and its store must carry org_id on every event from the start.
  4. Impacted docs. dashboard-scope.md (“No org/team/multi-user screens for now”) and the tech-stack doc’s “explicitly not adopted” list now contradict this decision. Backlog #6 already lists orgs/teams as schema entities.

Ranked by value for you.

Onboarding & auth

  • Live password feedback with a positive line (“meets all the necessary requirements”) instead of only errors.
  • One consolidated consent checkbox covering all legal docs.
  • Verify-email modal with an edit pencil (fix a typo without restarting) and a resend countdown.
  • Security context in the email: expiry, requesting IP, city, time, “safe to ignore”.
  • “You can change this later” under a choice. Fits your pre-checked-defaults model selection.

Empty and loading states

  • Layout-stable empties. Charts keep their dashed grid and axes, KPI tiles show “—” with “No prior data”, so the page doesn’t jump when the first data lands. (I saw no true loading skeletons, so I can’t speak to those.)
  • Empty state anatomy = icon, bold one-liner, one line of instruction, CTA in place (“No API keys yet / Create your first API key…”).
  • Filter-aware empty copy for tables: “Try adjusting the date range or filters”.
  • Disabled-with-reason. The button label or helper text says why: “Complete address details to continue”, “You can’t delete your organization’s only workspace. Create another first.”, “Add a budget to enable this setting.” Adopt everywhere.

API keys

  • Search accepts a pasted key. Great for leak response: paste the exposed key, find whose it is.
  • Preset caps with a Custom option ($50 / $250 / $1,000 / Custom / None). Localize the amounts to the org’s currency.
  • ⓘ tooltips on every label in the create form.
  • Owner segmented control (Me / Teammate / Org) once orgs exist.
  • Reveal-once flow: not captured, so I can’t cite a pattern. My own suggestion, not theirs: modal that can’t be dismissed by an outside click, prominent copy button, an “I’ve saved it” confirm, and a ready-to-paste curl snippet.

Analytics & logs

  • One shared toolbar across Activity and Logs: refresh, filter, range picker with a short chip (“1d”, “1mo”) and label.
  • Timezone selector on analytics (they show GMT+5). Matters for WAT/CAT/EAT users and for whether “today” means what they think.
  • Metric toggle (Tokens | Spend | Requests) driving one chart instead of three.
  • “Explore ›” drill-in on every summary panel, landing on a pre-filtered detail view.
  • Top-N panels (top models, top users) and KPI tiles carrying a delta vs prior period.
  • Column chooser gear on the logs table so density is user-controlled.

Layout & settings

  • Two-column settings sections: icon, title, description on the left; controls on the right (Privacy, Routing, Notifications). Scannable, consistent.
  • Save is disabled until dirty; settings pages open with a small meta header (created at/by, copyable mono ID).
  • Inherited-limit banner with a link to where it’s set. Use this once org-level caps exist.
  • Effective-access preview. “574 available / 2 partial / 3 unavailable” shows the result of stacked rules. A compact “N of M models enabled” chip on each key row gives you the same for per-key allowlists.
  • Link-card grid on Overview (icon, title, one line, chevron), trimmed to three or four cards for you.
  • Members table: name + email, role badge, key count, spend; sortable; role filter.
  • Test Connection before Save (from Observability). Reuse if you ever add webhooks.

Billing

  • Single primary CTA (“Add Credits”) next to the balance, transactions below, refresh top-right.
  • Explain the why of a required field in one sentence (billing address).

Given lean scope, admin-only rate limits, and one-final-rate pricing.

Contradicts your pricing/transparency stance

  • Visible top-up platform fee (5.5%) in Account Type. That’s a cost composition. Your customer sees one rate.
  • Provider-level controls: allowed/ignored providers, per-provider zero-data-retention toggles, data-training toggles, provider sort, regional routing. They expose the provider and cost structure you’ve chosen to hide. Your only privacy control is the retention opt-in already in scope.
  • A “Provider” column in logs and any cache hit rate tile: check with your own pricing stance before showing either.

Contradicts admin-only rate limits

  • Nothing in the screenshots exposes rate limits directly, which is consistent with you. The nearest thing is Guardrails’ “Budget Policies”, which is spend, not rate. Keep spend caps customer-facing and rate limits internal.

Unnecessary complexity for v1

  • Guardrails as a first-class object (named policy bundles assigned to members/keys, four policy types, three inheritance levels). You need two policies, model allowlist and spend cap, on the key, plus org-level defaults. Keep the schema able to hold them at org and key level; skip the abstraction.
  • Prompt-injection and PII detection, allowlists, IP allowlist. Separate products.
  • Routing/Auto Router, Presets, Tools, Files, BYOK, Classifiers, Observability destinations, video webhooks, Chat/Rankings/Benchmarks/Apps. None serve “signup → key → first call”.
  • Logs tabs for Sessions, Videos, Batches, Upstream Requests. One requests table.
  • Profile-as-dashboard (heatmap, streaks, keys summary) duplicating Activity.
  • Enterprise / Business upsell cards inline in settings.
  • Crypto toggle, MetaMask sign-in. Not your audience.
  • Auto top-up. Their copy says it needs “a payment method that supports offline charging.” Check mobile-money and local-card support before promising it; defer.
  • 18+ attestations as product UI. Ask legal; don’t copy speculatively.

Onboarding choices that fight your priority

  • Five-step wizard with an Individual/Organization fork. Yours is three steps; silent personal org removes the fork.
  • Landing on the marketing homepage after onboarding (1.57.05). One click further from a key than it needs to be. Land on Overview with the key visible.
  • Forced choices with no default on key creation (Expiration* and Credit limit* required, “Select…” placeholders). Fine for a deliberate second key; hostile for a first one. Your auto-generated first key should use defaults (a product call: whether the default carries a modest cap).
  • Email verification as a gate before anything else. Suggestion: let users reach the dashboard and get their key, and require a verified email before the first top-up, since no call works without credit anyway. Your call.

Structural confusion

  • The same concept in several places (Members in workspace cards and in ACCOUNT nav; Guardrails in nav and in Activity tabs; key model limits only via Guardrails).
  • Three scopes competing (org menu top-right, workspace switcher top-left, user Profile) with Logs, Activity, and Credits under “ACCOUNT” while the workspace switcher still sits above them. It’s unclear whether they’re filtered by workspace.
  • Preferences mixing user cookie settings, org ID, tier, and attestations.

  • Global top nav mixing marketing and product (Home, Models, Benchmarks, Chat, Rankings, Apps, Ori, Docs), plus ⌘K search and the org menu at far right.
  • Left sidebar with two groups: a workspace-scoped group of 11 (Overview, API Keys, Files, Guardrails, BYOK, Routing, Presets, Tools, Observability, Classifiers, Settings) and an ACCOUNT group of 9 (Profile, Activity, Logs, Credits, Members, Management Keys, Notifications, Privacy, Preferences), with a workspace switcher on top.
  • ~20 sidebar destinations. Depth is shallow but tab-heavy: sidebar → page → tabs → detail (Guardrails › Workspace Guardrail, Observability › destinations › new › grafana).
  • URLs mix two schemes: /workspaces/default/keys, /workspaces/default/routing vs /logs, /settings/organization-members, /settings/notifications.
  • Billing is “Credits” under ACCOUNT; org settings are reached via Preferences → Organization → “Manage”, which lands on Members.

Verdict: the sidebar-plus-switcher skeleton is worth adapting. The ACCOUNT/workspace split and the marketing-in-the-app top nav are not. It’s built for a product with 20 surfaces; you have seven.

Your domain split already helps: marketing, docs, and model pages live on router.africa; the dashboard lives on app.router.africa. So no marketing nav inside the app.

[ Org switcher ▾ ] [ Docs ] [ ⌘K? ] [ User ▾ ]
BUILD MANAGE
Overview Billing (tabs: Balance & top-up · Transactions · Rates)
API Keys Team (Members · Invitations)
Usage (Overview · By model · By key · By member)
Logs Settings (Profile · Security · Organization · Data & privacy · Notifications)
  • Seven sidebar items, two groups. Maps one-to-one onto your seven areas plus Team. Onboarding is a flow, not a nav item.
  • Depth capped at page + tab. Key detail and log-row detail open in a side panel or drawer, not a new route.
  • One switcher (org), no workspace switcher in v1. Put the org in the URL from day one (/o/:orgSlug/keys) even while everyone has one org. Their /workspaces/default/… scheme shows the cost of not deciding: two URL families. If workspaces come later, they slot in as /o/:org/w/:workspace/….
  • Rates live under Billing, as your scope says, but the model/rate list is a shared component that onboarding and the key form reuse.
  • Progressive disclosure for solo users. Team and the org switcher stay hidden (or collapsed to an “Invite teammates” entry in Settings) until there’s a second member or second org.
  • Role-aware nav. Members see Overview, their own Keys, their own Usage; Billing and Team are hidden or read-only. Hide what they can’t use rather than showing dead ends.
  • Flow for the first session (yours, not theirs): Sign up → pick models (defaults pre-checked) → key created and shown once → Overview with a quickstart curl and “Add credits”. Invite teammates is offered after, not before.

  1. Currency per org: fixed at creation? What happens to members in other countries?
  2. Member removal: revoke their keys by default, or reassign? (I’d revoke by default.)
  3. Member visibility: can Members see others’ usage and logs? Can admins read saved prompts if retention is opted in?
  4. Email verification timing: before dashboard, or before first top-up?
  5. First-key defaults: any default spend cap or expiry, or none?
  6. Workspaces: confirm sequencing after orgs (section 3).
  7. Better Auth organization plugin: verify fit before estimating; verify Bifrost’s governance hierarchy.
  8. Spend-cap authority with two levels: which system is authoritative (extends your existing openrouter-api-comparison.md #30 follow-up).

Docs to update once these settle: dashboard-scope.md (Auth section, Overview, API Keys, Billing, plus a new Team section) and the tech-stack doc’s “explicitly not adopted” list.