# Confirm the domains and keep the key of an account sign in

> Confirm the domains and keep the key of an account sign in: CustomDomain™ API reference. Covers request parameters, the request body, responses and error codes.

Source: https://docs.customdomain.ai/docs/api-reference/provider-accounts/keepBrowserSessionAccount

## `POST https://api.customdomain.ai/v1/browser-sessions/{sid}:keep`

**The console only**, for the member who started the account sign in (`POST /provider-accounts:sign-in`). The key that waits (`key_ready`) is kept as a provider account only now, in one step, for the domains the person confirmed: `scope` is always named (`all` of the account's domains, or `selected` ones), and each selected domain must be one the key lists (`422` `domain_not_listed`). A call that is refused keeps nothing and leaves the session waiting inside its ten minutes. The key is claimed for the call, so a double press stores it once (`409` `browser_wrong_state` for the second). A workspace an operator suspended keeps nothing (`403` `workspace_suspended`) and the key still waits.

The account is the workspace's own, made by secure sign in in the console (`origin: browser_agent`, `made_by.how: console_sign_in`), for the application the sign in named, or for every application when it named none. `access` is `continuous` (the default) or `one_time`; a provider whose credential is used once and never kept (see `POST /provider-accounts`) is `one_time` only (`422` `use_once_credential`). `application_ids` shares the key with other applications of the workspace (decision D5): an admin or an owner only (`403`), every id one of the workspace's (`404` otherwise), and a key for every application takes none (`422` `serves_every_application`).

When the workspace already holds a continuous key for the same provider account, for the same application, the new key is swapped into that account instead of adding a row: the answer is `200` with `swapped: true`, the replaced key is named for deletion by hand on the account (`agent_key.old_key`) and in the answer (`replaced_key`: its name and the provider's page that deletes it), and the domains chosen join its scope and never narrow it. Every swap takes an admin, an owner or the member who connected the account, as replacing the key by `POST /provider-accounts/{id}/reconnect` does: another member's keep is `403` whether or not it widens the account, and the key still waits, so the member can cancel the sign in and be told which key to delete. The two keys carry different names (an account sign in names its key to the second), so the one to delete is never the one in use. GoDaddy is the exception until its written permission is on file: its second sign in adds a second row. Every account made, swapped or shared is in the audit log (`provider_account.created`, `.key_replaced` with the name of the key it replaced as `old_key_name`, `.updated`, `.shared`).

A sign in that renews an account (`POST /provider-accounts/{id}/reconnect` with `method` `secure_sign_in`; the session's `renews_account_id` names the account) is kept with an empty body, `{}`: the key swaps into that account's own row and the account keeps its domains, scope, access and applications, so a body that names `scope`, `domains`, `access` or `application_ids` is `400` (the account is changed by `PATCH /provider-accounts/{id}`). It is refused, keeping the key pending, with `404` for an account removed meanwhile, `403` for a member who no longer manages it, `422` `different_account` for a key of another provider account (`domains`, when the proof was the list, names the domains the account holds that the new key does not list), and `422` `account_not_verifiable` for an account that holds no domain and has no account number to compare the key with (remove it and add it again with a new sign in).

A session of another workspace or member, a connect session and an unknown id are `404`; a session that is not waiting for the keep step is `409`, and one whose ten minutes passed `410`.

### Authentication

`apiKey`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `sid` | path | string | yes | The cloud browser session id, `bs_` and 32 hex characters. |

### Request body (JSON)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scope` | `all`, `selected` | no |  |
| `domains` | array of string | no | With `selected`: at least one domain the key lists. With `all`: none. |
| `access` | `continuous`, `one_time` | no |  |
| `application_ids` | array of string | no | The whole set of other applications the key is shared with. Left out, a new account is shared with none and an existing one keeps its shares. |

### Responses

| Status | Description |
| --- | --- |
| `200` | The key was swapped into an account that already existed: the one the workspace held for this provider account, or the one a renewal sign in is for. |
| `201` | The account was made. |
| `400` | Error envelope: {code, title, details}. |
| `401` | Error envelope: {code, title, details}. |
| `403` | Error envelope: {code, title, details}. |
| `404` | Error envelope: {code, title, details}. |
| `409` | Error envelope: {code, title, details}. |
| `410` | Error envelope: {code, title, details}. |
| `422` | `domain_not_listed`, `use_once_credential`, `serves_every_application`, or for a renewal `different_account` (the key is another provider account's) or `account_not_verifiable` (nothing to compare the key with). |
| `503` | Error envelope: {code, title, details}. |

### `200` response body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `account` | object | yes |  |
| `swapped` | boolean | yes | True when the key went into an account the workspace already held. |
| `replaced_key` | object | no | The key a swap took out of use: it is no longer the account's key, and it still lives at the provider (nothing is revoked automatically). Present only when the swap replaced a different key that has a name; absent for a new account and when the new key is the same key. |

The full specification is served at `GET https://api.customdomain.ai/v1/openapi.json`.
