SSO Data Sharer Webhook
Real-time information about SSO users can be pushed to a third party system via the data sharer webhooks described in this document.
Introduction
This service notifies an external third party system about users, sharing information such as user details and contact preferences etc. Third parties can then use this to ingest data about SSO users and keep user details up to date. This service will share updates whenever a user performs an action, e.g. when they update their first name or opt in or out of a contact method.
The service can be configured to point to a given endpoint, along with a secured key which can be used to identify and validate the request. The JSON body detailed below will be sent to this endpoint whenever the user updates their SSO account.
Example
An example webhook request for a configured service. All webhooks requests will contain the full user profile, regardless of what was changed.
| Field | Type | Definition |
|---|---|---|
| id | Number | The user's unique SSO ID |
| version | Number | The model version for this webhook payload |
| recordRevoked | Boolean | True if the user has requested their account be deleted under GDPR. You must either delete the user record from your system or remove all PII data associated with this user's SSO ID. |
| clientId | String | The ID associated with this client e.g. CORTEX |
| registerMetadata.registerSource | String | The source location the user first registered |
| registerMetadata.registerType | String | The type of registration |
| registerMetadata.registerPlatform | String | The platform the user registered on |
| userProfile.id | Number | The user's unique SSO ID |
| userProfile.email | String | The user's email address |
| userProfile.emailVerified | Boolean | True if the user's email is verified - false otherwise |
| userProfile.guardianEmail | String | The email address of their guardian if the user is a minor |
| userProfile.minorId | String | If the user is a minor this is their username/nickname |
| userProfile.firstName | String | The user's first name |
| userProfile.otherNames | String | The user's middle name |
| userProfile.lastName | String | The user's last name |
| userProfile.title | String | The user's title, e.g. Mr, Mrs, Dr |
| userProfile.birthDate | ISO 8601 Datetime | The user's date of birth |
| userProfile.gender | String | The user's gender. Based on RFC 6350: M = Male, F = Female, O = Other, N = None or not applicable, U = Unknown |
| userProfile.address1 | String | The user's address line 1 |
| userProfile.address2 | String | The user's address line 2 |
| userProfile.town | String | The user's town |
| userProfile.region | String | The user's region / county |
| userProfile.country | String | The user's country |
| userProfile.postcode | String | The user's postcode |
| userProfile.contactNumber | String | The user's phone number |
| userProfile.screenName | String | The user's screen name / display name |
| userProfile.screenNameApproved | Boolean | True if the user's screen name has been approved through moderation |
| userProfile.profilePicture | String | URL to the user's profile picture |
| userProfile.profilePictureApproved | Boolean | True if the user's profile picture has been approved through moderation |
| userProfile.companyName | String | The user's company name |
| userProfile.companyPhoneNumber | String | The user's company phone number |
| userProfile.companyAddressOne | String | The user's company address line 1 |
| userProfile.companyAddressTwo | String | The user's company address line 2 |
| userProfile.companyTown | String | The user's company town |
| userProfile.companyCountry | String | The user's company country |
| userProfile.companyPostcode | String | The user's company postcode |
| userProfile.lastUpdated | ISO 8601 Datetime | The last time the user updated their profile information |
| userProfile.createdAt | ISO 8601 Datetime | The date and time the user created their SSO account |
| userProfile.metadata | JSON | Unstructured JSON object that contains additional information about the user, for example: "metadata": { "object": {}, "key": "value", "number": 1, "array": [1, "value"], "boolean": false } |
| userProfile.suspension | Object | If the user's account has been suspended this field will contain information about it. If the user is not suspended then this field will be null. |
| userProfile.suspension.type | String | The type of account suspension |
| userProfile.suspension.expiresAt | ISO 8601 Datetime | The date and time this suspension will elapse. If null this account is suspended indefinitely. |
| userProfile.suspension.reason | String | A free text field providing additional context for suspension reason. This field can be null. |
| userProfile.passwordReset | Boolean | True if the user has reset their password. This field may be absent if no password reset has occurred. |
| userProfile.lastPasswordReset | ISO 8601 Datetime | The date and time of the user's most recent password reset. Only present if a password reset has occurred. |
| userProfile.firstLogin | ISO 8601 Datetime | The date and time the user first logged in |
| userProfile.lastLogin | ISO 8601 Datetime | The date and time the user most recently logged in |
| clientPreferences | Array | This contains the list of account preferences available to the user |
| clientPreferences.clientId | String | The ID associated with this client i.e. CORTEX |
| clientPreferences.name | String | The display name of the preference |
| clientPreferences.description | String | The description of the preference |
| clientPreferences.key | String | The unique key for this preference. Note: this is unique per client ID, not per user. |
| clientPreferences.set | Boolean | If true this indicates that the user has responded to this preference. This is useful for some preferences where the user is not obliged to select an option i.e. a checkbox preference. In this case we know the user has acknowledged the preference but not chosen any options. |
| clientPreferences.options | Array | A list of options available to the user for this preference |
| clientPreferences.options.id | Number | The globally unique ID of this option |
| clientPreferences.options.value | String | The display text for this option |
| clientPreferences.options.metadata | Object | Key / value pairs of additional metadata associated with this option. Both keys and values are strings. |
| clientPreferences.options.selected | Boolean | True if the user has selected this option - false otherwise |
| entitlements | Array | A list of active entitlements this user has. Expired entitlements are excluded. Version 3 only — this field is not present in version 2 payloads. |
| entitlements.id | String | The ID of this entitlement |
| entitlements.name | String | The name of this entitlement |
| entitlements.validFrom | ISO 8601 Datetime | The date and time this entitlement is valid from |
| entitlements.validTo | ISO 8601 Datetime | The date and time this entitlement is valid to. This will be null for entitlements that are open ended or never expire i.e. a lifetime membership or staff entitlement. |
| accountLinks | Array | A list of account IDs linked to this SSO account. Version 3 only — this field is not present in version 2 payloads. |
| accountLinks.sourceSystemId | String | The system this account link relates to e.g. cortex_VM for Ticketmaster |
| accountLinks.sourceSystemUserId | String | The ID of the user's account within that system |
| accountLinks.sourceSystemCreatedAt | ISO 8601 Datetime | The date and time this account link was created at the source, i.e. at Ticketmaster. |
| accountLinks.createdAt | ISO 8601 Datetime | The date and time this account link was created |
| accountLinks.lastModified | ISO 8601 Datetime | The date and time this account link was last updated |
| accountLinks.primary | Boolean | True if this is the primary account link for this source system |
| accountLinks.secondaryLinks | Array | A list of secondary account links associated with this primary link. Each entry has the same structure as an accountLink. This field is only present when secondary account links are enabled for the client configuration. |
Model Versions
The webhook supports multiple model versions.
Version 2 includes: id, version, recordRevoked, clientId, registerMetadata, userProfile, and clientPreferences.
Version 3 includes everything in Version 2, plus:
-
entitlements— the user's active entitlements -
accountLinks— external accounts linked to this SSO account (with optional secondary links)
Example:
{
"id": 6688176,
"version": 3,
"clientId": "CLIENT",
"registerMetadata": {
"registerSource": "XX",
"registerType": "XX",
"registerPlatform": "XX"
},
"entitlements": [
{
"id": "68623c8e5fab911b5396d1a9",
"name": "pre season bundle 2026",
"validFrom": "2026-03-18T17:51:20Z",
"validTo": "2026-03-31T10:00:00Z"
}
],
"accountLinks": [
{
"sourceSystemId": "System4",
"sourceSystemUserId": "fTVOpxDMyUmOwVXXX",
"createdAt": "2021-06-20T15:29:57.58203Z",
"lastModified": "2021-06-20T15:29:57.58203Z"
},
{
"sourceSystemId": "XXXX_SG",
"sourceSystemUserId": "718863",
"createdAt": "2023-06-23T10:00:33.115011Z",
"lastModified": "2023-06-23T10:00:33.115011Z"
},
{
"sourceSystemId": "YYYY_VM",
"sourceSystemUserId": "718863",
"sourceSystemCreatedAt": "2024-12-03T09:09:27.445024Z",
"createdAt": "2023-06-29T15:02:19.905433Z",
"lastModified": "2024-12-03T09:09:27.463658Z"
}
],
"clientPreferences": [
{
"clientId": "CLIENT",
"name": "Highlights, news, and videos",
"description": "Send me the latest news and videos from the club, including transfers and match highlights",
"set": true,
"key": "001-highlights-news-videos",
"options": [
{
"id": 958,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 959,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Tickets and Memberships",
"description": "Send me ticket announcements and availability, Memberships, and Season Ticket information",
"set": true,
"key": "002-tickets-memberships",
"options": [
{
"id": 960,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 961,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Club Shop",
"description": "Send me the latest from the club shop",
"set": true,
"key": "003-club-shop",
"options": [
{
"id": 962,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 963,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Premium Hospitality and commercial opportunities",
"description": "Send me Premium hospitality news and offers, and commercial opportunities",
"set": true,
"key": "004-premium-hospitality-commercial",
"options": [
{
"id": 964,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 965,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Selhurst Park venue hire and events",
"description": "Send me club events and venue hire communications from Selhurst Park",
"set": true,
"key": "005-venue-hire-events",
"options": [
{
"id": 966,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 967,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Partners and sponsors",
"description": "Send me news and promotions from Palace partners",
"set": true,
"key": "006-partners-sponsors",
"options": [
{
"id": 968,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 969,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Palace for Life Foundation",
"description": "Send me the latest news and updates from the Palace for Life Foundation",
"set": true,
"key": "007-palace-life-foundation",
"options": [
{
"id": 970,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 971,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "Palace Women's Team",
"description": "Send me the latest news and updates from the Palace Women's team",
"set": true,
"key": "008-palace-womens-team",
"options": [
{
"id": 972,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 973,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
},
{
"clientId": "CLIENT",
"name": "I am also happy to hear from the Club via SMS",
"set": true,
"key": "009-other-contact-methods-sms",
"options": [
{
"id": 974,
"value": "Yes",
"metadata": {
"hidden": "false",
"order": "1",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
},
{
"id": 975,
"value": "No",
"metadata": {
"hidden": "false",
"order": "2",
"type": "opt-in",
"visualType": "radio"
},
"selected": false
}
]
}
],
"userProfile": {
"id": 6688176,
"email": "[email protected]",
"firstName": "Bob",
"lastName": "Fisher",
"birthDate": "1988-01-01T00:00:00Z",
"gender": "M",
"address1": "line1",
"address2": "line2",
"town": "London",
"region": "Sussex",
"country": "United Kingdom",
"postcode": "BNX YYY",
"contactNumber": "0797777",
"lastUpdated": "2026-03-18T17:51:52.4Z",
"metadata": {},
"createdAt": "2021-06-20T12:12:08.178Z",
"passwordReset": true,
"lastPasswordReset": "2026-03-03T14:25:51.557038Z",
"firstLogin": "2021-06-29T11:14:07.162229Z",
"lastLogin": "2026-03-18T17:41:28.364391Z"
}
}Preferences webhook
In addition to the profile webhook described above, the data sharer supports a separate preferences webhook. This is a dedicated channel for receiving real-time preference change notifications with a richer preference data model.
The preferences webhook fires whenever a user updates their preference selections (e.g. opting in or out of a contact method, changing a preference option).
The preferences webhook is configured as a separate pipeline. A client can receive both webhooks.
The profile webhook described above includes a clientPreferences section with basic preference data. The preferences webhook provides a richer, dedicated preference payload with additional fields.
| Capability | Profile Webhook | Preferences Webhook |
|---|---|---|
| Triggered by | Any SSO profile update | Preference selection changes only |
| Preference key & name | Yes | Yes |
| Option id, value, selected | Yes | Yes |
| Preference description | No | Yes |
| Preference type (OptIn, Global) | No | Yes |
| Visual type (Radio, Checkbox, Select) | No | Yes |
| Preference deprecated flag | No | Yes |
| Last updated timestamp | No | Yes |
| Option index (display ordering) | No | Yes |
| Option metadata (key/value pairs) | No | Yes |
| Option linked IDs (external system refs) | No | Yes |
| Option deprecated flag | No | Yes |
| User profile data (name, address, etc.) | Yes (full profile) | No |
| Entitlements | Yes (v3 only) | No |
| Account links | Yes (v3 only) | No |
Example payloads
Anonymous user
{
"clientId": "XXX",
"userId": 27146712,
"anonymous": true,
"email": "[email protected]",
"uuid": "8b4d1f52-6499-41e2-a6f4-26d8616988df",
"preferences": [
{
"key": "001-highlights-news-videos",
"name": "Highlights, news, and videos",
"description": "Send me the latest news and videos from the club, including transfers and match highlights",
"set": false,
"type": "OptIn",
"visualType": "Radio",
"deprecated": false,
"lastUpdated": null,
"options": [
{
"id": 958,
"index": 1,
"value": "Yes",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
},
{
"id": 959,
"index": 2,
"value": "No",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
}
]
},
{
"key": "002-tickets-memberships",
"name": "Tickets and Memberships",
"description": "Send me ticket announcements and availability, Memberships, and Season Ticket information",
"set": false,
"type": "OptIn",
"visualType": "Radio",
"deprecated": false,
"lastUpdated": null,
"options": [
{
"id": 960,
"index": 1,
"value": "Yes",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
},
{
"id": 961,
"index": 2,
"value": "No",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
}
]
},
{
"key": "003-club-shop",
"name": "Club Shop",
"description": "Send me the latest from the club shop",
"set": false,
"type": "OptIn",
"visualType": "Radio",
"deprecated": false,
"lastUpdated": null,
"options": [
{
"id": 962,
"index": 1,
"value": "Yes",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
},
{
"id": 963,
"index": 2,
"value": "No",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
}
]
}
],
"version": 1,
"createdAt": "2026-03-18T17:41:02.949459786Z"
}Real SSO user
{
"clientId": "XXX",
"userId": 6688176,
"anonymous": false,
"email": "[email protected]",
"uuid": "1ed05d06-c7e2-4637-a184-1fd0073b7727",
"preferences": [
{
"key": "001-highlights-news-videos",
"name": "Highlights, news, and videos",
"description": "Send me the latest news and videos from the club, including transfers and match highlights",
"set": true,
"type": "OptIn",
"visualType": "Radio",
"deprecated": false,
"lastUpdated": "2026-03-18T17:41:48.769214Z",
"options": [
{
"id": 958,
"index": 1,
"value": "Yes",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
},
{
"id": 959,
"index": 2,
"value": "No",
"metadata": {},
"linkedIds": [],
"selected": true,
"deprecated": false
}
]
},
{
"key": "002-tickets-memberships",
"name": "Tickets and Memberships",
"description": "Send me ticket announcements and availability, Memberships, and Season Ticket information",
"set": true,
"type": "OptIn",
"visualType": "Radio",
"deprecated": false,
"lastUpdated": "2026-03-18T17:41:48.769214Z",
"options": [
{
"id": 960,
"index": 1,
"value": "Yes",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
},
{
"id": 961,
"index": 2,
"value": "No",
"metadata": {},
"linkedIds": [],
"selected": true,
"deprecated": false
}
]
},
{
"key": "003-club-shop",
"name": "Club Shop",
"description": "Send me the latest from the club shop",
"set": true,
"type": "OptIn",
"visualType": "Radio",
"deprecated": false,
"lastUpdated": "2026-03-18T17:41:48.769214Z",
"options": [
{
"id": 962,
"index": 1,
"value": "Yes",
"metadata": {},
"linkedIds": [],
"selected": false,
"deprecated": false
},
{
"id": 963,
"index": 2,
"value": "No",
"metadata": {},
"linkedIds": [],
"selected": true,
"deprecated": false
}
]
}
],
"version": 1,
"createdAt": "2026-03-18T17:41:48.805845172Z"
}Payload fields
| Field | Type | Required | Definition |
|---|---|---|---|
| clientId | String | Yes | The ID associated with this client |
| userId | Number | Yes | The user's unique SSO ID |
| anonymous | Boolean | Yes | Whether this is an anonymous user |
| String | Yes | The user's email address | |
| minorId | String | Optional | If the user is a minor, this is their username/nickname |
| guardianEmail | String | Optional | The email address of their guardian if the user is a minor |
| uuid | String | Yes | A unique identifier for this user's account |
| version | Number | Yes | The payload version |
| createdAt | ISO 8601 Datetime | Yes | The timestamp of this webhook event |
| preferences | Array | Yes | The user's current preference selections |
| preferences.key | String | Yes | The unique key identifying this preference |
| preferences.name | String | Yes | The display name of the preference |
| preferences.description | String | Optional | A description of the preference |
| preferences.set | Boolean | Optional | True if the user has responded to this preference, even if no options were selected. May be null. |
| preferences.type | String | Optional | The preference classification, e.g. OptIn, Global. May be null. |
| preferences.visualType | String | Yes | The UI display type: Radio, Checkbox, or Select |
| preferences.deprecated | Boolean | Yes | True if this preference has been deprecated |
| preferences.lastUpdated | ISO 8601 Datetime | Optional | The last time this specific preference was updated. May be null. |
| preferences.options | Array | Yes | The available options for this preference |
| preferences.options.id | Number | Yes | The globally unique ID of this option |
| preferences.options.index | Number | Yes | The display order index for this option |
| preferences.options.value | String | Yes | The display text for this option |
| preferences.options.metadata | Object | Yes | Key / value pairs of additional metadata associated with this option |
| preferences.options.linkedIds | Array | Yes | External system references linked to this option (e.g. OPTA football team IDs) |
| preferences.options.linkedIds.text | String | Optional | Display text for this linked ID. May be null. |
| preferences.options.linkedIds.sourceSystem | String | Yes | The external system this ID relates to |
| preferences.options.linkedIds.sourceSystemId | String | Yes | The ID within that external system |
| preferences.options.selected | Boolean | Optional | True if the user has selected this option. May be null. |
| preferences.options.deprecated | Boolean | Yes | True if this option has been deprecated |
Which webhook should I use?
- Use the profile webhook if you need the full user profile (name, email, address, etc.) alongside basic preference data, entitlements, and account links.
- Use the preferences webhook if you need detailed, real-time preference change data with enriched metadata (type, visual type, option metadata, linked IDs, deprecation flags).
- Use both if you need full coverage — the profile webhook for identity and account data, and the preferences webhook for rich preference data.
Updated 13 days ago
