# Create a membership pass.

`POST /api/digital-pass/membership-pass`

- **Success:** `200 OK`
- **Products:** Operator (`FOH`), Digital Passes (`DIGITALPASSES`) (any one of these products, not all)
- **Features:** Digital Passes - Membership (`DIGITALPASSESMEMBERSHIP`), Front of House Generic Access (`FOHGENERIC`) (any one of these features, not all)

HTML version: [Create a membership pass.](https://support.gladstonesoftware.cloud/reference/digital-passes/create-a-membership-pass)

## Overview

Creates a digital membership pass for a member — the wallet pass a member adds to their phone and presents at a checkpoint — and returns a link from which they download it.

Send the `X-Timezone` header on every call. It is validated before anything else runs and must be an IANA timezone name such as `Europe/London`, `America/New_York` or `UTC`. A missing, empty or unrecognised value fails the request with `400` and no pass is created. The timezone governs how dates and times are formatted on the face of the pass, so send the member's timezone rather than your server's.

**This call has a side effect on the member record.** It is not a read. Before building the pass it fetches the member's identifiers, and if the member has no `DigitalPass` identifier it generates a pass value and writes a new `DigitalPass` identifier against the member. That identifier is what a card reader matches when the member presents the pass, and it persists after this call. Calling the endpoint a second time for the same member reuses the existing identifier rather than issuing a new one.

You do not choose the site. The member's site is read from their profile and used both to generate the pass value and to look up the digital pass configuration, so a pass always belongs to the member's own site.

Digital passes must be enabled and configured for that site. If they are not, the request fails with `400` — see the Errors table for the exact messages.

## Endpoint

`POST {base_url}/api/digital-pass/membership-pass`

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

## Request body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `memberId` | integer (int32) | No | The member the pass is issued to. Everything else the pass needs — the site, the member's name and their `DigitalPass` identifier — is looked up from this one value, so it is the only input besides the `X-Timezone` header. The field is a non-nullable integer, so omitting it sends `0`; no member matches `0` and the request fails with `404`. |

## Sample request

```bash title="cURL"
curl -X POST '{base_url}/api/digital-pass/membership-pass' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true' \
  -H 'Content-Type: application/json' \
  -d '{
  "memberId": 12345
}'
```

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `passPortalDownloadLink` | string | A URL to the pass portal, where the member downloads the generated pass and adds it to their phone's wallet. Give this to the member — do not fetch it server-side and treat the body as the pass file. |

## Sample response

```json title="200 OK"
{
  "passPortalDownloadLink": "string"
}
```

## Errors

| Status | Meaning | When |
|--------|---------|------|
| `400` | Bad request | The `X-Timezone` header is missing (`X-Timezone header is required`), empty (`X-Timezone header cannot be empty`) or not a recognised IANA name (`Invalid IANA timezone name in X-Timezone header: …`). Also returned when the pass value could not be generated, or when the pass itself could not be created — for example because digital passes are disabled for the member's site, or the site has no Digital Passes service URL or API key configured. The message is prefixed `Failed to create membership pass:`. |
| `403` | Forbidden | Your token is not permitted to read this member's identifiers or profile. The message is prefixed `Access denied while attempting to create membership pass:`. This is about the member you asked for, not about the endpoint — check the member is within your integration's scope. |
| `404` | Not found | No member matches `memberId`, so their identifiers or profile could not be read. The message is prefixed `Cannot create membership pass:`, or `Failed to create membership pass:` when the failure came from the pass creation step itself. |
| `500` | Internal server error | An underlying step failed for a reason other than the above — reading identifiers or the profile, generating the pass value, writing the `DigitalPass` identifier, or creating the pass. Note that a failure to write the `DigitalPass` identifier always surfaces as `500`, never `400` or `404`. The pass is not created, but a pass value may already have been generated, so retry rather than assuming nothing happened. |
