# Get membership type restrictions

`GET /api/configuration/membership-types/{id}/restrictions`

- **Success:** `200 OK`
- **Products:** Operator (`FOH`), Consumer (`CONSUMER`) (any one of these products, not all)
- **Features:** Online Joining (`ONLINEJOIN`), Front of House Generic Access (`FOHGENERIC`) (any one of these features, not all)

HTML version: [Get membership type restrictions](https://support.gladstonesoftware.cloud/reference/configuration/get-membership-type-restrictions)

## Overview

Returns the rules that govern how many people a **group membership** may cover, and how those
people may be distributed across price levels. A group membership is one policy shared by several
linked members — a family or corporate membership — as opposed to an individual membership held by
one person.

This endpoint only applies to group memberships. If the membership type you name is an individual
membership, the request fails with `422`, not an empty result. There is no flag on this response
telling you which kind you asked about, so if you are iterating over a catalogue you will need to
tolerate `422` for most of it. That, not `404`, is the response you should expect for a perfectly
valid membership type that simply is not a group product.

Reach for it when you are building a join or renewal flow that lets the buyer choose how many
adults and children the membership covers: `maxCapacity` bounds the total, and each entry in
`priceLevels` bounds one category within that total.

The values returned here are maintained through
[Update membership type restrictions](update-membership-type-restrictions.md).

## Endpoint

`GET {base_url}/api/configuration/membership-types/{id}/restrictions`

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

## Path parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | string | Yes | The membership type to read restrictions for, maximum 15 characters. Take it from the `id` of a membership type returned by [Get all membership types](get-all-membership-types-with-optional-filtering.md) or [Get membership type by ID](get-membership-type-by-id.md). It is an operator-defined code, not a generated identifier. Sending it empty is rejected with `400`; sending an unknown code gives `404`; sending a valid code for an individual (non-group) membership type gives `422`. |

## Sample request

```bash title="cURL"
curl -X GET '{base_url}/api/configuration/membership-types/FAMILY/restrictions' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true'
```

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `maxCapacity` | integer (int32) | The greatest number of members the group membership may cover in total. **Beware the sentinel.** A configured capacity of `0` means unlimited, and no ceiling checks apply. This endpoint returns `9999` in place of that `0`. So `9999` means "no limit configured", not a deliberate ceiling of 9,999 people; do not render it to a buyer as a real number, and do not send it back to the update endpoint expecting to preserve the meaning. Any other value is a genuine configured limit, and genuine limits cannot exceed 32767. |
| `priceLevels` | array of object | The per-price-level bounds that apply within `maxCapacity`. A price level is the pricing category a member sits in (adult, junior, concession and so on), so these entries are how "at least one adult, at most two" is expressed. Only price levels that have had a restriction configured appear; a price level absent from this array simply has no count rule of its own. An **empty array is normal** and means no per-price-level rule exists, leaving only `maxCapacity` in force. At most one entry exists per price level — duplicates are rejected when the restrictions are written. Note that only individual values are checked against `maxCapacity`, never their total, so the maximums here can add up to more than `maxCapacity`; when they do, `maxCapacity` is the binding limit. |
| `priceLevels[].id` | string | Identifies which price level the bounds apply to, maximum 15 characters. Match it against the `id` of a price level from [Get all price levels](get-all-price-levels.md) to obtain the display name and the actual price — this response carries no description or amount, only the identifier. |
| `priceLevels[].minimumMembersPerPriceLevel` | integer (int32) | The fewest members that must be assigned to this price level — this is how a rule such as "a family membership must include at least one adult" is expressed. It is `0` or higher, never greater than `maximumMembersPerPriceLevel`, and never greater than `maxCapacity` unless `maxCapacity` is the unlimited sentinel; those three relationships are enforced when the restriction is written, so you can rely on them here. Expect `null` where no minimum was set. |
| `priceLevels[].maximumMembersPerPriceLevel` | integer (int32) | The greatest number of members that may be assigned to this price level. It is `0` or higher and is never null — a value is mandatory when the restriction is written. It cannot exceed `maxCapacity` unless `maxCapacity` is the unlimited sentinel. Unlike `maxCapacity`, `0` here carries no special "unlimited" meaning; the unlimited meaning of `0` applies only to the overall capacity. |

## Sample response

```json title="200 OK"
{
  "maxCapacity": 5,
  "priceLevels": [
    {
      "id": "ADULT",
      "minimumMembersPerPriceLevel": 1,
      "maximumMembersPerPriceLevel": 2
    },
    {
      "id": "JUNIOR",
      "minimumMembersPerPriceLevel": null,
      "maximumMembersPerPriceLevel": 3
    }
  ]
}
```

## Errors

| Status | Meaning | When |
|--------|---------|------|
| `400` | Bad request | The `{id}` segment resolved to an empty string. The body is the plain-text string `MembershipTypeId must be specified`. In practice this happens when you build the URL with a blank id and the trailing path still matches the route. |
| `404` | Not found | No membership type exists with that id. The body is plain text: `Unable to find Membership Type {id}.` |
| `422` | Unprocessable entity | The membership type exists but is an individual membership, not a group one, so it has no group capacity or price level rules to return. The body is plain text: `Membership Type {id} is not a group membership.` This is the expected outcome for most membership types and should not be treated as an error in a catalogue sweep. |
| `500` | Internal server error | An unexpected server-side failure while reading the membership type or its restrictions. The body is empty. |
