# Retrieves all checkpoints with basic details and configuration

`GET /api/accesscontrol/checkpoints`

- **Success:** `200 OK`
- **Products:** Operator (`FOH`), Integrations (`INTEGRATIONS`) (any one of these products, not all)
- **Features:** DataHub (4Global) Integration (`DATAHUB`), TRP Integration (`TRP`), Front of House Generic Access (`FOHGENERIC`) (any one of these features, not all)

HTML version: [Retrieves all checkpoints with basic details and configuration](https://support.gladstonesoftware.cloud/reference/access-control/retrieves-all-checkpoints-with-basic-details-and-configuration)

## Overview

Lists every checkpoint configured in the system, together with the restrictions that apply at each one. A *checkpoint* (also called an entry point) is a physical access point at a site — a turnstile, a door, a reception desk card reader.

This endpoint returns **configuration, not a decision**. It tells you which restrictions a checkpoint enforces and what each restriction does; it does not evaluate a particular member against them. Access control hardware calls this endpoint to cache checkpoint configuration locally, and admin interfaces call it to display and manage that configuration.

Two things about the response are easy to get wrong, and both are covered in the field descriptions below:

- A checkpoint's restrictions come either from a shared profile or from the checkpoint's own configuration, never both. `profileId` tells you which.
- Four restrictions (`ReceptionMessages`, `OfficeMessages`, `UnpaidSales`, `Sites`) are always present on every checkpoint and are returned with no `id`.

## Endpoint

`GET {base_url}/api/accesscontrol/checkpoints`

`{base_url}` is the environment URL issued to your integration. See [Authenticating with Gladstone APIs](../../guides/authenticating-with-gladstone-apis.md).

## Query parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `siteIds` | string | No | Restricts the result to checkpoints at the given sites. Pass a **comma-separated list** of site identifiers, not a single id. Omit it (or send an empty value) to return every checkpoint at every site. Every id you pass must exist, or the whole request fails with `400` and none of the checkpoints are returned; there is no partial match. Each id corresponds to the `siteId` returned on the checkpoints themselves. |

## Sample request

```bash title="cURL"
curl -X GET '{base_url}/api/accesscontrol/checkpoints' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true'
```

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `[].checkpointId` | string | Identifies this checkpoint. Use it as the stable key when caching checkpoint configuration on hardware or correlating a checkpoint across calls. |
| `[].profileId` | string | Identifies the shared restriction profile this checkpoint uses, if it has been assigned one. A profile is a reusable set of restrictions applied across several checkpoints so they can be configured once. **This field determines where `restrictions` came from:** when `profileId` is non-null the entries in `restrictions` are the profile's, and the checkpoint's own individually configured restrictions are not returned at all; when it is null they are the checkpoint's own. Do not merge the two — assigning a profile replaces the checkpoint's restrictions rather than adding to them. |
| `[].siteId` | string | Identifies the site this checkpoint is physically located at. These are the values you pass to the `siteIds` query parameter to filter the list. |
| `[].name` | string | The checkpoint's description, for display to staff — for example on an admin screen or a reader's status display. This is the untranslated base text; for a localised label use `translations` instead. |
| `[].translations` | array of object | Localised variants of the checkpoint's text, one entry per language. Empty when no translations have been configured, in which case fall back to `name`. |
| `[].translations[].type` | string | Identifies which piece of checkpoint text this entry translates, so that a checkpoint can carry translations for more than one attribute. |
| `[].translations[].culture` | string | The language this entry is written in. Match it against the locale you are rendering for, and fall back to `name` when no entry matches. |
| `[].translations[].text` | string | The translated text itself — display this in place of `name` when `culture` matches the locale you are rendering for. |
| `[].restrictions` | array of object | The rules this checkpoint enforces, each pairing a condition (`type`, `id`) with what to do when it is met (`action`). Two kinds of entry are mixed in this one array. The first kind is the configured restrictions, taken from the profile named by `profileId` or, when that is null, from the checkpoint itself. The second kind is four entries that are **appended to every checkpoint unconditionally** — one each for `ReceptionMessages`, `OfficeMessages`, `UnpaidSales` and `Sites` — so the array is never empty and always contains at least those four. Because `Sites` appears in both kinds, you can receive more than one `Sites` entry on the same checkpoint; distinguish them by `id`. |
| `[].restrictions[].id` | string | Identifies the specific value the restriction applies to, interpreted according to `type` — a member status code when `type` is `Status`, a site identifier when it is `Sites`, and so on. **Null on the four always-appended entries** (`ReceptionMessages`, `OfficeMessages`, `UnpaidSales`, `Sites`), because those are checkpoint-wide switches rather than rules about a particular value. Treat a null `id` as "applies to this condition in general" and do not skip the entry. |
| `[].restrictions[].type` | string | What the restriction tests, returned as a **name** rather than a numeric value. One of `Subscriptions`, `ResourceProducts`, `Status`, `Sites`, `Products`, `ReceptionMessages`, `OfficeMessages`, `UnpaidSales` or `PrimaryUnpaidSales`. Together with `id` this forms the condition; `action` says what happens when it is met. |
| `[].restrictions[].action` | string | What the checkpoint must do when the restriction matches, returned as a **name**: `Allow` lets the member through, `Deny` refuses entry, and `Infringe` lets the member through but records an infringement against them — it is not a refusal, so hardware that treats anything other than `Allow` as a rejection will wrongly turn members away. |

## Sample response

```json title="200 OK"
[
  {
    "checkpointId": "string",
    "profileId": "string",
    "siteId": "string",
    "name": "string",
    "translations": [
      {
        "type": "string",
        "culture": "string",
        "text": "string"
      }
    ],
    "restrictions": [
      {
        "id": "string",
        "type": "string",
        "action": "string"
      }
    ]
  }
]
```

## Errors

| Status | Meaning | When |
|--------|---------|------|
| `400` | Bad request | One or more of the ids in `siteIds` does not exist. The message names them: `One or more sites do not exist: "<ids>"`. The check is all-or-nothing — a single bad id fails the whole request. |
| `404` | Not found | |
| `500` | Internal server error | |
