# Get Custom Domains

> GET /v1/kb/knowledge-bases/{id}/domains · Knowledge base API

Source: https://developer.kustomer.com/api/knowledge-base/get-custom-domains

```http
GET https://{orgname}.api.kustomerapp.com/v1/kb/knowledge-bases/{id}/domains
Authorization: Bearer <API key>
```

## Authorization

Requires any one of these roles: `org.permission.kb.read`; or legacy `org.user.content.kb.read`, `org.user.kb.read`, `org.admin.content.kb.read`, `org.admin.kb.read`. The API key or user must hold at least one of them. Legacy roles predate permission sets and still work.

Returns custom domains.

## About Knowledge bases

A knowledge base is one help center site, with its own address, languages, theme and brand. Every org has a default knowledge base, and an org with several brands can add one knowledge base per brand.

A knowledge base is the site that holds your help content: its categories, its published articles, its theme and its settings. Admins manage knowledge bases in the knowledge base settings. Each one belongs to exactly one [brand](https://developer.kustomer.com/api/core-resources#brands), and a brand can have only one knowledge base. The default knowledge base (`default: true`) uses the org's default brand. When you create a knowledge base, Kustomer also creates its root category. If you don't send a `theme`, Kustomer also creates a theme for it from the Midtown template.

#### Addresses

Every knowledge base has a unique `subdomain`. The help center is served at `https://<subdomain>.kustomer.help` for US orgs, `https://<subdomain>.kustomer.support` for EU orgs and `https://<subdomain>.kustomer.info` for India orgs. The default knowledge base's subdomain is the org name. Other knowledge bases must use the org name followed by a hyphen, such as `acme-outdoors`: lowercase letters, digits and hyphens, at most 63 characters, not ending in a hyphen. You can't change `subdomain` or `brand` after you create the knowledge base, and `default` is a reserved `name`.

The public knowledge base endpoints work out which knowledge base to serve from the subdomain of the host you call. Your org host, `https://<org>.api.kustomerapp.com`, serves the default knowledge base. Pass `knowledgeBaseId` to read a different one.

#### Settings

- `languages` maps each language code to `{ enabled, title }`, where `title` is the help center's title in that language. `defaultLanguage` is the knowledge base's main language. New knowledge bases default to `en_us` and the title "Knowledge Base".
- `theme` is the ID of the theme the help center uses. Changing it switches the site's look.
- `logo`, `favicon`, `homepageTitle` and `metaTags` brand the site. `noIndex: true` asks search engines not to index it.
- `baseUrl` overrides the address Kustomer uses when it builds links to the help center.

#### Custom domains

A custom domain serves the help center on your own hostname, such as `help.example.com`. When you add one, Kustomer requests a TLS certificate for it, and `certificateStatus` starts as `PENDING_VALIDATION`. You then add the DNS records that Kustomer provides: one to validate the certificate, and a CNAME that points your hostname at Kustomer. The domain is live once the certificate is `ISSUED` and `domainStatus` changes from `pending` to `ready`.

| `certificateStatus` | Meaning |
| --- | --- |
| `PENDING_VALIDATION` | Waiting for the validation DNS record. |
| `ISSUED` | The certificate is valid. |
| `VALIDATION_TIMED_OUT` | The record wasn't found in time. Update the domain to reissue the certificate. |
| `FAILED`, `EXPIRED`, `REVOKED`, `INACTIVE` | The certificate can't be used. |

Deleting an issued domain starts a removal that runs in the background, and `domainStatus` is `pendingRemoval` until it finishes. Removal can't finish while your DNS still points the hostname at Kustomer, so remove the CNAME record too.

#### Which endpoint to use

| To | Call |
| --- | --- |
| Create a knowledge base for a brand | [`POST /v1/kb/knowledge-bases`](https://developer.kustomer.com/api/knowledge-base/create-knowledge-base) |
| Read or change a knowledge base's settings | [`GET`](https://developer.kustomer.com/api/knowledge-base/get-knowledge-base-by-id) or [`PATCH /v1/kb/knowledge-bases/{id}`](https://developer.kustomer.com/api/knowledge-base/update-knowledge-base) |
| Add a custom domain | [`POST /v1/kb/knowledge-bases/{id}/domain`](https://developer.kustomer.com/api/knowledge-base/create-custom-domain) |
| List custom domains, or check one's status | [`GET …/{id}/domains`](https://developer.kustomer.com/api/knowledge-base/get-custom-domains), with `certificateStatus` to filter, or [`GET …/{id}/domains/{domainId}`](https://developer.kustomer.com/api/knowledge-base/get-custom-domain-by-id) |
| Change the hostname, or reissue a timed-out certificate | [`PUT …/{id}/domain/{domainId}`](https://developer.kustomer.com/api/knowledge-base/update-custom-domain) |
| Remove a custom domain | [`DELETE …/{id}/domain/{domainId}`](https://developer.kustomer.com/api/knowledge-base/delete-custom-domain) |

This reference has no endpoint that lists knowledge bases. To find a knowledge base ID, read the `knowledgeBase` relationship of one of its categories, or the `knowledgeBase` in an article's `categories`. `PATCH` only changes the fields you send. Reads need a knowledge base read role, and writes need `org.admin.kb.write` or the matching permission.

Related: [Brands](https://developer.kustomer.com/api/core-resources#brands), [Knowledge base themes](https://developer.kustomer.com/api/knowledge-base#themes), [Knowledge base categories](https://developer.kustomer.com/api/knowledge-base#categories), [Regions and base URLs](https://developer.kustomer.com/docs/get-started/regions-and-base-urls)

### Recipes

#### 1. Add a language to a help center

Turn on a new language and give the help center a title in it, without dropping the languages it already has.

**Step 1.** [`GET /v1/kb/knowledge-bases/{id}`](https://developer.kustomer.com/api/knowledge-base/get-knowledge-base-by-id.md). Read the knowledge base and keep its `languages` map. Each key is a language code such as `en_us` or `fr`, and each value is `{ enabled, title }`.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/kb/knowledge-bases/$KB_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" > kb.json
```

```bash title="kusty"
kusty api GET /v1/kb/knowledge-bases/$KB_ID --fields attributes.languages > kb.json
```

**Step 2.** [`PATCH /v1/kb/knowledge-bases/{id}`](https://developer.kustomer.com/api/knowledge-base/update-knowledge-base.md). Add the new language to the map and send the whole map back. `PATCH` changes only the fields you send, but it replaces `languages` as a unit, so a map with only the new language would turn the others off.

```bash title="cURL"
curl --request PATCH "https://api.kustomerapp.com/v1/kb/knowledge-bases/$KB_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "$(jq '{languages: (.data.attributes.languages + {fr: {enabled: true, title: "Centre d’aide"}})}' kb.json)"
```

```bash title="kusty"
kusty api PATCH /v1/kb/knowledge-bases/$KB_ID \
  --data "$(jq '{languages: (.data.attributes.languages + {fr: {enabled: true, title: "Centre d’aide"}})}' kb.json)"
```

> Turning a language on doesn't translate anything. Categories need text for it in their `langs`, and each article needs a published version in that language before customers can read it there. See [article versions and languages](https://developer.kustomer.com/api/knowledge-base#articles-versioning-and-languages).

#### 2. Serve the help center on your own domain

Put a knowledge base on a hostname such as `help.example.com` and wait until its certificate is issued and the domain is live.

**Step 1.** [`POST /v1/kb/knowledge-bases/{id}/domain`](https://developer.kustomer.com/api/knowledge-base/create-custom-domain.md). Send the hostname as `domain` (at most 63 characters). Kustomer requests a TLS certificate for it, so the domain starts with `certificateStatus` `PENDING_VALIDATION` and `domainStatus` `pending`. Keep the domain's `id`, and add the DNS records Kustomer provides for it: one that validates the certificate, and a CNAME that points your hostname at Kustomer.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/kb/knowledge-bases/$KB_ID/domain" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"domain": "help.example.com"}'
```

```bash title="kusty"
kusty api POST /v1/kb/knowledge-bases/$KB_ID/domain --field domain=help.example.com
```

**Step 2.** [`GET /v1/kb/knowledge-bases/{id}/domains/{domainId}`](https://developer.kustomer.com/api/knowledge-base/get-custom-domain-by-id.md). Check the domain every few minutes after you add the records. It's live once `certificateStatus` is `ISSUED` and `domainStatus` is `ready`. DNS changes can take a while to propagate, so don't poll in a tight loop.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/kb/knowledge-bases/$KB_ID/domains/$DOMAIN_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/kb/knowledge-bases/$KB_ID/domains/$DOMAIN_ID \
  --fields attributes.certificateStatus,attributes.domainStatus
```

**Step 3.** [`PUT /v1/kb/knowledge-bases/{id}/domain/{domainId}`](https://developer.kustomer.com/api/knowledge-base/update-custom-domain.md). If the validation record wasn't found in time, `certificateStatus` becomes `VALIDATION_TIMED_OUT`. Fix the DNS record, then send the domain again to reissue the certificate. The same call changes the hostname.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/kb/knowledge-bases/$KB_ID/domain/$DOMAIN_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"domain": "help.example.com"}'
```

```bash title="kusty"
kusty api PUT /v1/kb/knowledge-bases/$KB_ID/domain/$DOMAIN_ID --field domain=help.example.com
```

> To find domains that need attention, list a knowledge base's domains with [`GET …/{id}/domains`](https://developer.kustomer.com/api/knowledge-base/get-custom-domains) and `certificateStatus=VALIDATION_TIMED_OUT`. To retire a domain, [delete it](https://developer.kustomer.com/api/knowledge-base/delete-custom-domain) and remove its CNAME record, or the removal can't finish.

#### 3. Launch a help center for a new brand

Give a second brand its own knowledge base, with its own address and the same look as an existing help center.

**Step 1.** [`GET /v1/brands`](https://developer.kustomer.com/api/core-resources/get-brands.md). Find the brand's ID. The default brand already has the default knowledge base, and each brand can have only one, so pick a brand whose `default` is `false` and that has no knowledge base yet.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/brands?pageSize=100" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/brands --all \
  | jq -r 'select(.data.attributes.name == "Acme Outdoors") | .data.id'
```

**Step 2.** [`GET /v3/kb/themes`](https://developer.kustomer.com/api/knowledge-base/get-themes.md). To reuse an existing look, find the theme to share. Otherwise leave `theme` out of the next step and Kustomer creates a new theme from the Midtown template.

```bash title="cURL"
curl "https://api.kustomerapp.com/v3/kb/themes" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v3/kb/themes --all | jq -r '[.data.id, .data.attributes.name] | @tsv'
```

**Step 3.** [`POST /v1/kb/knowledge-bases`](https://developer.kustomer.com/api/knowledge-base/create-knowledge-base.md). Send `name`, `brand` and `subdomain`. The subdomain must be your org name, a hyphen and a suffix, such as `acme-outdoors`, in lowercase letters, digits and hyphens. Neither `brand` nor `subdomain` can change later, so double-check them. Kustomer also creates the knowledge base's root category.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/kb/knowledge-bases" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"name\": \"Acme Outdoors\", \"brand\": \"$BRAND_ID\", \"subdomain\": \"acme-outdoors\", \"theme\": \"$THEME_ID\", \"noIndex\": true}"
```

```bash title="kusty"
kusty api POST /v1/kb/knowledge-bases \
  --field name="Acme Outdoors" --field brand=$BRAND_ID \
  --field subdomain=acme-outdoors --field theme=$THEME_ID --field noIndex:=true
```

> `noIndex: true` asks search engines not to index the new help center while you fill it. Send `noIndex: false` with [`PATCH`](https://developer.kustomer.com/api/knowledge-base/update-knowledge-base) when it's ready to launch. A brand that already has a knowledge base can't get a second one.

### Example object

A real record from [`GET /v1/kb/knowledge-bases/{id}`](https://developer.kustomer.com/api/knowledge-base/get-knowledge-base-by-id.md):

```json
{
  "type": "knowledge_base",
  "id": "5e15fa56a07888001927f8e5",
  "attributes": {
    "name": "default",
    "subdomain": "company",
    "default": true,
    "logo": "https://s.imgur.com/images/icons/icon-60.png",
    "favicon": "",
    "homepageTitle": "asd",
    "includeAllData": true,
    "defaultLanguage": "en_us",
    "baseUrl": "https://company.kustomer.help",
    "languages": {
      "en_us": {
        "enabled": true,
        "title": "asd"
      },
      "af": {
        "enabled": true,
        "title": "afrikaans title"
      },
      "de": {
        "enabled": true,
        "title": "de title"
      },
      "en_gb": {
        "enabled": true,
        "title": "en_gb title"
      },
      "en_ca": {
        "enabled": true,
        "title": "en_ca title"
      },
      "zh_cn": {
        "enabled": true,
        "title": ""
      },
      "es": {
        "enabled": true,
        "title": "es title"
      }
    },
    "noIndex": true,
    "createdAt": "2020-01-08T15:50:46.730Z",
    "updatedAt": "2021-01-22T20:51:40.488Z",
    "modifiedAt": "2021-01-22T20:51:40.488Z"
  },
  "relationships": {
    "org": {
      "links": {
        "self": "/v1/orgs/5e15fa33623f88001a8e0bb5"
      },
      "data": {
        "type": "org",
        "id": "5e15fa33623f88001a8e0bb5"
      }
    },
    "brand": {
      "links": {
        "self": "/v1/brands/5e15fa56623f88001a8e0bc0"
      },
      "data": {
        "type": "brand",
        "id": "5e15fa56623f88001a8e0bc0"
      }
    },
    "modifiedBy": {
      "links": {
        "self": "/v1/users/5e15fa45623f88001a8e0bbb"
      },
      "data": {
        "type": "user",
        "id": "5e15fa45623f88001a8e0bbb"
      }
    },
    "theme": {
      "links": {
        "self": "/v2/kb/themes/600b3ab7569d78162f085eaf"
      },
      "data": {
        "type": "theme",
        "id": "600b3ab7569d78162f085eaf"
      }
    }
  },
  "links": {
    "self": "/v1/kb/knowledge-bases/5e15fa56a07888001927f8e5"
  }
}
```

Fields:

- `attributes.name` (string): The name admins see in the knowledge base settings. `default` is reserved for the default knowledge base, so other knowledge bases can't use it.
- `attributes.subdomain` (string): The help center's address: `https://<subdomain>.kustomer.help` for US orgs, `.kustomer.support` for EU orgs and `.kustomer.info` for India orgs. Set it when you create the knowledge base; it can't be changed later.
- `attributes.default` (boolean): `true` only for the org's default knowledge base, which uses the default brand and is served from your org host. Read-only.
- `attributes.logo` (string): URL of the logo shown in the help center header.
- `attributes.favicon` (string): URL of the icon browsers show in the tab. An empty string means none is set.
- `attributes.homepageTitle` (string): The title of the help center home page. New knowledge bases default to "Knowledge Base".
- `attributes.defaultLanguage` (string): The knowledge base's main language, as a language code such as `en_us`. Defaults to `en_us`.
- `attributes.baseUrl` (string): Overrides the address Kustomer uses when it builds links to the help center. Leave it unset to use the subdomain address.
- `attributes.languages` (object): The help center's languages, keyed by language code, each `{ enabled, title }`. `PATCH` replaces the whole map, so send every language you want to keep.
- `attributes.languages.en_us.enabled` (boolean): Whether this language is turned on for the help center.
- `attributes.languages.en_us.title` (string): The help center's title in this language.
- `attributes.noIndex` (boolean): `true` asks search engines not to index the help center.
- `relationships.brand` (object): The brand this knowledge base belongs to. Set it when you create the knowledge base; it can't be changed.
- `relationships.theme` (object): The theme the help center uses. Send a different theme ID as `theme` on `PATCH` to switch the site's look; the theme must exist in your org.

### Relationships

- Points to **Brands** via `relationships.brand`: Each knowledge base belongs to exactly one brand, and a brand can have only one knowledge base. The default knowledge base uses the org's default brand.
- Points to **Knowledge base themes** via `relationships.theme`: The theme a knowledge base's help center displays. Switching a knowledge base to another theme changes the site's look; editing the theme itself goes through its draft and publish cycle.
- Referenced by **Knowledge base articles** via `relationships.knowledgeBases` (list): The knowledge bases that list an article on their home page, from the article's `knowledgeBases` attribute, where `featured` pins it. Which knowledge bases an article appears in at all follows from its categories.
- Referenced by **Knowledge base categories** via `relationships.knowledgeBase`: Every knowledge base category belongs to one knowledge base, the same as its parent's. Each knowledge base has its own tree, starting from a root category Kustomer creates with the knowledge base.
- Referenced by **Knowledge base forms** via `relationships.knowledgeBase`: The knowledge base a contact form belongs to. A form can belong to one knowledge base, and a knowledge base can have many forms.

### Permissions

Fewest roles for a read-only integration: `org.permission.kb.read`. For every endpoint: `org.permission.kb.read`, `org.permission.kb.create`, `org.permission.kb.update`, `org.permission.kb.delete`.

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Knowledge Base ID |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | integer | no | Page number of results to return. |
| `pageSize` | integer | no | Number of results to return per page. |
| `certificateStatus` | string | no | Filter domains by certificate status. |

## Responses

### 200

OK

### 400

Bad Request

### 401

Unauthorized

### 403

Forbidden

### 404

Not Found

## Example request

```bash
curl --request GET \
  --url 'https://api.kustomerapp.com/v1/kb/knowledge-bases/5e15fa56a07888001927f8e5/domains' \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```
