<!-- OpenSmartRoute: Platform journeys. https://opensmartroute.ai/docs/PLATFORM_JOURNEYS -->
# Platform journeys: plans, features, navigation, onboarding and offboarding

This document walks through the hosted platform the way a person meets it: what you can do before you sign
up, what happens the moment you do, what each plan unlocks, where every feature lives in the navigation, how a
workspace grows into a team, and how a person, a team or a whole organization leaves cleanly. Every page,
endpoint and price named here exists on the platform today; the reference behind each one is the
[platform guide](https://opensmartroute.ai/docs/PLATFORM.md), the fastest route to a first request is the
[platform quickstart](https://opensmartroute.ai/docs/QUICKSTART_PLATFORM.md), and the REST API reference is at `/docs/api`.

```mermaid
flowchart LR
    V["Visitor<br/>website, docs, estimate"] --> S["Sign up<br/>/platform/signup"]
    S --> N["New user<br/>getting-started checklist"]
    N --> A["Active user<br/>keys, integrations, apps"]
    A --> T["Team<br/>organization, members, tenants"]
    T --> P["Paying workspace<br/>Pro, Team, Enterprise, pay as you go"]
    A --> O["Offboarding<br/>export, revoke, delete"]
    T --> O
    P --> O
```

## 1. Who uses the platform

| Person | What they want | Where they spend their time |
|---|---|---|
| **Visitor** | See whether routing saves money and is real | `/`, `/pricing`, `/models`, `/rankings`, `/compare`, `/roi`, `/estimate`, `/status`, `/docs` |
| **New user** | A first routed request and a reason to come back | `/platform/signup`, the dashboard overview with its checklist, `/platform/playground`, `/platform/dashboard/keys` |
| **Developer** | Wire an application, an IDE or an agent to the router | `/platform/dashboard/keys`, `/integrations`, `/providers`, `/activity`, `/events` |
| **Team admin or owner** | Give a team one router with shared rules, budgets and evidence | `/platform/dashboard/workspace`, `/members`, `/tenants`, `/governance`, `/audit`, `/notifications` |
| **Finance or team lead** | Know what was spent, saved and billed | `/platform/dashboard/usage`, `/savings`, `/impact`, `/spend`, `/billing` |
| **Operator** | Run the deployment itself: users, plans, providers, mail, health | `/platform/admin/...` (the operator console, a separate sign-in) |

Two kinds of identity exist. A **user** signs in to the dashboard (e-mail and password, or Microsoft,
Google, GitHub, GitLab, LinkedIn where the deployment enables them) and belongs to one or more
**workspaces**; an **API key** belongs to a workspace and is what applications send. Operators are a third,
separate directory with their own sign-in at `/platform/admin/login` and two-factor authentication.

## 2. Plans: what each one unlocks

The plan is attached to the workspace, not the person. Every feature a plan sells is live the moment the plan
applies; nothing needs separate activation. Prices and quotas come from one catalogue (`plans.py`), which is
what `/pricing`, *Plan and billing* and `GET /api/v1/info` all read.

| Plan | Price | Requests / month | Beyond the quota | Requests / min | Keys · seats · tenants | Adds | Support |
|---|---|---|---|---|---|---|---|
| **Free** | $0 | 15,000 | refused (`429`) | 30 | 2 · 3 · 0 | Routing decisions with full trace, the OpenAI-compatible proxy, outcome feedback, your own model providers (`byok`) | community |
| **Pay as you go** | $0 / month, prepaid credits | no quota | paid by the token; `402` when credits run out | 300 | 10 · 5 · 0 | + plans (persona -> skill -> model); every model on offer by the token | community |
| **Pro** | $49 / month or $490 / year; 14-day trial | 300,000 | $10 per 100k | 300 | 10 · 10 · 0 | + plans | e-mail, first answer within 48 h |
| **Team** | $199 / month or $1,990 / year | 2,000,000 | $8 per 100k | 1,000 | 25 · 50 · 10 | + tenants, health and learner statistics, hash-chained audit trail | priority, within 8 h |
| **Enterprise** | from $999 / month, through sales | 20,000,000 | $5 per 100k | 3,000 | 100 · 500 · 50 | + organization SSO, region pinning, custom quotas and retention, 99.9 % availability SLA | dedicated, within 4 h |

Quotas count metered requests (a decision, a chat completion or embedding through the proxy, an estimate, a
feedback event) per calendar month (UTC). At 80 % the `quota` alert warns; at 100 % a plan with an overage rate
and a live subscription keeps flowing and is invoiced, any other plan answers `429 monthly quota exhausted` with
`X-Upgrade: true`. `GET /api/v1/quota` tells you where you stand; the same bar sits on the dashboard overview,
the governance page and *Plan and billing*.

### Feature to page map

| Feature id | What it gates | Where it lives | Plans |
|---|---|---|---|
| `route`, `chat`, `trace` | `POST /api/v1/route`, `POST /v1/chat/completions`, the per-request trace | Playground, Activity, Events, Integrations | every plan |
| `feedback` | `POST /api/v1/feedback` - outcomes reach the learners and the rankings | Activity (outcome form), Learning | every plan |
| `byok` | Your own model providers execute the chosen target | Model providers | every plan |
| `plan` | `plan: true` - persona -> skill -> model composition | Integrations, Playground | Pay as you go, Pro, Team, Enterprise |
| `tenants` | Per-tenant constraints, budgets and tenant-pinned keys | Tenants, API keys | Team, Enterprise (enterprise edition) |
| `stats` | Health snapshot, learner statistics, deployment alerts | Health, Learning | Team, Enterprise (enterprise edition) |
| `audit` | Hash-chained decision trail with verification and export | Audit trail | Team, Enterprise (enterprise edition) |
| `sso` | Organization single sign-on with role mapping | Workspace | Enterprise |

The sidebar marks pages the plan does not include with a lock and the page names the cheapest plan that has
the feature with an *Upgrade* button. A `403` with `X-Upgrade: true` is the API's way of saying the same.
On a deployment running the community edition, tenants, statistics and audit are not exposed whatever the plan
(`403` with `X-Edition: enterprise`).

## 3. Navigation

### The website (no account needed)

| Page | What it is for |
|---|---|
| `/` | The landing page with live deployment figures (`GET /api/v1/stats/public`) and the status pill |
| `/pricing` | The plan ladder with the monthly / annual switch and *Talk to sales* for Enterprise |
| `/models`, `/vendors`, `/providers` | Every routing target with cost, latency and health; one page per LLM vendor; what the deployment executes on |
| `/rankings` | Targets ranked by observed quality per domain, and the model leaderboard from published benchmarks |
| `/compare`, `/roi`, `/estimate` | Alternatives side by side, the savings estimate against always calling one model, a quote before routing |
| `/marketplace` | Agents, skills, personas, prompts and stack templates to install |
| `/extension`, `/desktop`, `/downloads` | The browser extension and the desktop app: what they do and how to install them; every installer in one place |
| `/blog` | Posts, written and published through the platform's own router |
| `/status` | Readiness checks polled every 15 s next to the deployment-wide figures |
| `/support` | The support and *Talk to sales* forms (`/support#sales`, `?plan=` preselects a plan) |
| `/newsletter` | What the daily issue contains and the double opt-in form |
| `/terms`, `/privacy` | The terms of service and the privacy notice, with the version in effect |
| `/docs` | This documentation, the REST API reference at `/docs/api`, the changelog at `/docs/changelog` |
| `/platform/playground` | Route a request in the browser - *Get an answer*, *See the decision* or *Compare models* - and copy the equivalent `curl`; the page asks for a (free) sign-in first, because decisions are metered on your workspace |

### Sign-in and account pages

`/platform/signup`, `/platform/login`, `/platform/forgot-password`, `/platform/reset-password?token=...`,
`/platform/verify-email?token=...`, `/platform/invite/<token>`, `/platform/cli/authorize` (the device sign-in
approval page the CLI, the browser extension and the desktop app open), `/platform/email/preferences?token=...`
(the switches behind every optional e-mail, no sign-in needed) and `/platform/logout`. Links minted before the
`/platform` prefix existed redirect to their new home with the query string intact.

### The dashboard sidebar

The dashboard is everything under `/platform/dashboard`. The header carries the **workspace switcher**
(personal workspace and every organization you belong to), the **notifications bell** with the unread count,
the theme toggle, the **assistant** and the account menu (docs, support, sign out; the way back to the console
when an operator session exists). The sidebar is grouped as follows.

| Section | Page | Path | What you do there | Plan |
|---|---|---|---|---|
| Overview | Overview | `/platform/dashboard` | Requests, tokens and spend of the last 7 days, the quota bar, the 24-hour traffic and latency series, active alerts, the getting-started checklist until it is complete, *What's new* | all |
| Overview | Activity | `/platform/dashboard/activity` | Every metered request (endpoint, target, domain, complexity, tokens, outcome - never the prompt); open the trace drawer, report an outcome, download the trace as JSON, share `?request_id=` | all |
| Overview | Human queue | `/platform/dashboard/handoffs` | Requests the router deferred to a person; a teammate answers or withdraws them | all |
| Insights | Usage | `/platform/dashboard/usage` | Per day, target, endpoint, app and tenant; CSV export | all |
| Insights | Savings | `/platform/dashboard/savings` | Routed cost against a baseline model; CSV export for finance | all |
| Insights | AI spend | `/platform/dashboard/spend` | What the browser extension observed the team spend outside the router against the router's quote | all |
| Insights | Impact | `/platform/dashboard/impact` | The one-page value report: cost saved, requests and success, data protected, governance score; per key, tenant or client app | all |
| Build | API keys | `/platform/dashboard/keys` | Create, name, scope, limit, rotate and revoke keys; pin a key to a tenant | all |
| Build | Apps | `/platform/dashboard/apps` | Install the browser extension and the desktop app, see whether each is connected and what it sent, the CLI / SDK sign-in | all |
| Build | Model providers | `/platform/dashboard/providers` | Connect your own Azure OpenAI, Bedrock, Vertex / Gemini, OpenAI, Anthropic or any OpenAI-compatible endpoint; check, map, rotate, remove | all (`byok`) |
| Build | Integrations | `/platform/dashboard/integrations` | SDK snippets with your key (TypeScript, OpenAI Python client, curl) and MCP configuration for VS Code, Cursor, Windsurf, Claude Code and Claude Desktop | all |
| Build | Marketplace | `/platform/dashboard/listings` | What you published and everything you installed | all |
| Operate | Governance | `/platform/dashboard/governance` | Controls in force, compliance posture and score, guard activity, key hygiene, the workspace policy editor, budgets, *Compliance report* download | all |
| Operate | Events | `/platform/dashboard/events` | The router's event history (1 hour to 7 days), filters, search by request or trace id, **Live** follow | all |
| Operate | Learning | `/platform/dashboard/learning` | How the router learns from your outcomes: strategy weights, leaderboards, the routing SLM and the autopilot | all (leaderboards: `stats`) |
| Operate | Health | `/platform/dashboard/health` | Deployment readiness, traffic and latency percentiles, circuit breakers, decision cache | `stats` |
| Operate | Notifications | `/platform/dashboard/notifications` | The alert inbox, delivery channels (e-mail, webhook, Slack, Teams) with *Send test*, the delivery log | all |
| Organization | Tenants | `/platform/dashboard/tenants` | Per-tenant constraints, budgets and spend | `tenants` |
| Organization | Audit trail | `/platform/dashboard/audit` | The hash-chained decision trail with chain verification; CSV / JSONL export | `audit` |
| Organization | Members | `/platform/dashboard/members` | Members, roles and pending invitations of an organization; on a personal workspace, the *become an organization* step | all |
| Organization | Workspace | `/platform/dashboard/workspace` | Name, slug and plan; create or switch to an organization; organization SSO; *Delete organization* | all (SSO: `sso`) |
| Account | Plan and billing | `/platform/dashboard/billing` | Quota, subscription, trial, plan cards, pay as you go, coupons, credits, invoices, usage and charges, service level | all |
| Account | Support | `/platform/dashboard/support` | Open a ticket, follow the conversation live, close it | all |
| Account | Account | `/platform/dashboard/account` | Sign-in identities, password, browser sessions, e-mail preferences, agreements, *Download my data*, *Delete my account* | all |

Every table with *Export CSV* downloads exactly the rows shown. A failed read says what it means (session
expired, feature not on the plan, budget exhausted with the amounts, rate limit with the retry delay) with a
*Retry* button.

### The operator console

Operators sign in at `/platform/admin/login`. The console sidebar is grouped into **Deployment** (Overview,
Analytics with the activation funnel, Health, Request log), **Directory** (Users, Workspaces, Tenants, Leads,
Sales, Support, Plans, Billing, Finance, Coupons), **Learning** (Routing SLM), **Platform** (Providers, Offers,
Marketplace, Blog and newsletter, Growth, Model rankings, Services, Notifications, Reports, Automation,
Newsletter, Configuration, Terms and privacy) and **Access** (Operators, Audit log, Mail, Search). Every page and
its endpoints are listed under *Operator console* in the [platform guide](https://opensmartroute.ai/docs/PLATFORM.md#operator-console).

## 4. The new user, step by step

```mermaid
flowchart LR
    A["1 Try it<br/>estimate, compare, roi"] --> B["2 Sign up<br/>key shown once"]
    B --> C["3 Confirm e-mail"]
    C --> D["4 First request<br/>playground or curl"]
    D --> E["5 Connect a provider"]
    E --> F["6 A target answers"]
    F --> G["7 Report an outcome"]
    G --> H["8 Wire your app<br/>SDK, MCP, apps"]
    H --> I["9 Come back<br/>usage, savings, report"]
```

The dashboard overview shows the same steps as the **getting-started checklist** (`GET /api/v1/onboarding`)
until every one is done. Setup steps and first-value milestones are kept apart on purpose: a finished
checklist is not proof the workspace got anything out of the platform - the milestones are.

Not everyone starts at the signup form. **Joining a team by invitation** is the other way in: the invitation
e-mail links to `/platform/invite/<token>` (valid fourteen days), which shows the workspace, the role offered
and the address it was sent to (`GET /api/v1/auth/invites/{token}`). Sign in - or create the account - with
that address and accept (`POST /api/v1/auth/invites/{token}/accept`): you join with the offered role, the
e-mail address counts as confirmed (the invitation reached that inbox) and your session moves to the team's
workspace, so steps 1-3 below are already done. You still get a personal free workspace of your own.

### Step 1 - Try it without an account

`/estimate` quotes a request before it is sent (`POST /api/v1/estimate` is public, rate-limited per IP),
`/compare` puts alternatives side by side, `/roi` estimates the saving against always calling one model, and
`/models` and `/rankings` show every target with its cost, latency and observed quality. None of this needs a
key. The playground itself (`/platform/playground`) asks for the free sign-in first - decisions are metered on
your workspace - which is step 2.

### Step 2 - Sign up

`/platform/signup` with a provider button or an e-mail address (add a password if you want to sign in by
e-mail later; at least 8 characters). Behind it is `POST /api/v1/signup` (five sign-ups per IP address and day).
It creates you, a **personal workspace on the Free plan** and its **first API key**, signs you in and sends a
welcome message and the confirmation link.

:::warning[The API key is shown once]
Copy it into a secret manager before leaving the page. It cannot be shown again; you can create, rotate and
revoke keys at any time on `/platform/dashboard/keys`.
:::

### Step 3 - Confirm your e-mail address

The link in the mail goes to `/platform/verify-email?token=...` (valid three days; `POST /api/v1/auth/verify`).
Signing in through a provider that vouches for the address, accepting an invitation sent to it or completing a
password reset confirms it too. Until then the Account page shows a banner with *Send again*
(`POST /api/v1/auth/verify/send`, once a minute). Checklist step: **Confirm your e-mail address**.

### Step 4 - Route a first request

In the playground - *See the decision* - the request is routed on your workspace, shows the target chosen, the
alternatives and the strategies' scores, and appears on `/platform/dashboard/activity` with its trace. From a
terminal:

```bash
curl -s "$OSR_URL/api/v1/route" -H "Authorization: Bearer $OSR_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "Summarise this contract clause for a non-lawyer"}'
```

Checklist steps: **Create an API key** (already done by signup; `POST /api/v1/keys` for more) and **Route a first
request** (`POST /api/v1/route`).

### Step 5 - Connect a model provider

A routing decision is free; an *answer* needs a target that can execute. **Nothing has to be connected for
that**: the deployment's own providers execute the catalogue's targets for every workspace (on the hosted
platform the Azure OpenAI tiers, the self-hosted Ollama models - Qwen, Gemma, GLM, DeepSeek, gpt-oss - and the
speech server), and `/platform/dashboard/providers` lists them under *Included with the platform* with each
provider's health and the target -> model pairs (`platform_providers` in `GET /api/v1/workspace/providers`;
`GET /api/v1/targets` marks them `executable`). Bringing your own is optional: on the same page pick a preset -
Azure OpenAI, Amazon Bedrock, Google Vertex AI / Gemini, OpenAI, Anthropic, Mistral, Groq, OpenRouter, an
in-house Ollama, vLLM or LiteLLM gateway, any OpenAI-compatible endpoint - paste your own key, *Check* it and map
catalogue targets to models on it. Your key never leaves the workspace; requests to that provider are billed by
the provider to you; targets you did not map keep the platform's providers. Checklist step: **Models ready**
(ticked by the platform's providers or by your own).

### Step 6 - A target answers

Point any OpenAI client at `/v1` with `model: "auto"` (every plan), or send `execute: true` on `/api/v1/route`
(plans with the `plan` feature - Pro and up):

```bash
curl -s "$OSR_URL/v1/chat/completions" -H "Authorization: Bearer $OSR_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "auto", "messages": [{"role": "user", "content": "Summarise this contract clause for a non-lawyer"}]}'
```

The answer carries `X-OSR-Target` and the token usage; the Activity row now has tokens, provider cost and, under
the target, the provider and upstream model that answered (`ollama-qwen3-5-4b / qwen3.5:4b`).
First-value milestone: **A target answered a request (not only a routing decision)**.

### Step 7 - Report an outcome

Expand the Activity row (or open its trace) and report good / poor, a quality score and, optionally, the target
that would have done better; from code, `POST /api/v1/feedback {request_id, target_id, success, quality}`. The
learners update on your own traffic and `/platform/dashboard/learning` shows what changed. Checklist step:
**Report an outcome so the router learns**; milestone: **An answer was reported as good**.

### Step 8 - Wire your application, IDE and apps

- `/platform/dashboard/integrations`: copy-ready snippets with your key - the TypeScript SDK from npm, the
  OpenAI Python client against `/v1`, curl - and MCP configuration for VS Code, Cursor, Windsurf, Claude Code
  and Claude Desktop.
- `/platform/dashboard/apps`: install the **browser extension** (Chrome, Edge and Firefox - Safari is not
  available yet; the pre-send advisor on ChatGPT, Claude, Gemini, Copilot and Perplexity) and the **desktop
  app** (Windows, macOS and Linux; the routed command bar over any application). Both connect
  with a device sign-in: the app shows a code, opens `/platform/cli/authorize`, you approve, and a key labelled
  for that app appears on the keys page. The **CLI** does the same with `osr login`.
- Give a key that leaves your hands the smallest `scopes` (`read`, `route`, `execute`, `feedback`, `manage`),
  an `expires_in_days` and `limits` (daily / monthly budget, requests per minute, allowed targets).

### Step 9 - Come back

The second day is the milestone **Came back on another day**. What brings people back: `/platform/dashboard/usage`
and `/savings` (what routing cost and saved), `/impact` (the one-page report a team lead or auditor takes away),
the weekly **value report** e-mailed to owners (schedule under Account › E-mail: daily, weekly, monthly or off),
alerts in the inbox and by e-mail (quota at 80 %, budgets, error rate, guard activity) and *What's new* on the
overview after each release.

A workspace that has not routed anything a day after signing up receives one **getting-started reminder** with
its next step (category *getting started*, switchable off like every optional mail).

## 5. The existing user: journeys by task

### Developer - day to day

| Task | Where | Notes |
|---|---|---|
| Create a key for a service, CI or a partner | `/platform/dashboard/keys` | Scopes, expiry (1-3650 days), limits; the secret is shown once |
| Rotate a key | Keys page › *Rotate* (`POST /api/v1/keys/{key_id}/rotate`) | New secret for the same key; the old one stops at once, the expiry is kept |
| Find out why a request went where it went | `/platform/dashboard/activity` › trace drawer, or `GET /api/v1/trace/{request_id}` | Signals, admission, ranking, the winner and why, execution, what crossed the boundary |
| Follow the router live | `/platform/dashboard/events` › **Live** | `GET /api/v1/events/stream` |
| Quote before sending | `POST /api/v1/estimate`, the MCP `estimate` tool | Metered as `estimate`; no execution |
| Build a plan (persona -> skill -> model) | `plan: true` on `/api/v1/route` | Plans on Pay as you go, Pro, Team and Enterprise |
| Use the router from an IDE or agent | `/platform/dashboard/integrations` › MCP | Or `osr mcp --remote` from the CLI |
| Answer a deferred request | `/platform/dashboard/handoffs` | Resolving feeds an outcome to the learners |

### Growing into a team

1. **Become an organization.** On a personal workspace the *Members* page offers exactly this: `POST /api/v1/workspace/convert`
   with a name changes only the kind - plan, subscription, keys, tenants and usage stay; you receive a fresh
   free personal workspace alongside. Or create a second workspace with `POST /api/v1/workspaces` and switch
   between them in the header (`POST /api/v1/workspaces/{account_id}/switch`).
2. **Invite people.** `/platform/dashboard/members` › *Invite* (`POST /api/v1/workspace/invites`): the invitee
   gets a link to `/platform/invite/<token>` valid fourteen days; the same link is returned once to you.
   *Resend* issues a fresh link. Seats follow the plan (`max_members`). Checklist step for organizations:
   **Invite a teammate**.
3. **Roles.** `member` routes and reads usage, savings and activity; `admin` also manages keys, tenants,
   members and the workspace name; `owner` grants or removes `owner`, configures SSO and deletes the
   organization. An organization always keeps at least one owner.
4. **One key per person.** In a team workspace, a key per person makes *Impact per API key* the per-person
   view.
5. **Organization SSO** (Enterprise). `/platform/dashboard/workspace` › SSO (`PUT /api/v1/workspace/sso`): the
   company identity provider (Microsoft, Google, GitHub, GitLab, LinkedIn or any OIDC issuer), the allowed
   e-mail domains, a default role and a `role_map` from the provider's group claim, re-applied at every
   sign-in. The sign-in page shows the provider as `org-<slug>`.

### Governance and compliance

| Task | Where |
|---|---|
| Set rules for every request of the workspace (data boundary, deny lists, cost and latency caps, budgets, request logging) | `/platform/dashboard/governance` › policy editor (`PUT /api/v1/policy`, admin) |
| Give a customer or team its own rules and budgets | `/platform/dashboard/tenants` (`PUT /api/v1/tenants`), then a **tenant-pinned key** on the keys page |
| Read the compliance posture and fix what it flags | Governance › posture card; each finding links to the page that fixes it |
| Hand an auditor evidence | Governance › *Compliance report* (`GET /api/v1/governance/report?format=markdown`) |
| Verify the decision trail | `/platform/dashboard/audit` (Team and Enterprise) |
| Be told when something happens | `/platform/dashboard/notifications` › channels (e-mail, webhook, Slack, Teams) |
| See who signed in, changed a role or a key | `GET /api/v1/workspace/audit` (admins); your own history `GET /api/v1/me/audit` |

### Money: usage, savings and billing

| Task | Where |
|---|---|
| What was spent, per day, target, endpoint, app or tenant | `/platform/dashboard/usage` (`GET /api/v1/usage`) |
| What routing saved against a baseline model | `/platform/dashboard/savings` (`GET /api/v1/savings`) |
| The value report for a lead or an auditor | `/platform/dashboard/impact` |
| What the team spends outside the router | `/platform/dashboard/spend` (needs the browser extension) |
| Cap spend | Budgets in the workspace policy, per tenant and per key (`429` with `X-Budget-*` when reached) |
| Upgrade, change interval, cancel | `/platform/dashboard/billing` (owners and admins) |
| Provider cost and the workspace's charge, by day, model, provider, key or tenant | Billing › *Usage and charges* (`GET /api/v1/billing/usage`) |
| Invoices | Billing › invoices (`GET /api/v1/billing/invoices`) |
| The service level this month | Billing › *Service level* (`GET /api/v1/sla`) |

### Support

`/platform/dashboard/support` opens a ticket (subject, category, priority, optionally the request id it is
about). The confirmation carries the reference `OSR-00042`; the conversation updates live, e-mailed links
(`?ticket=OSR-00042`) open it directly, a reply reopens a resolved ticket and *Close* ends it. Tickets from
Team and Enterprise workspaces open at `high` priority at least. The assistant in the header answers from the
documentation first.

## 6. Plan changes

```mermaid
stateDiagram-v2
    [*] --> Free: signup
    Free --> Trial: checkout of a promoted plan, or a coupon
    Free --> Pro: checkout
    Free --> PayAsYouGo: switch on the billing page
    Trial --> Pro: subscription starts
    Trial --> Free: trial ends without payment
    Pro --> Team: plan change in place, prorated
    Team --> Enterprise: through sales
    Pro --> Free: cancel at period end
    Team --> Free: cancel at period end
    PayAsYouGo --> Pro: checkout
```

- **Upgrade.** *Plan and billing* › plan cards › *Subscribe* (`POST /api/v1/billing/checkout {plan, interval}`).
  A workspace without a subscription goes to Stripe Checkout; one that already has a subscription has its
  prices swapped in place with prorations - never a second subscription - and the plan applies at once. The
  first subscription of a workspace starts with the plan's trial (Pro: 14 days; the payment method is
  collected at checkout).
- **Coupons and the launch offer.** A promoted plan starts a free trial without payment; a coupon code entered
  on the billing page (`POST /api/v1/billing/coupons/redeem`) does the same. Owners are mailed three days
  before a coupon trial ends; a trial that ends without a subscription returns the workspace to Free.
- **Pay as you go.** The *Pay as you go* card switches the workspace to the prepaid plan without Stripe
  Checkout; *Buy credits* tops up the wallet, and every model on offer is paid by the token from it.
  `402` when the credits run out.
- **Enterprise.** *Talk to sales* (`/support#sales`) records an inquiry (`OSR-S-00007`); the deal is applied
  by an operator on the workspace, together with custom quotas, retention and region where agreed.
- **Downgrade or cancel.** *Cancel at period end* (`POST /api/v1/billing/cancel`): the plan stays until the paid
  period ends, then the workspace returns to Free; keys, history, members and providers stay. To keep a paid
  plan but change it, use the plan cards. *Manage subscription* opens the Stripe Billing Portal for the
  payment method, billing details and receipts.
- **Payment problems.** A failed charge sets the state to `past_due`, mails the owners a link to update the
  payment method and shows a banner on the billing page; a paid invoice clears it. A subscription Stripe gives
  up on returns the workspace to Free.

What a downgrade removes is exactly what the plan sold: tenants, statistics and audit pages lock again, plans
are refused with `403` and `X-Upgrade: true`, and the quota falls to the new plan's. Data is not deleted by a
plan change.

## 7. Offboarding

Three different things end at three different scopes: a **person leaves a team**, a **person leaves the
platform**, or a **team shuts a workspace down**. Each one has a checklist below. Everything on it is on the
audit trail, so an offboarding can be evidenced afterwards.

### A person leaves a team

The person can go themselves: **Leave** on the members page (`DELETE /api/v1/workspace`) removes their own
membership and moves their session to their personal workspace; an owner hands ownership over first. When the
departure is managed instead, a workspace `admin` or `owner` runs the checklist:

1. **Revoke the keys they held.** `/platform/dashboard/keys` › *Revoke* on every key they created or used
   (`DELETE /api/v1/keys/{key_id}`); one key per person makes this a single row. Keys minted by their
   extension, desktop app or CLI carry those names.
2. **Remove the membership.** `/platform/dashboard/members` › *Remove* (`DELETE /api/v1/workspace/members/{user_id}`).
   Their browser sessions stop reaching the workspace at once; they keep their own personal workspace.
3. **Ownership first.** If they were the last `owner`, grant `owner` to someone else before removing them -
   an organization always keeps one.
4. **SSO-managed teams.** Remove them from the mapped group in the identity provider; with `require_match: true`
   the next sign-in refuses them, and without it they fall back to the default role until removed.
5. **Check the trail.** `GET /api/v1/workspace/audit` shows the removal (`member.removed`), the key revocations
   and their last sign-ins.

### A person leaves the platform

Done by the person on `/platform/dashboard/account`:

1. **Download my data** (`GET /api/v1/me/export?days=`): one JSON document with the profile, identities,
   sessions, memberships and history, and the current workspace with its plan, members, key prefixes, tenants,
   policy, SSO, usage, request log and reported outcomes of up to a year.
2. **Hand over what others depend on.** Transfer `owner` on any organization with other members; an organization
   with other members needs another owner before the account can go. Rotate or revoke keys that live in
   shared systems if a teammate will keep using them - keys belong to the workspace, not to the person.
3. **Cancel a paid subscription on the personal workspace first** (*Plan and billing* › *Cancel at period
   end*, or the Stripe portal). Deleting the account disables workspaces only you belonged to and revokes
   their keys, but it does not cancel a subscription - only *Delete organization* does that immediately.
4. **Switch off the mail you no longer want** meanwhile, under Account › E-mail (or the link in any message).
5. **Delete my account** (`POST /api/v1/me/delete {confirm, password}`): type the e-mail address and, when one
   is set, the password. Sessions, linked identities and memberships go; workspaces only this user belonged to
   (the personal workspace) are disabled and their keys revoked; a notice is e-mailed. The lifecycle log keeps
   the deletion event.

### A team shuts a workspace down

Done by an `owner` of the organization:

1. **Export what finance and compliance need.** *Usage*, *Savings*, *Activity* and *Audit trail* export CSV
   (the audit trail also as the JSONL the offline verifier reads); *Compliance report* on Governance downloads
   the evidence bundle; invoices stay reachable in the Stripe portal.
2. **Decide between cancelling and deleting.** *Cancel at period end* keeps the workspace on Free with its
   history, keys and members - the right choice for a pause. *Delete organization* ends it.
3. **Disconnect clients.** Revoke the keys used by services, CI, the extension and the desktop app so nothing
   keeps calling (`DELETE /api/v1/keys/{key_id}`); remove BYOK providers if the credentials should not remain
   stored (`/platform/dashboard/providers`).
4. **Delete organization** on `/platform/dashboard/workspace` (`POST /api/v1/workspace/delete {confirm, password}`):
   type the organization's name or slug and, when one is set, the password. Keys, members, invitations,
   tenants, policy, the SSO connection, usage and outcomes go at once; a live subscription is cancelled
   immediately - nothing more is billed, the paid remainder is not refunded automatically. Every member keeps
   their personal workspace and their session moves to it. The deletion is on the audit trail (`account.deleted`).

Personal workspaces are not deleted on their own; they go with the user.

### What the platform keeps, and for how long

- **Request rows and traces** follow the deployment's retention (`OSR_PLATFORM_RETENTION_DAYS`) or the
  workspace's own `retention_days` on an Enterprise agreement; `GET /api/v1/governance` reports the value in
  force. Prompt and answer text is stored only where the workspace opted in with `log_payloads`, and
  `DELETE /api/v1/activity/logs` erases it while the decision facts stay.
- **The account audit log** (sign-ins, invitations, roles, removals, deletions, operator actions) is kept as
  evidence of what happened; it names actors and actions, never prompt text.
- **Outgoing mail** sits in the outbox under the deployment's retention; every optional category can be
  switched off by the recipient at any time.
- **Region.** A workspace's keys, usage and traces never leave the regional stack it was created in.

## 8. Operators: onboarding and offboarding users from the console

The operator console mirrors every step above for the people running the deployment:

| Task | Where in the console |
|---|---|
| Watch new workspaces move from signup to a first answer, a good outcome, a return visit and a paid plan; find the ones stuck before their first request and send them the getting-started reminder | Analytics › *Activation funnel*, *Stuck before the first request*, *Send reminders now* |
| Create a user with a personal workspace, plan and first key; re-send or force the e-mail confirmation; issue a reset link | Users › *Create*, the user's page |
| Set a plan by hand (deployments without Stripe), custom quotas, retention and region after a sales agreement | Workspaces › the workspace's page › plan, *Custom quotas and retention* |
| Apply a won deal, run a coupon promotion | Sales, Coupons |
| Offboard a user: disable, sign out everywhere, delete (workspaces they alone belonged to are disabled, keys revoked) | Users › the user's page, or a bulk action on selected rows |
| Offboard a workspace: disable or delete it, remove members, revoke keys | Workspaces › the workspace's page |
| See every lifecycle event, filter by action, actor, user or workspace, export CSV | Audit log |
| Onboard or remove an operator, reset a locked-out operator's two-factor authentication, revoke console sessions | Operators (superadmins) |

Every console action is an API call recorded with `operator:<username>` as the actor, so the same
administration works from scripts with the static admin token.

## 9. Quick reference: the endpoint behind each step

| Step | Endpoint |
|---|---|
| Sign up | `POST /api/v1/signup` |
| Confirm e-mail / send again | `POST /api/v1/auth/verify`, `POST /api/v1/auth/verify/send` |
| Sign in by e-mail; forgot / reset | `POST /api/v1/auth/password/login`, `POST /api/v1/auth/password/forgot`, `POST /api/v1/auth/password/reset` |
| Set, change or remove the password | `POST /api/v1/auth/password`, `DELETE /api/v1/auth/password` |
| Device sign-in (CLI, extension, desktop) | `POST /api/v1/auth/device/code`, `POST /api/v1/auth/device/approve`, `POST /api/v1/auth/device/token` |
| Getting-started checklist | `GET /api/v1/onboarding` |
| Keys | `POST /api/v1/keys`, `PATCH /api/v1/keys/{key_id}`, `POST /api/v1/keys/{key_id}/rotate`, `DELETE /api/v1/keys/{key_id}` |
| Route, execute, quote, feedback | `POST /api/v1/route`, `POST /v1/chat/completions`, `POST /api/v1/estimate`, `POST /api/v1/feedback` |
| Trace and events | `GET /api/v1/trace/{request_id}`, `GET /api/v1/events`, `GET /api/v1/events/stream` |
| Included models and your own providers | `GET /api/v1/workspace/providers`, `GET /api/v1/targets`, `GET /v1/models` |
| Usage, savings, quota, service level | `GET /api/v1/usage`, `GET /api/v1/savings`, `GET /api/v1/quota`, `GET /api/v1/sla` |
| Organization | `POST /api/v1/workspaces`, `POST /api/v1/workspace/convert`, `POST /api/v1/workspaces/{account_id}/switch` |
| Members and invitations | `GET /api/v1/workspace/members`, `POST /api/v1/workspace/invites`, `POST /api/v1/workspace/invites/{id}/resend`, `DELETE /api/v1/workspace/members/{user_id}` |
| Accept an invitation | `GET /api/v1/auth/invites/{token}`, `POST /api/v1/auth/invites/{token}/accept` |
| Leave an organization yourself | `DELETE /api/v1/workspace` |
| Sessions and sign-out | `GET /api/v1/sessions`, `DELETE /api/v1/sessions/{session_id}`, `POST /api/v1/auth/logout` |
| SSO | `PUT /api/v1/workspace/sso` |
| Policy, tenants, governance | `PUT /api/v1/policy`, `PUT /api/v1/tenants`, `GET /api/v1/governance`, `GET /api/v1/governance/report` |
| Billing | `POST /api/v1/billing/checkout`, `GET /api/v1/billing/subscription`, `POST /api/v1/billing/portal`, `GET /api/v1/billing/invoices`, `POST /api/v1/billing/cancel`, `POST /api/v1/billing/coupons/redeem` |
| Reports and e-mail preferences | `PUT /api/v1/workspace/reports`, `GET /api/v1/me/email-preferences`, `PUT /api/v1/me/email-preferences` |
| Support | `POST /api/v1/support/tickets`, `GET /api/v1/support/tickets/{key}`, `POST /api/v1/support/tickets/{key}/messages`, `POST /api/v1/support/tickets/{key}/close` |
| History and export | `GET /api/v1/me/audit`, `GET /api/v1/workspace/audit`, `GET /api/v1/me/export` |
| Delete | `POST /api/v1/me/delete`, `POST /api/v1/workspace/delete` |

## Related

- [Platform quickstart](https://opensmartroute.ai/docs/QUICKSTART_PLATFORM.md) - the first request in five minutes.
- [Platform guide](https://opensmartroute.ai/docs/PLATFORM.md) - every endpoint, header, plan rule and dashboard page in full.
- [Browser extension](https://opensmartroute.ai/docs/EXTENSION.md) and [Desktop app](https://opensmartroute.ai/docs/DESKTOP.md) - the two client apps and how they connect.
- [Cost estimates and the MCP server](https://opensmartroute.ai/docs/MCP.md) - the router inside VS Code, Cursor, Claude and agents.
- [Security](https://opensmartroute.ai/docs/SECURITY.md) - the threat model behind the guard, PII redaction and key scopes.
