EPC - EDP - Data Feed Specification

Definitions & List of Abbreviations

Abbreviation Description
EPC Emirates Platinum Card
EDP Enterprise Data Platform (target data lake)
PII Personally Identifiable Information
DDS Direct Deduction from Salary
HRMS Human Resource Management System
AED United Arab Emirates Dirham
VAT Value Added Tax
BG_ID HRMS Business Group Identifier
AR Accounts Receivable
GL General Ledger
SSO Single Sign-On
DPO Data Protection Officer
M / O / C Mandatory / Optional / Conditional

1. Interface Description

Business Value

EPC operates the Emirates Platinum Card membership programme: employee and dependant enrolment, tiered memberships, partner offers and venue access, and the collection of membership fees by card or salary deduction.

This interface delivers the programme's operational data to the Enterprise Data Platform so that it can be combined with other enterprise datasets for reporting and analysis. Two consuming use cases are in scope:

Objective

To provide a complete, regularly refreshed extract of EPC operational data in a form that EDP can load without bespoke transformation logic on the EPC side, and to define unambiguously:

2. Assumptions & Risk

Assumptions

Risks

Risk Mitigation
Personal data, including data relating to dependants who are not employees, is delivered into a platform where it may be used for model training. Trained models cannot be selectively un-trained, so a subsequent erasure request cannot be satisfied by deleting records from the platform. Documented as an explicit decision in section 3.1. Requires DPO approval recorded before the first production delivery. EDP to confirm retention and erasure procedures.
Free-text fields (member.note, redemption.notes, invoice narrative) contain unstructured content entered by operators, the content of which has not been surveyed. EPC to complete a content review of free-text fields before first production delivery. EDP to treat these fields as unclassified until that review completes.
Monetary values misinterpreted as major units, overstating amounts by a factor of 100. Section 4.4.1 defines the convention. currency and exponent delivered alongside every monetary field. Section 4.4.2 identifies the one dataset that uses major units.
Coded identifiers loaded without reference data, producing unreadable dimensions. Section 4.6 code lists delivered with every extract. Section 4.4.5 lists every coded field and its corresponding code list.
Non-production membership numbers carry an environment suffix and will not reconcile against production. Section 5.3. The two environments are to be treated as separate key spaces and not joined.
Schema drift on the EPC side breaks EDP ingestion silently. Enumerated value sets are closed (section 4.6). EDP to alert on unrecognised values rather than discard. EPC to give advance notice of field additions; see section 5.4.

3. Non-Functional Requirements

3.1 Security Requirements

Sr No. Non-Functional Requirement Value
1 PHI or Credit Card data? No to both. The feed carries no patient health information. EPC holds no card numbers at any point; the card tokens and mandate references it does hold, and the raw payment-gateway messages, are excluded (section 6.2). The delivered dataset is therefore outside PCI-DSS scope.
2 PII included? Yes. The feed contains identified personal data relating to employees and to their dependants, including names, contact details, dates of birth, gender, marital status, home addresses, family relationships and free-text notes. Fields carrying PII are marked in the Data Definitions tables.
3 Authentication Pattern Determined by the transfer mechanism agreed under 5.1. No inbound interface is exposed by this feed.
4 Secure Channel / Encryption in Transit To be confirmed with the transfer mechanism (5.1). Encryption in transit is required.
5 Encryption at Rest To EDP standard, at the destination agreed under 5.1
6 Internet exposed? No public endpoint is created by this feed. Exposure of the destination is determined by the mechanism agreed under 5.1.
7 Credentials in payload None. Authentication credentials and password material are excluded from every dataset (section 6.2).

4. Solution View

4.1 Logical

Component Value
Source EPC (Emirates Platinum Card)
Target EDP (Enterprise Data Platform)
Direction Unidirectional, EPC to EDP
Extract type Full extract of every dataset on each delivery
Transfer protocol Open — requires EDP decision. See 5.1
Data format Open — requires EDP decision. See 5.1
Cadence Open — requires EDP decision. See 5.1

4.2 Architecture

> This section is deliberately unresolved. The transfer mechanism, encoding

> and scheduling have not been agreed and are an EDP-side decision — see 5.1.

> The data content of the feed, defined in 4.4 to 4.6, is independent of that

> decision and does not change with it.

Once the transfer mechanism is agreed, this section will document the interface

architecture, security mechanisms and exception-handling guidelines for the

chosen approach.

4.3 Interface Touchpoints / Use Cases

4.3.1 Membership reporting

Membership growth, tier mix, renewal and lapse behaviour, and dependant enrolment. Primary datasets: member, membership, tier, tier_enrollment, with member_type, member_subtype and tier_type for labels.

4.3.2 Fee collection and reconciliation

Amounts billed, collected and refunded, across both card and salary-deduction routes. Primary datasets: payment, payment_refund, transaction, invoice, invoice_line. For salary deduction specifically, dds_deduction_cycle and payroll_feed_line are authoritative — see section 4.4.6.

4.3.3 Programme utilisation

Take-up of partner offers and venue access, and the value delivered to members. Primary datasets: redemption, venue_checkin, venue_checkin_companion, offer, partner, partner_location.

4.3.4 Point-in-time and historical analysis

Reconstruction of prior state — a member's status at a past date, a tier's VAT treatment when a charge was raised. Only audit_log supports this; all other datasets carry current state only. See section 4.4.7.

4.4 Data Conventions

These conventions apply across all datasets and must be implemented by EDP before the field definitions in section 4.5 can be interpreted correctly.

4.4.1 Monetary values

All monetary fields whose name ends in Value are integers in minor units (fils). They are never decimals.

Element Meaning
Value Integer amount in minor units
currency ISO currency code of the amount. Always AED at time of writing
exponent Number of decimal places. Always 2 at time of writing

Display value = Value / 10^exponent. For example amountValue = 300 with exponent = 2 represents AED 3.00.

Every dataset carrying a monetary field delivers currency and exponent alongside it. Where the source record has no such field of its own (see 4.4.3), EPC stamps currency = AED and exponent = 2 at extraction. With the single exception in 4.4.2, the feed delivers minor units only; no dataset carries the same amount at two scales.

4.4.2 Exception — dataset using major units

One dataset carries amounts in major units (decimal AED) because it reproduces values exactly as posted to the finance system. It is the only exception in the feed.

Dataset Fields in major units
invoice_line unitSellingPrice, taxAmount, distributionAmount

Note that invoice header totals (totalAmountValue, totalBaseAmountValue, totalTaxAmountValue) remain in minor units. Reconciling an invoice header against its lines therefore requires a scale conversion.

The tier fee is delivered as feeValue (minor units) only. The major-unit fee shown in EPC's own user interfaces is computed for display and is not stored; it is not part of the feed.

4.4.3 Datasets with no native currency field

The following carry monetary values without a currency or exponent field in the source. EPC stamps currency = AED and exponent = 2 on these records at extraction; the stamped fields appear in each dataset's field table.

Dataset Monetary fields Stamped at extraction
membership installmentAmountValue, lastInstallmentAmountValue, ddsChargeAmountValue currency, exponent
dds_deduction_cycle amountValue currency, exponent
payment_refund amountValue currency, exponent
payroll_feed totalAmountValue currency, exponent
payroll_feed_line amountValue currency, exponent
redemption transactionAmountValue, discountAmountValue currency, exponent
venue_checkin paymentAmountValue, excessQuotaPriceValue, additionalGuests.*PriceValue currency, exponent
venue_checkin_companion priceValue currency, exponent
tier feeValue currency, exponent
offer priceValue, lifestyleHubDetails.*PriceValue currency, exponent
transaction amountValue exponent (currency is native)
invoice totalAmountValue, totalBaseAmountValue, totalTaxAmountValue exponent (trxCurrency is native)

payment carries both fields natively. invoice_line is in major units and carries neither; see 4.4.2.

4.4.4 Date and time formats

Type Format Example
Timestamp ISO 8601, UTC, Z suffix 2026-09-04T08:41:59.255Z
Date YYYY-MM-DD 2026-09-04
Accounting period YYYY-MM 2026-09

Timestamps within records are delivered as stored, in UTC. The time zone that defines a delivery day is an open decision — see 5.1, where EPC recommends Asia/Dubai for consistency with the payroll and financial reporting calendar.

4.4.5 Coded identifiers

The following fields carry stable identifiers, not display labels. EDP must join to the corresponding code list in section 4.6.

Field Dataset Resolve against
memberType member member_type
memberSubType member member_subtype
relation member, member_family member_subtype
company.id member company
companyGroupId company company_group
tierType.id tier tier_type
tierId membership, payment, invoice, payroll_feed_line tier
eligibilityRuleId membership, payment tier_eligibility_rule
categories, subcategories offer benefit_category, benefit_subcategory
documentId member_policy_acceptance policy_document

Labels are subject to change over time; identifiers are stable. EDP should resolve labels at query time rather than persisting them into fact records.

Identifier formats are not uniform. Three shapes appear across the feed and all

are valid: UUIDs (9a5a488e-9ebe-45fa-bc06-7b33baf68752), ULIDs

(01KYMKHRDEF88PBPV7ZX3AP2JB), and short lower-case slugs (employee, spouse,

base, airlines). Slugs are the earliest identifiers; later records use generated

values. Treat every identifier as an opaque string — do not validate its format,

and do not assume a single pattern per dataset.

An identifier must never be read as a label. The two diverge in live data:

Code list Identifier Actual name
member_type family "EK Temporary"
tier_type premium "Club"
tier_type 01kk1bb0hjp7h8czcbpxnxhsgf "Premium"
company_group airlines "CORE"

Inferring meaning from an identifier will therefore produce wrong results. Always

join to the code list.

The member_type and member_subtype code lists carry an hrmsMapping column giving the corresponding HRMS value, allowing EDP to join directly to enterprise HR reference data.

4.4.6 Selecting the correct dataset for fee analysis

Question Dataset
What was billed? payment
What money moved? transaction
What document was issued? invoice, invoice_line
What did payroll actually deduct? dds_deduction_cycle where state = confirmed, and payroll_feed_line where successFlag = Y

Important: for salary-deducted memberships, payment.completedAt is set at enrolment, before any money moves. It must not be used as a collection date. The authoritative collection date is payment.deductedAt, or equivalently the confirmedAt of the corresponding dds_deduction_cycle record.

A salary-deducted membership records a single payment covering its entire term. Per-period billing is recorded only in dds_deduction_cycle.

4.4.7 Current state versus history

All datasets except audit_log carry current state only. Where an analysis depends on a value as it stood at a past date, audit_log is the only source.

Two datasets have status transitions that carry no timestamp on the record itself:

Transition Dataset How to date it
General status changes membership Specific transitions carry cancelledAt, unsubscribedAt and convertedAt; there is no general last-modified timestamp. Other transitions are dated from the audit_log entries of the owning member (entityType = member).
active to expired tier_enrollment tier_enrollment writes no audit_log entries of its own. Expiry is a side effect of the owning membership ending, so date it from that membership's endDate, cancelledAt, unsubscribedAt or convertedAt, or from the member's audit_log entries.

redemption.status has a voided value defined, but no current process produces it (see 4.5.16); there is therefore no transition to date.

4.4.8 Nested collections

Records are delivered as whole objects with nested collections intact. EDP flattens to the grain stated for each dataset in section 4.5. The nested collections are:

Parent Nested collection Resulting dataset
member memberships[] membership
member memberships[].ddsDeductionCycles[] dds_deduction_cycle
member family[] member_family
member companions[] member_companion
member documents[] member_document
member acceptedPolicyDocuments[], policyDocumentAcceptanceHistory[] member_policy_acceptance
payment refunds[] payment_refund
invoice lines[] invoice_line
payroll_feed lines[] payroll_feed_line
venue_checkin companions[] venue_checkin_companion
tier eligibilityRules[] tier_eligibility_rule
offer eligibilityRules[] offer_eligibility_rule
partner locations[] partner_location
company memberSubTypes[] company_member_subtype

Where a child dataset requires the parent key, EPC injects it at extraction; the injected keys are listed in the relevant field tables.

4.4.9 Notation used in section 4.5

Column Meaning
Field Field name as delivered
Type Data type. minor units denotes an integer per 4.4.1
Req M Mandatory, always present · O Optional, may be absent · C Conditional, present only in defined circumstances
PII Y where the field carries personal data
Description Meaning of the field, and any interpretation notes

An optional field may occasionally be delivered as an explicit null rather than being absent; this occurs in particular on partner and partner_location. EDP should treat null and absent identically.

4.5 Dataset Definitions

Thirty-five datasets are delivered, in six groups. Each definition states the record grain, the primary key, and any key injected by EPC at extraction.

4.5.1 Dataset Inventory

Group Datasets Count
Member & household member, membership, dds_deduction_cycle, member_family, member_companion, member_document, member_policy_acceptance 7
Financial payment, payment_refund, transaction, invoice, invoice_line, payroll_feed, payroll_feed_line 7
Programme utilisation redemption, venue_checkin, venue_checkin_companion, search_history 4
Catalogue tier, tier_eligibility_rule, tier_enrollment, offer, offer_eligibility_rule, partner, partner_location, company, company_member_subtype, benefit_category, benefit_subcategory, policy_document 12
Reference data member_type, member_subtype, tier_type, company_group 4
Change history audit_log 1
Total 35

4.5.2 member

Grain: one record per enrolled person. Primary members (employees) and dependants share this dataset.

Primary key: id

Distinguishing rule: records carrying primaryMemberId are dependants; records without it are primary members.

Field Type Req PII Description
id String (UUID) M Unique record identifier. Referenced as memberId by all child datasets.
memberId String M Membership number issued to the member; ten digits. Appears as "Membership No" on partner-facing records. See 5.3 for the non-production suffix.
staffId String C Y Employee number as held in HRMS. Primary join key to enterprise HR data. Present on primary members only.
previousStaffIds Array[String] M Y Employee numbers previously held. Retained so historical records remain joinable after a staff number change. Empty array where none.
name String M Y Given name.
middleName String O Y Middle name.
surname String M Y Family name.
email String M Y Email address used for programme correspondence.
phone String O Y Mobile number.
gender String O Y male or female. Frequently absent; see 6.1.
maritalStatus String O Y single or married. Primary members only. Frequently absent; see 6.1.
birthdate String (date) O Y Date of birth. Determines dependant age eligibility. Frequently absent; see 6.1.
company.id String M Employing company. Resolve against company.
grade String O Employment grade as reported by HRMS.
coreGrade String O Normalised grade band, EK.01 to EK.14. Used by tier eligibility rules. Frequently absent; see 6.1.
department String O Department as reported by HRMS.
workAddress String O Place of work as reported by HRMS.
address.country String O Y Home address — country.
address.address String O Y Home address — street and locality, single line.
memberType String M Membership category identifier. Resolve against member_type.
memberSubType String O Membership sub-category identifier. Resolve against member_subtype.
relation String C Dependants only: relationship to the primary member. Resolve against member_subtype.
primaryMemberId String (UUID) C Dependants only: the member.id of the household's primary member.
dependantId String O The dependant's correlation identifier within the household.
hrmsFamilyMemberId String O Y HRMS person identifier for this dependant. Durable link to the enterprise family record.
status String (enum) M Enrolment lifecycle state. Values in 4.6.1.
statusReason String O Narrative accompanying the current status.
registrationSource String (enum) O How the record was created. Values in 4.6.11.
deactivatedBy String (enum) O What caused deactivation: system, hrms or program_management.
deactivatedAt String (timestamp) O When the member was deactivated. Cleared on reactivation.
suspensionEndDate String (date) C Date a suspension lifts. Present only while status = suspended.
hrmsJoiningDate String (date) O Employment start date from HRMS. Not a programme enrolment date. Primary members only.
hrmsValidated Boolean O Whether the record has been confirmed against HRMS.
leavingReason String O Y Reason for leaving employment, as reported by HRMS.
lastDayOfService String (date) O Y Final day of employment.
isRetiree Boolean O Whether classified as a retiree.
isAlumni Boolean O Alumni classification, recalculated nightly from joining date and date of birth. May revert to false if upstream data is corrected.
ddsLimit Number O Y Salary-deduction headroom as last reported by payroll.
availedDds Number O Y Salary-deduction amount already committed.
ddsCheckedAt String (timestamp) O When ddsLimit and availedDds were last refreshed. Required to assess their currency.
loginMethod String (enum) M sso or email_password.
lastLoginAt String (timestamp) O Most recent sign-in. Engagement indicator.
idPhotoStatus String (enum) O pending, approved or rejected. The image itself is not delivered; see 6.2.
idPhoto String O Internal storage reference for the identity photograph. Delivered as an opaque string; not resolvable outside EPC. The reference to any superseded photograph is withheld; see 6.2.
permissions.sms Boolean O Consent to receive SMS.
permissions.email Boolean O Consent to receive email.
invitationSentAt String (timestamp) O When the enrolment invitation was first sent.
lastInvitationSentAt String (timestamp) O When an invitation was most recently re-sent.
note String (max 2000) O Y Free-text administrative note. Unstructured; content not surveyed. See section 2 Risks.
isFace Boolean M *Derived.* Whether the member holds a Face card, computed from grade.
actionRequired Boolean M *Derived.* Whether the record is missing information required to complete enrolment.
actionMessage String M *Derived.* Which details are missing, as a readable list. Empty when actionRequired is false.
requiresPaymentInstrumentUpdate Boolean M *Derived.* Whether any membership awaits a renewed payment method.
paymentInstrumentUpdateDeadline String (timestamp) O *Derived.* Earliest such deadline across the member's memberships.
createdAt String (timestamp) M When the record was created.
updatedAt String (timestamp) O When the record was last modified.
createdBy.type String (enum) M Actor category. Values in 4.6.12.
createdBy.id String M Actor identifier.
createdBy.name String O Y Actor display name.
createdBy.email String O Y Actor email address.

4.5.3 membership

Grain: one record per enrolment in a tier. A member may hold several concurrently — a base tier plus upgrades or add-ons.

Primary key: id · Injected key: memberId

Field Type Req PII Description
id String (UUID) M Unique identifier for the enrolment.
memberId String (UUID) M *Injected.* The member holding this membership.
tierId String M Tier enrolled in. Resolve against tier.
eligibilityRuleId String O The tier rule under which the member qualified. Determines price, payment options and quota. Absent on older enrolments.
paymentId String (UUID) O The payment that purchased this membership.
status String (enum) M Membership lifecycle state. Values in 4.6.2. Note the treatment of converted and scheduled.
paymentType String (enum) M How the membership is funded. Values in 4.6.3.
startDate String (timestamp) M Start of the membership term. A full timestamp, not a date.
endDate String (timestamp) M End of the membership term. A full timestamp.
autoRenewal Boolean O Whether the membership renews automatically at term end.
statusReason String O Narrative accompanying the current status.
unsubscribedAt String (timestamp) O When the member opted out.
unsubscribedBy.id String O Identifier of the party that performed the opt-out.
unsubscribedBy.type String (enum) O Actor category. Values in 4.6.12.
unsubscribedBy.name String O Y Actor display name.
cancelledAt String (timestamp) O When the membership was cancelled.
paymentSchedule String (enum) O one_time or installment.
totalInstallments Integer O Instalments in the current arrangement. Resets if the payment method changes mid-term.
paidInstallments Integer O Instalments collected to date.
originalTotalInstallments Integer O Instalments agreed at enrolment. Use for lifetime counts — survives a mid-term change of payment method.
installmentAmountValue Integer (minor units) O Amount of each instalment.
lastInstallmentAmountValue Integer (minor units) O Amount of the final instalment where it differs to absorb rounding.
nextInstallmentDate String (date) O When the next instalment falls due.
installmentStatus String (enum) O active, suspended or completed.
paymentPeriodMonths Integer O Length of the payment period in months.
ddsChargeAmountValue Integer (minor units) O Salary-deduction charge where it differs from the tier fee. Set on mid-term conversions, where the member owes only the pro-rated difference, and on dependants, where it is the pro-rated price the dependant was charged (one-time or instalment plan total). When absent, the tier fee applies.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
pendingRenewalSince String (timestamp) O When the membership entered payment recovery.
pendingRenewalReason String (enum) O instrument_failed or retry_exhausted.
recoveryDeadlineAt String (timestamp) O Deadline for restoring payment before the membership lapses.
renewsMembershipId String (UUID) O The membership this one renews. Follow for continuous-tenure analysis.
convertsMembershipId String (UUID) O Set on the successor of a mid-term upgrade, referencing the source membership.
convertedToMembershipId String (UUID) O Set on the source, referencing its successor.
convertedAt String (timestamp) O When the conversion took effect. The source membership's effective end date.
requiresPaymentInstrumentUpdate Boolean M *Derived.* Whether this membership awaits a renewed payment method.
paymentInstrumentUpdateDeadline String (timestamp) O *Derived.* The deadline for doing so.
createdAt String (timestamp) O When the enrolment was created.

4.5.4 dds_deduction_cycle

Grain: one record per membership per monthly billing period.

Injected keys: membershipId, memberId

> Authoritative for salary-deduction reconciliation. A salary-deducted membership records a single payment for its entire term, so payment alone cannot identify which months were billed. This dataset is that record.

Field Type Req PII Description
membershipId String (UUID) M *Injected.* The membership being billed.
memberId String (UUID) M *Injected.* The member.
periodMonth String (period) M Billing period, YYYY-MM.
state String (enum) M emitted, confirmed or released. Only confirmed indicates money left payroll. Values in 4.6.7.
amountValue Integer (minor units) M Amount billed for the period.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
feedId String (UUID) M The payroll batch carrying the line. Resolve against payroll_feed.
interfaceLineId Integer O The line within that batch. Resolve against payroll_feed_line.
emittedAt String (timestamp) M When the deduction line was raised.
confirmedAt String (timestamp) C When payroll confirmed the deduction. Present only when state = confirmed.
releasedAt String (timestamp) C When the attempt was abandoned. Present only when state = released.
releaseReason String O Why the period was released.

4.5.5 member_family

Grain: one record per family member recorded against a primary member. A family record denotes a known relative; the person becomes a dependant member only upon enrolment.

Injected key: primaryMemberId

Field Type Req PII Description
primaryMemberId String (UUID) M *Injected.* The primary member this family record belongs to.
memberId String M Y HRMS person identifier for the family member.
relation String O Relationship to the primary member. Resolve against member_subtype. Empty where the HRMS relationship type has no configured equivalent.
dependantId String O Set once the person has been enrolled as a dependant member. Presence marks the family record as converted.
dependantStatus String O Enrolment state of the resulting dependant.
name String O Y Given name as held in HRMS.
surname String O Y Family name as held in HRMS.
email String O Y Email address as held in HRMS.
phone String O Y Mobile number as held in HRMS.
birthdate String (date) O Y Date of birth. Determines eligibility against dependant age limits.
contactStatus String O Whether the relationship remains current in HRMS.
error String O Readable explanation of why the family member cannot currently be enrolled, most commonly incomplete contact details or an inactive HRMS relationship.

4.5.6 member_companion

Grain: one record per companion registered by a member. Companions are guests a member may bring to venues; they hold no membership.

Injected key: memberId

Field Type Req PII Description
memberId String (UUID) M *Injected.* The member who registered the companion.
name String M Y Given name.
surname String M Y Family name.
gender String (enum) M Y male or female.
addedAt String (timestamp) M When the companion was registered.
status String (enum) M active or inactive.

4.5.7 member_document

Grain: one record per document held against a member. Metadata only — document contents are not delivered.

Injected key: memberId

Field Type Req PII Description
memberId String (UUID) M *Injected.* The member the document belongs to.
id String (UUID) M Unique identifier for the document.
name String M Y File name as supplied.
documentType String O Classification of the document.
status String (enum) M active or archived.
uploadedAt String (timestamp) M When the document was provided.
uploadedBy.type String (enum) M Actor category. Values in 4.6.12.
uploadedBy.id String M Actor identifier.
uploadedBy.name String O Y Actor display name.
filePath String M Internal storage reference. Delivered as an opaque string; not resolvable outside EPC.

4.5.8 member_policy_acceptance

Grain: one record per acceptance of a policy document, including superseded acceptances. The complete consent history is therefore present.

Injected key: memberId

Field Type Req PII Description
memberId String (UUID) M *Injected.* The member who accepted.
documentId String M The document accepted. Resolve against policy_document.
documentType String (enum) M Kind of document. Values in 4.6.17.
version Integer M Version accepted. Consent is version-specific: a new version requires a fresh acceptance.
entityType String (enum) M What the document was bound to. Values in 4.6.17.
entityId String M Identifier of that entity.
targetGroup String (enum) O Audience to which the document applies. Values in 4.6.17.
status String (enum) M State of the acceptance: accepted or waiting. Values in 4.6.17.
acceptedAt String (timestamp) M When the acceptance was recorded.
isCurrent Boolean M *Derived.* true for the acceptance in force; false for superseded acceptances.

4.5.9 payment

Grain: one record per collection attempt, successful or otherwise.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier for the attempt.
memberId String (UUID) M The member being charged.
dependantId String O Set where the charge relates to a dependant's membership.
tierId String M Tier being paid for.
eligibilityRuleId String M Rule that determined the price.
invoiceId String (UUID) O Invoice raised for this payment.
paymentType String (enum) M Funding route. Values in 4.6.3.
provider String (enum) M cpg (card payment gateway) or dds (salary deduction).
paymentReason String (enum) O Why the charge was raised. Values in 4.6.5.
orderCode String O Order reference exchanged with the payment gateway. Card payments only.
refId String O Gateway-side reference for the order. Card payments only.
cpgOrderStatus String O Last order status string returned by the payment gateway, as received. Card payments only.
amountValue Integer (minor units) M Amount charged.
currency String M ISO currency code.
exponent Integer M Decimal places.
totalFeeValue Integer (minor units) O Full fee, where this payment covers only part of it.
status String (enum) M Outcome of the attempt. Values in 4.6.4.
statusReason String O Narrative explanation of the outcome.
errorCode String O Machine-readable failure code. Basis for decline analysis.
recurringType String (enum) O CIT (member present) or MIT (taken automatically).
installmentNumber Integer O Position of this instalment in the plan.
totalInstallments Integer O Instalments in the plan.
retryCount Integer O Retries following a decline for insufficient funds.
transientRetryCount Integer O Retries following a technical failure. Counted separately from declines.
nextRetryAt String (timestamp) O When the next retry is scheduled.
transientAdminAlerted Boolean O Whether a technical-failure alert has been raised for this payment.
parentPaymentId String (UUID) O The originating payment, for retries and instalments.
renewalMembershipId String (UUID) O Membership being renewed by this payment.
scheduledStartDate String (date) O Start of the term the renewal will cover.
scheduledEndDate String (date) O End of that term.
convertsMembershipId String (UUID) O Membership being upgraded away from. The amount is the pro-rated difference, not the target tier's full fee.
refundedAmountValue Integer (minor units) O Total refunded against this payment to date.
refundedReasonCode String (enum) O Reason for the most recent refund. Full history in payment_refund. Values in 4.6.6.
refundedReasonDetails String (max 500) C Y Free-text detail. Present when refundedReasonCode = other.
refundedAt String (timestamp) O When the most recent refund was issued.
refundedBy String O Identifier of the party that issued the most recent refund.
createdAt String (timestamp) M When the attempt was raised.
updatedAt String (timestamp) O When the record was last modified.
completedAt String (timestamp) O When the attempt completed. For salary deduction this is set at enrolment, before money moves — do not use as a collection date. See 4.4.6.
deductedAt String (timestamp) C Salary deduction only. When payroll confirmed the money was taken. The authoritative collection date for deducted memberships.

4.5.10 payment_refund

Grain: one record per individual refund. A payment may be refunded more than once, and partially.

Primary key: id · Injected key: paymentId

Field Type Req PII Description
paymentId String (UUID) M *Injected.* The payment being refunded.
id String (UUID) M Unique identifier for the refund.
amountValue Integer (minor units) M Amount refunded.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
reasonCode String (enum) M Reason for the refund. Values in 4.6.6.
reasonDetails String (max 500) C Y Free-text detail. Mandatory when reasonCode = other.
refundType String (enum) M cpg (to card) or dds (through payroll).
refundedAt String (timestamp) M When the refund was issued.
payrollFeedId String (UUID) C Payroll batch carrying the refund. Salary-deduction refunds only.
payrollPushedAt String (timestamp) C When payroll confirmed the refund. While absent, a payroll refund remains in flight.
refundedBy String M Identifier of the party that issued the refund.

4.5.11 transaction

Grain: one record per ledger movement — a payment taken or a refund given.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier.
memberId String (UUID) M The member.
paymentId String (UUID) M Payment the movement belongs to.
type String (enum) M payment or refund.
status String (enum) M completed, failed or pending.
amountValue Integer (minor units) M Amount moved.
currency String M ISO currency code.
exponent Integer M Decimal places. Stamped at extraction; see 4.4.3.
description String M Readable description of the movement.
tierName String M Tier name as at the time of the movement. Retained so historical statements are not rewritten by later renaming.
reasonCode String (enum) C Refund reason. Refund movements only. Values in 4.6.6.
reasonDetails String (max 500) O Y Free-text refund detail.
refundEntryId String (UUID) C The specific refund settled. Resolve against payment_refund.
actorId String O Identifier of the party that initiated the movement, where a person did.
createdAt String (timestamp) M When the movement was recorded.
updatedAt String (timestamp) O When the record was last modified.

4.5.12 invoice

Grain: one record per invoice or credit note.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier.
paymentId String (UUID) M Payment the document relates to.
memberId String (UUID) M The member.
tierId String M Tier concerned.
membershipId String (UUID) O Membership concerned.
refundEntryId String (UUID) C On credit notes, the refund being documented.
type String (enum) M invoice or credit_note.
trxNumber String M Document number as issued.
trxDate String (date) M Document date.
trxCurrency String M Currency of the document.
exponent Integer M Decimal places applying to the header totals. Stamped at extraction; see 4.4.3.
comments String M Narrative shown on the document.
internalNotes String M Y Allocation reference. Embeds the employee number and a short order reference.
totalAmountValue Integer (minor units) M Total including tax.
totalBaseAmountValue Integer (minor units) M Total excluding tax.
totalTaxAmountValue Integer (minor units) M Tax portion.
arSubmission Boolean M Whether the document is submitted to Accounts Receivable. false for salary-deducted memberships, which are documented but not posted to AR.
erpInvoiceNumber String O Number assigned by the finance system.
erpErrorDetails String O Failure detail returned by the finance system.
erpSubmittedAt String (timestamp) O When the document was submitted.
erpResponseAt String (timestamp) O When the finance system responded.
pdfStatus String (enum) M pending, generated or failed.
pdfGeneratedAt String (timestamp) O When the printable document was produced.
pdfError String O Error from the last failed generation attempt.
pdfFileKey String O Internal storage reference for the generated PDF. Opaque outside EPC.
retryCount Integer M Submission attempts made.
nextRetryAt String (timestamp) O When the next submission attempt is scheduled.
status String (enum) M pending, submitted, completed or failed.
createdAt String (timestamp) M When the document was raised.
updatedAt String (timestamp) O When it was last modified.
createdBy String M Identifier of the party that raised it.

4.5.13 invoice_line

Grain: one record per line on an invoice or credit note.

Injected key: invoiceId

> Scale exception. The monetary fields on this dataset are in major units (decimal AED), whereas invoice header totals are in minor units. See 4.4.2.

Field Type Req PII Description
invoiceId String (UUID) M *Injected.* Parent document.
lineNumber Integer M Position of the line on the document.
description String M What is being charged.
unitSellingPrice Number (major units) M Price excluding tax, as decimal AED.
quantityOrdered Integer M Quantity.
uomCode String M Unit of measure.
taxAmount Number (major units) M Tax on the line, as decimal AED. Negative on credit notes.
taxRateCode String M Tax rate applied.
segment2 String M Cost centre in the enterprise chart of accounts.
segment3 String M Nominal code.
segment4 String M Subnominal code.
distributionAmount Number (major units) M Amount posted to that account combination.

4.5.14 payroll_feed

Grain: one record per batch submitted to payroll.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier for the batch.
type String (enum) M Nature of the batch. Values in 4.6.9.
status String (enum) M Batch outcome. Values in 4.6.8.
periodMonth String (period) M Payroll period, YYYY-MM.
batchName String M Batch identifier as presented to payroll.
fileBatchName String M File-level batch identifier.
s3Bucket String M Internal storage location of the submitted file. Opaque outside EPC.
s3Key String M Internal storage reference of the submitted file. Opaque outside EPC.
applicationName String M Payroll application targeted.
totalLines Integer M Lines in the batch.
successCount Integer M Lines accepted by payroll.
failedCount Integer M Lines rejected by payroll.
totalAmountValue Integer (minor units) M Total value of the batch.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
interfaceLoadId String O Reference returned by payroll on receipt.
failureReason String O One-line explanation where the batch failed.
failedAt String (timestamp) O When the batch was marked failed.
submittedAt String (timestamp) O When the batch was submitted.
completedAt String (timestamp) O When processing completed.
createdAt String (timestamp) M When the batch was created.
updatedAt String (timestamp) O When it was last modified.
createdBy String M Originator of the batch.

4.5.15 payroll_feed_line

Grain: one record per deduction or refund line. The most direct join between programme data and enterprise payroll records.

Injected keys: feedId, periodMonth

Field Type Req PII Description
feedId String (UUID) M *Injected.* Batch the line belongs to.
periodMonth String (period) M *Injected.* Payroll period.
interfaceLineId Integer M Line number within the batch.
staffId String M Y Employee number the deduction is raised against. Primary payroll join key.
memberId String (UUID) M The member.
membershipId String (UUID) M The membership.
tierId String O Tier the membership belongs to.
paymentId String (UUID) O Payment the line settles, resolved once payroll confirms.
isDependant Boolean M Whether the deduction covers a dependant's membership.
primaryMemberId String (UUID) C The employee bearing the cost, where the line relates to a dependant.
elementType String M Payroll element the deduction posts to.
applicationName String M Payroll application targeted.
amountValue Integer (minor units) M Amount to deduct.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
remarks String M Y Narrative shown on the payslip. Carries the dependant reference on dependant lines.
payrollDate String (date) M Date the deduction is scheduled for.
successFlag String (enum) O Y or N — whether payroll accepted the line. Primary reconciliation field. Absent while awaiting response.
errorDetails String O Reason for rejection.
refundEntryId String (UUID) C Refund returned by this line, on refund batches.
membershipType String O Membership descriptor, on seasonal batches.
costingLob String O Line of Business, seasonal batches (payroll VALUE_7). Absent on lines before Oct 2026.
costingRc String O Responsibility Centre, seasonal batches (VALUE_8).
costingAc String O Nominal, seasonal batches (VALUE_9).
costingSubNominal String O Sub Nominal, seasonal batches (VALUE_10).
costingAnalysisKey String O Analysis Key, seasonal batches (VALUE_11).
costingAmount String O Legacy: the amount, on seasonal lines before Oct 2026 only.
glJournalId String (UUID) O GL batch this line was aggregated into.
postedToGlAt String (timestamp) O When the line was included in a GL submission.

4.5.16 redemption

Grain: one record per offer redeemed at a partner.

Primary key: id

> redemption and venue_checkin are disjoint. An offer is either redeemable or a venue-access offer, never both. See 4.6.10.

Field Type Req PII Description
id String (UUID) M Unique identifier.
memberId String (UUID) M The member who redeemed.
memberDisplayId String M The member's membership number, as quoted at the point of sale.
memberName String M Y Given name at the time of redemption.
memberSurname String M Y Family name at the time of redemption.
offerId String (UUID) M Offer redeemed.
partnerId String (UUID) M Partner honouring the offer.
locationId String M Partner location.
partnerUserId String (UUID) M Partner staff member who processed the redemption.
offerName String M Offer name as at the time of redemption.
locationName String M Location name as at the time of redemption.
offerType String (enum) M discount, special_price or special_deal. Venue access is excluded by definition.
transactionAmountValue Integer (minor units) M Amount spent by the member before discount.
discountAmountValue Integer (minor units) M Amount saved by the member. Principal programme value measure.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
notes String (max 500) O Y Free-text note entered by partner staff.
status String (enum) M completed or voided. voided is reserved: no current EPC process produces it, so every record carries completed at time of writing. Should it appear, exclude voided from value totals.
voidedReason String O Reserved alongside voided; not populated by any current process.
redeemedAt String (timestamp) M When the redemption took place.
createdAt String (timestamp) M When the record was created.
createdBy.type String (enum) M Actor category. Values in 4.6.12.
createdBy.id String M Actor identifier.
createdBy.name String O Y Actor display name.

4.5.17 venue_checkin

Grain: one record per visit to a venue offering Lifestyle Hub access.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier.
memberId String (UUID) M The member checking in.
memberDisplayId String M The member's membership number.
memberName String M Y Given name at the time of the visit.
memberSurname String M Y Family name at the time of the visit.
offerId String (UUID) M Venue offer.
partnerId String (UUID) M Partner operating the venue.
locationId String M Venue location.
partnerUserId String (UUID) M Venue staff member who admitted the party.
offerName String M Offer name as at the time of the visit.
locationName String M Location name as at the time of the visit.
accessType String (enum) O Entitlement used: individual, couple or family. Determines who entered free. Absent on visits predating per-entitlement quotas; see 6.1.
isPaid Boolean M Whether any charge was raised for the visit.
paymentAmountValue Integer (minor units) M Total charged.
excessQuotaPriceValue Integer (minor units) M Entry fee charged to the member where the day's allocation was already exhausted.
isExcessQuota Boolean M Whether the visit occurred after the allocation was exhausted.
quotaConsumed Boolean M Whether the visit consumed a place from the day's allocation.
quotaRecovered Boolean O Whether that place was returned at check-out. Absent while the party remains on site.
additionalGuests.adultCount Integer M Paying adult guests beyond the member's own party.
additionalGuests.childCount Integer M Paying child guests.
additionalGuests.adultPriceValue Integer (minor units) M Price charged per adult guest.
additionalGuests.childPriceValue Integer (minor units) M Price charged per child guest.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
offerLocationDate String M Composite grouping key of offer, location and date.
status String (enum) M checked_in, checked_out or cancelled.
checkInTime String (timestamp) M Arrival.
checkOutTime String (timestamp) O Departure. Dwell time is the difference between the two.
cancelledAt String (timestamp) O When the visit was cancelled.
createdAt String (timestamp) M When the record was created.
createdBy.type String (enum) M Actor category. Values in 4.6.12.
createdBy.id String M Actor identifier.
createdBy.name String O Y Actor display name.

4.5.18 venue_checkin_companion

Grain: one record per companion on a visit.

Injected key: checkinId

Field Type Req PII Description
checkinId String (UUID) M *Injected.* The visit.
id String M Identifier of the companion.
name String M Y Given name. May relate to a person who is not an employee.
surname String M Y Family name.
relationship String (enum) M adult or child. A pricing category, not a family relationship.
isPaid Boolean M Whether this companion was charged for.
priceValue Integer (minor units) M Amount charged. Zero where the companion entered free.
currency String M ISO currency code. Stamped at extraction.
exponent Integer M Decimal places. Stamped at extraction.
source String (enum) M How the companion was identified. Values in 4.6.13.
isMember Boolean M Whether the companion holds a membership in their own right.
isSpouse Boolean M Whether the companion occupied the spouse place. At most one per visit.

4.5.19 search_history

Grain: one record per member per distinct normalised query. A rolling snapshot, not an event log.

Primary key: composite of memberId and normalizedQuery

> Repeating a search does not add a record; it overwrites searchedAt on the existing one. Each member retains at most 100 records, the oldest being pruned, and a record expires 90 days after its last search. The dataset therefore answers "what has each member searched for recently", not "how many searches were made". Search counts and long-run trends cannot be derived from it, and a full extract carries only the trailing 90 days.

Field Type Req PII Description
memberId String (UUID) M Y The member who searched. Attribution renders these records personal data.
originalQuery String M Y The query as most recently typed, verbatim.
normalizedQuery String M The query lower-cased and trimmed. Grouping key.
searchedAt String (timestamp) M When this query was most recently searched by the member.

4.5.20 tier

Grain: one record per tier. A tier is a purchasable level of membership with a fee, a term and eligibility rules.

Primary key: id

Field Type Req PII Description
id String M Unique identifier.
name String M Internal name.
label String M Name presented to members.
description String O Descriptive copy.
color String O Brand colour used in member-facing presentation.
tierType.id String M Tier type. Resolve against tier_type.
tierType.group String (enum) M base, upgrade or add_on.
feeValue Integer (minor units) M Standard fee for the term, in minor units. The major-unit fee shown in EPC user interfaces is derived from this value and is not delivered; see 4.4.2.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
startDate String (timestamp) M Start of the window during which the tier may be purchased. A full timestamp, not a date.
endDate String (timestamp) M End of that window. A full timestamp; end-of-day values appear as ...T19:59:59.999Z.
membershipDuration Integer O Length of the resulting membership, in months.
membershipEndDate String (date) O Fixed end date, used instead of a duration for fixed-season tiers.
taxable Boolean M Whether the fee attracts VAT. Reflects the current setting only. This value changes over a tier's life; historical VAT analysis must use audit_log. See 4.4.7.
financeConfig.costCentre String O Cost centre revenue posts to.
financeConfig.nominal String O Nominal code.
financeConfig.subnominal String O Subnominal code.
financeConfig.analysisKey String O Analysis key.
financeConfig.erpCommentPrefix String O Narrative prefix applied to finance postings.
ddsConfig.staffElementType String O Payroll element used to deduct from an employee.
ddsConfig.dependantElementType String O Payroll element used for a dependant's membership.
status String (enum) M Tier lifecycle state: pending, active, inactive or expired. Values in 4.6.16.
statusReason String O Narrative accompanying the current status.
createdAt String (timestamp) M When the tier was created.
updatedAt String (timestamp) O When it was last modified.
createdBy.type / .id / .name Object M Originator.

4.5.21 tier_eligibility_rule

Grain: one record per rule on a tier. Rules determine who may purchase a tier, on what payment terms, and how many places exist.

Injected key: tierId

Field Type Req PII Description
tierId String M *Injected.* Tier the rule belongs to.
id String M Rule identifier. Referenced by membership.eligibilityRuleId.
name String M Rule name.
paymentTypes Array[String] M Payment methods the rule permits. Values in 4.6.3; free_dependant never appears on a rule.
paymentPeriod String (enum) M Instalment period offered under the rule: monthly or one_time. Values in 4.6.18.
quota Integer O Maximum places available. Absent denotes unlimited.
status String (enum) M active or inactive.
conditions[].key String M Member attribute tested.
conditions[].logicalOperator String (enum) M Comparison applied. Values in 4.6.14.
conditions[].value Mixed O Value compared against. May be string, number, boolean or array.

4.5.22 tier_enrollment

Grain: one record per member per tier. Records consumption of an eligibility rule's quota.

Primary key: composite of tierId and memberId

Field Type Req PII Description
tierId String M Tier enrolled in.
memberId String (UUID) M Member enrolled.
eligibilityRuleId String M Rule whose quota the place was taken from.
paymentType String (enum) M Payment method used.
enrolledAt String (timestamp) M When the place was taken.
status String (enum) M active or expired. No expiry timestamp is carried; see 4.4.7 for how to date the transition.

4.5.23 offer

Grain: one record per offer.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier.
offerId String M Reference presented to members.
name String M Offer name.
partnerId String (UUID) M Partner providing the offer.
partnerLocations Array[String] M Locations at which the offer is honoured. An empty array denotes all of the partner's locations.
offerType String (enum) M Nature of the offer. Values in 4.6.10.
percentage Number C Discount percentage. Discount offers only.
priceValue Integer (minor units) C Fixed member price. Special-price offers only.
categories Array[String] M Benefit categories. Resolve against benefit_category.
subcategories Array[String] O Benefit subcategories. Resolve against benefit_subcategory.
keywords Array[String] O Search terms associated with the offer.
label String O Merchandising label.
badges Array[String] O Merchandising badges.
isFeatured Boolean M Whether the offer is promoted.
isVisibleToAll Boolean M Whether the offer bypasses eligibility rules and is shown to all members.
startDate String (date) M Start of the redemption window.
endDate String (date) O End of the redemption window.
viewStartDate String (date) M Start of the visibility window, often wider than the redemption window.
viewEndDate String (date) O End of the visibility window.
shortDescription String (max 500) M Summary presented in listings.
longDescription String O Full descriptive copy.
description.discountInfo String O What the offer provides.
description.includes String O What is included.
description.guests String O Guest entitlements.
description.howToBook String O Booking instructions.
description.howToRedeem String O Redemption instructions.
description.termsAndConditions String O Terms attached to the offer.
description.disclaimer String O Disclaimer text.
quota Integer O Capacity limit; absent or null denotes unlimited. Meaning depends on offerType. For redeemable offers it is the lifetime number of redemptions permitted, enforced against completedRedemptionsCount. For venue offers it is a legacy daily capacity, superseded by the per-entitlement quotas in lifestyleHubDetails.accessOptions[] wherever those are present.
quotaCheckedIn Integer M Venue offers: places occupied today, across all entitlement levels.
quotaCheckedOut Integer M Venue offers: places released today, across all entitlement levels.
quotaSnapshotDate String (date) O Day to which the occupancy counters relate.
accessQuotaCounters.*.checkedIn Integer O Venue offers: places occupied today under one entitlement level. The key is individual, couple or family. Shares quotaSnapshotDate.
accessQuotaCounters.*.checkedOut Integer O Venue offers: places released today under that entitlement level.
completedRedemptionsCount Integer M Redeemable offers: lifetime count of completed redemptions.
lifestyleHubDetails.accessType Array[String] C Entitlement levels offered: individual, couple, family. Mirror of accessOptions[].accessType.
lifestyleHubDetails.accessOptions[].accessType String (enum) C Entitlement level: individual, couple or family.
lifestyleHubDetails.accessOptions[].quota Integer O Daily capacity for that entitlement level; absent or null denotes unlimited. Authoritative daily capacity for venue offers. Absent on offers configured before per-entitlement quotas existed; those fall back to quota.
lifestyleHubDetails.adultPriceValue Integer (minor units) O Standard adult companion price.
lifestyleHubDetails.childPriceValue Integer (minor units) O Standard child companion price.
lifestyleHubDetails.guestDayPassAdultPriceValue Integer (minor units) O Adult day-pass price for additional guests.
lifestyleHubDetails.guestDayPassChildPriceValue Integer (minor units) O Child day-pass price for additional guests.
lifestyleHubDetails.excessQuotaDayPassAdultPriceValue Integer (minor units) O Adult price once the daily allocation is exhausted.
lifestyleHubDetails.excessQuotaDayPassChildPriceValue Integer (minor units) O Child price once the daily allocation is exhausted.
lifestyleHubDetails.accessDescription String O Guidance on venue access.
lifestyleHubDetails.howToRegister String O Registration instructions.
lifestyleHubDetails.additionalGuests String O Guidance on additional guests.
lifestyleHubDetails.cancelWindowMinutes Integer O Cancellation window, in minutes.
currency String M ISO currency code. Stamped at extraction; see 4.4.3.
exponent Integer M Decimal places. Stamped at extraction.
heroImagePath String O Internal storage reference for the primary image. Opaque outside EPC.
additionalImagePaths Array[String] O Internal storage references for further images. Opaque outside EPC.
status String (enum) M Offer lifecycle state: pending, active, inactive or expired. Values in 4.6.16.
statusReason String O Narrative accompanying the current status.
createdAt String (timestamp) M When the offer was created.
updatedAt String (timestamp) O When it was last modified.
createdBy.type / .id / .name Object M Originator.

4.5.24 offer_eligibility_rule

Grain: one record per rule on an offer. Determines which members are shown the offer.

Injected key: offerId

Field Type Req PII Description
offerId String (UUID) M *Injected.* Offer the rule belongs to.
id String M Rule identifier.
name String M Rule name.
status String (enum) M active or inactive.
conditions[].key String M Member attribute tested.
conditions[].logicalOperator String (enum) M Comparison applied. Values in 4.6.14.
conditions[].value Mixed O Value compared against.

4.5.25 partner

Grain: one record per partner business.

Primary key: id

Field Type Req PII Description
id String (UUID) M Unique identifier.
brandName String M Trading name presented to members.
legalName String O Registered company name.
brandLogoPath String O Internal storage reference for the logo. Opaque outside EPC.
heroImagePath String O Internal storage reference. Opaque outside EPC.
additionalImagePaths Array[String] O Internal storage references for further images. Opaque outside EPC.
partnerTier String O Commercial classification of the partnership.
partnerGroup String O Commercial grouping.
businessAddress String M Registered address.
city String M City.
country String M Country.
website String O Public website.
tradeLicenseNumber String O Trade licence reference.
contractId String M Contract reference governing the partnership.
contractStartDate String (date) M Contract start.
contractEndDate String (date) O Contract end. Absent denotes open-ended.
accountAgent String O Y Person managing the relationship.
primaryContact.name String O Y Named contact at the partner.
primaryContact.email String O Y Contact email address.
primaryContact.phone String O Y Contact telephone number.
socialMediaAccounts[].platform String (enum) O Social platform. Values in 4.6.18.
socialMediaAccounts[].url String O Profile URL.
status String (enum) M Partner lifecycle state: pending, active or inactive. Values in 4.6.16.
statusReason String O Narrative accompanying the current status.
createdAt String (timestamp) M When the partner was created.
updatedAt String (timestamp) O When last modified.
createdBy.type / .id / .name Object M Originator.

4.5.26 partner_location

Grain: one record per partner outlet. Coordinates support catchment and proximity analysis.

Injected key: partnerId

Field Type Req PII Description
partnerId String (UUID) M *Injected.* Owning partner.
id String M Location identifier. Referenced by redemption and venue_checkin.
name String M Outlet name.
address String M Street address.
coordinates.latitude Number M Latitude, decimal degrees.
coordinates.longitude Number M Longitude, decimal degrees.
contact.name String O Y Outlet contact name.
contact.email String O Y Outlet contact email.
contact.phone String O Y Outlet contact telephone.
status String (enum) M active or inactive.

4.5.27 company

Grain: one record per participating company.

Primary key: id

Field Type Req PII Description
id String M Unique identifier. Referenced by member.company.id.
name String M Company name.
description String O Description.
companyGroupId String M Parent group. Resolve against company_group.
bgIds Array[String] O HRMS Business Group identifiers (BG_ID). Direct join key to enterprise organisational structure.
eligibleMemberTypes Array[String] M Member types the company may enrol. Resolve against member_type.
maxFreeDependants Integer M Free dependant places available to each employee.
hrContact.name String M Y HR contact name.
hrContact.email String M Y HR contact email address.
emailPasswordOnly Boolean O Whether the company is outside SSO, its members using email and password.
status String (enum) M pending, active or inactive. Values in 4.6.16.
statusReason String O Narrative accompanying the current status.
createdAt String (timestamp) M When the company was created.
updatedAt String (timestamp) O When last modified.
createdBy.type / .id / .name Object M Originator.

4.5.28 company_member_subtype

Grain: one record per member subtype configured for a company. Sets dependant enrolment limits.

Injected key: companyId

Field Type Req PII Description
companyId String M *Injected.* The company.
memberSubTypeId String M Subtype being limited. Resolve against member_subtype.
maxDependants Integer M Number of dependants of this subtype an employee may enrol.
maxUpgradeDependants Integer O Number that may concurrently hold an upgrade tier. Falls back to maxDependants where absent.

4.5.29 benefit_category and benefit_subcategory

Grain: one record per category, and one per subcategory. Required to resolve offer.categories and offer.subcategories.

Field Type Req PII Description
id String M Category or subcategory identifier.
categoryId String C Parent category. Subcategories only.
name String M Display name.
description String O Description.
sortOrder Integer C Presentation order. Categories only.
icon String O Presentation asset reference: an image reference for categories, an icon name for subcategories. Opaque outside EPC.
mapPinIcon String O Map-pin icon name. Categories only.
status String (enum) M pending, active or inactive for categories; active or inactive for subcategories. Values in 4.6.16.
createdAt String (timestamp) C Creation. Categories only.
updatedAt String (timestamp) O Last modification. Categories only.

4.5.30 policy_document

Grain: one record per version of a policy document.

Primary key: composite of id and version

Field Type Req PII Description
id String M Identifier of the document. Together with version, identifies the record.
documentType String (enum) M Kind of document. Values in 4.6.17.
title String M Title of the document version.
version Integer M Version number. Consent is recorded against a specific version.
content String M Full text of the document version, as presented to the reader. Up to 350 KB.
forceAccept Boolean M Whether this version must be accepted before the reader may continue using the service.
entityType String (enum) M What the document is bound to. Values in 4.6.17.
entityId String M Identifier of that entity.
targetGroup String (enum) M Audience to which the document applies. Values in 4.6.17.
status String (enum) M Document state: active or archived. Applies to the document as a whole, not to individual versions. Values in 4.6.17.
createdAt String (timestamp) M When the version was created.
updatedAt String (timestamp) O When the document was last modified.

4.5.31 Reference datasets

Four code lists. Each carries id, name, description (optional), status (pending, active or inactive; see 4.6.16), createdAt and updatedAt (optional). The additional columns below carry the analytical value.

Dataset Resolves Additional fields
member_type member.memberType, company.eligibleMemberTypes hrmsMapping (String, O) — corresponding HRMS employment-type value, permitting a direct join to enterprise HR reference data.
member_subtype member.memberSubType, member.relation, member_family.relation, company_member_subtype.memberSubTypeId hrmsMapping (Array[String], O) — corresponding HRMS relationship values. maximumAge (Integer, O) — age limit for dependants of this subtype. tag (String enum, O) — spouse or child for entitlement purposes; absent denotes neither.
tier_type tier.tierType.id group (String enum, M) — base, upgrade or add_on. level (Integer, O) — rank within the upgrade ladder.
company_group company.companyGroupId type (String enum, O) — internal or external; see 4.6.18. Absent on the earliest configured group.

4.5.32 audit_log

Grain: one record per change to any record in the programme. Append-only, indexed on timestamp.

Primary key: id

> The only dataset supporting point-in-time analysis. All other datasets carry current state. This is also the largest dataset in the feed by a substantial margin — see 5.2.

Field Type Req PII Description
id String M Unique identifier for the change.
entityType String (enum) M Category of record changed. 28 values; see 4.6.15.
entityId String M Identifier of the record changed. Resolve against the corresponding dataset's id.
action String M Action performed, in the vocabulary of that record type — e.g. create, update, suspend, enroll-tier, approve-id-photo.
actor.type String (enum) M Actor category. Values in 4.6.12.
actor.id String M Actor identifier.
actor.name String O Y Actor display name.
actor.email String O Y Actor email address.
timestamp String (timestamp) M When the change occurred.
fieldUpdates[].key String M Field changed, expressed as a path, e.g. /status, /memberships/0/endDate.
fieldUpdates[].operation String (enum) M add, remove, replace or other.
fieldUpdates[].oldValue String (JSON) M Y Previous value, JSON-encoded. Truncated beyond 1 KB.
fieldUpdates[].newValue String (JSON) M Y New value, JSON-encoded. Truncated beyond 1 KB.
fieldUpdates[].isLarge Boolean O true where the value exceeded 1 KB and was truncated. Treat such values as incomplete.
isLargeLog Boolean M Whether the change record as a whole exceeded the size threshold.
largeLogPath String O Internal storage reference for overflow values. Opaque outside EPC.
additionalData Object O Y Context specific to the action, as free-form keys and values.

4.6 Reference Data & Code Lists

All sets below are closed. A value outside these lists indicates a schema change on the EPC side and must be alerted on rather than discarded — see section 2 (Risks) and 5.4.

4.6.1 member.status

Value Description
pending_invite Record created; invitation not yet sent
pending_invitation_acceptance Invitation sent; not yet accepted
pending_approval Awaiting administrative approval
pending_id_photo Awaiting identity photograph
pending_tier Awaiting tier selection
pending_payment Awaiting payment
active Fully enrolled
inactive No longer participating
suspended Temporarily withdrawn
rejected Application declined

4.6.2 membership.status

Value Description
active In force
scheduled Purchased in advance; commences at a future date
expired Term ended
unsubscribed Member opted out
suspended Temporarily withdrawn
cancelled Terminated
converted Upgraded mid-term; the successor membership carries the entitlement. Exclude from active membership counts

4.6.3 paymentType

Value Description
credit_card Paid by card
salary_deduction Deducted through payroll
company_paid Funded by the employer
free_dependant Free dependant place
free_of_charge Complimentary

4.6.4 payment.status

Value Description
initiated Attempt started
pending Awaiting outcome
completed Collected
failed Declined or errored
expired Not completed within the permitted window
partially_refunded Part of the value returned
refunded Fully returned

4.6.5 payment.paymentReason

Value Description
enrollment First purchase
dependant_enrollment First purchase for a dependant
installment Scheduled instalment
dependant_installment Instalment for a dependant
renewal Renewal of a term
dependant_renewal Renewal of a dependant's term
conversion Mid-term upgrade
instrument_update Verification of a new payment method

4.6.6 Refund reasonCode

Value Description
system_error Fault on the EPC side
duplicate_payment Charged more than once
member_request Requested by the member
payment_failure Collection problem
service_unavailability Benefit could not be provided
other Detail carried in reasonDetails

4.6.7 dds_deduction_cycle.state

Value Description
emitted Line raised; not yet confirmed by payroll
confirmed Money left payroll. The authoritative collection signal
released Attempt failed definitively; the period becomes billable again

4.6.8 payroll_feed.status

Value Description
generated Batch built; not yet submitted
submitted Sent to payroll
completed Fully accepted
partially_failed Some lines rejected
failed Batch rejected
duplicate Superseded by another batch

4.6.9 payroll_feed.type

Value Description
regular_membership Standard membership deductions
termination Leaver adjustments
face_card Face card deductions
voucher_event Voucher and event charges
seasonal_membership Fixed-season memberships
refund Amounts returned

4.6.10 offerType

Value Description
discount Percentage reduction
special_price Fixed member price
special_deal Bundled or conditional offer
lifestyle_hub Venue access. Appears in venue_checkin, never in redemption

4.6.11 registrationSource

Value Description
self_register Member self-registered
backoffice_register Created by a programme administrator
hrms_register Created from the HRMS feed

4.6.12 Actor type

Value Description
system Automated process
admin Programme administrator
member The member
hr_integration HRMS interface
partner_user Partner staff

4.6.13 venue_checkin_companion.source

Value Description
dependant An enrolled dependant member
hrms A family member recorded in HRMS who has not enrolled
companion A companion registered by the member
primary The household's primary member

4.6.14 Eligibility rule operators

Value Description
equals · not_equals Exact match, or its negation
in · not_in Membership of a set, or its negation
less_than · less_than_equal Numeric or date comparison
greater_than · greater_than_equal Numeric or date comparison
is_null · is_not_null Presence test

4.6.15 audit_log.entityType

approval, approval_policy, category, company, companyGroup, content, location-association, loyalty-card-session, member, memberSubtype, memberType, notificationTemplate, offer, partner, partner-role, partner_user, payment, policy-document, policy-document-acceptance, redemption, report-run, role, tier, tierConfig, tierType, track-feed, user, venue_checkin.

Note that entityType values reflect historical vocabulary and are not uniformly cased.

4.6.16 Lifecycle and other status values

Status and type fields not enumerated in their own section above take the following closed sets.

Dataset(s) Field Values
tier, offer status pending, active, inactive, expired
partner, company, benefit_category, member_type, member_subtype, tier_type, company_group status pending, active, inactive
benefit_subcategory, partner_location, tier_eligibility_rule, offer_eligibility_rule, member_companion status active, inactive
member_document status active, archived
tier_enrollment status active, expired
redemption status completed, voided (reserved; see 4.5.16)
venue_checkin status checked_in, checked_out, cancelled
invoice status pending, submitted, completed, failed
invoice pdfStatus pending, generated, failed
invoice type invoice, credit_note
transaction status completed, failed, pending
transaction type payment, refund
membership paymentSchedule one_time, installment
membership installmentStatus active, suspended, completed
membership pendingRenewalReason instrument_failed, retry_exhausted
member deactivatedBy system, hrms, program_management
member loginMethod sso, email_password
member idPhotoStatus pending, approved, rejected
member, member_companion gender male, female
member maritalStatus single, married
payment provider cpg, dds
payment recurringType CIT, MIT
payment_refund refundType cpg, dds
payroll_feed_line successFlag Y, N
venue_checkin_companion relationship adult, child
venue_checkin, offer accessType individual, couple, family
tier, tier_type tierType.group, group base, upgrade, add_on
member_subtype tag spouse, child

4.6.17 policy_document code sets

Apply to policy_document and member_policy_acceptance.

Field Values
documentType terms_and_conditions, privacy_policy
entityType global, tier, partner, member, program_management_user, partner_user
targetGroup member, program_management_user, partner_user, public
policy_document.status active, archived
member_policy_acceptance.status accepted, waiting

4.6.18 Other closed sets

Dataset Field Values
company_group type internal, external
tier_eligibility_rule paymentPeriod monthly, one_time
tier_eligibility_rule paymentTypes[] As 4.6.3, excluding free_dependant
partner socialMediaAccounts[].platform facebook, instagram, linkedin, x, youtube, tiktok
member coreGrade EK.01 to EK.14

4.7 Sample Records

Records below are taken from the UAT environment. **Structure, identifier formats,

code values, amounts and dates are real**, so they show exactly what the feed

looks like. Personal fields have been replaced with fictional values — names,

email addresses, telephone numbers, employee numbers, membership numbers and the

identifiers that resolve to a person. Nothing below relates to a real individual.

Optional fields that were absent in the source record are shown absent, since that

is itself informative — see 6.1.

4.7.1 member — primary member, active

{
  "id": "b7c41e02-9a3d-4f18-8e55-2c9d7a614f30",
  "memberId": "8292538047-eu-uat",
  "staffId": "EK998877",
  "name": "Amina",
  "surname": "Rahman",
  "email": "amina.rahman@example.com",
  "phone": "+9715XXXXXXX",
  "company": { "id": "368bd56d-ae38-484b-aa83-d4a58181fb96" },
  "memberType": "employee",
  "coreGrade": "EK.10",
  "status": "active",
  "registrationSource": "backoffice_register",
  "loginMethod": "email_password",
  "idPhotoStatus": "approved",
  "isFace": false,
  "actionRequired": false,
  "actionMessage": "",
  "requiresPaymentInstrumentUpdate": false,
  "createdAt": "2026-07-15T10:31:02.114Z",
  "updatedAt": "2026-07-28T14:54:03.236Z",
  "createdBy": { "type": "admin", "id": "…", "name": "…" },
  "memberships": [ /* see 4.7.3 */ ]
}

Note memberType is employee — an identifier, not a label. It resolves to

"EK Permanent" in the member_type code list.

4.7.2 member — dependant

{
  "id": "f10c8b44-27ae-4d93-a6b1-88e0c3f7a521",
  "memberId": "5186822519-eu-uat",
  "name": "Layla",
  "surname": "Rahman",
  "email": "layla.rahman@example.com",
  "primaryMemberId": "b7c41e02-9a3d-4f18-8e55-2c9d7a614f30",
  "hrmsFamilyMemberId": "9911223",
  "relation": "spouse",
  "memberType": "employee",
  "memberSubType": "spouse",
  "coreGrade": "EK.07",
  "status": "pending_invitation_acceptance",
  "registrationSource": "hrms_register",
  "loginMethod": "email_password",
  "company": { "id": "368bd56d-ae38-484b-aa83-d4a58181fb96" }
}

The presence of primaryMemberId is what makes this a dependant. **staffId is

absent**, as it is on every dependant — reach the employee number through the

primary member.

4.7.3 membership

{
  "id": "27703d45-8988-4db3-9371-d5c260914070",
  "memberId": "f10c8b44-27ae-4d93-a6b1-88e0c3f7a521",
  "tierId": "9a5a488e-9ebe-45fa-bc06-7b33baf68752",
  "eligibilityRuleId": "db8be072-dcf7-4a5b-9be6-c549f2da8db5",
  "status": "active",
  "paymentType": "free_dependant",
  "startDate": "2026-07-28T14:54:02.859Z",
  "endDate": "2027-07-31T19:59:59.999Z",
  "autoRenewal": false,
  "createdAt": "2026-07-28T14:54:03.236Z"
}

Both dates are full timestamps, not calendar dates. The instalment fields are

absent because this membership carries no charge, and paymentId is absent for the

same reason.

4.7.4 payment — salary deduction

{
  "id": "d4a90f61-33bc-42e7-9ac5-6b1e80c2f7d9",
  "memberId": "b7c41e02-9a3d-4f18-8e55-2c9d7a614f30",
  "tierId": "9a5a488e-9ebe-45fa-bc06-7b33baf68752",
  "eligibilityRuleId": "db8be072-dcf7-4a5b-9be6-c549f2da8db5",
  "invoiceId": "0a1f6c73-58d2-4e19-b7a4-91cc3e5f0d82",
  "paymentType": "salary_deduction",
  "provider": "dds",
  "paymentReason": "enrollment",
  "amountValue": 30000,
  "currency": "AED",
  "exponent": 2,
  "status": "completed",
  "createdAt": "2026-07-15T10:37:22.030Z",
  "completedAt": "2026-07-15T10:37:22.030Z",
  "deductedAt":  "2026-07-16T02:00:50.452Z",
  "refunds": []
}

This record demonstrates the most important trap in the feed. amountValue is

30000 with exponent 2, so the amount is AED 300.00 — not 30,000. And

completedAt equals createdAt to the millisecond, because for salary deduction it

is stamped at enrolment; the money did not move until deductedAt, the following

day. Reporting collections on completedAt would book this in the wrong period.

See 4.4.6.

4.7.5 redemption

{
  "id": "01KYMKHRDEF88PBPV7ZX3AP2JB",
  "memberId": "9c2e5741-6b08-4a3f-95d1-7fe4a0b83c66",
  "memberDisplayId": "2813865170-eu-uat",
  "memberName": "Yusuf",
  "memberSurname": "Haddad",
  "offerId": "6b1ccb92-b91d-48e5-91cf-5e00c1374f68",
  "partnerId": "5b4b1253-0e89-473e-b414-5e00e1f4c18a",
  "locationId": "4d3a14c9-681a-485b-8122-0e982d1833ca",
  "offerName": "Introduction to Golf Course",
  "locationName": "Desert Links Golf Resort",
  "offerType": "special_price",
  "transactionAmountValue": 100000,
  "discountAmountValue": 55000,
  "currency": "AED",
  "exponent": 2,
  "status": "completed",
  "redeemedAt": "2026-07-28T14:55:05.134Z",
  "createdAt": "2026-07-28T14:55:05.134Z"
}

The member spent AED 1,000.00 and saved AED 550.00. Note the record id is a

ULID while offerId and partnerId are UUIDs — see the note on identifier formats

in 4.4.5. currency and exponent are stamped by EPC at extraction (4.4.3).

4.7.6 tier

{
  "id": "9a5a488e-9ebe-45fa-bc06-7b33baf68752",
  "name": "Platinum 2026",
  "label": "Platinum",
  "tierType": { "id": "base", "group": "base" },
  "feeValue": 30000,
  "currency": "AED",
  "exponent": 2,
  "startDate": "2026-02-28T20:00:00.000Z",
  "endDate": "2027-02-27T19:59:59.999Z",
  "membershipDuration": 12,
  "taxable": true,
  "financeConfig": {
    "costCentre": "53050",
    "nominal": "48001",
    "subnominal": "P929",
    "analysisKey": "00000000",
    "erpCommentPrefix": "Platinum Base Membership"
  },
  "status": "active",
  "createdAt": "2026-07-06T15:34:29.936Z"
}

feeValue 30000 with exponent 2 is AED 300.00; currency and exponent are

stamped at extraction (4.4.3). membershipEndDate is absent because membershipDuration is set — exactly

one of the two is present. taxable reflects the tier's setting today; for the

VAT treatment applied to a past charge, use audit_log (4.4.7).

4.7.7 tier_eligibility_rule

{
  "tierId": "9a5a488e-9ebe-45fa-bc06-7b33baf68752",
  "id": "db8be072-dcf7-4a5b-9be6-c549f2da8db5",
  "name": "EK Group Annually",
  "paymentTypes": ["credit_card", "salary_deduction", "company_paid", "free_of_charge"],
  "paymentPeriod": "one_time",
  "status": "active",
  "conditions": [
    { "key": "companyGroupId", "logicalOperator": "in",     "value": "airlines" },
    { "key": "memberType",     "logicalOperator": "equals", "value": "employee" }
  ]
}

value is typed loosely: a plain string here even where the operator is in. It may

also be a number, boolean or array — see 4.5.21.

4.7.8 payroll_feed

{
  "id": "a6a65072-e5bc-47a3-b1dc-b5e0c57841ab",
  "type": "termination",
  "status": "completed",
  "periodMonth": "2026-08",
  "batchName": "16082026040040",
  "totalLines": 1,
  "successCount": 1,
  "failedCount": 0,
  "totalAmountValue": 2500,
  "createdAt": "2026-08-16T04:00:40.626Z"
}

batchName is DDMMYYYYHHMMSS. totalAmountValue 2500 is AED 25.00.

4.7.9 Reference code lists

[
  { "id": "employee", "name": "EK Permanent",       "hrmsMapping": "EMP",  "status": "active" },
  { "id": "family",   "name": "EK Temporary",       "hrmsMapping": "TEMP", "status": "active" },
  { "id": "01kjyb6pd62vt1yjdhaj3jsvp0", "name": "Associate Permanent",     "status": "active" }
]
[
  { "id": "spouse", "name": "Spouse", "tag": "spouse",
    "hrmsMapping": ["Wife", "Husband", "Spouse"], "status": "active" },
  { "id": "child",  "name": "Child",  "tag": "child",
    "hrmsMapping": ["Child", "Daughter", "Son", "Step Child", "Legitimate Child"],
    "status": "active" },
  { "id": "01kjw4r60zvc9rdwecqrmb3sah", "name": "Parent",
    "hrmsMapping": ["Father", "Mother", "Parent"], "status": "active" }
]

The child entry's hrmsMapping array is abridged above; the live list is longer.

Three things to carry from these:

5. Delivery

5.1 Transfer mechanism, format and cadence — requires EDP decision

Not yet agreed. The following are open and must be decided by EDP before

build can commence. EPC has no fixed requirement on any of them and can

accommodate a range of options.

Decision Options to consider Owner
Transfer mechanism Object-storage drop, managed file transfer, database load, streaming, or an EDP-provided ingestion endpoint EDP
Destination An EDP-provided landing area, or a location provided by EPC for EDP to collect from EDP
Encoding Row-oriented (e.g. delimited JSON, CSV) or columnar (e.g. Parquet), and whether compressed EDP
Cadence Frequency, and the time of day that suits downstream processing EDP
Day boundary The time zone that defines a delivery day. EPC recommends Asia/Dubai, matching the payroll and financial reporting calendar, so that daily aggregates reconcile with finance EDP
Completion signalling How EDP is told a delivery is complete and safe to ingest EDP
Nested structures Whether EPC delivers whole records with nested collections intact (see 4.4.8), or flattened to the grain of each dataset EDP
Authentication and encryption Credential exchange, transport security and encryption at rest EDP
Failure and retry handling Behaviour on a failed or partial delivery, and how recovery is signalled Joint

Two properties of the data are worth carrying into that decision:

5.2 Volumetrics

Indicative record counts from the non-production environment. **These are not

production volumes**; they indicate relative dataset sizes and scaling

behaviour, and are provided to inform the decisions in 5.1.

Dataset Records Ratio to member count Scaling driver
audit_log 4,171 21.5x Activity. Grows without bound, independent of headcount
payment 373 1.9x Memberships multiplied by instalments
transaction 355 1.8x Payments and refunds
tier_enrollment 230 1.2x Memberships
member 194 1.0x Population
invoice 187 1.0x Payments
venue_checkin 52 0.3x Engagement
redemption 30 0.2x Engagement
search_history 27 0.1x Engagement. Bounded: at most 100 records per member, trailing 90 days (4.5.19)
payroll_feed 38 batches n/a One to two per period per feed type
Catalogue datasets offer 95, policy_document 82, partner 30, tier 20 n/a Slow-changing

Notes:

5.3 Identifier key spaces

Membership numbers (memberId) carry an environment suffix outside production,

for example 1234567890-eu-staging. Non-production and production identifiers

therefore do not correspond.

**The two environments must be treated as separate key spaces and must not be

joined.** This holds regardless of the transfer mechanism chosen.

5.4 Schema change management

Change Notice EDP action
New field added to an existing dataset Advance notice; schema version incremented None required. Additive changes are backward-compatible
New value added to a closed code list Advance notice; schema version incremented Load the revised code list
New dataset added Advance notice; revised specification issued Extend ingestion
Field removed or renamed, or a dataset withdrawn Advance notice; revised specification issued and agreed before the change Coordinate cut-over

6. Appendix

6.1 Data Completeness Notes

Fields populated less consistently in live data than their definitions suggest. EDP should build tolerantly rather than constraining on them.

Field Dataset Expectation
birthdate, gender, maritalStatus, coreGrade member Frequently absent. The derived actionRequired flag identifies records lacking required detail; prefer it to testing each field individually
staffId member Never present on dependants. Reach the employee number via primaryMemberId
hrmsJoiningDate member Primary members only. HRMS supplies no joining date for dependants
eligibilityRuleId membership Absent on older enrolments
dds_deduction_cycle records membership Absent for memberships predating the per-period ledger. For those, payment.deductedAt is the fallback collection signal
accessType venue_checkin Absent on visits predating per-entitlement quotas
relation member_family Empty where the HRMS relationship type has no configured equivalent. The family record still exists
quotaRecovered venue_checkin Absent while the party remains on site
additionalGuests venue_checkin On the earliest visits this is a plain integer (a headcount) rather than the object described in 4.5.17. Treat an integer as adultCount, with the other three fields zero
reason, refundedReason payment_refund, payment Legacy free-text refund reasons written before the coded reasonCode existed. May still be present on older records until a backfill completes; superseded by reasonCode and refundedReasonCode wherever both are present
type company_group Absent on the earliest configured group
search_history records search_history Rolling window only: at most 100 per member, expiring 90 days after the last search. See 4.5.19

6.2 Excluded Fields

The following are withheld from the feed. Their exclusion is by agreement and does not affect reconciliation: payment outcomes remain fully described by status, statusReason and errorCode.

Field Dataset Category Rationale
passwordHash, loginAttempts, lockedUntil member Credential Authentication material
passwordHash, passwordHistory, loginAttempts, lockedUntil (partner users and administrative users) Credential Authentication material
invitationToken, invitationExpiresAt (administrative users) Credential Account-takeover vector
agreementId membership, payment Instrument token Capable of authorising charges
cardId, lastFourDigits, paymentMethod membership, payment PCI Cardholder data
cpgLogs[] payment PCI Raw payment-gateway request and response bodies; the sole location in which cardholder data may appear in free form. Excluding it keeps the delivered dataset outside PCI-DSS scope
Identity photograph images member Biometric The images are not delivered. The storage reference of the current photograph (idPhoto) and the review status (idPhotoStatus) are delivered; the reference to any superseded photograph (previousIdPhotoPath) is withheld
erpLogs[] invoice Third-party payload Raw request and response bodies exchanged with the finance system. The outcome is fully described by status, erpInvoiceNumber, erpErrorDetails, erpSubmittedAt and erpResponseAt
hrmsResponse payroll_feed Third-party payload Raw response body returned by payroll. The outcome is fully described by status, successCount, failedCount, interfaceLoadId, failureReason and the per-line successFlag and errorDetails
returnUrl, redirectionUrl, postPaymentRedirectPath payment Internal Browser redirect targets used during card checkout; no analytical content
pendingApprovalId tier, offer, partner, company Internal Transient lock held while a change awaits internal approval
renewalNotificationsSent membership Internal Idempotency cache for reminder notifications
tierRuleKey tier_enrollment Internal Storage index key; derivable from tierId and eligibilityRuleId
Storage index attributes (GSI keys, sort keys) all Internal Present on some records; carry no information beyond the fields already delivered
documents[] partner Out of scope Metadata of contract documents held against a partner; the files themselves are not held in a deliverable form

The following datasets are out of scope for this interface: general ledger journals, user notifications, member session records, payment instrument history, partner location associations, card-management sessions, and all internal operational datasets (approval workflow, role and permission configuration, notification templates, content management, reporting engine state, asynchronous job orchestration and search indexes).

6.3 Approvals

Approval Owner Required before Status
Interface design and field scope EPC / EDP technical Build commencement Pending
Data protection sign-off — see section 2 Risks DPO First production delivery Pending
Free-text content review EPC First production delivery Pending
Transfer mechanism, format and cadence agreed (5.1) EDP Build commencement Pending
Production cut-over EPC / EDP Production delivery Pending

6.4 Open Items

Ref Item Owner
1 Transfer mechanism, destination, encoding, cadence and completion signalling — see 5.1 EDP
2 Confirmation of retention period and erasure procedure for delivered personal data EDP / DPO
3 Criteria for promotion from non-production to production delivery EPC / EDP
4 Whether a reference transform implementation is required for the nested-collection flattening in 4.4.8 EDP
5 Historical depth expected at first delivery. Note the programme commenced operation in 2026; no data predates it EPC / EDP