List purchase intents
GET /v2/api-gateway/purchase-intents
Your organization's purchase intents, newest first. Paginated with current_ / per_ (default 10, maximum 100). Filter by card_ or by status — for example everything still AWAITING_. status is matched against the effective status, so AWAITING_ and APPROVED never return a row that is already past its expires_, and EXPIRED returns every row that is — whether or not anything had written that down yet.
Request
Authentication: your API key in the x-api-key header.
Query parameters
| Field | Type | Description |
|---|---|---|
card_ | string, uuid | Only intents for this card. |
status | string | Only intents in this status.One of: AWAITING_APPROVAL, APPROVED, CONSUMED, DENIED, EXPIRED, CANCELLED |
recurring | boolean | true for standing approvals only, false for one-off ones only. A standing approval that is still in force reads CONSUMED, because the first charge spent it and it goes on authorizing the same purchase. |
current_ | integer | Page number, starting at 1. Default 1. Maximum 10000 — past that, narrow with card_ or status rather than paging deeper. |
per_ | integer | Intents per page. Minimum 1, maximum 100. Default 10. A larger value is rejected with a 400 — it is not silently reduced. |
Example request
cURL
curl --request GET \
--url 'https://api.themooncard.com/v2/api-gateway/purchase-intents' \
--header 'x-api-key: YOUR_API_KEY'Responses
200 Success
| Field | Type | Description |
|---|---|---|
purchase_ required | array of object | |
purchase_ required | string | Purchase intent id. |
purchase_ required | string | The ask-first card this approval is for. |
purchase_ required | string, nullable | The cardholder who was asked, or null when the card has no cardholder. |
purchase_ required | string | Who was asked to approve. cardholder when the card has one — the approval is that person’s and is never forwarded to the organization. account when the card has no cardholder, in which case the request goes to the email address of the account that owns the card, and when the card is on the organization’s own cardholder (the one a card issued without naming a cardholder lands on), which is the account holder. Always one of the two.One of: cardholder, account |
purchase_ required | string | AWAITING_ until the cardholder answers; APPROVED once they have and until an authorization spends it; CONSUMED afterwards. DENIED, EXPIRED and CANCELLED are terminal and mean nothing will be charged. Expiry is evaluated when the intent is read, so a row past expires_ reports EXPIRED here whether or not anything had written it down yet.One of: AWAITING_APPROVAL, APPROVED, CONSUMED, DENIED, EXPIRED, CANCELLED |
purchase_ required | string | single — one merchant, one amount inside the symmetric tolerance band, and exactly one authorization, spendable for 15 minutes once approved. order — a budget: up to max_ in total at that merchant, over any number of authorizations, for valid_ days from the moment it was approved. An approval created before this field existed reads single, which is what it was.One of: single, order |
purchase_ required | object | The merchant the approval covers. |
purchase_ required | string, nullable | Merchant name, or null when only an MCC was given. |
purchase_ required | string, nullable | Merchant category code, or null when only a name was given. |
purchase_ required | array of string | EVERY merchant name this approval matches: merchant.name first, then the other spellings the request gave and the ones Moon expanded from a brand it recognises. Any of them matching the acquirer descriptor is enough, and the approver was shown the whole list before deciding. Empty when the approval named only an MCC. |
purchase_ required | string, nullable | The site the purchase is being made on, as a bare hostname, or null when the request did not name one. Advisory: a card network carries no domain, so the authorization gate neither checks this nor could. It is what the approver was shown next to the merchant and where the agent was told to use the credential. |
purchase_ required | number | The approved amount, in the card's own currency, in major units. |
purchase_ required | string | ISO code of the card's ledger account currency. |
purchase_ required | number, nullable | The price as the merchant stated it, in merchant_, when the request gave it that way (merchant_ + merchant_). amount is then Moon's conversion of it into the card's currency, which is what the authorization is compared with. Null when the request gave amount. |
purchase_ required | string, nullable | The merchant currency (uppercase ISO 4217) of merchant_, or null. |
purchase_ required | number, nullable | The rate (merchant_ to the card's currency) amount was converted with when the request was made: a market rate with no spread. The network converts the real charge at its own rate, which the tolerance absorbs. Null when the request gave amount. |
purchase_ required | object | How far an authorization may sit from amount and still match. The wider of the two applies, symmetrically in both directions. |
purchase_ required | number, nullable | Percentage slack on amount, or null when none applies. |
purchase_ required | number, nullable | Slack in the card's own currency, in major units like amount, or null when none applies. |
purchase_ required | string | The sentence the cardholder read before deciding. |
purchase_ required | boolean | A standing approval. Once the first authorization spends it, any later authorization from the same merchant for the same amount (within the same tolerance) is let through without a new request — with no expiry, until it is cancelled. Such an approval reads CONSUMED while it is still in force, because the first charge spent it; DELETE /purchase-intents/{id} is what ends it. |
purchase_ required | number, nullable | How much this merchant may charge per UTC calendar month, in the card's own currency. Null on a one-off approval. This is what bounds a standing approval: the per-charge tolerance decides the first charge only. |
purchase_ required | number | Taken from the current calendar month's budget so far. 0 before the first charge, and 0 again on the first read of a new month. |
purchase_ required | string, nullable | First day of the month recurring_ is counting, as YYYY-MM-DD. Null until the first charge. |
purchase_ required | string, nullable | The merchant category the standing approval was first used at, pinned at that first charge. A later authorization carrying a different category is refused. Null when the network sent none, in which case nothing is pinned. |
purchase_ required | number, nullable | How many days the approval stays spendable once it has been approved — an order's window, or a recurring approval's grace before its first charge. Null on a plain single approval, which may be spent for 15 minutes once approved. answer_ (60 by default) always bounds ANSWERING the request; this is how long the answer is worth anything, and expires_ is rewritten to it on approval. |
purchase_ required | number, nullable | An order's budget: amount plus the tolerance band, in the card's own currency. Every authorization at that merchant is accepted while the running total stays inside it, with no lower bound per charge — which is what lets a split shipment or a small verification authorization through. Null on anything that is not an order. |
purchase_ required | number, nullable | How much of that budget has been taken. Null on anything that is not an order. Refunds and reversals do not give budget back. |
purchase_ required | number, nullable | max_ minus spent, floored at zero. Null on anything that is not an order. An order that reaches its total closes itself and reads CONSUMED; unlike a standing recurring approval, it then authorizes nothing further. |
purchase_ required | string | After this instant the approval is worthless and an authorization on the card is declined with INTENT_ again. Until the approver answers it is the deadline to ANSWER (answer_ after the request, 60 by default). On approval it is rewritten to how long the approval may be SPENT: valid_ days out for an order and a recurring approval, 15 minutes out for a single one (see spendable_until). ISO-8601 UTC with milliseconds, e.g. "2026-09-16T17:05:00.000Z". |
purchase_ required | string, nullable | Until when an APPROVED approval may be spent: the same instant as expires_ once the intent has been approved, and null before that — while it is awaiting an answer expires_ is the deadline to ANSWER, not to spend. Null on a recurring approval too, which has no spend deadline once it is in force. ISO-8601 UTC with milliseconds, e.g. "2026-09-16T17:05:00.000Z". |
purchase_ required | string | When the request was made. ISO-8601 UTC with milliseconds, e.g. "2026-09-16T17:05:00.000Z". |
purchase_ required | string, nullable | When the cardholder approved it, or null. ISO-8601 UTC with milliseconds, e.g. "2026-09-16T17:05:00.000Z". |
purchase_ required | string, nullable | When it was approved, denied or cancelled, or null. ISO-8601 UTC with milliseconds, e.g. "2026-09-16T17:05:00.000Z". |
purchase_ required | string, nullable | How the person answered: email (the one-time link or the page it opens), mcp (an agent connection recorded the answer the person gave it) or web (the account owner answered in the Moon app, signed in). Null until answered. Treat this as an open set: branch on the values you know and fall through on the rest. |
purchase_ required | string, nullable | Reserved for a feature that is not generally available yet. Always null today; ignore it. |
purchase_ required | string, nullable | The authorization that spent this approval, or null. |
purchase_ required | string, nullable | The key_ of the agent key that signed the request — the RFC 7638 JWK thumbprint register_ returned. Null when the request was not signed, which is allowed. |
purchase_ required | string, nullable | That key’s current label. Read from the key on every request, so renaming a key renames it on intents that already exist. |
purchase_ required | array of string | Reserved for a feature that is not generally available yet. Always null today; ignore it. |
purchase_ required | object, nullable | Reserved for a feature that is not generally available yet. Always null today; ignore it. |
purchase_ required | integer, nullable | Reserved for a feature that is not generally available yet. Always null today; ignore it. |
pagination required | object | |
pagination. required | integer | Total number of items across all pages. |
pagination. required | integer | Number of the last page (0 when there are no items). |
pagination. required | integer, nullable | Previous page number, or null on the first page. |
pagination. required | integer, nullable | Next page number, or null on the last page. |
pagination. required | integer | Page size that was applied. |
pagination. required | integer | 1-based current page. |
pagination. required | integer | 1-based index of the first item on this page (0 when empty). |
pagination. required | integer | 1-based index of the last item on this page (0 when empty). |
400 Error
Validation failed (errors[] lists each offending field) or a domain rule rejected the request ({ message, code }).
The body is the standard error object: see Errors.
401 Error
Missing or invalid credentials, e.g. { "message": "Invalid API Key", "code": "UNAUTHORIZED" }.
The body is the standard error object: see Errors.
500 Error
Unexpected server error. Body is { message: "Internal server error", code: "INTERNAL_.
The body is the standard error object: see Errors.
Last updated September 25, 2026