# User journeys

> Map every user-facing CustomDomain™ flow to the surface that implements it: widget for end customers, console and API for developers, and MCP for AI agents.

Source: https://docs.customdomain.ai/docs/user-journeys

The completeness map: every user-facing flow and the surface that implements it.

## Personas

* **Developer / operator**: integrates the product, works in the **console** and
  via the **API**.
* **End customer**: the SaaS's customer connecting their own domain, works in the
  **widget**.
* **Platform operator**: runs and monitors the stack.

## End-customer journeys (widget)

| #  | As a customer, I want to…                          | Surface / path                                                                                                                             |
| -- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| C1 | Enter my domain and have its DNS provider detected | Widget → Domain analysis (`POST /v1/domains:check`)                                                                                        |
| C2 | Connect automatically when possible                | Widget → sign in with the provider (`oauth:start` → callback), one-click setup (`domainconnect:start`) or secure sign-in (`browser:start`) |
| C3 | Get exact records to add when manual               | Widget → Manual config from `GET /v1/connections/{id}/records` (copy buttons)                                                              |
| C4 | Enter a scoped provider credential to auto-write   | Not in the widget, which asks for no key; the console and the API take an API key (`POST /v1/connections/{id}/apply`)                      |
| C5 | See progress until my domain is live               | Widget → In progress (polls status) → Success                                                                                              |
| C6 | Recover from errors / switch to manual             | Widget → Error screen (retry / switch)                                                                                                     |
| C7 | Not lose my place accidentally                     | Widget → exit-confirm + session-expired overlays                                                                                           |
| C8 | Forward my setup to a colleague to finish          | Widget → Share (`loadSharedFlow`, `POST /v1/sharing/connect` → `GET /share/{token}`)                                                       |
| C9 | Buy a new domain from within the widget            | Widget → Buy (`purchaseDomain`, `POST /v1/registrar/checkout` → `/fulfill`)                                                                |

## Developer journeys (console + API)

| #   | As a developer, I want to…                                 | Surface / path                                                                                                                                                                                                                                                                            |
| --- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| D1  | Create and manage applications                             | Console → Applications and each application's page (`POST`/`GET /v1/applications`, `GET`/`PATCH`/`DELETE /v1/applications/{id}`, its keys and connect target)                                                                                                                             |
| D2  | Create, list, and revoke API keys                          | Console → **API & SDK** → API keys (`POST`/`GET`/`DELETE /v1/applications/{id}/keys`)                                                                                                                                                                                                     |
| D3  | Invite teammates and set roles                             | Console → Team (`POST /v1/members`, `PATCH /v1/members/{id}`, `:accept`)                                                                                                                                                                                                                  |
| D4  | Connect a domain from the console                          | Console → Domains (`POST /v1/connections`)                                                                                                                                                                                                                                                |
| D5  | Inspect a connection and drive it                          | Console → Domain detail, for a domain of any application (`GET /v1/connections/{id}`, `/records`, the apply rails, all with the tenant API key)                                                                                                                                           |
| D6  | See which providers auto-configure                         | [DNS providers](/docs/dns/providers) in these docs, or the public `GET /v1/providers` and `/v1/providers/census` (the console has no providers page; each domain's detected provider shows on Domains)                                                                                    |
| D7  | Receive events and inspect deliveries                      | Console → **API & SDK** → Webhooks to register and delete endpoints, and **Activity** for the timeline of deliveries (`POST`/`GET`/`DELETE /v1/webhooks`, `GET /v1/webhook-deliveries`)                                                                                                   |
| D8  | Track usage against quota                                  | Console → Usage (`GET /v1/billing/usage`)                                                                                                                                                                                                                                                 |
| D9  | View and change plan                                       | Console → Billing (`GET /v1/plans`, `POST /v1/billing/checkout`, `/portal`)                                                                                                                                                                                                               |
| D10 | Embed the widget safely                                    | Console → **Widget** (Install, Design, Try it live). Your server mints the token: `POST /api/widget-token` with an API key (console applications) or `POST /v1/tokens` with the client secret (applications created over the API). The widget JWT is app- (and optionally domain-) scoped |
| D11 | Buy a new domain, [money-safe](/docs/sell/buying-a-domain) | Console → More → Buy a domain (`/app/sell`: search → in-page checkout authorizes → registration → capture; auto-connected)                                                                                                                                                                |
| D12 | Resume an abandoned setup                                  | Console → Domains → **Finish setup** (reopens the guided flow at the right step)                                                                                                                                                                                                          |
| D13 | Point an agent at the MCP server                           | Console → More → MCP server (`/app/mcp`: endpoint, client setup for Claude Code, Claude Desktop, Codex, Cursor, VS Code, ChatGPT and others, a connection test). Switch it on under Settings → Features                                                                                   |
| D14 | Review and revoke what agents may do                       | Console → More → Agents (`/app/settings/agents`: each grant's agent, application, last use and scopes, with Revoke). It switches on after your first approval on the consent page (`/agent/consent`)                                                                                      |

## AI-agent journeys (MCP)

An agent drives domains through the [MCP server](/docs/mcp/overview), hosted at
`https://mcp.customdomain.ai/mcp`, which wraps the same `/v1` API with twenty-three tools.
A person approves what the agent may do first: see
[Agent access](/docs/agents/overview).

| #   | As an agent, I want to…                                                                                                                     | Tool                                                                                            |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| M1  | Check if a domain is available and priced                                                                                                   | `search-domain-availability`                                                                    |
| M2  | Suggest available domains from keywords                                                                                                     | `generate-domain-suggestions`                                                                   |
| M3  | Register a domain (fail closed behind an authz callback; off on the hosted service)                                                         | `create-domain-order` → `check-order-status`                                                    |
| M4  | Connect a domain the user already owns                                                                                                      | `connect-domain` → `check-connection-status`                                                    |
| M5  | See how a domain can be configured before acting                                                                                            | `discover-provider`                                                                             |
| M6  | Forward a domain to another URL (301)                                                                                                       | `forward-domain` → `check-connection-status`                                                    |
| M7  | Set up email (MX/SPF/DKIM/DMARC) for a domain                                                                                               | `add-email` → `check-connection-status`                                                         |
| M8  | Re-apply a managed connection, or take any connection down (the person confirms the domain first, and the grant needs `domains:disconnect`) | `reapply-connection` / `disconnect-domain`                                                      |
| M9  | See every connected domain and its status (page by page when the list is cut)                                                               | `list-connections`                                                                              |
| M10 | Check a domain's HTTPS certificate                                                                                                          | `check-certificate-status`                                                                      |
| M11 | Find out why a domain is not live, then re-run the check after the fix                                                                      | `diagnose-connection` → `recheck-connection` → `check-connection-status`                        |
| M12 | Find out whether the workspace may connect new domains                                                                                      | `check-billing-status`                                                                          |
| M13 | List the domain purchases                                                                                                                   | `list-domain-orders`                                                                            |
| M14 | Move a domain's nameservers to the application's DNS host, follow the move, and move them back (the person confirms first)                  | `migrate-nameservers` → `check-nameserver-status` / `rollback-nameservers`                      |
| M15 | Use a key the workspace already keeps instead of starting a new sign-in (the person confirms first, and the grant needs `domains:connect`)  | `list-provider-accounts` / `find-saved-access` → `use-saved-access` → `check-connection-status` |


## Platform-operator journeys

| #  | As an operator, I want to…                 | Surface / path                                                                                             |
| -- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| O2 | Serve HTTPS for live domains automatically | Edge on-demand TLS gated by `ask`                                                                          |
| O3 | Provision tenants for signups              | `POST /v1/tenants:provision` (provision secret)                                                            |
| O4 | Keep tenants isolated                      | Tenant-scoped handlers; cross-tenant → 404                                                                 |
| O5 | Keep secrets safe                          | Hashed keys, provider credentials used once or kept encrypted, sealed console key, no key material in logs |

## Coverage note

The `setup_type` values `automatic` and `manual` (plus the sign-in, one-click
setup and secure sign-in rails, and DNS hosting where the application offers it)
are the paths the **widget** drives today, and the API key way belongs to the
console and the API; `async` additionally
powers [managed connections](/docs/connect-flow/managed-connections), and `mcp`
covers agent-driven setup through the [MCP server](/docs/mcp/overview). A connection
can be disconnected with `DELETE /v1/connections/{id}` (reverting a managed template
first); see
[Offboarding](/docs/connect-flow/offboarding).
