---
title: "Begin the cloud browser sign in for a connection"
method: POST
path: "/connections/{id}/browser:start"
tags: ["Cloud browser"]
---

# Begin the cloud browser sign in for a connection

`POST /connections/{id}/browser:start`

## Request

- Base URL: `https://api.customdomain.ai/v1`
- URL: `https://api.customdomain.ai/v1/connections/{id}/browser:start`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

**Customer present only.** For a DNS provider with no sign in of its own, the customer signs in to the provider inside a temporary browser that a browser hosting company runs for a few minutes. They type their own username, password and any verification code into the provider's real sign in page, so CustomDomain™ never receives them, and nothing is stored. Our software then reads the provider's DNS page for this one domain, shows the customer the exact changes, and makes them only after the customer approves. It never creates an API key at the provider, and a session never runs without the customer present.

Returns the address of the popup page that shows the browser. Its fragment carries a single use bootstrap code, which no server sees; the popup trades it at `POST /browser-sessions:redeem`. Only an end user's widget token (bound to the domain and to the end user) or the console may start one: an agent, the MCP server and a plain API key are refused with `browser_customer_present_only`. The request must carry an `Origin` header on the server's return origin allowlist. A browser sends one (the widget and the popup do), and the console's server must add it to the call it makes for a customer. A request with no `Origin` at all, such as a server to server call, is refused with `browser_customer_present_only` and a message that says the header is missing; an `Origin` that is not on the list is refused the same way.

A record set an integrator supplied, and any type or value the provider's page cannot write, is refused before the customer signs in (`browser_unsupported_records`, with the types named). The rail is offered only for a provider that has no sign in of its own, and only while the deployment has it on (`rails.cloud_browser` on the domain check).

## Path parameters

- `id` string, required

## Request body

- object
  - `provider` string, required: DNS provider id; defaults to the detected provider.
  - `return_origin` string, required: Web origin the popup posts its result to; must be on the server's allowlist.
  - `consent_version` string, required: The id of the consent text the customer was shown, stored with the session.
  - `locale` string: The language the popup reads in, a plain code such as `en`. Defaults to `en`.
  - `viewport_hint` object: Optional. The size of the popup's live area, so the provider's sign in page fills it at full size. The remote browser is created at this width when it is a whole number from 360 to 600 and at this height when it is a whole number from 480 to 800; a side outside its range is ignored and the provider's default is used for it. Leave it out for the default.
    - `width` integer: Whole CSS pixels, 360 to 600: the live area's width plus the remote page's scrollbar, which the popup clips.
    - `height` integer: Whole CSS pixels, 480 to 800.

## Response `200`

The session was created.

- object
  - `session_id` string, required: The session id, `bs_` and 32 hex characters.
  - `open_url` string, uri, required: The popup page, with `#c=<bootstrap code>&l=<locale>` in its fragment.
  - `vendor` string, required: The browser hosting company, shown to the customer.
  - `expires_at` string, date-time, required: The latest the session can end.

## Other responses

- `400`: Error envelope: {code, title, details}.
- `401`: Error envelope: {code, title, details}.
- `403`: `browser_customer_present_only` (an agent, the MCP server, a plain API key, a request with no `Origin` header, or an `Origin` that is not on the return origin allowlist) or `browser_provider_not_allowed` (the rail is not offered for this provider or workspace, or the provider has a sign in of its own).
- `404`: Error envelope: {code, title, details}.
- `409`: `browser_session_active`: a secure sign in is already running for this domain.
- `422`: `browser_unsupported_records`: the record set cannot be written through the provider's page. `types` names what is in the way.
- `429`: `browser_rate_limited`: too many starts for this domain or workspace. `Retry-After` says when the window turns.
- `503`: `browser_unavailable` (not configured, switched off or paused), `browser_busy` (the browser vendor answered that it is busy right now; try again after `Retry-After`) or `browser_capacity` (the vendor is not answering, or a limit of sessions or monthly minutes is reached). Offer the manual steps.

---

[API](https://skmtc.dev/customdomain/apis/customdomain-control-plane-api.md) · [All operations](https://skmtc.dev/customdomain/apis/customdomain-control-plane-api/llms.txt) · [OpenAPI document](https://skmtc.dev/customdomain/apis/customdomain-control-plane-api/revisions/34d89cb7a7cd?raw)
