Skip to main content

Payload collections and fields

For review — no decision recorded

Prepared 5 October 2026.

This page proposes one concrete manual catalogue model for stakeholder review. It shows Payload collection fields, nested shapes, relationships, draft-save requirements and proposed publication gates. It is not a deployed schema, migration, API contract or approval to implement. Every example value is fictional and makes no claim about a real casino, company, payment method or offer.

Decision requested​

Review the field paths, types, relationships, candidate enums and publication minimums below. For each collection, say which fields to add, remove, rename or change type, and which may be required to save an incomplete authoring draft versus required before publication. Identify feedback by collection and field path, for example: casinoProfiles.paymentPolicies[].processingTime.basis.

Model boundaries​

The proposed roots are independent records when identity, reuse or publication requires it. Array rows and block rows belong to their parent lifecycle; a relational child table generated by Payload is not another collection. The selected manual scope is Casino profiles and market-scoped Bonus Offers, with retained support and exact publication records. Cashback, casino VIP programmes and events remain extension examples; this page does not add their collection roots or impose the welcome shape on them.

The candidate spelling promotionalOffers names a proposed collection. The current CMS has a bonusOffers collection; this proposal does not claim it has been renamed, migrated or replaced. Existing users and media collections are referenced where needed; this page does not redefine authentication or uploads.

Field provenance. Existing proposal means the source names this field or broad field family and the row preserves that shape. Candidate means the row selects a new type, spelling, nesting, enum, validation rule, draft-save requirement or publication gate. When a source-backed row adds one of those details, its Source cell says Existing proposal; Candidate: ... and names the new detail. Candidate details remain proposed; the authorities leave many exact descriptors and publication minimums open.

Requiredness columns are separate. “Draft save” describes whether an authoring record/row can be saved before it is complete. “Publication gate” describes the proposed conditions when a casinoProfiles or promotionalOffers revision is published. A field may be optional in a saved draft and required at publication. Reference collections are not independently published; a root publication resolves the exact values it uses.

Payload type notationMeaning here
text, textarea, number, checkbox, date, select, richTextNative Payload scalar/editor fields. Exact decimals use text, never floating-point number.
relationship → collectionNative Payload relationship to one local collection record unless marked many. casinoId is an application mapping to Core, not a cross-database relationship.
upload → mediaReference to the existing media collection.
groupOne fixed nested object.
arrayZero or more same-shape owned rows. Row IDs are Payload's native hidden string IDs.
blocksZero or more typed owned rows; each row carries Payload's native block discriminator.
jsonOnly for validated immutable publication snapshots/manifests. Editable catalogue facts use typed native fields.

Payload supplies each collection's native id using the configured adapter's existing ID type; no UUID migration is proposed. Native createdAt/updatedAt metadata and versions: true authoring history are framework metadata, not fields duplicated below. Native versions do not make authoring content public. Profile/Offer publication is a separate explicit action and immutable record. Array/block row IDs are the stable child identity: no second component ID and no identity-by-position. A locale is selected per publication; localized copy fields are shown as (localized).

Collection inventory​

SlugIdentity and responsibilityCardinality and key boundary
brandsCommercial brand identity and display name.One Brand may be related to many Casino products; a name is not a unique identifier.
casinosCMS mapping to a Core Casino identity.One casinoId mapping per CMS Casino; Brand may be absent only while the record is incomplete.
marketsExplicit audience/jurisdiction applicability context.Stable unique key; not inferred from language, currency, retrieval route or display label.
companiesIdentified legal entity reused in attributed roles.Legal name alone does not prove identity; no Company-to-Brand relation is added.
paymentMethodsReusable payment method identity and icon.One method can occur in many profile-owned payment rows; it does not imply availability.
casinoProfilesCasino- and Market-scoped facts, owned detail and localized copy.One authoring profile per (casino, market); profile publication is independent per locale.
promotionalOffersCasino- and Market-scoped Bonus Offer and typed terms.Stable offerId; several same-purpose Offers may share Casino and Market. Each publishes independently per locale.
evidenceImmutable retained source material and capture/admission context.Reused by support bindings; a URL alone is not retained evidence.
cataloguePublicationsImmutable approved publish or withdrawal entry.One exact profile or Offer subject, key and increasing revision per entry.
publicationSelectionsCurrent entry pointer for a publication key.One current selection per key, including a withdrawal entry.
publicationDeliveriesDurable delivery intent and acknowledgement state.Refers to one exact immutable entry; retry identity stays stable.

Relationship map​

LEGAL_STATEMENT_ROWS, PAYMENT_POLICY_ROWS, TERM_VARIANT_ROWS, WELCOME_STAGE_ROWS, BENEFIT_COMPONENT_BLOCKS and SUPPORT_BINDING_ROWS are owned Payload children, not collection roots. Each support binding belongs to exactly one owning profile or Offer. A publication has exactly one controlled polymorphic authoring subject: the profile alternative or the Offer alternative, never both. A Brand or Company relationship is resolved to immutable values or exact retained versions in a publication; changing a referenced record does not rewrite an earlier publication.

brands​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
nametext1RequiredIf used in a profile snapshot, non-empty resolved display nameExisting proposal; Candidate: native text type and draft-save minimumCommercial Brand name, distinct from a registered Company's legal name.
aliasesarray0..nOptionalNone; include only if a consumer needs aliasesExisting proposal; Candidate: text-row nesting and draft/publication gateOptional alternate names; names do not identify or merge entities.
aliases[].valuetext1 per rowRequired in rowSame as parentCandidateCandidate row spelling and shape; preserve the observed value.
logoupload → media0..1OptionalIf included, snapshot pins exact media identity/versionExisting proposal; Candidate: upload type and media targetReuses the existing media mechanism. No new media collection.

Brand is a reference, not a public publication root. A Casino draft may omit its Brand; publishing a profile requires an established Brand association on its Casino.

casinos​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
casinoIdtext1RequiredRequired and immutable for profile and Offer publicationExisting proposal; Candidate: text type and draft-save minimumUnique validated mapping to an existing Core Casino ID; never a cross-database foreign key or CMS-created Core identity.
brandrelationship → brands0..1OptionalRequired and editorially established before profile publicationExisting proposalIncomplete Casino drafts may lack a Brand. One current Brand per established Casino; history retains earlier association.
staffLabeltext0..1OptionalNever exposed as public contentCandidatePrivate staff-facing label; must not substitute for public Brand/Casino identity.

Proposed unique constraint: casinoId. Do not use Casino name, domain, translation or Market as its identity key.

markets​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
keytext1RequiredRequired and stable in every profile/Offer contextExisting proposal; Candidate: text type and draft-save minimumUnique immutable internal Market key.
labeltext1RequiredResolved into the publication context/snapshotExisting proposal; Candidate: text type and draft-save minimumHuman-readable Market label; it is not the applicability rule.
scopeKindselect: jurisdiction, audience, combined1RequiredMust match the explicit supported scopeCandidateCandidate enum; prevents the model treating locale or currency as Market.
scopeDescriptiontextarea1RequiredRequired to explain the selected scopeCandidateExplicit curated description of audience and/or jurisdiction applicability.
jurisdictionLabelsarray of text0..nOptionalRequired only when scopeKind is jurisdiction or combinedCandidateCandidate list of source-supported jurisdiction labels; do not infer from retrieval IP or a display flag.
jurisdictionLabels[].valuetext1 per rowRequired in rowSame as parentCandidateNo country registry or code set is selected here.

locale, currency and observed access are separate dimensions. No Market fallback is proposed.

companies​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
legalNametext1RequiredIf referenced by a profile statement, exact value is resolved and retainedExisting proposal; Candidate: text type and draft-save minimumLegal entity name. A common name alone does not establish identity.
registrationIdentifiertext0..1OptionalIf included, retain its stated jurisdiction and supportCandidateCandidate spelling for a supported registration identifier.
registrationJurisdictiontext0..1OptionalRequired when registrationIdentifier is presentCandidateCandidate field; no jurisdiction is guessed from name or address.

Companies are reused by typed legal-statement roles. Corporate group/ownership relations and a shared regulator/licence registry are not added.

paymentMethods​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
keytext1RequiredStable identity when resolved into a publicationExisting proposal; Candidate: text type and draft-save minimumUnique immutable Payment Method key.
displayNametext1RequiredExact display value is resolved if referencedExisting proposal; Candidate: text type and draft-save minimumReusable public-facing method name.
iconupload → media0..1OptionalIf included, snapshot pins exact media identity/versionExisting proposal; Candidate: upload field and media targetReuses existing media; method identity alone does not assert casino support.

Direction, currency, limits, fees and timing stay on a profile-owned policy row so their conditions remain correlated.

casinoProfiles​

casinoProfiles is a nonlocalized Casino/Market authoring root with localized editorial fields. Rows below give the full editable shape; child id values are native Payload row IDs, not additional fields. Proposed index: unique (casino, market) at the native relationship fields.

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
casinorelationship → casinos1RequiredRequired; related Casino must have established BrandExisting proposalOne Casino identity.
marketrelationship → markets1RequiredRequired; explicit scope resolvedExisting proposalOne Market presence.
legalStatementsarray0..nOptionalOptional family; every included statement must be complete and supportedExisting proposal; Candidate: optional draft and included-row publication gateProfile-owned attributed legal assertions; not independent licence verification.
legalStatements[].roleselect: owner, operator, licenceHolder, other1 per rowRequired in rowRequired for every included assertionCandidateCandidate role enum. Licence-holder spelling is a domain display term; code value remains a review choice.
legalStatements[].companyrelationship → companies0..1OptionalRequired when the entity is identified; otherwise retain assertedEntityName and an open identity issueExisting proposal; Candidate: concrete relationship cardinality and conditional gateNo fictitious Company record to complete an uncertain name.
legalStatements[].assertedEntityNametext0..1OptionalRequired if company is absent and the attributed statement is publishedCandidateExact source-attributed entity name, not a verified identity.
legalStatements[].assertiontextarea1 per rowRequired in rowRequired for every included statementCandidateHuman-readable attributed statement, not a verification result.
legalStatements[].licenceNumbertext0..1OptionalIf present, must have matching supportExisting proposal; Candidate: text type and exact field pathNumber exactly as asserted.
legalStatements[].regulatorNametext0..1OptionalIf present, must have matching supportExisting proposal; Candidate: text type and exact field pathAttributed authority name; no regulator registry is proposed.
legalStatements[].jurisdictiontext0..1OptionalIf present, must have matching supportExisting proposal; Candidate: text type and exact field pathStated jurisdiction; not inferred from Market label.
paymentPoliciesarray0..nOptionalOptional family; each included policy row must be complete for its direction/currencyExisting proposal; Candidate: optional draft and included-row publication gateCorrelated payment capabilities, not a flat method list.
paymentPolicies[].paymentMethodrelationship → paymentMethods1 per rowRequired in rowRequired for every included policyExisting proposal; Candidate: exact nested relationship pathReused method identity.
paymentPolicies[].directionselect: deposit, withdrawal1 per rowRequired in rowRequired; never merge directionsCandidateCandidate enum.
paymentPolicies[].currencytext0..1OptionalRequired for each known monetary amount/fee; never fallback from Market, locale or another rowExisting proposal; Candidate: text type and exact nested pathExplicit source currency code.
paymentPolicies[].minimumgroup with state, amount0..1OptionalIf represented, use the allowed exact-value states belowCandidateCandidate nested shape. A known zero is amount: "0", not absence.
paymentPolicies[].minimum.stateselect: known, unknown, notApplicable1 when group existsRequired in rowknown requires amount and currency; other states carry neitherCandidatenone and unlimited are not valid minimum states.
paymentPolicies[].minimum.amounttext decimal0..1OptionalRequired only when state is knownCandidateNonnegative canonical decimal string.
paymentPolicies[].maximumgroup with state, amount0..1OptionalIf represented, use the allowed exact-value states belowCandidateCandidate nested shape for a maximum.
paymentPolicies[].maximum.stateselect: known, unknown, unlimited, notApplicable1 when group existsRequired in rowknown requires amount and currency; unlimited means the source explicitly states no upper boundCandidateNo currency or number fallback. none is not a maximum state.
paymentPolicies[].maximum.amounttext decimal0..1OptionalRequired only when state is knownCandidateNonnegative canonical decimal string.
paymentPolicies[].feegroup with state, amount0..1OptionalIf represented, use the allowed fee states belowCandidateCandidate nested shape.
paymentPolicies[].fee.stateselect: known, unknown, none, notApplicable1 when group existsRequired in rowknown requires amount and currency; none means source explicitly says no fee; no unlimited feeCandidateZero fee is a known amount "0", distinct from none.
paymentPolicies[].fee.amounttext decimal0..1OptionalRequired only when state is knownCandidateNonnegative canonical decimal string.
paymentPolicies[].processingTimegroup with state, minimum, maximum, unit, basis0..1OptionalIf a timing claim is included, retain its amount/range, unit and start basisCandidateCandidate structured processing-time claim; not a community payout observation.
paymentPolicies[].processingTime.stateselect: known, unknown, notApplicable1 when group existsRequired in rowknown requires minimum, maximum when a range is stated, unit and basisCandidateNo numeric value can be detached from its time basis.
paymentPolicies[].processingTime.minimumnumber safe integer0..1OptionalRequired for known single value/rangeCandidateNonnegative integer quantity.
paymentPolicies[].processingTime.maximumnumber safe integer0..1OptionalRequired only for a stated range; must be ≥ minimumCandidateNonnegative integer quantity.
paymentPolicies[].processingTime.unitselect: minutes, hours, days0..1OptionalRequired when timing state is knownCandidateCandidate unit enum.
paymentPolicies[].processingTime.basisselect: requestSubmitted, verificationComplete, approvalComplete0..1OptionalRequired when timing state is knownCandidateCandidate start event enum; a bare duration is incomplete.
cashierTermsgroup0..1OptionalOptional family; any published row must preserve ordinary cashier scopeExisting proposal; Candidate: concrete optional group and publication gateDistinct from an Offer award/cashout restriction.
cashierTerms.limitsarray0..nOptionalIncluded limits need direction, period, value state and currency when knownCandidateCandidate owned list; each row is scoped to the cashier policy.
cashierTerms.limits[].directionselect: deposit, withdrawal1 per rowRequired in rowRequiredCandidateCandidate enum.
cashierTerms.limits[].periodselect: perTransaction, daily, weekly, monthly, other1 per rowRequired in rowRequired; do not merge periodsCandidateCandidate period enum.
cashierTerms.limits[].otherPeriodtext0..1OptionalRequired only when period is otherCandidateSource wording for another explicit period.
cashierTerms.limits[].basisselect: calendar, rolling, transaction, sourceSpecified1 per rowRequired in rowRequired; perTransaction requires transactionCandidateCandidate window basis so “daily” cannot hide calendar-versus-rolling semantics.
cashierTerms.limits[].timeZonetext0..1OptionalRequired for basis=calendar; must identify the source-stated zoneCandidateNo inferred timezone or schedule calculation.
cashierTerms.limits[].basisDescriptiontext0..1OptionalRequired only for basis=sourceSpecifiedCandidateRetains another explicit source-defined window basis.
cashierTerms.limits[].valuegroup with state, amount, currency1 per rowRequired in rowknown requires exact amount and currency; upper-limit unlimited only when explicitly statedCandidateCandidate exact limit shape; no Offer cashout cap reuse.
cashierTerms.generalRequirementstextarea0..1OptionalIf published, source binding requiredCandidateAttributed general deposit/withdrawal requirement; not an arbitrary filter.
cashierTerms.restrictionsarray of typed statements0..nOptionalEach included statement has a supported kind and evidence bindingExisting proposal; Candidate: concrete array shape and inclusion gateSupported restrictions remain profile-owned.
cashierTerms.restrictions[].kindselect: identityCheck, inactivity, closure, disputes, responsibleGambling, other1 per rowRequired in rowRequiredCandidateCandidate known restriction kinds; not a universal capability enum.
cashierTerms.restrictions[].statementtextarea1 per rowRequired in rowRequired when the row is includedCandidateKeep exact scope and wording; other does not create a filter.
supportgroup0..1OptionalOptional family; included advertised capabilities retain supportExisting proposal; Candidate: concrete group shape and optionalityDescribes stated support, not platform test results.
support.contactsarray0..nOptionalIncluded contacts need a channel; redact private staff contact dataCandidateCandidate representation for public-facing contact channels.
support.contacts[].channelselect: liveChat, email, telephone, other1 per rowRequired in rowRequiredCandidateCandidate channel enum.
support.contacts[].availabilityStatementtextarea0..1OptionalIf included, support binding requiredCandidateAdvertised availability only; no “online now” freshness claim.
support.contacts[].languagesarray of text0..nOptionalIf included, retain the stated language labelsCandidateCandidate owned language list.
editorialCopygroup, fields localized1Optional in draftRequired per selected locale: title and summaryExisting proposal; Candidate: concrete localized group and title/summary minimumLocalized editorial copy and SEO; must not create unsupported structured filters.
editorialCopy.titletext (localized)1 per localeOptionalRequired for that locale's profile publicationCandidateCandidate field spelling/minimum.
editorialCopy.summarytextarea (localized)1 per localeOptionalRequired for that locale's profile publicationCandidateCandidate field spelling/minimum.
editorialCopy.bodyrichText (localized)0..1 per localeOptionalOptional; included claims need editorial supportCandidateReviewed narrative may explain an unfamiliar feature.
editorialCopy.seoTitletext (localized)0..1 per localeOptionalOptionalCandidateSearch presentation text.
editorialCopy.seoDescriptiontextarea (localized)0..1 per localeOptionalOptionalCandidateSearch presentation text.
supportBindingsarray0..nOptionalEvery public factual field/row must resolve to retained evidence and the exact typed field keyExisting proposal; Candidate: concrete row shape and binding granularityBindings attach support to a profile root or a stable owned row; details follow below.
unresolvedIssuesarray0..nOptionalAn open issue blocks publication only when it affects a required or included public assertionExisting proposal; Candidate: issue-row shape and conditional publication gateRetain missing facts, identity gaps and conflicts; do not normalize by source arrival order.

promotionalOffers​

A promotionalOffers root is one Bonus Offer scoped to one Casino and one Market. purpose is not identity; there is no unique (casino, market, purpose) or (offer, currency) rule. Each term variant keeps currency and explicit eligibility together. The welcome nesting below is one candidate mechanic shape, not a universal Offer grammar.

In the table, paths such as components[blockType=cash].award.amount mean fields directly on the cash block row. There is no nested cash or freeSpins group inside components; blockType is Payload's native discriminator. Each components[] row has its own native hidden row id.

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
offerIdtext1RequiredRequired and immutable after first publicationExisting proposal; Candidate: text type and draft-save minimumUnique stable Offer identity, separate from Payload id.
casinorelationship → casinos1RequiredRequired; resolves one Casino identityExisting proposalOne scoped product.
marketrelationship → markets1RequiredRequired; resolves explicit scopeExisting proposalOne Market; no language/Market fallback.
purposeselect: welcome, recurringReward, standaloneReward, other1RequiredRequired; does not determine identity or schemaCandidateCandidate purpose enum. other requires a reviewed description in localized copy.
mechanicselect: welcomePackage1RequiredRequired and supported by the selected typed shapeCandidateOnly the welcome package shape is detailed here. A new mechanic requires its own selected typed shape.
validitygroup with state, startsAt, endsAt1Optional while unknownRequired state; known validity dates must be orderedExisting proposal; Candidate: group shape and required explicit statePublication time is not an Offer start time.
validity.stateselect: known, unknown1Required when group existsRequiredCandidateCandidate explicit state; no inferred date.
validity.startsAtdate ISO-8601 instant0..1OptionalRequired only for a known startExisting proposal; Candidate: ISO date field type and conditional requirednessExact source-supported instant where present.
validity.endsAtdate ISO-8601 instant0..1OptionalRequired only for a known endExisting proposal; Candidate: ISO date field type and conditional requirednessExact source-supported instant where present.
termVariantsarray0..nOptional; an incomplete draft may have noneAt least one publishable applicable variantExisting proposal; Candidate: empty-draft and one-variant publication gatesSame currency may occur on distinct eligible variants; no currency-only uniqueness.
termVariants[].currencytext1 per rowOptional in incomplete rowRequired for each published variant and every known monetary valueExisting proposal; Candidate: text field type and incomplete-row ruleSource-supported currency code; no conversion or missing-currency fallback.
termVariants[].eligibilitygroup with audience, conditions1 per rowOptional in incomplete rowRequired; no missing eligibility fallbackCandidateCandidate shape for the applicability statement.
termVariants[].eligibility.audienceselect: newCustomers, existingCustomers, allEligibleCustomers, invitedCustomers, other1 when group existsRequired in rowRequiredCandidateCandidate audience enum; retrieval route does not prove player eligibility.
termVariants[].eligibility.conditionstextarea0..1OptionalRequired when audience is other; otherwise add when a source condition narrows eligibilityCandidateSupported condition in readable form, attached to this currency variant.
termVariants[].validityOverridegroup with state, startsAt, endsAt0..1OptionalIf present, must be explicit and valid for this variantCandidateCandidate variant-specific override; never silently inherit a conflicting date.
termVariants[].stagesarray0..nOptional in an incomplete draftFor welcomePackage, at least one complete stage with at least one complete benefit blockExisting proposal; Candidate: welcome-specific publication minimumOwned welcome terms. Other mechanics do not get welcome stages by default.
termVariants[].stages[].displayOrdernumber safe integer1 per rowRequired in rowRequired; unique within the variant in this candidateCandidatePresentation order is not identity; row ID preserves identity after reordering.
termVariants[].stages[].triggerselect: firstDeposit, registration, recurringPeriod, other1 per rowRequired in rowRequired and source-supportedCandidateCandidate trigger enum.
termVariants[].stages[].qualifyingDepositgroup exact amount0..1OptionalRequired only when trigger is a depositCandidateKeep qualifying deposit separate from award and cashier minimums.
termVariants[].stages[].componentsblocks: cash, freeSpins0..nOptional in draftAt least one complete component per published welcome stageExisting proposal; Candidate: exact cash/freeSpins Payload block typesTyped heterogeneous benefits; child fields stay with their component conditions.
termVariants[].stages[].components[blockType=cash].award.kindselect: fixedAmount, percentage1 in cash blockRequired in rowRequiredCandidateCandidate award kind.
termVariants[].stages[].components[blockType=cash].award.amounttext decimal1 in cash blockRequired in rowRequired; percentage is an exact rate, not a floating-point numberCandidateNonnegative canonical decimal string.
termVariants[].stages[].components[blockType=cash].award.currencytext0..1OptionalRequired when award kind is fixedAmount; omitted for percentageCandidateExplicit currency for money only.
termVariants[].stages[].components[blockType=cash].award.rateBasisselect: depositAmount0..1OptionalRequired when award kind is percentageCandidateCandidate percentage basis; never store an unbased rate.
termVariants[].stages[].components[blockType=cash].award.maximumgroup exact amount0..1OptionalIf included, known value requires amount and currencyCandidateAward ceiling remains separate from any cashout cap.
termVariants[].stages[].components[blockType=cash].wageringgroup with state, multiplier, basis1Optional in incomplete blockState required; if required, multiplier and basis requiredCandidateCandidate typed wagering requirement.
termVariants[].stages[].components[blockType=cash].wagering.stateselect: required, none, unknown, notApplicable1Required in rowRequiredCandidatenone means an explicit source states no wagering requirement; zero multiplier is not a substitute.
termVariants[].stages[].components[blockType=cash].wagering.multipliertext decimal0..1OptionalRequired only when state is requiredCandidateNonnegative exact multiplier.
termVariants[].stages[].components[blockType=cash].wagering.basisselect: bonusOnly, bonusPlusDeposit, depositOnly0..1OptionalRequired only when state is requiredCandidateCandidate basis enum; 30 without basis is incomplete.
termVariants[].stages[].components[blockType=cash].cashoutLimitgroup exact upper limit0..1OptionalIf included, state required; known requires amount and currencyCandidateOffer cashout cap; never use ordinary cashier limit here.
termVariants[].stages[].components[blockType=freeSpins].countnumber safe integer1 in freeSpins blockRequired in rowRequired and greater than zero for a published spin benefitCandidateCount is an integer. Zero is a known zero count, not an absent or unknown count; omit the component when no spins are offered.
termVariants[].stages[].components[blockType=freeSpins].gameNamesarray of text0..nOptionalRequired when source limits spins to named gamesCandidateNo games collection or canonical game identity is added.
termVariants[].stages[].components[blockType=freeSpins].spinValuegroup exact money0..1OptionalRequired if the source specifies spin value; amount and currency stay pairedCandidateDecimal string plus explicit currency.
termVariants[].stages[].components[blockType=freeSpins].wageringgroup with state, multiplier, basis1Optional in incomplete blockState required; if required, multiplier and basis requiredCandidateSeparate from the cash component's wagering.
termVariants[].stages[].components[blockType=freeSpins].wagering.stateselect: required, none, unknown, notApplicable1Required in rowRequiredCandidateSame explicit wagering-state meaning as the cash block.
termVariants[].stages[].components[blockType=freeSpins].wagering.multipliertext decimal0..1OptionalRequired only when state is requiredCandidateExact multiplier.
termVariants[].stages[].components[blockType=freeSpins].wagering.basisselect: bonusOnly, winningsOnly, bonusPlusDeposit0..1OptionalRequired only when state is requiredCandidateCandidate basis enum.
termVariants[].stages[].components[blockType=freeSpins].winningsCapgroup exact upper limit0..1OptionalIf included, state required; known value requires amount and currencyCandidateSpin winnings cap, separate from the spin's face value.
editorialCopygroup, fields localized1Optional in draftRequired per locale: title and summaryExisting proposal; Candidate: concrete localized group and title/summary minimumLocalized Offer copy; does not replace typed terms.
editorialCopy.titletext (localized)1 per localeOptionalRequired for that locale's Offer publicationCandidateCandidate field spelling/minimum.
editorialCopy.summarytextarea (localized)1 per localeOptionalRequired for that locale's Offer publicationCandidateCandidate field spelling/minimum.
editorialCopy.bodyrichText (localized)0..1 per localeOptionalOptional; included terms must agree with typed termsCandidateReviewed explanation, not an alternate terms store.
editorialCopy.seoTitletext (localized)0..1 per localeOptionalOptionalCandidateSearch presentation text.
editorialCopy.seoDescriptiontextarea (localized)0..1 per localeOptionalOptionalCandidateSearch presentation text.
supportBindingsarray0..nOptionalEvery published factual field/row has retained evidence and a typed field keyExisting proposal; Candidate: concrete row shape and binding granularityTargets Offer root or stable term/stage/component row identity.
unresolvedIssuesarray0..nOptionalOpen issue blocks publication only when it affects required or included public termsExisting proposal; Candidate: issue-row shape and conditional publication gateKeep conflict or gap explicit; never resolve by arrival order.

Native block/array IDs preserve child identity when update/import supplies them. Reordering a stage does not change its support binding. Currency variants select supported terms; they do not convert amounts, and two eligible rows may use the same currency. A shared lifecycle keeps cash and spins together when they form one proposition; separate conditions alone do not create another Offer.

evidence​

Evidence is immutable retained support. It may originate from a manual admission; no parser execution or editorial generation record is required. A source URL is optional context, never sufficient evidence on its own. Evidence and bindings are private support, not public profile/Offer content.

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
originselect: manualAdmission, retrievedCapture, other1Required to admit an immutable recordIf used by a publication, included in the private support manifestCandidateCandidate origin values distinguish human admission from retrieval without requiring a parser.
sourceIdentitytext1RequiredRetained with referenced publicationExisting proposal; Candidate: text field type and requirednessName or stable identity of publisher/source; not a staff identity.
sourceUrltext0..1OptionalOptional provenance context; never satisfies retention aloneExisting proposal; Candidate: text field type and optionalityURL can later change or expire. Do not place private URLs in public page examples.
capturedAtdate ISO-8601 instant0..1Optional for manual material; required for captured materialRequired when origin is retrievedCaptureExisting proposal; Candidate: ISO date type and conditional requirednessCapture time, distinct from author admission and publication time.
admittedAtdate ISO-8601 instant1RequiredRetained in support manifestCandidateCandidate admission timestamp for manual/retrieved material.
retainedExcerpttextarea0..1Optional if a retained artifact is presentPublication retains exact excerpt when relied uponExisting proposal; Candidate: textarea type and evidence-admission ruleCaptured excerpt or transcription; enough context to inspect the assertion.
artifactupload → media0..1Optional if a retained excerpt is presentCandidate gate: do not rely on it until private access and immutable retention are selected and proven; an existing media relationship alone proves neitherCandidateCandidate reuse of existing media. One of excerpt or artifact must be present before evidence admission. The sample uses only retainedExcerpt; it claims no artifact ACL.
contentIdentitytext1RequiredCopied into retained support manifestExisting proposal; Candidate: text type and admission minimumStable identity for retained content/capture; algorithm remains an implementation contract.

No URL-only support, mutable-latest-document lookup, or public exposure of retained staff material is proposed. Evidence is write-once once admitted; correction adds new evidence and supersedes affected content.

Shared support and issue rows​

These rows are owned by casinoProfiles or promotionalOffers; they do not become collections. targetRowId is Payload's stable child ID for an owned row, or empty only when the binding targets a root. fieldKey is selected from a code-defined typed vocabulary, not an arbitrary JSON path. The exact field-key registry is an implementation input; the examples here show the review shape.

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
supportBindings[].targetKindselect: root, ownedRow1 per rowRequired in rowRequired for each bindingCandidateCandidate target shape.
supportBindings[].targetRowIdtext0..1OptionalRequired when targetKind is ownedRow; must resolve to an existing child ID on this rootCandidateStable native array/block ID, not row position or copied component ID.
supportBindings[].fieldKeyselect1 per rowRequired in rowRequired; key must belong to target's typed shapeCandidateCandidate allowlist includes legalStatement, paymentPolicy, cashierLimit, supportContact, offer.validity, offerTerm.eligibility, welcomeStage.qualifyingDeposit, welcomeStage.trigger, cashComponent, freeSpinsComponent, validity.endsAt, and editorialCopy.summary.
supportBindings[].evidencerelationship → evidence1 per rowRequired in rowRequired for each public factual bindingExisting proposal; Candidate: exact relationship field pathRetained source material that supports the exact field.
supportBindings[].excerptLocatortext0..1OptionalIf available, retain exact page/section/time locatorCandidatePoints within the retained artifact; not a mutable remote lookup.
unresolvedIssues[].kindselect: missing, conflict, identity, scope, unsupported1 per rowRequired in rowOpen issue on required/included public assertion blocks publicationCandidateCandidate issue kinds; do not convert an issue into a guessed value.
unresolvedIssues[].targetRowIdtext0..1OptionalRequired when issue concerns an owned child; must resolve to its stable IDCandidateCandidate row-target shape.
unresolvedIssues[].fieldKeyselect from the same typed key vocabulary0..1OptionalRequired when issue concerns a specific fieldCandidateNo arbitrary writable JSON path.
unresolvedIssues[].summarytextarea1 per rowRequired in rowRetain with publication review record when relevantCandidateHuman-readable gap/conflict; no private staff analysis in public snapshot.
unresolvedIssues[].statusselect: open, resolved1 per rowRequired in rowMust be resolved before publication if it affects an included assertionCandidateCandidate lifecycle state for a retained issue.
unresolvedIssues[].resolutiontextarea0..1OptionalRequired when status is resolvedCandidateRecords how the issue was resolved; does not erase prior evidence.

Shared nested field dictionaries​

The following rows complete the exact paths inside the reusable groups above. Their candidate shapes are typed Payload groups/arrays; they are not generic JSON objects. Every row separates authoring-save completeness from the publish condition.

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
cashierTerms.limits[].value.stateselect: known, unknown, unlimited, notApplicable1 per valueRequired in rowRequired; known requires amount and currencyCandidateCandidate exact upper-limit states.
cashierTerms.limits[].value.amounttext decimal0..1OptionalRequired only when state is knownCandidateNonnegative canonical decimal text; 0 is a known zero limit.
cashierTerms.limits[].value.currencytext0..1OptionalRequired only when state is knownCandidateExplicit source currency; no fallback.
termVariants[].stages[].qualifyingDeposit.stateselect: known, unknown, notApplicable1 when group existsRequired in rowknown requires amount and currencyCandidateCandidate state for a deposit trigger value.
termVariants[].stages[].qualifyingDeposit.amounttext decimal0..1OptionalRequired only when state is knownCandidateExact nonnegative amount.
termVariants[].stages[].qualifyingDeposit.currencytext0..1OptionalRequired only when state is knownCandidateExplicit source currency.
termVariants[].stages[].components[blockType=cash].award.maximum.stateselect: known, unknown, unlimited, notApplicable1 when group existsRequired in rowknown requires amount and currencyCandidateAward maximum is not a cashout limit.
termVariants[].stages[].components[blockType=cash].award.maximum.amounttext decimal0..1OptionalRequired only when state is knownCandidateExact award ceiling.
termVariants[].stages[].components[blockType=cash].award.maximum.currencytext0..1OptionalRequired only when state is knownCandidateExplicit source currency.
termVariants[].stages[].components[blockType=cash].cashoutLimit.stateselect: known, unknown, unlimited, notApplicable1 when group existsRequired in rowknown requires amount and currencyCandidateOffer cashout cap only; ordinary cashier limits stay on the profile.
termVariants[].stages[].components[blockType=cash].cashoutLimit.amounttext decimal0..1OptionalRequired only when state is knownCandidateExact upper limit.
termVariants[].stages[].components[blockType=cash].cashoutLimit.currencytext0..1OptionalRequired only when state is knownCandidateExplicit source currency.
termVariants[].stages[].components[blockType=freeSpins].spinValue.stateselect: known, unknown, notApplicable1 when group existsRequired in rowknown requires amount and currencyCandidatenone/unlimited do not describe a spin's face value.
termVariants[].stages[].components[blockType=freeSpins].spinValue.amounttext decimal0..1OptionalRequired only when state is knownCandidateExact nonnegative spin value.
termVariants[].stages[].components[blockType=freeSpins].spinValue.currencytext0..1OptionalRequired only when state is knownCandidateExplicit source currency.
termVariants[].stages[].components[blockType=freeSpins].winningsCap.stateselect: known, unknown, unlimited, notApplicable1 when group existsRequired in rowknown requires amount and currencyCandidateCap on spin winnings; distinct from spin face value.
termVariants[].stages[].components[blockType=freeSpins].winningsCap.amounttext decimal0..1OptionalRequired only when state is knownCandidateExact upper limit.
termVariants[].stages[].components[blockType=freeSpins].winningsCap.currencytext0..1OptionalRequired only when state is knownCandidateExplicit source currency.
termVariants[].validityOverride.stateselect: known, unknown1 when group existsRequired in rowRequired; known override dates must be orderedCandidateCandidate explicit state for variant-specific dates.
termVariants[].validityOverride.startsAtdate ISO-8601 instant0..1OptionalRequired only for a known start overrideCandidateSource-supported override, not publication time.
termVariants[].validityOverride.endsAtdate ISO-8601 instant0..1OptionalRequired only for a known end overrideCandidateSource-supported override.
support.contacts[].languages[].valuetext1 per rowRequired in rowRetain exact stated language labelCandidateArray rows have Payload's native hidden string ID.
termVariants[].stages[].components[blockType=freeSpins].gameNames[].valuetext1 per rowRequired in rowRequired when source limits spins to named gamesCandidateNot a canonical game identity; array rows have native hidden string IDs.

Exact values and candidate validation​

These are concrete review choices, not accepted numeric policy. For every decimal field above, propose a nonnegative fixed-point text value: no exponent, sign or separators; canonical zero is 0; no leading or trailing insignificant zeroes; at most 20 integer digits and 8 fractional digits. A stricter mechanic-specific bound may apply. Preserve the source decimal lexeme until validation; do not convert through JavaScript floating point. Each known money value requires its own explicit source currency. The example uses EUR only as a fictional value; no conversion, supported-currency list or fallback is selected.

DescriptorCandidate allowed statesRequired companion fields and validation
Minimum money amountknown, unknown, notApplicableknown requires nonnegative decimal text and currency. Zero is a known value. none and unlimited are invalid.
Feeknown, unknown, none, notApplicableknown requires decimal and currency; none means the source explicitly says no fee. Zero remains a known zero fee.
Maximum/cap/upper limitknown, unknown, unlimited, notApplicableknown requires decimal and currency; unlimited requires an explicit source claim of no upper bound. none is not a cap value.
Wageringrequired, none, unknown, notApplicablerequired requires exact multiplier plus basis. none means explicitly no wagering requirement; zero is not a substitute.
CountNo nullable state field; store a number only when knownCount is a safe integer. A published free-spins benefit requires count greater than zero; a known zero is distinct from missing/unknown and is not a free-spins block.
Validityknown, unknownA known range carries source-supported ISO instants and startsAt ≤ endsAt; publication time never fills a missing start.

none, unlimited, unknown, notApplicable and numeric zero are not interchangeable. A field only permits the states listed for its descriptor. Missing currency never falls back to another variant, Market or locale. Competing supported statements stay as evidence plus an unresolved conflict until reviewed.

cataloguePublications​

This immutable collection has exactly two proposed subject types: casinoProfile and bonusOffer. Snapshot content is validated against the subject-specific contentSchema; editable facts above remain native Payload fields. dependencies and supportManifest are immutable exact values retained for review, not writable domain-field bags.

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
publicationKeytext1No partial record; required on appendRequired canonical key, server-derived from exact tupleExisting proposal; Candidate: exact text encodingCandidate wire encoding is shown in the example; not concatenated display labels. Profile tuple is subject + casinoId + marketKey + locale; Offer tuple is subject + stable offerId + locale. This field is not unique by itself.
revisionnumber safe integer1Required on appendMonotonic positive revision within key; stale append rejectedExisting proposal; Candidate: safe-integer storage typeUnique constraint is (publicationKey, revision); no revision reused for a key.
operationselect: publish, withdraw1Required on appendRequired; withdrawal is another immutable entry and advances current selectionExisting proposal; Candidate: exact enum spellingsExplicit operation, not hard-delete.
subjectTypeselect: casinoProfile, bonusOffer1Required on appendMust match the controlled subject relationshipExisting proposal; Candidate: exact enum spellingsExactly two subject kinds in this slice.
subjectpolymorphic relationship → casinoProfiles OR promotionalOffers1 unionRequired on appendExactly one matching subject; context must agreeExisting proposal; Candidate: serialized relationship shapeNative polymorphic value is { "relationTo": "collectionSlug", "value": localId }; select exactly one of the two targets.
priorPublicationrelationship → cataloguePublications0..1Absent on publish; required on withdrawWithdrawal pins the exact currently selected entry being withdrawn, with the same publicationKeyExisting proposal; Candidate: explicit local relationship fieldA withdrawal is a new entry/revision; it does not point to a replacement draft or delete prior history.
contextgroup with Casino, Market and locale1Required on appendRequired; each value must agree with subjectCandidateCandidate explicit frozen context group.
context.casinoIdtext1Required on appendMust match the subject's Casino mappingCandidateFrozen external Casino identity.
context.marketKeytext1Required on appendMust match the subject's MarketCandidateFrozen applicability context.
context.localetext1Required on appendRequired for independent locale publicationCandidateMust be a configured locale; no implicit locale fallback.
sourceVersiontext1 for publishRequired on publish appendPins exact native authoring versionExisting proposal; Candidate: text spelling and conditional requirednessNative Payload version identity; not a second public-status field.
inputIdentitytext1 for publishRequired on publish appendApproval binds to this exact resolved candidate and its dependenciesCandidateCandidate stable identity for the reviewed input. Withdrawal pins the prior selected entry instead.
approvedByrelationship → users1Required on appendRequired human actor for publish or authorized withdrawalExisting proposal; Candidate: exact relationship path/cardinalityReuses existing staff account; never exposed publicly.
approvedAtdate ISO-8601 instant1Required on appendRequired approval/withdrawal timeExisting proposal; Candidate: ISO date type and requirednessRetained staff action time.
reasonCodeselect: initialPublication, contentCorrection, scheduledUpdate, withdrawal1Required on appendRequired for publish and withdrawalCandidateCandidate reason-code values; remove/change through review. Retained with actor, time and exact input.
reasonNotetextarea0..1OptionalOptional staff explanation; privateExisting proposal; Candidate: textarea spelling/typeNot part of public payload.
contentSchematext1 for publishRequired on publish appendIdentifies subject-specific snapshot shape/versionExisting proposal; Candidate: exact v1 schema labels belowWithdrawal records explicit withdrawn operation and no actionable content.
contentjson, immutable validated snapshot1 for publishRequired on publish appendValidated per subject type and schema versionExisting proposal; Candidate: exact v1 subject schemas belowSnapshot JSON only; no untyped editable catalogue facts. Absent on withdrawal.
dependenciesjson, immutable validated manifest1 for publishRequired on publish appendExact values/revisions used to compose the snapshotExisting proposal; Candidate: typed dependency union belowNo reconstruction from mutable live relations. Private; no arbitrary values bag.
supportManifestjson, immutable validated manifest1 for publishRequired on publish appendExact retained evidence/content identity used by snapshotExisting proposal; Candidate: typed support-entry schema belowPrivate; public reads exclude it.

Candidate immutable JSON shapes​

contentSchema selects one of two fixed candidate structures. title, summary and SEO values are strings for the one locale in context.locale; body, when present, preserves its serialized rich-text object. Editable Payload authoring fields remain locale maps. The snapshot contains resolved display values, not live Payload relationship IDs. Every row in this dictionary is a candidate shape for stakeholder review.

Snapshot JSON pathJSON field/typeRequirednessSourceMeaning or validation
casinoProfile.v1objectOne per profile publicationCandidateVersioned schema tag; not an executable API contract.
casinoProfile.v1.casinoId, .marketKey, .localestringRequiredCandidateFrozen publication context matching the authoring subject.
casinoProfile.v1.brand.namestringRequiredCandidateResolved Brand value.
casinoProfile.v1.title, .summarystringRequiredCandidateSelected-locale copy; context.locale identifies the locale.
casinoProfile.v1.bodyserialized rich-text objectOptionalCandidateSelected-locale rich-text value; preserves the native editor representation.
casinoProfile.v1.seoTitle, .seoDescriptionstringOptionalCandidateSelected-locale SEO text.
casinoProfile.v1.legalStatements[]array of fixed objectsOptionalCandidateEach object has role, companyLegalName or assertedEntityName, assertion, and optional licenceNumber, regulatorName, jurisdiction.
casinoProfile.v1.paymentPolicies[]array of fixed objectsOptionalCandidateEach object has methodName, direction, currency, minimum, maximum, fee, and processingTime; exact states and types follow the source field dictionary.
casinoProfile.v1.cashierTerms.limits[]array of fixed objectsOptionalCandidateEach object has direction, period, conditional otherPeriod, basis, conditional timeZone/basisDescription, and value.
casinoProfile.v1.support.contacts[]array of fixed objectsOptionalCandidateEach object has channel, optional availabilityStatement, and languages[] strings.
bonusOffer.v1objectOne per Offer publicationCandidateVersioned schema tag; one Offer and locale per entry.
bonusOffer.v1.offerId, .casinoId, .marketKey, .localestringRequiredCandidateFrozen subject and scope.
bonusOffer.v1.purpose, .mechanicstring enumRequiredCandidateValues must match the typed candidate definitions above.
bonusOffer.v1.validityfixed objectRequiredCandidatestate plus conditional startsAt and endsAt ISO instants.
bonusOffer.v1.termVariants[]array of fixed objectsAt least oneCandidateEach has currency, eligibility, optional validityOverride, and stages[]; same-currency eligible variants remain distinct.
bonusOffer.v1.termVariants[].stages[]array of fixed objectsAt least one for welcomePackageCandidateEach has trigger, conditional qualifyingDeposit, and components[].
bonusOffer.v1.termVariants[].stages[].components[]discriminated union objectAt least one per published welcome stageCandidateblockType=cash carries award, wagering, optional cashoutLimit; blockType=freeSpins carries count, gameNames[], optional spinValue, wagering, winningsCap. No nested block-name group or untyped attributes bag.
bonusOffer.v1.title, .summarystringRequiredCandidateSelected-locale copy; context.locale identifies the locale.
bonusOffer.v1.bodyserialized rich-text objectOptionalCandidateSelected-locale rich-text value; preserves the native editor representation.
bonusOffer.v1.seoTitle, .seoDescriptionstringOptionalCandidateSelected-locale SEO text.

dependencies is an array of fixed, discriminated dependency entries. The kind field selects the permitted fields; the local ID uses the configured Payload collection-ID scalar and versionIdentity pins an exact retained version when the source has versions. No entry has a free-form values object.

Dependency JSON pathJSON typeRequired by kindSourceMeaning
dependencies[].kindstring enum: casino, brand, market, company, paymentMethod, mediaAlwaysCandidateSelects exactly one typed dependency variant.
dependencies[].localIdconfigured native Payload ID scalarAlwaysCandidateLocal relationship identity only; no forced UUID representation.
dependencies[].versionIdentitystringWhen an exact native version existsCandidatePins the resolved version used by the snapshot.
dependencies[].casinoIdstringcasinoCandidateCore Casino mapping.
dependencies[].namestringbrandCandidateExact resolved Brand name.
dependencies[].key, dependencies[].label, dependencies[].scopeKind, dependencies[].scopeDescriptionstringmarketCandidateExact Market identity and scope used for the publication.
dependencies[].legalName, dependencies[].registrationIdentifier, dependencies[].registrationJurisdictionstringcompanyCandidateExact resolved Company values when present.
dependencies[].key, dependencies[].displayNamestringpaymentMethodCandidateExact resolved Payment Method identity/display values.
dependencies[].mediaIdentitystringmediaCandidateExact retained media identity, never a mutable remote URL alone.

supportManifest is an array of fixed support entries. Each entry binds a public subject path to one admitted evidence identity and copies enough retained material to inspect that support after the evidence record or remote source changes. Each key below is typed; no generic arbitrary JSON path or source-value bag is permitted.

Support JSON pathJSON typeRequirednessSourceMeaning
supportManifest[].targetKindstring enum: root, ownedRowRequiredCandidateRoot or stable row target.
supportManifest[].targetRowIdstringRequired when target is ownedRowCandidateExact Payload array/block child ID.
supportManifest[].fieldKeystring from the same allowlisted typed vocabularyRequiredCandidateExact semantic field, not an arbitrary JSON path.
supportManifest[].evidenceIdconfigured native Payload ID scalarRequiredCandidateLocal Evidence identity.
supportManifest[].contentIdentity, supportManifest[].origin, supportManifest[].sourceIdentitystringRequiredCandidateExact admitted material identity and origin.
supportManifest[].admittedAtISO-8601 instantRequiredCandidateAdmission time.
supportManifest[].capturedAtISO-8601 instantRequired only for captured materialCandidateCapture time, if applicable.
supportManifest[].retainedExcerptstringRequired when the entry relies on an excerptCandidateExact excerpt retained with this publication.
supportManifest[].artifactIdentitystringOptional; only after private immutable media handling is selected and provenCandidateExact artifact reference. A media relationship alone establishes neither private access nor immutable retention.
supportManifest[].excerptLocatorstringOptionalCandidateLocator within retained material.

Proposed write rule: append entry, advance its selection and create delivery intent in the same already-active database transaction. Any failure rolls all three back. A delayed publish delivery cannot undo a later withdrawal. Keep staff identity, reason, draft notes and private manifests out of public responses. This is a proposal contract, not proof of a migration, transaction guard or API.

publicationSelections​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
publicationKeytext unique1Required on pointer writeExact same canonical key as current entryExisting proposal; Candidate: exact serialization/type (selection row unique; entry row not unique)One current pointer per publication key.
publicationrelationship → cataloguePublications1Required on pointer writePoints to the newest immutable entry, including withdrawalExisting proposal; Candidate: exact relationship path and requirednessNo mutable authoring content on selection.
revisionnumber safe integer1Required on pointer writeMust equal the pointed entry's revision and advance monotonicallyCandidateCandidate denormalized guard for the current revision.

This collection is a small mutable pointer. It is not a second content authority, and a pointer change cannot rewrite an earlier snapshot.

publicationDeliveries​

Field pathPayload field / targetCardinalityDraft savePublication gateSourceMeaning or proposed validation
deliveryIdentitytext unique1Required when intent is createdStable across retries for the same exact entry and targetExisting proposal; Candidate: text type and delivery-key spellingDurable deduplication identity.
publicationrelationship → cataloguePublications1Required when intent is createdExact immutable entry; never a live authoring lookupExisting proposal; Candidate: exact relationship path and requirednessRetains publish or withdrawal order.
targetselect: coreCatalogueAdapter1Required when intent is createdExact selected consumer targetCandidateCandidate target value for this bounded slice.
statusselect: pending, delivered, retryable, superseded1Required when intent is createdAcknowledgement updates delivery state only, never snapshot contentCandidateCandidate minimal delivery states; delayed older publish must be superseded after withdrawal.
attemptCountnumber safe integer1Defaults to 0Nonnegative; increments for each attemptCandidateCandidate delivery counter.
lastAttemptAtdate ISO-8601 instant0..1Optional before first attemptSet only after an attemptCandidateTechnical delivery metadata.
acknowledgedAtdate ISO-8601 instant0..1Optional until acknowledgementSet with delivered; must refer to exact entryCandidateAcknowledgement time.

The outbox intent is created with the immutable entry and current selection. Retry state does not edit the approved publication.

Synthetic end-to-end example​

Every name, ID, amount, date, assertion and URL-like identifier below is fictional. Collection id values illustrate the configured native Payload ID type; owned array/block id values are native stable string row IDs. approvedBy: 501 is a fictional relationship to an existing users record, intentionally outside these 11 collection roots. The authoring copy maps each localized field to a locale; each immutable content object is the exact single-locale projection named by context.locale. The two publications share one dataset but have separate profile and Offer keys, revisions, selections and deliveries.

{
"brands": [
{ "id": 1, "name": "Example Lantern", "aliases": [{ "id": "brand-alias-1", "value": "Lantern Demo" }] }
],
"casinos": [
{ "id": 10, "casinoId": "casino_demo_0042", "brand": 1, "staffLabel": "Lantern sample record" }
],
"markets": [
{ "id": 20, "key": "example-market", "label": "Example Market", "scopeKind": "audience", "scopeDescription": "Fictional adult audience used only to demonstrate field shape." }
],
"companies": [
{ "id": 40, "legalName": "Example Lantern Operations Ltd" }
],
"paymentMethods": [
{ "id": 30, "key": "example-transfer", "displayName": "Example Transfer" }
],
"evidence": [
{
"id": 60,
"origin": "manualAdmission",
"sourceIdentity": "Fictional review-page illustration",
"admittedAt": "2026-10-05T10:00:00.000Z",
"retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.",
"contentIdentity": "illustration:payload-fields:1"
}
],
"casinoProfiles": [
{
"id": 70,
"casino": 10,
"market": 20,
"legalStatements": [
{ "id": "legal-row-1", "role": "operator", "company": 40, "assertedEntityName": "Example Lantern Operations Ltd", "assertion": "Fictional operator relationship for schema illustration." }
],
"paymentPolicies": [
{
"id": "payment-row-1",
"paymentMethod": 30,
"direction": "deposit",
"currency": "EUR",
"minimum": { "state": "known", "amount": "10" },
"maximum": { "state": "unknown" },
"fee": { "state": "none" },
"processingTime": { "state": "unknown" }
}
],
"cashierTerms": {
"limits": [
{ "id": "cashier-limit-1", "direction": "withdrawal", "period": "daily", "basis": "rolling", "value": { "state": "known", "amount": "500", "currency": "EUR" } }
]
},
"support": {
"contacts": [
{ "id": "support-contact-1", "channel": "liveChat", "availabilityStatement": "Fictional example hours: weekdays, 09:00–17:00 Example Time.", "languages": [{ "id": "support-language-1", "value": "en" }] }
]
},
"editorialCopy": {
"title": { "en": "Example Lantern in Example Market" },
"summary": { "en": "Fictional copy showing one localized profile." }
},
"supportBindings": [
{ "id": "profile-binding-1", "targetKind": "ownedRow", "targetRowId": "legal-row-1", "fieldKey": "legalStatement", "evidence": 60, "excerptLocator": "illustration:operator-role" },
{ "id": "profile-binding-2", "targetKind": "ownedRow", "targetRowId": "payment-row-1", "fieldKey": "paymentPolicy", "evidence": 60, "excerptLocator": "illustration:example-transfer-deposit" },
{ "id": "profile-binding-3", "targetKind": "ownedRow", "targetRowId": "cashier-limit-1", "fieldKey": "cashierLimit", "evidence": 60, "excerptLocator": "illustration:daily-withdrawal-limit" },
{ "id": "profile-binding-4", "targetKind": "ownedRow", "targetRowId": "support-contact-1", "fieldKey": "supportContact", "evidence": 60, "excerptLocator": "illustration:live-chat" }
],
"unresolvedIssues": []
}
],
"promotionalOffers": [
{
"id": 80,
"offerId": "offer_demo_welcome_1",
"casino": 10,
"market": 20,
"purpose": "welcome",
"mechanic": "welcomePackage",
"validity": { "state": "known", "startsAt": "2026-10-01T00:00:00.000Z", "endsAt": "2026-12-31T23:59:59.000Z" },
"termVariants": [
{
"id": "term-eur-1",
"currency": "EUR",
"eligibility": { "audience": "newCustomers", "conditions": "Fictional first-deposit condition." },
"stages": [
{
"id": "stage-first-deposit-1",
"displayOrder": 1,
"trigger": "firstDeposit",
"qualifyingDeposit": { "state": "known", "amount": "10", "currency": "EUR" },
"components": [
{
"id": "cash-block-1",
"blockType": "cash",
"award": { "kind": "percentage", "amount": "100", "rateBasis": "depositAmount", "maximum": { "state": "known", "amount": "500", "currency": "EUR" } },
"wagering": { "state": "required", "multiplier": "30", "basis": "bonusPlusDeposit" },
"cashoutLimit": { "state": "known", "amount": "50", "currency": "EUR" }
},
{
"id": "free-spins-block-1",
"blockType": "freeSpins",
"count": 20,
"gameNames": [{ "id": "game-name-1", "value": "Example Game" }],
"spinValue": { "state": "known", "amount": "0.2", "currency": "EUR" },
"wagering": { "state": "required", "multiplier": "40", "basis": "winningsOnly" },
"winningsCap": { "state": "known", "amount": "100", "currency": "EUR" }
}
]
}
]
}
],
"editorialCopy": {
"title": { "en": "Example Lantern welcome package" },
"summary": { "en": "Fictional cash and spins terms for the schema example." }
},
"supportBindings": [
{ "id": "offer-binding-1", "targetKind": "root", "fieldKey": "offer.validity", "evidence": 60, "excerptLocator": "illustration:validity" },
{ "id": "offer-binding-2", "targetKind": "ownedRow", "targetRowId": "term-eur-1", "fieldKey": "offerTerm.eligibility", "evidence": 60, "excerptLocator": "illustration:new-customers" },
{ "id": "offer-binding-3", "targetKind": "ownedRow", "targetRowId": "stage-first-deposit-1", "fieldKey": "welcomeStage.qualifyingDeposit", "evidence": 60, "excerptLocator": "illustration:first-deposit" },
{ "id": "offer-binding-6", "targetKind": "ownedRow", "targetRowId": "stage-first-deposit-1", "fieldKey": "welcomeStage.trigger", "evidence": 60, "excerptLocator": "illustration:stage-trigger" },
{ "id": "offer-binding-4", "targetKind": "ownedRow", "targetRowId": "cash-block-1", "fieldKey": "cashComponent", "evidence": 60, "excerptLocator": "illustration:cash-benefit" },
{ "id": "offer-binding-5", "targetKind": "ownedRow", "targetRowId": "free-spins-block-1", "fieldKey": "freeSpinsComponent", "evidence": 60, "excerptLocator": "illustration:spin-benefit" }
],
"unresolvedIssues": []
}
],
"cataloguePublications": [
{
"id": 100,
"publicationKey": "v1:[\"casinoProfile\",\"casino_demo_0042\",\"example-market\",\"en\"]",
"revision": 1,
"operation": "publish",
"subjectType": "casinoProfile",
"subject": { "relationTo": "casinoProfiles", "value": 70 },
"context": { "casinoId": "casino_demo_0042", "marketKey": "example-market", "locale": "en" },
"sourceVersion": "example-profile-version-1",
"inputIdentity": "example-profile-candidate-1",
"approvedBy": 501,
"approvedAt": "2026-10-05T11:00:00.000Z",
"reasonCode": "initialPublication",
"contentSchema": "casinoProfile.v1",
"content": {
"casinoId": "casino_demo_0042",
"marketKey": "example-market",
"locale": "en",
"brand": { "name": "Example Lantern" },
"title": "Example Lantern in Example Market",
"summary": "Fictional copy showing one localized profile.",
"legalStatements": [{ "role": "operator", "companyLegalName": "Example Lantern Operations Ltd", "assertion": "Fictional operator relationship for schema illustration." }],
"paymentPolicies": [{ "methodName": "Example Transfer", "direction": "deposit", "currency": "EUR", "minimum": { "state": "known", "amount": "10" }, "maximum": { "state": "unknown" }, "fee": { "state": "none" }, "processingTime": { "state": "unknown" } }],
"cashierTerms": { "limits": [{ "direction": "withdrawal", "period": "daily", "basis": "rolling", "value": { "state": "known", "amount": "500", "currency": "EUR" } }] },
"support": { "contacts": [{ "channel": "liveChat", "availabilityStatement": "Fictional example hours: weekdays, 09:00–17:00 Example Time.", "languages": ["en"] }] }
},
"dependencies": [
{ "kind": "casino", "localId": 10, "casinoId": "casino_demo_0042" },
{ "kind": "brand", "localId": 1, "name": "Example Lantern" },
{ "kind": "market", "localId": 20, "key": "example-market", "label": "Example Market", "scopeKind": "audience", "scopeDescription": "Fictional adult audience used only to demonstrate field shape." },
{ "kind": "company", "localId": 40, "legalName": "Example Lantern Operations Ltd" },
{ "kind": "paymentMethod", "localId": 30, "key": "example-transfer", "displayName": "Example Transfer" }
],
"supportManifest": [
{ "targetKind": "ownedRow", "targetRowId": "legal-row-1", "fieldKey": "legalStatement", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:operator-role" },
{ "targetKind": "ownedRow", "targetRowId": "payment-row-1", "fieldKey": "paymentPolicy", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:example-transfer-deposit" },
{ "targetKind": "ownedRow", "targetRowId": "cashier-limit-1", "fieldKey": "cashierLimit", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:daily-withdrawal-limit" },
{ "targetKind": "ownedRow", "targetRowId": "support-contact-1", "fieldKey": "supportContact", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:live-chat" }
]
},
{
"id": 101,
"publicationKey": "v1:[\"bonusOffer\",\"offer_demo_welcome_1\",\"en\"]",
"revision": 1,
"operation": "publish",
"subjectType": "bonusOffer",
"subject": { "relationTo": "promotionalOffers", "value": 80 },
"context": { "casinoId": "casino_demo_0042", "marketKey": "example-market", "locale": "en" },
"sourceVersion": "example-offer-version-1",
"inputIdentity": "example-offer-candidate-1",
"approvedBy": 501,
"approvedAt": "2026-10-05T11:05:00.000Z",
"reasonCode": "initialPublication",
"contentSchema": "bonusOffer.v1",
"content": {
"offerId": "offer_demo_welcome_1",
"casinoId": "casino_demo_0042",
"marketKey": "example-market",
"locale": "en",
"purpose": "welcome",
"mechanic": "welcomePackage",
"validity": { "state": "known", "startsAt": "2026-10-01T00:00:00.000Z", "endsAt": "2026-12-31T23:59:59.000Z" },
"termVariants": [{ "currency": "EUR", "eligibility": { "audience": "newCustomers", "conditions": "Fictional first-deposit condition." }, "stages": [{ "trigger": "firstDeposit", "qualifyingDeposit": { "state": "known", "amount": "10", "currency": "EUR" }, "components": [{ "blockType": "cash", "award": { "kind": "percentage", "amount": "100", "rateBasis": "depositAmount", "maximum": { "state": "known", "amount": "500", "currency": "EUR" } }, "wagering": { "state": "required", "multiplier": "30", "basis": "bonusPlusDeposit" }, "cashoutLimit": { "state": "known", "amount": "50", "currency": "EUR" } }, { "blockType": "freeSpins", "count": 20, "gameNames": ["Example Game"], "spinValue": { "state": "known", "amount": "0.2", "currency": "EUR" }, "wagering": { "state": "required", "multiplier": "40", "basis": "winningsOnly" }, "winningsCap": { "state": "known", "amount": "100", "currency": "EUR" } }] }] }],
"title": "Example Lantern welcome package",
"summary": "Fictional cash and spins terms for the schema example."
},
"dependencies": [
{ "kind": "casino", "localId": 10, "casinoId": "casino_demo_0042" },
{ "kind": "brand", "localId": 1, "name": "Example Lantern" },
{ "kind": "market", "localId": 20, "key": "example-market", "label": "Example Market", "scopeKind": "audience", "scopeDescription": "Fictional adult audience used only to demonstrate field shape." }
],
"supportManifest": [
{ "targetKind": "root", "fieldKey": "offer.validity", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:validity" },
{ "targetKind": "ownedRow", "targetRowId": "term-eur-1", "fieldKey": "offerTerm.eligibility", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:new-customers" },
{ "targetKind": "ownedRow", "targetRowId": "stage-first-deposit-1", "fieldKey": "welcomeStage.qualifyingDeposit", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:first-deposit" },
{ "targetKind": "ownedRow", "targetRowId": "stage-first-deposit-1", "fieldKey": "welcomeStage.trigger", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:stage-trigger" },
{ "targetKind": "ownedRow", "targetRowId": "cash-block-1", "fieldKey": "cashComponent", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:cash-benefit" },
{ "targetKind": "ownedRow", "targetRowId": "free-spins-block-1", "fieldKey": "freeSpinsComponent", "evidenceId": 60, "contentIdentity": "illustration:payload-fields:1", "origin": "manualAdmission", "sourceIdentity": "Fictional review-page illustration", "admittedAt": "2026-10-05T10:00:00.000Z", "retainedExcerpt": "Fictional example only: Example Lantern is the Brand. Example Lantern Operations Ltd is identified as operator. Example Transfer accepts deposits in EUR; the stated deposit minimum is EUR 10, no deposit fee is charged, and no deposit maximum or processing time is stated. The cashier terms state a rolling daily withdrawal limit of EUR 500. The profile states live chat is available weekdays from 09:00 to 17:00 Example Time and is offered in English. The welcome package is for new customers after a first deposit of EUR 10, is available from 1 October 2026 through 31 December 2026, and gives a 100% deposit match up to EUR 500 with 30x bonus-plus-deposit wagering and a EUR 50 cashout cap. It also gives 20 Example Game spins worth EUR 0.2 each, with 40x winnings-only wagering and a EUR 100 winnings cap. All names and terms in this excerpt are fictional.", "excerptLocator": "illustration:spin-benefit" }
]
}
],
"publicationSelections": [
{ "id": 110, "publicationKey": "v1:[\"casinoProfile\",\"casino_demo_0042\",\"example-market\",\"en\"]", "publication": 100, "revision": 1 },
{ "id": 111, "publicationKey": "v1:[\"bonusOffer\",\"offer_demo_welcome_1\",\"en\"]", "publication": 101, "revision": 1 }
],
"publicationDeliveries": [
{ "id": 120, "deliveryIdentity": "example-delivery-profile-1", "publication": 100, "target": "coreCatalogueAdapter", "status": "pending", "attemptCount": 0, "lastAttemptAt": null, "acknowledgedAt": null },
{ "id": 121, "deliveryIdentity": "example-delivery-offer-1", "publication": 101, "target": "coreCatalogueAdapter", "status": "pending", "attemptCount": 0, "lastAttemptAt": null, "acknowledgedAt": null }
]
}

The sample profile and Offer are independent publication units. The ordinary cashier withdrawal limit (500 EUR/day rolling in this fictional data) is distinct from the Offer cashout cap (50 EUR); the Offer award ceiling (500 EUR) is a third value. Cash and free-spin wagering retain their own bases. The JSON illustrates native relationship/row identity and proposed snapshot intent; it is not an executable Payload config, JSON Schema or API DTO.

Review checklist​

Please identify feedback with the exact collection and field path. In particular, decide the candidate field types and enum values; whether the proposed profile and welcome Offer minimums fit a manual first model; which fields should remain saveable while incomplete; and whether a future cashback, VIP or event shape needs another selected typed increment. Also flag any relationship, currency, source-support or publication state that the sample fails to preserve.

Recorded outcome​

No decision recorded. Reviewing this model or its editorial wording does not approve product policy, implementation, migration, API contract, schedule or deployment. Record an actual agreement in the authoritative owner and update this page to the reviewed revision and conditions.