Get all member consent profiles
GET /api/members/consent/profiles
Success: 200 OK
- Products: Operator (
FOH), Consumer (CONSUMER), Integrations (INTEGRATIONS) (any one of these products, not all) - Features: Online Bookings (
ONLINEBOOK), Online Joining (ONLINEJOIN), TRP Integration (TRP), Front of House Generic Access (FOHGENERIC) (any one of these features, not all)
Overview
Bulk-exports what every member has and has not agreed to: the legal agreements they have signed, the marketing campaigns they have opted into, the data-processing campaigns they have accepted, and the channels they are happy to be contacted on. This is the endpoint to drive a consent-management or CRM sync from — it walks the whole member base rather than one member at a time.
It has two mutually exclusive modes:
- Delta mode (the default) — returns members whose record was created or modified between
dateFromanddateTo. Omit both and the window quietly defaults to the last day only, so a call with no parameters is not a full export. - Full export mode — set
returnAllRecords=trueand omit both dates. Sending either date alongside it fails with400.
Two things about the date filter catch people out. First, it filters on the member record's created and modified dates, not on when consent was given — a member whose consent has not changed but whose address has will still appear, and a consent change that does not touch the member record may not. Second, either date being matched is enough: the filter is created-in-range or modified-in-range.
Paging runs on member id ascending, using a continuation token; there is no offset. Tokens are mode-specific — one minted in full-export mode is rejected if replayed in delta mode. Keep returnAllRecords, limit and the dates identical across a sequence. Stop when continuation-token comes back as an empty string, which is the only end-of-data signal.
One shape quirk: the response is a single object carrying profiles and continuation-token, not an array, even though the field paths below are written with a leading [].
This is consent data. Anything you cache from it goes stale the moment a member changes their mind, so re-run the delta regularly rather than treating an export as durable.
Endpoint
GET {base_url}/api/members/consent/profiles
{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
dateFrom | string (date-time) | No | The start of the window, matched against the member record's created and modified dates. ISO 8601. It cannot be in the future. Defaults to the start of yesterday when omitted — not to the beginning of time — which is why an unparameterised call returns very little. Cannot be combined with returnAllRecords=true. |
dateTo | string (date-time) | No | The end of the window, in the same format. Defaults to now when omitted, and cannot be in the future, so there is no point padding it forward. Cannot be combined with returnAllRecords=true. |
limit | integer (int32) | No | How many member profiles to return per page. Valid range is 1 to 100; above 100 is rejected with 400. 0 or a negative value is not an error — it is silently replaced by the default of 25. Keep it the same across a paging sequence. |
continuation-token | string | No | The cursor for the next page, copied verbatim from the previous response. It carries the last member id seen, and paging resumes at the next member id above it. Do not build one by hand — a malformed token is rejected with 400. A token minted with returnAllRecords=true carries no usable date and is rejected if replayed with returnAllRecords=false. Omit it for the first page. Note that the token does not carry your date window: you must re-send dateFrom and dateTo on every page. |
returnAllRecords | boolean | No | Switches from delta mode to a full export of every member. Defaults to false. Mutually exclusive with dateFrom and dateTo. It must stay the same for every call in a paging sequence, because it changes what a continuation token means. |
Sample request
curl -X GET '{base_url}/api/members/consent/profiles' \
-H 'Authorization: Bearer {accessToken}' \
-H 'X-Use-SSO: true'Response fields
| Field | Type | Description |
|---|---|---|
[].profiles | array of object | One page of members, ordered by member id ascending, at most limit long. Empty when nothing matched or when you have paged past the end; an empty page always comes with an empty continuation-token. Members are included whether or not they have given any consent, so an entry with empty campaign arrays means "asked and declined, or never asked" — not that the member is missing. |
[].profiles[].memberId | integer (int32) | The member this consent profile belongs to, and the cursor paging advances through. Only ids greater than 0 are returned, so the non-member placeholder never appears. |
[].profiles[].onlineConsentDate | string (date-time) | When the member consented to having an online account. null when they never have — typically a member who only ever deals with the centre in person. |
[].profiles[].onlineConsentGuardianName | string | The name of the adult who gave online consent on the member's behalf, recorded when the member is below the tenant's age of consent. null for an adult member, and also null for a junior whose consent was never captured — its presence, not its absence, is the reliable signal. |
[].profiles[].privacyPolicySignedDate | string (date-time) | When the member accepted the privacy policy. null if they never have. Read it together with privacyPolicySigned, which is the authoritative flag. |
[].profiles[].privacyPolicySigned | boolean | Whether the member has accepted the privacy policy. This is recorded separately rather than derived from the date, so treat it as the answer and the date as supporting detail; they can disagree on older records. |
[].profiles[].termsAndConditionsSignedDate | string (date-time) | When the member signed the operator's terms and conditions, taken from the member's signed agreements. null when no terms and conditions agreement is recorded for them. There is no accompanying boolean — null is the "not signed" signal. |
[].profiles[].healthCommitmentStatementSignedDate | string (date-time) | When the member signed the health commitment statement — the physical-activity readiness declaration many operators require before use of a gym. null when none is recorded. |
[].profiles[].modifiedOn | string (date-time) | When the member record was last changed — not when consent last changed. Falls back to the creation date for a member who has never been modified, so it is never null for a record that has a creation date. This is one of the two fields the date window filters on. |
[].profiles[].createdOn | string (date-time) | When the member record was created. The other field the date window filters on: a newly created member appears in a delta run even if nothing has been modified since. |
[].profiles[].campaignPreferences | object | The member's opt-ins, split into three lists by the category the operator assigned to each campaign. Always present; its three arrays may each be empty. |
[].profiles[].campaignPreferences.marketingCampaigns | array of object | Campaigns in the MARKETING category that the member has opted into — the ones governing whether you may market to them. Only opt-ins appear; a campaign the member has declined is simply absent, so absence means "no consent", not "unknown". |
[].profiles[].campaignPreferences.marketingCampaigns[].campaignId | integer (int32) | The campaign's id, as configured by the operator. Stable within a tenant and different between tenants. This is the id you use when updating the member's campaign consents. |
[].profiles[].campaignPreferences.marketingCampaigns[].campaignName | string | The operator's name for the campaign. Display text and changeable — key on campaignId. |
[].profiles[].campaignPreferences.marketingCampaigns[].campaignDescription | string | The longer description the operator wrote for the campaign, usually the wording shown to the member when they opted in. null when none was configured. |
[].profiles[].campaignPreferences.marketingCampaigns[].captureDate | string (date-time) | The date the consent was given. Returned as a date with the time truncated to midnight, so do not expect the exact moment of capture. This is your evidence of when consent was obtained. |
[].profiles[].campaignPreferences.marketingCampaigns[].expiryDate | string (date-time) | The date the consent lapses, likewise truncated to midnight. The platform does not filter expired consents out of this response — a campaign whose expiryDate is in the past is still listed, so compare it against today yourself before treating the member as consented. |
[].profiles[].campaignPreferences.marketingCampaigns[].guardianName | string | The adult who gave this consent on the member's behalf, required when the member is below the age of consent. null when the member consented for themselves. |
[].profiles[].campaignPreferences.marketingCampaigns[].category | string | The campaign's category, with spaces stripped. Always MARKETING for entries in this array, so it is redundant here — it exists because the same shape is reused across the three lists. |
[].profiles[].campaignPreferences.dataCampaigns | array of object | Campaigns in the DATA_PROCESSING category the member has opted into — the lawful-basis consents for processing their data, as distinct from permission to market to them. Same shape as marketingCampaigns. |
[].profiles[].campaignPreferences.dataCampaigns[].campaignId | integer (int32) | The data-processing campaign's operator-configured id. |
[].profiles[].campaignPreferences.dataCampaigns[].campaignName | string | The operator's name for the campaign. Display text; key on campaignId. |
[].profiles[].campaignPreferences.dataCampaigns[].campaignDescription | string | The operator's longer description, usually the wording the member agreed to. null when none was configured. |
[].profiles[].campaignPreferences.dataCampaigns[].captureDate | string (date-time) | When the consent was given, truncated to midnight. |
[].profiles[].campaignPreferences.dataCampaigns[].expiryDate | string (date-time) | When the consent lapses, truncated to midnight. Expired entries are still returned — check the date yourself. |
[].profiles[].campaignPreferences.dataCampaigns[].guardianName | string | The adult who consented on a junior member's behalf. null when the member consented for themselves. |
[].profiles[].campaignPreferences.dataCampaigns[].category | string | Always DATA_PROCESSING for entries in this array. |
[].profiles[].campaignPreferences.communicationTypes | array of object | The channels the member has agreed to be contacted on — email, SMS and so on, as configured by the operator. A channel that is absent has not been consented to. Note these entries carry no expiry: a channel consent does not lapse on its own. |
[].profiles[].campaignPreferences.communicationTypes[].channelId | string | The channel's code, trimmed of padding. This is the stable identifier to match on; the set of codes is operator-configured. |
[].profiles[].campaignPreferences.communicationTypes[].channelName | string | The operator's display name for the channel, such as Email. Changeable — key on channelId. |
[].profiles[].campaignPreferences.communicationTypes[].captureDate | string (date-time) | When the member agreed to this channel, truncated to midnight. |
[].continuation-token | string | The cursor to send back as continuation-token for the next page. An empty string when there is no more data — that, not a short page, is how you know to stop. It encodes the last member id in the page and is only valid for the same returnAllRecords mode that produced it. |
Sample response
[
{
"profiles": [
{
"memberId": 12345,
"onlineConsentDate": "2026-08-14T19:00:00Z",
"onlineConsentGuardianName": "string",
"privacyPolicySignedDate": "2026-08-14T19:00:00Z",
"privacyPolicySigned": true,
"termsAndConditionsSignedDate": "2026-08-14T19:00:00Z",
"healthCommitmentStatementSignedDate": "2026-08-14T19:00:00Z",
"modifiedOn": "2026-08-14T19:00:00Z",
"createdOn": "2026-08-14T19:00:00Z",
"campaignPreferences": {
"marketingCampaigns": [
{
"campaignId": 12345,
"campaignName": "string",
"campaignDescription": "string",
"captureDate": "2026-08-14T19:00:00Z",
"expiryDate": "2026-08-14T19:00:00Z",
"guardianName": "string",
"category": "string"
}
],
"dataCampaigns": [
{
"campaignId": 12345,
"campaignName": "string",
"campaignDescription": "string",
"captureDate": "2026-08-14T19:00:00Z",
"expiryDate": "2026-08-14T19:00:00Z",
"guardianName": "string",
"category": "string"
}
],
"communicationTypes": [
{
"channelId": "string",
"channelName": "string",
"captureDate": "2026-08-14T19:00:00Z"
}
]
}
}
],
"continuation-token": "string"
}
]Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | returnAllRecords=true was sent together with dateFrom and/or dateTo. The body is You cannot specify a dateFrom and/or dateTo if returnAllRecords is set to true. |
400 | Bad request | dateFrom is in the future. The body is DateFrom {dateFrom} cannot be in the future. |
400 | Bad request | dateTo is in the future. The body is DateTo {dateTo} cannot be in the future. |
400 | Bad request | dateFrom or dateTo is not a recognisable ISO 8601 date. The body is a validation error rather than one of the messages above. |
400 | Bad request | limit is greater than 100. The body is Invalid value supplied for number of profiles per page. Limit must be an integer from 1 to 100. A limit of 0 or below is not an error — it falls back to 25. |
400 | Bad request | A continuation token from full-export mode was replayed with returnAllRecords=false. The body is The continuation-token {token} is not valid while returnAllRecords is false. |
400 | Bad request | The continuation token is malformed — a part that is not a key and value pair, or a value that will not parse. The body names the offending element or value. |
500 | Internal server error | An unexpected server-side failure while reading the consent profiles. |