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)
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 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. 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.
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
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 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
[
{
"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. |