Troubleshoot a live offer
Diagnose OfferKit code rejections, unexpected discounts, missing loyalty or referral rewards, gift-card balances, and webhook delivery failures.
Start with the exact runtime outcome. Avoid changing campaign configuration until you can reproduce the customer’s identity, cart, currency, code, and time context.
A code does not work
- Look up the voucher by its exact code.
- Confirm the voucher is enabled and the parent campaign is active.
- Compare campaign and voucher activation windows with the configured timezone.
- Check total and per-user redemption limits.
- Check customer assignment and whether the request identified that customer.
- Confirm order currency and required cart fields.
- Re-run validation and inspect every explanation.
Common explanations:
| Code | What to inspect |
|---|---|
voucher_not_found | Typo, wrong environment, or deleted code |
campaign_inactive | Campaign status, missing parent, or campaign activation window |
voucher_disabled | Voucher active setting |
voucher_expired | Voucher start and end timestamps |
redemption_limit_reached | Voucher usage counter and total limit |
per_user_redemption_limit_reached | Customer identity and prior activity |
customer_required | Missing customer context for the policy |
customer_mismatch | Voucher assigned to another customer |
currency_mismatch | Campaign currency versus order currency |
validation_failed | Attached rule and supplied context |
The discount amount is wrong
- Confirm amounts were sent in minor units.
- Confirm percentage values use basis points.
- Check
maxDiscountAmounton percentage vouchers. - Check product and collection IDs on every cart item.
- Compare the amount basis: subtotal, tax, shipping, and prior discounts.
- Inspect priority, exclusivity, and the returned calculation breakdown.
- Confirm the cart was rechecked at commit rather than using an old preview.
An automatic promotion is missing
Call qualification with includeSkipped: true. Inspect campaign status and dates, tier
status and dates, currency, campaign rule, tier rule, priority, and exclusivity. A
rule_error indicates invalid or unavailable rule evaluation; a rule_failed outcome
means the supplied context did not pass a valid rule.
Remember that a promotion campaign must have auto-apply enabled to participate.
A gift-card balance looks wrong
Fetch the current voucher and its transaction ledger. Reconcile every credit, redemption, rollback, and adjustment entry. Check for two application orders using different idempotency keys for the same intended purchase.
Do not repair the balance by editing a cached number in your application. There is no public ledger-preserving gift adjustment or voucher rollback endpoint. Use a tracked support compensation workflow; see Retries, refunds, and recovery.
Loyalty points are missing or duplicated
- Confirm the customer is enrolled in the correct program.
- Find the source event in your application and the member transaction ledger.
- Confirm the application actually called
members.earn. - Compare
basePoints,applyMultiplier, current tier, and expiration timestamp. - Deduplicate the source event in your handler;
eventIdis for correlation and should also be part of your application-side uniqueness strategy. - Check the worker and expiration entries if points disappeared after their expiry date.
A referral reward is missing
Find the conversion using its referral code and application conversionEventId. Confirm
the conversion succeeded and inspect both outcome objects. For loyalty-point rewards,
verify the recipient was already enrolled. For voucher outcomes, look up the issued code.
If the conversion exists but messaging failed, replay only the delivery workflow—do not call conversion again with a new event ID.
A webhook is failing
Open the webhook and inspect its latest deliveries:
401usually indicates the wrong secret, re-serialized body, or signature parsing;404indicates a stale endpoint path;429means the receiver needs capacity or queueing;5xxmeans the receiver failed after delivery;- transport errors indicate DNS, TLS, routing, or connection problems.
Fix the receiver, then replay the delivery. The handler must deduplicate by OfferKit event ID because replay delivers the same event again.
A retry produced a conflict
The HTTP Idempotency-Key header identifies one logical request body for 24 hours.
Reusing it for a different body returns a conflict. Body idempotencyKey fields and
referral event IDs replay stored outcomes under different scopes; they do not all compare
request bodies. Keep the original input and follow Retries and
recovery.
Escalation evidence
Capture:
- deployment version and environment;
- timestamp and timezone;
- API route or SDK method;
- customer external ID and OfferKit ID;
- order external ID and OfferKit ID;
- campaign, voucher, tier, program, or reward IDs;
- idempotency key or source event ID;
- response reason codes and explanations;
- relevant event, delivery, and audit-log IDs.
Remove API keys, webhook secrets, passwords, and unnecessary personal data before sharing diagnostic material.
Find a complete reason-code list
The API conventions list voucher decision
reasons and promotion-specific differences. A successful HTTP request can still return
valid: false or ok: false; check the business result before recording success.
Launch and operate OfferKit
Prepare OfferKit offers for launch, test checkout and reward delivery, monitor live decisions, and handle support incidents throughout each campaign.
Migrate existing referrals
Migrate existing referral codes and conversion history into OfferKit, verify customer mappings, and keep historical rewards from being issued again.