# Get member memberships and payment information

`GET /api/members/{memberId}/memberships`

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

HTML version: [Get member memberships and payment information](https://support.gladstonesoftware.cloud/reference/members/get-member-memberships-and-payment-information)

## Overview

Returns one member's memberships together with what they will be charged next. This is the endpoint behind a "my membership" screen: it combines the membership records with a live pricing calculation, which is why it can tell you the next payment amount when the bulk export cannot.

It covers memberships **allocated to** the member and memberships **they pay for** on behalf of their linked members, so a parent paying for a family sees the children's memberships here too. Where a membership type applies to links, it is reported once with everyone it covers listed in `assignedToMembers`, rather than once per person.

By default **expired memberships are excluded** — only memberships whose expiry date is today or later are returned. Set `includeExpired=true` to see history. Note the filter is on expiry date alone, so a continuous membership that has been given notice still counts as current until its date passes.

Three fields on this endpoint do not carry usable values, because of a known defect on this endpoint: `duration.typeInd` is always `0`, `paymentDetails.collectionInterfaceInd` is always `0`, and `documentationRequired[].documentDescription` is always `null`. Each is called out below. The bulk endpoint [Get all member memberships with pagination](get-all-member-memberships-with-pagination.md) returns the same information under different names and does populate them — but it in turn cannot give you next-payment figures.

The whole call fails if the pricing calculation fails; there is no partial response with memberships but no prices.

Each membership also carries a `cancellation` object saying whether the member you asked about can cancel it themselves, and what would happen if they did. It drives a self-service cancellation screen: show `cancellation.reason` (or your own copy keyed on `cancellation.reasonID`) and, when cancellation is allowed, call [Cancel a membership for the paying member](cancel-a-membership-for-the-paying-member.md). The verdict is worked out for the `memberId` in the path, so a membership that member is covered by but someone else pays for comes back as not cancellable by them.

## Endpoint

`GET {base_url}/api/members/{memberId}/memberships`

`{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 |
|------|------|----------|-------------|
| `memberId` | integer (int32) | Yes | The member whose memberships you want. Must be greater than `0` — `0` and `-999` are rejected with `400`. The member must exist, or you get `404`. Memberships this member pays for on behalf of linked members are included, so you do not need to call the endpoint again for each child. |

## Query parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `includeExpired` | boolean | No | Whether to include memberships that have already ended. Defaults to `false`, which returns only memberships whose expiry date is today or later — so a member with a long history looks like they have very few memberships unless you set this. The filter is on expiry date only; it takes no account of `renewalStopDate` or of whether the membership was ever paid for. |

## Sample request

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

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `[].id` | string | The membership **type** code, such as `ADULT` — what was bought, not which purchase. Operator-defined and shared by every member on that type. For the individual purchase, use `membershipRef`. |
| `[].name` | string | The operator's name for the membership type. Display text and changeable; key on `id`. |
| `[].description` | string | The longer, member-facing blurb configured for the type — wording written for websites and apps rather than for staff. `null` when the operator has not written one. |
| `[].membershipRef` | integer (int32) | The reference for this specific membership record, unique across the tenant. This is the key to store, and the value the next-payment figures are matched on — if it does not match, `paymentDetails.nextPayment` is left `null`. |
| `[].startDate` | string (date-time) | When the current term of this membership began. On a renewing membership it moves forward each term, so it is not the start of the member's relationship with the operator. |
| `[].expiryDate` | string (date-time) | When this term ends. It is also what `includeExpired` filters on: a membership is treated as current while this date is today or later. On a continuous membership the date is simply rolled forward at renewal. |
| `[].renewalStopDate` | string (date-time) | The date from which the membership stops renewing, set when a member gives notice. `null` while the membership is still set to renew indefinitely. A non-null value in the future is the signal that a member has cancelled but is still entitled. |
| `[].earliestEndDate` | string (date-time) | The earliest date the membership may be ended, reflecting any minimum term. `null` when no minimum term applies. Check it before offering a member a cancellation date. |
| `[].applyToLinks` | boolean | `true` when the membership type covers the buyer's linked members as well as the buyer. When it is `true`, `assignedToMembers` lists everyone covered and the membership appears once rather than once per person. |
| `[].backColor` | string | The colour the operator has assigned to this membership type, as a hex string. Cosmetic only. |
| `[].paidByMember` | object | Who pays for this membership: the member themselves when they pay their own way, otherwise their linked primary member. Always present. |
| `[].paidByMember.id` | integer (int32) | The paying member's id. Compare it with the `memberId` you asked for to tell a membership the member pays for themselves from one a primary member funds. |
| `[].paidByMember.name` | string | The paying member's first names and last name joined with a space. Display text; do not parse it back into parts. |
| `[].assignedToMembers` | array of object | Everyone this membership entitles. Normally one entry — the member it was allocated to. When `applyToLinks` is `true`, the linked members covered by the same purchase are listed too. |
| `[].assignedToMembers[].id` | integer (int32) | The covered member's id. |
| `[].assignedToMembers[].name` | string | The covered member's first names and last name joined with a space. |
| `[].duration` | object | How long a term of this membership type runs and whether it renews. Describes the type, not the time left on this particular membership. |
| `[].duration.isContinuous` | boolean | `true` when the membership auto-renews rather than simply expiring. This is the reliable field in this object — read it before drawing any conclusion from `expiryDate`. |
| `[].duration.typeInd` | integer (enum) | Intended to be the unit `value` is counted in — `0` monthly, `1` daily, `2` weekly. **In practice it is always `0` on this endpoint**, because of the known defect described in the overview. Do not rely on it; take the duration unit from the membership-type configuration, or from `duration.durationType` on the bulk endpoint, which returns the unit as a name. |
| `[].duration.value` | integer (int32) | How many units make up one term. Meaningful only alongside the unit, which this endpoint does not give you reliably — see `typeInd`. |
| `[].paymentDetails` | object | How this membership is invoiced and what is due next. `null` when no invoice was found for the membership — for example one granted without a sale — so check for null before reading into it. |
| `[].paymentDetails.paymentMethodId` | string | The payment method code on the invoice, as configured by the operator. |
| `[].paymentDetails.paymentMethodDescription` | string | The operator's label for that payment method, such as `Direct Debit`. Display text; see `translations` for other languages. |
| `[].paymentDetails.nextPaymentDue` | string (date-time) | Never populated. Use `nextPayment` for what is actually owed; there is no next-payment **date** available from this endpoint at all. |
| `[].paymentDetails.nextPaymentAmount` | number (double) | Never populated. The amount lives in `nextPayment.amount`, as a string rather than a number. Do not read an absent value here as "nothing to pay". |
| `[].paymentDetails.paymentStatus` | string | Where the invoice stands, as a name: `Unpaid`, `PartPaid`, `Paid`, `Void`, `PartCredited`, `PartCreditedPaid`, `Credited` or `CreditNote`. This is the invoice's status, not the membership's — a lapsed membership can still be `Paid`, and a current one `Unpaid`. |
| `[].paymentDetails.collectionInterfaceInd` | integer (enum) | Intended to say how the money is collected — `0` manual, `1` direct debit, `2` credit card, `3` external, `4` smart card, `5` cashless account, `6` loyalty points, `7` online authorisation, `8` invoicing account, `9` EFT. **In practice it is always `0` on this endpoint**, for the same reason as `duration.typeInd`. If you need the real collection route, read `collectionInterface` from the bulk endpoint, which returns it as a name. |
| `[].paymentDetails.translations` | array of object | Translations of the payment method description. Empty when the operator has configured none — fall back to `paymentMethodDescription`. |
| `[].paymentDetails.translations[].type` | string | Which piece of text this translation is for, since a record can carry translations of more than one attribute. |
| `[].paymentDetails.translations[].culture` | string | The culture the text is written for, such as `cy-GB`. Match it against your user's locale; there is no automatic fallback. |
| `[].paymentDetails.translations[].text` | string | The translated text itself. |
| `[].paymentDetails.nextPayment` | object | What the member will be charged next for this membership, calculated live at request time rather than read from stored data. `null` when pricing returned nothing for this `membershipRef` — which is normal for a membership that is not renewing, and is not an error. |
| `[].paymentDetails.nextPayment.amount` | string | The amount due at the next collection, as a **string**, not a number — parse it as a decimal rather than binding it to a float. This is the figure after any discount; `discount.priceBeforeDiscount` holds what it would otherwise have been. |
| `[].paymentDetails.nextPayment.currency` | string | The currency the amount is expressed in. Do not assume sterling — read it and format accordingly. |
| `[].paymentDetails.nextPayment.discount` | object | The discount applied to the next payment, if any. `null` when the member is paying the standard price. |
| `[].paymentDetails.nextPayment.discount.priceBeforeDiscount` | string | What the next payment would have been without the discount, as a string. Show it alongside `amount` if you want to display the saving; the difference is not given to you pre-calculated. |
| `[].paymentDetails.nextPayment.discount.discountValue` | string | The value of the discount, as a string. Whether this is a cash amount or a percentage depends on how the operator configured the discount, and the response does not tell you which. |
| `[].paymentDetails.nextPayment.discount.discountEndDate` | string (date-time) | When the discount stops applying, after which the member reverts to the full price. `null` when the discount has no end date. Use it to warn a member before their price goes up. |
| `[].isUsageSubscription` | boolean | `true` when the membership is a bundle of visits rather than a period of time — a ten-session pass, for example. When it is `true`, `usagesRemaining` is what matters, not `expiryDate`. |
| `[].usagesRemaining` | integer (int32) | How many uses are left on a usage-based membership. Returned as `0`, never `null`, both when none are left **and** when the membership is not usage-based — so always check `isUsageSubscription` before showing this to anyone. |
| `[].imageUrl` | string | The full URL of the image configured for this membership type, for display in apps and portals. `null` when the type has no image. |
| `[].paymentMethodId` | string | The payment method recorded on the membership itself, as opposed to on its invoice. Where the two differ, this is what the membership is set to use going forward. |
| `[].documentationRequired` | array of object | The documents the operator requires for this membership type, each flagged with whether the member has supplied it. Empty when none are required. This is a checklist, not the files themselves. |
| `[].documentationRequired[].documentTypeInd` | integer (enum) | One of: `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`. |
| `[].documentationRequired[].documentDescription` | string | Intended to be the operator's name for the required document. **In practice it is always `null` on this endpoint**, because of the known defect described in the overview. Use `documentTypeInd` to work out what is being asked for, or read `documentName` from the bulk endpoint. |
| `[].documentationRequired[].uploaded` | boolean | Whether the member has supplied this document. `false` means outstanding — the platform does not block the membership on it, so treat it as a prompt rather than a gate. |
| `[].documentationRequired[].translations` | array of object | Translations of the document text. Empty when the operator has configured none. |
| `[].documentationRequired[].translations[].type` | string | Which piece of the document's text this translation is for. |
| `[].documentationRequired[].translations[].culture` | string | The culture the text is written for, such as `cy-GB`. Match it against your user's locale; there is no automatic fallback to a default language. |
| `[].documentationRequired[].translations[].text` | string | The translated text itself. With `documentDescription` always `null` on this endpoint, these translations are the only document wording you get here. |
| `[].translations` | array of object | Translations of the membership type's own text — its name and description. Empty when the operator has configured none, in which case use `name` and `description` directly. |
| `[].translations[].type` | string | Which piece of text this translation is for, since a membership type can carry translations of both its name and its description. |
| `[].translations[].culture` | string | The culture the text is written for, such as `cy-GB`. |
| `[].translations[].text` | string | The translated text itself. |
| `[].cancellation` | object | Whether `memberId` can cancel this membership themselves, and what cancelling now would do. Present on every membership. Read `allowed` first, then `reasonID`. |
| `[].cancellation.allowed` | boolean | `true` when [Cancel a membership for the paying member](cancel-a-membership-for-the-paying-member.md) would succeed for this membership right now. `false` means it would be refused with `409` and the same `reasonID`. |
| `[].cancellation.reason` | string | The verdict in English: why the membership cannot be cancelled, or what cancelling it would do. Suitable to display, but not translated, so treat it as a fallback and key your own copy on `reasonID`. It never names a date and never mentions a refund. |
| `[].cancellation.reasonID` | integer (int32) | The verdict as a number. Not allowed: `2` only the paying member can cancel, `3` a membership that does not auto-renew and is past its cooling-off period, `4` a usage membership inside its cooling-off period with no uses left, `5` already cancelled (a `renewalStopDate` is set), `6` already expired. Allowed: `7` inside the cooling-off period, so cancelling ends the membership immediately; `8` outside the cooling-off period on an auto-renewing membership, so cancelling stops renewal and the membership stays active until the chosen date. `1` (self-service cancellations are not enabled) is also defined. The numbering is only ever added to, never changed. |
| `[].cancellation.cancellationDates` | array of string (date) | The dates the member may choose for the cancellation to take effect, as calendar dates (`YYYY-MM-DD`), earliest first. Each is the last day the member keeps the membership — the day before a renewal that will then not happen. Only populated when `reasonID` is `8`; empty for every other value. **It can also be empty when `reasonID` is `8`**, if the membership's own terms do not produce a date — check its length rather than assuming the first entry exists. Up to a year of dates is offered: twelve for a monthly membership, one for a yearly one. No date is earlier than `earliestEndDate`. |

## Sample response

```json title="200 OK"
[
  {
    "id": "string",
    "name": "string",
    "description": "string",
    "membershipRef": 1,
    "startDate": "2026-08-14T19:00:00Z",
    "expiryDate": "2026-08-14T19:00:00Z",
    "renewalStopDate": "2026-08-14T19:00:00Z",
    "earliestEndDate": "2026-08-14T19:00:00Z",
    "applyToLinks": true,
    "backColor": "string",
    "paidByMember": {
      "id": 12345,
      "name": "string"
    },
    "assignedToMembers": [
      {
        "id": 12345,
        "name": "string"
      }
    ],
    "duration": {
      "isContinuous": true,
      "typeInd": 0,
      "value": 1
    },
    "paymentDetails": {
      "paymentMethodId": "string",
      "paymentMethodDescription": "string",
      "nextPaymentDue": "2026-08-14T19:00:00Z",
      "nextPaymentAmount": 10.5,
      "paymentStatus": "string",
      "collectionInterfaceInd": 0,
      "translations": [
        {
          "type": "string",
          "culture": "string",
          "text": "string"
        }
      ],
      "nextPayment": {
        "amount": "string",
        "currency": "GBP",
        "discount": {
          "priceBeforeDiscount": "string",
          "discountValue": "string",
          "discountEndDate": "2026-08-14T19:00:00Z"
        }
      }
    },
    "isUsageSubscription": true,
    "usagesRemaining": 1,
    "imageUrl": "string",
    "paymentMethodId": "string",
    "documentationRequired": [
      {
        "documentTypeInd": 0,
        "documentDescription": "string",
        "uploaded": true,
        "translations": [
          {
            "type": "string",
            "culture": "string",
            "text": "string"
          }
        ]
      }
    ],
    "translations": [
      {
        "type": "string",
        "culture": "string",
        "text": "string"
      }
    ],
    "cancellation": {
      "allowed": true,
      "reason": "This membership will stop renewing and remain active until its cancellation takes effect",
      "reasonID": 8,
      "cancellationDates": [
        "2026-10-16",
        "2026-11-16",
        "2026-12-16"
      ]
    }
  }
]
```

## Errors

| Status | Meaning | When |
|--------|---------|------|
| `400` | Bad request | `memberId` is `0` or negative. The body is `{memberId} is an invalid member ID`. |
| `400` | Bad request | Returned when the membership or pricing lookup rejects the request. The body is the underlying rejection message. |
| `403` | Forbidden | Returned when the caller is refused access to this member's data. |
| `404` | Not found | `memberId` does not exist. The body is `The given member does not exist in database. MemberId: {memberId}`. A member who exists but holds no memberships returns `200` and an empty array instead. |
| `422` | Unprocessable entity | Returned when the next payment cannot be calculated. The whole call fails — you do not get the memberships without the prices. |
| `500` | Internal server error | An unexpected server-side failure, including an unexpected response while retrieving the memberships or their pricing. |
