Entitlements & refunds
A download link says how bytes are handed over. An entitlement says what the customer owns. Traide keeps the two separate: DigitalContentUrl is a replaceable delivery credential, while Entitlement is the durable, account-bound record of the customer's claim — with a lifecycle, an audit trail of uses, and revocation wired to refunds. Integrators should treat the entitlement as the source of truth for access decisions.
Entitlement, RedemptionEvent, and the related queries are not yet in the generated API reference; they will appear with the next schema regeneration. Until then, the SDL excerpts on this page are the authoritative shape.
The entitlement ledger
An entitlement is granted automatically whenever a digital line is delivered — on automatic fulfillment at payment, and on manual fulfillment. Granularity depends on the kind: DIGITAL_FILE lines grant one entitlement per line; the per-unit kinds (LICENSE_KEY/CODE/GIFT_CARD) grant one entitlement per unit — a quantity-3 key line produces three rows of quantity: 1, each bound to its own key. Its key fields:
| Field | Meaning |
|---|---|
customerEmail | Identity the claim is bound to. Always present, including guest checkouts |
quantity | Units covered by the claim |
productName / variantName / productSku | Snapshotted at purchase — they survive later catalog changes |
kind | The fulfillment kind, snapshotted at grant time |
licenseKey | For per-unit kinds: the secret credential this claim was issued against — see License keys, codes & gift cards |
status | Lifecycle state (below) |
revokedReason | Why the claim was withdrawn, if it was |
isUsable | Whether redemption is permitted right now — combines status with the expiry clock |
contentUrls | Download credentials issued against this entitlement |
redemptions | Uses of the entitlement, most recent first |
The lifecycle is expressed as states, not booleans — "revoked because refunded" and "expired because the term ended" are different facts, and only ACTIVE permits redemption:
enum EntitlementStatus {
PENDING
ACTIVE
SUSPENDED
EXPIRED
REVOKED
TRANSFERRED
}
enum EntitlementRevokedReason {
REFUND
CHARGEBACK
FRAUD
OPERATOR
SELLER
}
The customer library
Signed-in customers read their own library with me { entitlements }. It is owner-scoped — only ever the requesting user's entitlements — and includes items whose download links have since expired, which is what makes "re-download without email archaeology" possible on a storefront:
query {
me {
entitlements(first: 20) {
edges {
node {
productName
variantName
status
isUsable
grantedAt
contentUrls {
url
downloadNum
}
}
}
}
}
}
Guest purchases carry the checkout email as their identity (customerEmail). A guest's entitlements become visible in me { entitlements } once the entitlement is associated with their customer account — until then the claim exists but is not exposed through the library.
Operator and seller views
entitlements(first: …)— requiresMANAGE_ORDERS. Marketplace operators see every entitlement; a seller sees only claims against their own goods.entitlementRevoke(id, reason)— withdraw a customer's entitlement, invalidating any download links issued against it. RequiresMANAGE_MARKETPLACE. Thereasondefaults toOPERATOR; passFRAUDorSELLERwhen that is the real cause, since the reason drives downstream trust policy.
mutation {
entitlementRevoke(id: "RW50aXRsZW1lbnQ6MQ==", reason: FRAUD) {
entitlement {
id
status
revokedReason
}
entitlementErrors {
field
code
message
}
}
}
Refunds revoke access
With revokeEntitlementsOnRefund enabled on the marketplace configuration (it is on by default), a refund that completes — reaching the PAID refund status — revokes the entitlements covered by that refund with revokedReason: REFUND, and the associated download links stop validating. A refunded buyer does not keep a working download link.
This holds regardless of how the refund reached PAID: dashboard-driven refunds, automatic gateway processing, and gateway webhook confirmations all trigger revocation. Refund scope fans out — a whole-order or whole-seller-order refund revokes the digital lines it covers, not just refunds issued line-by-line.
To keep links alive for refunded buyers as a policy choice, disable the flag:
mutation {
marketplaceConfigurationUpdate(input: { revokeEntitlementsOnRefund: false }) {
marketplaceConfiguration {
revokeEntitlementsOnRefund
}
}
}
Redemption events
Every use of an entitlement is recorded as a RedemptionEvent:
type RedemptionEvent implements Node {
id: ID!
occurredAt: DateTime!
eventType: RedemptionEventType!
idempotencyKey: String
}
Three event types are live: DOWNLOAD (a file download — no idempotency key, every download is a distinct use), REVEAL (the first time a buyer reveals a key's secret — exactly one per key), and ACTIVATION (a use counted through the verification API, idempotent when the caller supplies an idempotency key). SCAN and CHECK_IN remain reserved for tickets and bookings, which will redeem against this same ledger.
Alongside the event exposed in the API, the download endpoint records request forensics (IP address and user agent) server-side with each download redemption. That row — not just the counter — is the evidence a chargeback dispute is argued from, and it covers guest downloads too.
Webhooks
Seven webhook events cover the digital lifecycle for integrators:
| Event | Fires when | Payload |
|---|---|---|
ENTITLEMENT_GRANTED | A customer's claim is created at delivery | The serialized entitlement |
ENTITLEMENT_REVOKED | A claim is withdrawn (refund, operator, fraud…) | The serialized entitlement |
DIGITAL_CONTENT_URL_CREATED | A download link is minted | The serialized link |
DIGITAL_CONTENT_URL_REVOKED | A link is invalidated | The serialized link |
LICENSE_KEY_ISSUED | A sold key binds to its entitlement at payment | The serialized key (secretLast4 only — never the secret) |
LICENSE_KEY_REVEALED | A key's first reveal | The serialized key |
LICENSE_KEY_VOIDED | A key is withdrawn (inventory void, or revocation on refund) | The serialized key |
Payloads mirror the corresponding GraphQL type's shape. Subscribe to them like any other event — see Subscribing to webhooks; the entitlement events and the three license-key events require the subscribing app to hold MANAGE_ORDERS.
Separately from webhooks, each download also records a DIGITAL_LINK_DOWNLOADED customer analytics event on the buyer's timeline.