Every Apple refund request now comes with a reason, and consumptionRequestReason is how you read it
Since WWDC24, every Apple CONSUMPTION_REQUEST carries a consumptionRequestReason, the customer's own stated reason for wanting a refund. There are five values, from UNINTENDED_PURCHASE to LEGAL, and each one should change what you send back inside your 12-hour window. Here is how to read every one.

Key takeaways
- Since App Store Server Notifications version 2.11, announced at WWDC24, every CONSUMPTION_REQUEST notification includes consumptionRequestReason, a string that states why the customer asked for the refund.
- There are exactly five values: UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL, and OTHER. Apple sends one per request.
- The reason does not decide the refund. It is context you use to choose your refundPreference and your consumption data before the 12-hour window closes.
- CONSUMPTION_REQUEST now fires for auto-renewable subscriptions too, not only consumables, so consumptionRequestReason reaches far more of your refunds than it did before WWDC24.
- A FULFILLMENT_ISSUE reason is a signal your own delivery may have failed. Contesting it burns the window and invites a chargeback later. Granting it is usually the cheaper answer.
- You reply by calling Send Consumption Information within 12 hours with customerConsented set to true and a refundPreference of GRANT_FULL, GRANT_PRORATED, or DECLINE. Apple treats your preference as one input, not a command.
- A refund still costs you the compute, API calls, storage, and payouts the purchase already consumed. The reason field is how you spend your defense only on the cases worth defending.
Apple changed how refund requests land on your server, and a lot of developers never noticed. Since the App Store Server Notifications 2.11 update announced at WWDC24, every CONSUMPTION_REQUEST notification carries a field called consumptionRequestReason. It is the customer's own stated reason for asking for their money back. One plain string, five possible values, delivered inside the same payload you already have twelve hours to answer.
The Apple refund request reason does not decide anything by itself. What it does is tell you which of five very different situations you are in, so you stop sending the same generic consumption data to a refund you should grant and a refund you should fight. Here is what the field is, the exact values Apple can send, what each one signals, and how it should change the preference and evidence you return.
What consumptionRequestReason actually is
consumptionRequestReason is a string field in the data object of a CONSUMPTION_REQUEST notification. Apple added it in App Store Server Notifications version 2.11, alongside the WWDC24 changes to the refund flow. Before that, the request arrived with the signed transaction and nothing about motive. You answered blind. Now the customer's stated reason travels with the request.
Read the word stated carefully. This is the reason the customer selected when they filed with Apple, not a fact Apple verified. UNINTENDED_PURCHASE does not prove the purchase went unused, and UNSATISFIED_WITH_PURCHASE does not prove the product was broken. The value is a lens, not a verdict. You still pair it with your own delivery and usage records.
It rides in the notification you already handle
CONSUMPTION_REQUEST is the one Apple flow that asks the developer for evidence at all. Its Google Play counterpart is the chargeback review through orders.reviewrefund. When one arrives, you have 12 hours to answer by calling Send Consumption Information, a PUT to the transactions consumption endpoint. consumptionRequestReason is now part of that same notification, so there is nothing new to subscribe to. If you already parse CONSUMPTION_REQUEST, the reason is one field you were probably ignoring.
The five reasons, and what each one is telling you
Apple documents exactly five values. One arrives per request. Here is the full set and how to read each in practice.
| Value | What the customer stated | What it usually means for you |
|---|---|---|
| UNINTENDED_PURCHASE | They did not mean to buy it | Often an accidental or family tap. Check delivery and consumption before you decide. |
| FULFILLMENT_ISSUE | They could not receive or use it | Points back at your own delivery. Verify your logs before you contest. |
| UNSATISFIED_WITH_PURCHASE | They were not happy with it | Buyer's remorse. Your consumption evidence carries the most weight here. |
| LEGAL | They cited a legal reason | Treat it as a grant. Contesting a legal request is not worth the window. |
| OTHER | Any reason not listed above | No signal on its own. Fall back to your delivery and usage data. |
UNINTENDED_PURCHASE is the accidental-tap bucket
This is the reason a parent selects after a child bought 10,000 coins, or an adult who fat-fingered a confirm. It correlates with purchases that were never opened or used. That is exactly why your own data matters. If your records show the consumable was fully delivered and heavily consumed, an unintended-purchase claim and a fully-spent balance do not agree, and that gap is worth reporting through consumptionPercentage.
FULFILLMENT_ISSUE points back at you
FULFILLMENT_ISSUE is the one reason that is partly about your app, not the customer. It means they say they could not receive or use what they paid for. Before you reflexively contest, pull your delivery logs. If your own server shows the entitlement never activated, or the credits never posted, the customer is right, and DECLINE is the wrong preference. Fighting a real fulfillment failure wastes the window and can push the customer to their bank, where a chargeback costs more than the refund would have.
UNSATISFIED_WITH_PURCHASE is where evidence decides
This is ordinary buyer's remorse, and it is the reason where your consumption data does the most work. The product worked. The customer used some or all of it and now wants the money back. A high consumptionPercentage, honest deliveryStatus of DELIVERED, and a refundPreference of DECLINE or GRANT_PRORATED is the case Apple is asking you to make. Send the numbers, not an argument.
LEGAL and OTHER
LEGAL means the customer invoked a legal or regulatory right. Reasonable people disagree, but as a rule this is not the window to litigate. Grant it and move on. OTHER is the catch-all Apple uses when the stated reason maps to none of the four above. It carries no signal by itself, so treat an OTHER exactly as you would a request with no reason at all: lead with your delivery status and usage evidence.

How the reason changes your answer, field by field
You reply to a CONSUMPTION_REQUEST by calling Send Consumption Information with a ConsumptionRequest body. The reason should shape three fields in that body.
customerConsented has to be true
Apple only accepts the submission when customerConsented is true, meaning the customer agreed to share consumption data. If you do not have that consent, you cannot send data at all, regardless of the reason. No consent, no evidence, and the request is decided without your numbers.
deliveryStatus and consumptionPercentage carry the facts
deliveryStatus says whether you delivered a working purchase. If it is anything other than DELIVERED, Apple requires consumptionPercentage to be 0. When you did deliver, consumptionPercentage is an integer in milliunits from 0 to 100,000, where 100,000 means the customer used the entire purchase. This pair is your factual core, and it is what should carry a FULFILLMENT_ISSUE or an UNSATISFIED_WITH_PURCHASE case, not the reason itself.
refundPreference is your one lever
refundPreference is where you state what you want. Apple documents three values: GRANT_FULL, GRANT_PRORATED, and DECLINE. Read the reason, weigh it against your data, then pick. FULFILLMENT_ISSUE with a failed delivery in your logs leans GRANT_FULL. UNSATISFIED_WITH_PURCHASE on a fully consumed product leans DECLINE or GRANT_PRORATED. LEGAL leans GRANT_FULL.
What a refund actually costs you
The reason field matters because a refund is rarely just the sale coming off your ledger. For a consumable that already ran, you paid to fulfill it. A credit pack that called a paid inference API, a batch of generated images that burned GPU time, a stored export that sits on your storage bill, a creator payout you already sent: those costs stay spent when the purchase is reversed. The store returns the customer's money. It does not return your compute.
That is why the reason is worth reading. Say a customer bought 5,000 credits that each trigger a paid API call, spent 4,000 of them, then filed under UNSATISFIED_WITH_PURCHASE. Your deliveryStatus is DELIVERED, your consumptionPercentage is 80,000 milliunits, and a DECLINE or GRANT_PRORATED preference is the difference between eating the API bill and recovering most of it. Now flip the reason to FULFILLMENT_ISSUE with logs showing the credits never posted, and the honest, cheaper move is GRANT_FULL before the customer escalates to their bank.
Reading the reason without overreacting
The trap is treating the reason as proof. UNINTENDED_PURCHASE is not a confession that the product was unused, and LEGAL is not always a genuine legal claim. The reason narrows the situation. Your delivery logs and consumption records resolve it. When they agree with the customer, grant early and cheaply. When they contradict the customer, that contradiction, expressed as deliveryStatus and consumptionPercentage, is the strongest thing you can send. RefundHalt reads consumptionRequestReason on every CONSUMPTION_REQUEST and pairs it with your real usage data automatically, so each reason gets the response it deserves inside the 12-hour window.
The change is small and easy to miss, but it moved the refund conversation in your favor. Apple is now telling you why, before you answer. Use it.
Frequently asked questions
- What is consumptionRequestReason?
- consumptionRequestReason is a string field Apple includes in every CONSUMPTION_REQUEST notification, added in App Store Server Notifications version 2.11 at WWDC24. It states the customer's own reason for requesting the refund, giving you context before you respond with consumption data inside the 12-hour window.
- What are the possible values of consumptionRequestReason?
- There are five: UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL, and OTHER. Apple sends exactly one per refund request. Each points at a different situation, from an accidental tap to a stated legal reason, and each should shape the refundPreference and consumption data you send back.
- Does the refund reason decide whether I keep the money?
- No. consumptionRequestReason is context, not a verdict. Apple still decides the refund, weighing your refundPreference, your deliveryStatus and consumptionPercentage, and the customer's history. The reason tells you which case to make. Your delivery and usage data is what makes it.
- How long do I have to respond to a CONSUMPTION_REQUEST?
- You have 12 hours from receiving the CONSUMPTION_REQUEST notification to call Send Consumption Information. The call must set customerConsented to true, or Apple rejects it. Miss the window and the refund is decided without any of your data.
- Does consumptionRequestReason appear for subscription refunds?
- Yes. The same WWDC24 update that added consumptionRequestReason also started sending CONSUMPTION_REQUEST for auto-renewable subscriptions, not only consumables. For most apps that means the reason field now reaches the refunds that matter most financially.
Sources and further reading
RefundHalt
The refund autopilot for the App Store and Google Play
Keep reading
Google Play's chargeback review gives you 24 hours to fight back, here's what to send
When a bank pulls a Google Play charge back, Google sends your server a PendingRefundReviewNotification and starts a 24-hour clock. Answer it through the ReviewRefund API with a refund preference and real consumption evidence, or the dispute is decided without you. Here is the whole flow, field by field.
Attach an appAccountToken to every App Store purchase, or you cannot defend the refund
Apple sends your server a CONSUMPTION_REQUEST when a customer asks for a refund, but the transaction never says who they are. appAccountToken is the UUID that links a purchase back to your user. Set it and you can answer Apple with real data. Skip it and you are guessing.