# Choose which help center a request acts on

_Category: Authentication_

Every REST API request that reads or changes content acts on exactly one help center. An API key always acts on its own help center. An OAuth access token acts on the only help center it reaches, or on the one you name with the `X-HCio-Site` header.

```
curl "https://api.helpcenter.io/v1/articles?limit=1" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "X-HCio-Site: 1234" \
  -H "Accept: application/json"
```

## API keys: always their own help center

A key belongs to the help center it was created in, and every request with it acts on that help center. The API ignores `X-HCio-Site` and `?site=` on requests made with a key, even when they name another help center. To work with several help centers, create a key in each one. See [API keys](https://developers.helpcenter.io/content/api-keys).

## OAuth tokens: the help centers a token reaches

A token reaches only help centers that meet both conditions:

- The HelpCenter.io account of the person who approved your app owns them.
- The person shared them with your app, on the consent screen or later in **Connected Apps**.

The API checks both on every request, so a change applies to your next request without a new token. When the person stops sharing a help center, requests that name it fail. When they share another one, it becomes reachable.

A help center that belongs to another account can't be shared this way, even when the person is on its team. The consent screen doesn't offer it. To work with it, use an API key created in that help center.

## How the API picks the help center

| The token reaches | You name no help center | You name one it reaches | You name anything else |
| --- | --- | --- | --- |
| One help center | That help center | That help center | `403` `site_forbidden` |
| Several help centers | `400` `site_required`, with their ids | The one you named | `403` `site_forbidden` |
| No help center | `400` `site_required`, with an empty list | Not possible | `403` `site_forbidden` |

If the token reaches one help center, you don't need to name it, but naming it does no harm and keeps your code working when the person shares a second one.

## Name the help center

Send the help center's numeric id in the `X-HCio-Site` header, or in the `site` query parameter:

```
curl "https://api.helpcenter.io/v1/articles?limit=1&site=1234" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json"
```

- **Use the numeric id.** Other values, such as a subdomain or a domain, are refused with `403` `site_forbidden`.
- **The header wins.** When a request carries both, the API uses `X-HCio-Site` and ignores `site`.
- **Two endpoints never need it.** `GET /v1/sites` and `GET /v1/account` describe the credential rather than one help center. They ignore the header and the parameter.

## Find the ids

`GET /v1/sites` lists the help centers the token reaches, ordered by id. It needs the `content.read` scope.

```
curl https://api.helpcenter.io/v1/sites \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json"
```

The response, for a token that reaches one help center:

```
{
  "status": "success",
  "sites": [
    {
      "id": 1234,
      "uuid": "8f14e45f-ceea-4f6a-9d3b-2c5e1a7b9c01",
      "name": "Acme Help",
      "subdomain": "acme",
      "domain": "acme.helpcenter.io",
      "url": "https://acme.helpcenter.io",
      "default_language": "en",
      "visibility": "public",
      "publicly_accessible": true,
      "languages": ["en"],
      "created_at": "2026-09-30 08:03:11"
    }
  ],
  "meta": {
    "items_count": 1
  }
}
```

`GET /v1/account` answers the same question in brief, in `kb.sites_count` and `kb.site_ids`, and needs no scope. Every field of both endpoints is in [Sites and account](https://developers.helpcenter.io/content/sites-and-account-api).

Don't keep an id forever. Read `GET /v1/sites` when your app starts a sync, and again whenever a request fails with `site_forbidden`.

## Errors

### 400 site_required

The token doesn't reach exactly one help center, and the request didn't name one. `sites` lists the ids you can name:

```
{
  "status": "error",
  "code": "site_required",
  "message": "This account spans more than one help center. Name the one to act on with the X-HCio-Site header or the site query parameter.",
  "sites": []
}
```

The message is the same when the token reaches no help center at all, as in this example, where `sites` is empty. That happens when the person's account owns no help center, for example someone who only works on another account's help center. Naming an id won't help: ask the person to connect your app with an account that owns the help center, or use an API key from that help center.

### 403 site_forbidden

The request named a help center the token doesn't reach:

```
{
  "status": "error",
  "code": "site_forbidden",
  "message": "The requested site is not part of this account."
}
```

The answer is the same whether the id exists or not, so it tells you nothing about other people's help centers. The usual causes: the person never shared that help center with your app, stopped sharing it in **Connected Apps**, the help center belongs to another account, or the value isn't a numeric id. Read `GET /v1/sites` again rather than retrying.

## AI assistants: add ?site= to the MCP server URL

AI assistants that connect through the [HelpCenter.io MCP server](https://developers.helpcenter.io/content/the-mcp-connector-for-ai-agents) choose the help center once, for the whole connection. When the person shares several help centers, add the id to the server URL when you add it to the assistant:

```
https://mcp.helpcenter.io/?site=1234
```

The MCP tools have no site argument. Without `?site=`, and with more than one help center shared, the tools answer that the connection hasn't said which help center it's for. With exactly one shared help center, no `?site=` is needed. A connection that uses an API key ignores `?site=`, like the API does. See [Connect an AI assistant to your help center](https://developers.helpcenter.io/content/connect-an-ai-assistant-to-your-help-center).

## Related

- [OAuth 2.1 for apps and AI clients](https://developers.helpcenter.io/content/oauth)
- [Sites and account](https://developers.helpcenter.io/content/sites-and-account-api)
- [Scopes](https://developers.helpcenter.io/content/scopes)
- [Connect an AI assistant to your help center](https://developers.helpcenter.io/content/connect-an-ai-assistant-to-your-help-center)
