Every webhook event the Seller API can deliver. Subscribe only to events you handle. Delivery is at-least-once — dedupe on eventId / X-Avrix-Event-Id.
Warning: Webhook payloads never include plaintext game keys. Persist entitlements from the synchronous POST /orders (or pull/export) response. Treat webhooks as lifecycle and correlation signals.
Note: GET /api/seller/v1/orders returns order aggregates (counts, references, allocation ids) — not a top-level status enum. Infer lifecycle from aggregates plus the events below.
Envelope shape (all events):
{
"eventId" : "evt_01J8XYZ..." ,
"eventType" : "order.fulfilled" ,
"eventVersion" : 1 ,
"createdAt" : "2026-08-05T09:14:22.108Z" ,
"data" : { }
}
Trigger You called POST /api/seller/v1/webhooks/{id}/test Seller action Verify signature, reject a corrupted signature, acknowledge 2xx Duplication Safe to ignore duplicates; use for connectivity only Related Webhook endpoint configuration
{
"eventType" : "test.ping" ,
"data" : {
"ok" : true ,
"webhookId" : "wh_7d3f..."
}
}
Trigger Order committed; entitlements issued Seller action Correlate on orderReference; confirm your vault already has entitlements from the HTTP response Duplication Common on retries; dedupe by eventId. May arrive before the HTTP response Related POST /api/seller/v1/orders , GET /api/seller/v1/orders?orderReference=
{
"eventType" : "order.fulfilled" ,
"data" : {
"orderReference" : "store-order-10432" ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"quantity" : 1 ,
"pulled" : 1 ,
"fulfilledAt" : "2026-08-05T09:14:22.108Z"
}
}
Webhook payloads never include key plaintext.
Trigger Fulfilment failed after commit was attempted (async failure path) Seller action Mark the store order failed; refund the buyer at your PSP if you already charged Duplication Dedupe by eventId; reconcile with GET /orders Related Order lifecycle, your PSP refunds
{
"eventType" : "order.failed" ,
"data" : {
"orderReference" : "store-order-10432" ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"reasonCode" : "NO_AVAILABLE_KEYS"
}
}
Trigger Preorder or hot-drop reservation accepted; keys not yet delivered Seller action Show “reserved / shipping later” to the buyer; wait for order.preorder_fulfilled or commit path Duplication Dedupe by eventId Related POST /orders , POST /orders/reserve
{
"eventType" : "order.reserved" ,
"data" : {
"orderReference" : "store-order-10432" ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"quantity" : 1 ,
"expectedReleaseAt" : "2026-12-12T00:00:00.000Z"
}
}
order.preorder_fulfilled#
Trigger Preorder converted to fulfilled delivery at release Seller action Deliver entitlements if your sync path obtained them; update store order to fulfilled Duplication Dedupe; may pair with aggregate changes on GET /orders Related Preorder reservations
{
"eventType" : "order.preorder_fulfilled" ,
"data" : {
"orderReference" : "store-order-10432" ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"quantity" : 1 ,
"fulfilledAt" : "2026-12-12T00:05:00.000Z"
}
}
Trigger Preorder / reservation cancel recorded against a prior order Seller action Reflect cancellation in your OMS; do not expect key quarantine events Duplication Dedupe by eventId Related POST /api/seller/v1/orders/cancel
{
"eventType" : "order.returned" ,
"data" : {
"orderReference" : "store-order-10432" ,
"quantity" : 1
}
}
Trigger Successful post-fulfilment key return / quarantine Seller action Mark keys returned in your vault; stop delivering those keyIds Duplication Often paired with refund.completed on the same return — handle both Related POST /keys/return , POST /refunds
{
"eventType" : "order.keys_returned" ,
"data" : {
"orderReference" : "store-order-10432" ,
"keyIds" : [ "k_8f21..." , "k_9a02..." ] ,
"returned" : 2 ,
"reason" : "buyer_refund"
}
}
Note: On a successful return, both order.keys_returned and refund.completed may fire. order.keys_returned carries keyIds; refund.completed carries optional adjustmentType.
Trigger Refund / chargeback adjustment finalised for a sale line Seller action Align finance ledger; confirm buyer was refunded at your PSP separately Duplication May accompany order.keys_returned; dedupe each event independently Related POST /api/seller/v1/refunds , GET /api/seller/v1/refunds
{
"eventType" : "refund.completed" ,
"data" : {
"orderReference" : "store-order-10432" ,
"refundId" : "rf_01J8..." ,
"adjustmentType" : "refund" ,
"adjustmentStatus" : "completed"
}
}
Trigger Keys pulled via POST /api/seller/v1/keys/pull (non-order path) Seller action Persist keys from the HTTP response; use webhook for ops correlation only Duplication Dedupe by eventId Related Key pull API
{
"eventType" : "keys.pulled" ,
"data" : {
"orderReference" : "store-order-10432" ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"pulled" : 1
}
}
Trigger A keyless redemption URL enters its expiry notice window (~24 hours before expiresAt) Seller action Nudge the buyer to redeem; after expiry, follow the keyless re-issue path Duplication Fires once per fulfillment Related Keyless fulfillment, order.activated
Payload carries ids only — never the redemption URL or token.
{
"eventType" : "redemption.expiring" ,
"data" : {
"fulfillmentId" : "kf_..." ,
"orderReference" : "store-order-10432" ,
"skuId" : "sku_..." ,
"platformCode" : "steam" ,
"provider" : "hosted_redemption" ,
"expiresAt" : "2026-08-13T02:00:00.000Z"
}
}
Trigger Allocation capacity or metadata changed Seller action Refresh GET /allocations / availability for the SKU Duplication Collapse bursts into one refresh Related Allocations, catalog sync
{
"eventType" : "allocation.updated" ,
"data" : {
"allocationId" : "alloc_..." ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"remaining" : 420
}
}
Trigger Allocation reached zero remaining Seller action Mark SKU unavailable on the storefront; re-check on next allocation update Duplication Treat as authoritative “empty” signal; still re-read allocations Related Availability
{
"eventType" : "allocation.depleted" ,
"data" : {
"allocationId" : "alloc_..." ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"remaining" : 0
}
}
Trigger Allocation crossed the configured low-stock threshold Seller action Alert merchandising / pause promotions if needed Duplication May fire once per crossing; do not decrement local counters blindly Related Allocations
{
"eventType" : "allocation.low_stock" ,
"data" : {
"allocationId" : "alloc_..." ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"remaining" : 25 ,
"threshold" : 50
}
}
Trigger Product metadata changed for a shared product Seller action Run incremental catalog sync (GET /catalog/changes or products delta) Duplication Coalesce into one sync job Related Catalog
{
"eventType" : "product.updated" ,
"data" : {
"productId" : "prod_..." ,
"updatedAt" : "2026-08-05T09:14:22.108Z"
}
}
Trigger Release advanced to announced Seller action Update storefront presentation / preorder messaging Duplication Idempotent presentation update Related Product lifecycle
{
"eventType" : "product.announced" ,
"data" : {
"productId" : "prod_..." ,
"releaseId" : "rel_..."
}
}
Trigger A keyless redemption URL has passed expiresAt without activation Seller action Mark the link dead; do not send the buyer to it. Re-issue only if your process allows Duplication Fires once per fulfillment (expiry_expired_at marker) Related redemption.expiring, keyless fulfillment
Payload carries ids only — never the redemption URL or token.
{
"eventType" : "redemption.expired" ,
"data" : {
"fulfillmentId" : "kf_..." ,
"orderReference" : "store-order-10432" ,
"skuId" : "sku_..." ,
"platformCode" : "steam" ,
"provider" : "hosted_redemption" ,
"expiresAt" : "2026-08-13T02:00:00.000Z" ,
"effectiveAt" : "2026-08-13T02:00:00.000Z"
}
}
Trigger Product removed from your visible catalog (tombstone) Seller action Remove or hide the product; stop taking new orders Duplication Treat as tombstone; confirm via GET /catalog/changes Related Catalog changes
{
"eventType" : "product.delisted" ,
"data" : {
"productId" : "prod_..." ,
"delistedAt" : "2026-08-05T09:14:22.108Z"
}
}
product.delisting_scheduled#
Trigger Product has a future archived_at — it will leave the catalog at effectiveAt Seller action Schedule delist in your store; do not treat as already gone. Immediate archive still emits product.delisted only Duplication Treat as advance notice; confirm via GET /catalog/changes Related product.delisted, catalog changes
{
"eventType" : "product.delisting_scheduled" ,
"data" : {
"productId" : "prod_..." ,
"effectiveAt" : "2026-09-01T00:00:00.000Z"
}
}
Trigger An async POST /catalog/exports job finished building the gzip NDJSON artifact Seller action GET /catalog/exports/{exportId} for the short-lived signed URLDuplication Once per export job Related Catalog snapshot
{
"eventType" : "catalog.export_ready" ,
"data" : {
"exportId" : "…" ,
"checksum" : "…" ,
"bytes" : 1048576 ,
"expiresAt" : "2026-08-18T12:00:00.000Z" ,
"totalProducts" : 1200
}
}
Trigger Release advanced to available Seller action Refresh catalog and sellability; enable purchase UI when allocations allow Duplication Idempotent Related Product lifecycle, allocations
{
"eventType" : "release.available" ,
"data" : {
"productId" : "prod_..." ,
"releaseId" : "rel_..."
}
}
Trigger Publisher moved a release date (pre-order slip signal) Seller action Update listing dates; notify pre-order buyers; re-check pre-order windows Duplication Latest date wins; compare newDate against your stored value Related Pre-orders, order.reserved, product lifecycle
{
"eventType" : "release.date_changed" ,
"data" : {
"productId" : "prod_..." ,
"releaseId" : "rel_..." ,
"skuIds" : [ "sku_..." ] ,
"oldDate" : "2026-11-14T00:00:00Z" ,
"newDate" : "2027-02-06T00:00:00Z"
}
}
Trigger Territory catalog list price changed for a SKU Seller action Refresh pricing; re-preview before next charge Duplication Latest price wins; do not apply deltas blindly Related GET /products/{id}/pricing, order preview
{
"eventType" : "sku.pricing_updated" ,
"data" : {
"skuCode" : "SANDBOX-ALWAYS-001" ,
"countryCode" : "US" ,
"currencyCode" : "USD" ,
"unitPriceCents" : 1999 ,
"effectiveAt" : "2026-08-12T09:00:00Z" ,
"previousPricing" : { "priceCents" : 2499 , "currencyCode" : "USD" } ,
"newPricing" : { "priceCents" : 1999 , "currencyCode" : "USD" }
}
}
effectiveAt states when the new price takes effect. For immediate changes it equals the
event's updatedAt; scheduled price changes stamp a future instant — apply the new price at
that boundary rather than on receipt. previousPricing / newPricing carry the explicit
old→new pair (previousPricing is null when no prior price existed for the country).
Trigger A shared SKU crossed the sellable boundary (any of the four gates flipped) Seller action Enable/disable the Buy button; confirm with GET /allocations before checkout Duplication State event — apply the latest sellable value Related Four sellability gates, GET /allocations, readinessBlockers
{
"eventType" : "sku.sellability_changed" ,
"data" : {
"skuId" : "sku_..." ,
"skuCode" : "SANDBOX-ALWAYS-001" ,
"productId" : "prod_..." ,
"sellable" : false ,
"reasons" : [ "NO_SKU_SHARE" ]
}
}
Trigger BMA or MCA became active Seller action Re-sync partners / catalog; SKUs under the contract may become sellable Duplication Idempotent commercial refresh Related Partners, four sellability gates
{
"eventType" : "contract.activated" ,
"data" : {
"contractId" : "ctr_..." ,
"partnerCompanyId" : "..."
}
}
Trigger Prior active contract term was superseded Seller action Refresh commercial terms; stop relying on the old term id Duplication Idempotent Related Contract lifecycle
{
"eventType" : "contract.superseded" ,
"data" : {
"contractId" : "ctr_..." ,
"supersededBy" : "ctr_..."
}
}
contract.amendment_accepted#
Trigger Amendment accepted by the counterparty Seller action Refresh terms that affect pricing, territory, or scope Duplication Idempotent Related Contract amendments
{
"eventType" : "contract.amendment_accepted" ,
"data" : {
"contractId" : "ctr_..." ,
"amendmentId" : "amd_..."
}
}
Trigger Seller invoice document created Seller action Fetch finance / invoice surfaces; notify accounting Duplication Dedupe by invoice id in data Related Finance endpoints
{
"eventType" : "invoice.created" ,
"data" : {
"invoiceId" : "inv_..." ,
"periodStart" : "2026-07-01" ,
"periodEnd" : "2026-07-31"
}
}
Trigger Report export is ready to download Seller action Download via the finance / reports API referenced in the payload Duplication Dedupe by report id Related Finance and settlement
{
"eventType" : "report.ready" ,
"data" : {
"reportId" : "rpt_..." ,
"reportType" : "api_sales" ,
"readyAt" : "2026-08-05T09:14:22.108Z"
}
}
system.webhook_endpoint_disabled#
Trigger The delivery circuit breaker auto-disabled one of your endpoints Seller action Fix the failing receiver, then POST /webhooks/{id}/enable — buffered events flush automatically Duplication Fires once per active → disabled transition Related Webhooks — retries, buffering, circuit breaker
Delivered to your company's other endpoints; the disabled endpoint's own copy is buffered and
arrives after re-enable. Paired with an in-app console notification and an email to company
admins.
{
"eventType" : "system.webhook_endpoint_disabled" ,
"data" : {
"endpointId" : "wh_..." ,
"endpointHost" : "store.example.com" ,
"reason" : "consecutive_delivery_failures" ,
"consecutiveFailures" : 10 ,
"disabledAt" : "2026-08-12T02:15:00.000Z"
}
}
Webhooks — registration, signatures, retries
Polling and reconciliation — missed-delivery recovery
Creating orders — where entitlements are first delivered