In this section: Wallet
Wallet
The wallet itself: its cards, benefits, spending strategy, eligibility, and the tools that add or update a card.
add_card
Add one credit card, or a BATCH of them, to the member's wallet. Requires wallet-change access. Every argument's own description carries that argument's rules; this is what no single argument can say.
| Scope | Quota |
|---|---|
miles:write | standard |
| Name | Type | Required | Description |
|---|---|---|---|
card_name | string | The card to add, as the member names it; matched against the Miles catalog, and an ambiguous name is refused with close matches rather than guessed. Ignored when cards is present. | |
nickname | string | A short label of the member's own for this holding, for telling copies of the same product apart. | |
date_opened | string | The date the account was opened, YYYY-MM-DD. | |
anniversary_date | string | The date the annual fee posts, YYYY-MM-DD. Do not derive it from date_opened: for many issuers they differ, and every free-night and credit-cycle figure Miles computes reads this field. | |
sign_up_bonus | string | The member's own record of the sign-up bonus they were offered. Reads back as user_sign_up_bonus; a key spelled sign_up_bonus on a card you read is the catalog's current offer and must never be written back. | |
signup_bonus_status | string | Where the sign-up bonus stands: pending / in_progress / received / expired. Once it is received or expired, sub_deadline stops raising alerts. | |
signup_bonus_received_on | string | The date the sign-up bonus posted, YYYY-MM-DD. Several welcome-offer rules run a 15- to 48-month clock from this day. | |
bonus_accepted_on | string | The date the member accepted this bonus offer, YYYY-MM-DD. This, not the account-open, product-change, or bonus-posted date, anchors a retention/clawback window. | |
sub_deadline | string | The date the sign-up bonus spend window closes, YYYY-MM-DD. Set it only from what the member told you, never from the card's marketing terms. | |
sub_target | number | The spend the sign-up bonus requires, in dollars. Never the amount the member has spent so far: Miles holds no transactions and has no field for progress. | |
notes | string | The member's own free-text note on this holding. Reads back as user_notes; a key spelled notes on a card you read is the catalog's note about the product and must never be written back. | |
status | string | The holding's status: active (the default), closed or pending. A retired product is accepted only with closed. | |
closed_on | string | The date the card closed, YYYY-MM-DD; pass it with status="closed". Left out, a closed card is stored as closed on an unknown date, never as closed today. | |
autopay_status | string | on or off, whether the member has the issuer's autopay set up. Omit it when the member has not said: absent means nobody has checked, which Miles reports differently from off. | |
retention_offers | object[] | The history of what the issuer offered to keep the member, as a list of {date, offer, took_it}. REPLACES the stored list, so send the whole history every time; sending one entry deletes the rest. | |
card_settings | object | The member's per-card selections (a relationship tier, a chosen bonus category, an earning-modifier opt-in), keyed by the setting id from the card's card_settings_available. A key the card does not define is refused, and the refusal names the ids it does define. | |
benefit_selections | object | Which vendor the member picked for a credit that locks to one, keyed by the credit's id from the card's benefits (airline_fees, splurge). Each value is a list of {choices, period, selected_on, source}, one per benefit window. choices is a list even for a credit that takes one pick; period is the window the pick governs -- 2026 on a calendar-year credit, 2026-05 on a cardmember-year one -- and is optional, derived from selected_on, needed explicitly only when it differs from the window selected_on falls in. Replaces the stored map: send the whole history. | |
original_card_name | string | The product the card was first opened as, for a card that was product-changed before it reached Miles. | |
product_history | object[] | Product changes that happened before this card reached Miles, oldest first, each {from_card, to_card, changed_date, direction, note} with every field optional; changed_date is YYYY-MM-DD and direction is upgrade or downgrade. REPLACES the stored list. For a change happening now, use update_card with product_change=true. | |
cardholder | string | The household member this card belongs to, by name as it appears in Household Profiles; a name matching no member is refused rather than guessed. With two or more members it is required: ask whose card it is, and pass skip to leave it Unassigned. A supporter feature: without Household Profiles the card is still added under the primary cardholder and the result carries a note saying so. | |
holder_type | string | Whether the cardholder is the primary account holder (the default) or an authorized_user on the card. | |
card_number_last4 | string | The last four digits of the account number, exactly four, for telling two copies of the same product apart. Anything longer is refused rather than stored. | |
intentional_duplicate | boolean | Pass true only when the member genuinely holds a second copy of a card the wallet already has; otherwise adding it again is reported as already present, not duplicated. | |
entry_key | string | An idempotency key of your own choosing, at most 64 characters. Repeating the same key makes the add an exact no-op, so a retry after a lost response cannot double-add. Ignored when cards is present. | |
cards | object[] | Batch form: a list of up to 100 entries using the same fields as a single add, each with its own card_name. When present, the top-level card_name and entry_key are ignored, and the result reports each entry in order as applied, already_present, ambiguous or rejected; a failed entry never blocks the rest. |
analyze_keep_cancel
Keep/downgrade/cancel analysis for one card: marginal value vs annual fee, duplicate-benefit discounting, downgrade paths. Name it with wallet_id or card_name (wallet_id wins); a name matching two holdings the SAME person holds is refused ambiguous_holding: call again with one holdings[].wallet_id. Two household members each holding one copy is not refused -- you get the member's own, plus household_note. credit_value_basis is recorded (from the member's recorded use), typical, or mixed.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
card_name | string | Name of a card in the member's wallet, fuzzy-matched. | |
wallet_id | string | A cc_N id from get_wallet_cards (other results call it wallet_entry_id). Takes only the cc_N shape. | |
cardholder | string | A household member's name or id, for THAT person's copy of a card the household holds more than once. Omit it for the member's own, which is the default. A name matching no member is refused, not guessed. | |
basis | string | auto (default) values each credit from the member's recorded use once enough is on record; typical ignores what the member recorded and answers for a typical cardholder. Membership only: without it every credit is typical and periods_needed is null, so recording more periods will not change the answer. typical results carry what_if. |
analyze_spending
Earning-potential analysis for a spending profile: for each category, the wallet's best card and the annual rewards value it produces -- pre-computed dollar figures, not estimates to redo.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
spending | object | required | Monthly spend in dollars keyed by category (dining, groceries, gas, travel, hotels, airlines, rent, entertainment, streaming, online_shopping, ...). Use only figures the user stated; never estimate one. |
candidate_cards | string[] | Card names not in the wallet (e.g. from search_cards or get_wallet_complement) to evaluate on the same profile; omit for a wallet-only read. | |
international | boolean | When true, factor foreign transaction fees into the return. Default false. | |
redemption_basis | string | The member's own stated way of redeeming, for this conversation. Omit unless the member said how they redeem. |
clear_cap_status
Remove a cap mark an agent recorded -- the retraction half of set_cap_status. Requires reconciliation write access, like it.
| Scope | Quota |
|---|---|
miles:write:reconcile | standard |
| Name | Type | Required | Description |
|---|---|---|---|
card_name | string | Card in the wallet, e.g. Blue Cash Preferred. | |
wallet_entry_id | string | Wallet entry id (cc_3), instead of card_name. | |
category | string | Capped category, e.g. groceries; omit if one cap. | |
cap_key | string | Cap key from a result's caps, instead of category. | |
cardholder | string | Household member name or me, if several hold it. |
get_dated_events
Everything with a real date across the wallet, inside the next N days -- transfer bonuses, SUB deadlines, annual fees, certificates, tracked credits ending (amount = value left), points expiring. One call for "what's ending this month" or "am I on track for any welcome bonus".
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
days | integer | Days out to look, inclusive (default 30). | |
kinds | string[] | Optional: restrict to specific kinds. Omit for every kind. |
get_eligibility
Application-rule status (Chase 5/24, issuer velocity limits) based on the user's wallet card-open dates.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
issuer | string | Narrow to one issuer's application rules (e.g. "Chase", "Amex"). | |
card | string | A specific card name; adds card-specific checks (lifetime language, family restrictions, One Sapphire). | |
member | string | On a Household Profiles account, the household member whose status to report; omit for a per-member breakdown under members. A household member's name; a name matching no member is refused, not guessed. | |
recent_denial_reason | string | A recent card denial the person states, by reason; every issuer then reads may_be_restricted, never open. | |
hard_inquiries_6m | integer | Hard inquiries in the last 6 months, when stated; read by issuer inquiry limits. |
get_needs_attention
Everything that needs eyes on it right now -- in the wallet, and on the cards the user is only considering.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
credit_window_days | integer | How many days ahead to look for expiring tracked credits. Default 14. | |
fee_window_days | integer | How many days ahead to look for an annual fee posting. Default 30. | |
sub_window_days | integer | How many days ahead to look for a sign-up-bonus spend deadline. Default 30. |
get_spending_strategy
Category-by-category map of which wallet card to use for every spending type.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
international | boolean | Set to true when the spending happens OUTSIDE the United States: the user names a foreign city or country, says abroad/overseas, or is planning an international trip. Ranks every category by net return after foreign transaction fees and drops U.S.-only earning categories. Default false. | |
redemption_basis | string | The member's own stated way of redeeming, for this conversation. Omit unless the member said how they redeem. |
get_travel_day_summary
Wallet-derived checklist for travel-day lounges and perks, filtered by airline and international context; prefer it over flat get_wallet_benefits for a travel day. Optionally provide both adjacent flight segments to assess a same-airport connection. Segment data is used for this answer only.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
airline | string | The carrier for this trip, to keep only benefits that apply on that airline. | |
international | boolean | Whether this is an international itinerary, to keep only benefits that apply to it. | |
arrival_segment | object | First leg: arrival_airport and arrival_time. Local times need IANA arrival_timezone; optional arrival_terminal, carrier, cabin. | |
departure_segment | object | Next leg: departure_airport and departure_time. Local times need IANA departure_timezone; optional departure_terminal, carrier, cabin. |
get_wallet_benefits
filtered_by_cardholder echoes member. All credits: benefit_type='credits'; named: mode='index' then credit_ids; filter doesn't resolve names.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
card_name | string | One card; omitted_card_names re-scopes. | |
benefit_type | string | Omit for all; categories: credits, lounge, status, hotel_status, airline_status, rental_car_status, other_status, protection, free_nights, certificates, other. | |
cardholder | string | Member name; omit for all. Unknowns are refused. | |
mode | string | Full or compact index. | |
credit_ids | string[] | Exact IDs; override benefit_type; []=none. |
get_wallet_card
ONE card the member holds, with their own entered layer on it -- nickname, notes, date_opened, anniversary_date, card_settings, benefit_selections, retention_offers, product_history, the sign-up-bonus fields, and updated_at.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
wallet_id | string | A cc_N wallet entry id from get_wallet_cards. Wins if both selectors arrive; takes only the cc_N shape, so a product name here is refused. | |
card_name | string | The member's own holding by name or nickname, not the catalog. Two household members each holding one copy answers about the member's own; ONE member holding two is refused ambiguous_holding: call again with one holdings[].wallet_id as wallet_id. | |
cardholder | string | A household member's name or id, for THAT person's copy of a card the household holds more than once. Omit it for the member's own. A name matching no member is refused, not guessed. |
get_wallet_cards
The wallet's cards, one per row -- the lean per-card reader. get_wallet_summary / get_wallet_benefits are whole-wallet; use this for "what X cards do I have" or a per-card field scan.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
issuer | string | Narrow to one issuer (e.g. "Chase", "Amex"). A filter matching nothing in a non-empty wallet is dropped, and the payload names it. | |
rewards_category | string | Narrow to one rewards category: transferable, cashback, hotel, airline, store or other; any narrows nothing. A filter matching nothing in a non-empty wallet is dropped, and the payload names it. | |
format | string | "summary" (default, about 15 fields per card), "with_multipliers" (summary plus a reward_multipliers array), or "full" (every field, including benefits and protections text; large for a big wallet). | |
include_closed | boolean | When true, append the member's closed holdings after the active ones, each with closed_on (YYYY-MM-DD, or null). Closed cards are hidden otherwise. | |
cardholder | string | On a Household Profiles account, one household member's name to return only their holdings; omit for the whole household. A name matching no member is refused, not answered household-wide. |
get_wallet_summary
The user's wallet: cards with fees, credits, and key benefits.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
cardholder | string | On a Household Profiles account, narrow every total to one household member's holdings; omit for the whole household. A name matching no member is refused rather than answered household-wide. |
get_weekly_update
What changed in points and miles recently -- the digest as pull: a scheduled agent can poll this instead of waiting on the email digest. Local reads only (indexed article dates, a changelog artifact, in-memory dataset) -- no paid vendor, no query embedding, no Miles token spend.
| Scope | Quota |
|---|---|
miles:read | standard |
| Name | Type | Required | Description |
|---|---|---|---|
days | integer | Look-back window in days, clamped to 1-90. Default 7. | |
categories | string[] | Subset of "news", "card_changes", "transfer_bonuses" and "offers" as a list, not one comma-joined string; omit for all four. |
remove_card
Remove a card from the user's wallet. Requires wallet-change access.
| Scope | Quota |
|---|---|
miles:write | standard |
| Name | Type | Required | Description |
|---|---|---|---|
lookup_card_name | string | The holding to remove, by card name or nickname, e.g. Amex Gold. A name matching more than one holding is refused; pass card_id instead. | |
card_id | string | The holding's cc_N id from get_wallet_cards; use it instead of lookup_card_name when the wallet holds two of the same card. | |
lookup_cardholder | string | Whose copy lookup_card_name means (a household member's name, e.g. Andy) when the household holds the card more than once. Identifies only; never changes the holder. |
set_cap_status
Record that a card's bonus spending cap is used up for the current period, so get_best_card ranks the card at its after-cap rate until the cap resets (returns_on). Requires reconciliation write access.
| Scope | Quota |
|---|---|
miles:write:reconcile | standard |
| Name | Type | Required | Description |
|---|---|---|---|
card_name | string | Card in the wallet, e.g. Blue Cash Preferred. | |
wallet_entry_id | string | Wallet entry id (cc_3), instead of card_name. | |
category | string | Capped category, e.g. groceries; omit if one cap. | |
cap_key | string | Cap key from a result's caps, instead of category. | |
cardholder | string | Household member name or me, if several hold it. | |
hit_on | string | When it was hit: YYYY-MM-DD or YYYY-MM. | |
hit_before_close | boolean | Answer to a confirm_close, as its fix says. | |
statement_closes_on | string | Day the statement ending the period closes (YYYY-MM-DD, or 20); the bonus is back the day after. | |
resets_on | string | First day the bonus earns again (YYYY-MM-DD), if known. |
update_card
Update a holding in the member's wallet -- nickname, status, notes, dates, the member's decision about it, or a product change. Requires wallet-change access. Every argument's own description carries that argument's rules; this is what no single argument can say.
| Scope | Quota |
|---|---|
miles:write | standard |
| Name | Type | Required | Description |
|---|---|---|---|
lookup_card_name | string | The holding to update, by card name or nickname, e.g. Amex Gold. A name matching more than one holding is refused; pass card_id instead. | |
card_id | string | The holding's id from get_wallet_cards; use it instead of lookup_card_name when the wallet holds two of the same card. | |
lookup_cardholder | string | Whose copy lookup_card_name means (a household member's name, e.g. Andy) when the household holds the card more than once. Identifies only; never changes the holder. | |
nickname | string | A short label of the member's own for this holding, for telling copies of the same product apart. | |
date_opened | string | The date the account was opened, YYYY-MM-DD. | |
anniversary_date | string | The date the annual fee posts, YYYY-MM-DD. Do not derive it from date_opened: for many issuers they differ, and every free-night and credit-cycle figure Miles computes reads this field. | |
sign_up_bonus | string | The member's own record of the sign-up bonus they were offered. Reads back as user_sign_up_bonus; a key spelled sign_up_bonus on a card you read is the catalog's current offer and must never be written back. It can accompany a product change to record a new upgrade offer. | |
signup_bonus_status | string | Where the sign-up bonus stands: pending / in_progress / received / expired. Set received when the bonus posts: that is what stops the sub_deadline alerts. | |
signup_bonus_received_on | string | The date the sign-up bonus posted, YYYY-MM-DD, sent with signup_bonus_status="received". Several welcome-offer rules run a 15- to 48-month clock from this day. On an ordinary update, a newly received status without this date stamps today; on a product change recording a new offer, omit it when unknown and Miles clears the old offer's date instead. | |
bonus_accepted_on | string | The date the member accepted this bonus offer, YYYY-MM-DD. Retention/clawback windows use this member-stated date, never an account-open, product-change, or bonus-posted date. When a product change keeps or newly records a bonus and it is not already stored, ask the member for this date before recording it. A newly supplied offer needs it in the same call; never reuse a stored prior-offer date. | |
sub_deadline | string | The date the sign-up bonus spend window closes, YYYY-MM-DD. Set it only from what the member told you, never from the card's marketing terms. | |
sub_target | number | The spend the sign-up bonus requires, in dollars. Never the amount the member has spent so far: Miles holds no transactions and has no field for progress. | |
notes | string | The member's own free-text note on this holding. Reads back as user_notes; a key spelled notes on a card you read is the catalog's note about the product and must never be written back. | |
status | string | The holding's status: active, closed or pending. closed alone stamps today as closed_on; add closed_on when the member says when it actually closed. | |
closed_on | string | The date the card closed, YYYY-MM-DD. Pass it with status="closed", or by itself to correct the date on a card already closed. | |
autopay_status | string | on or off, whether the member has the issuer's autopay set up. Omit it when the member has not said: absent means nobody has checked, which Miles reports differently from off. | |
disposition | string | What the MEMBER decided to do with this holding: keep / cancel / downgrade / upgrade / undecided. Set it only when the member states a decision in their own words, never by copying analyze_keep_cancel's recommendation. Omit it when nobody has decided; take it back to that state with clear_fields. | |
review_by | string | A date, YYYY-MM-DD, when the member wants to be reminded to revisit this holding's disposition. | |
fee_posts_on | string | The exact day the annual fee posts, YYYY-MM-DD: a fee that already posted (a past date) or one expected. Beats anniversary_date for an observed posting. | |
retention_offers | object[] | The history of what the issuer offered to keep the member, as a list of {date, offer, took_it}. REPLACES the stored list, so send the whole history every time; sending one entry deletes the rest. | |
card_settings | object | The member's per-card selections, keyed by the setting id from the card's card_settings_available. MERGES with what is stored, so send only what changed; null as a value clears one setting. A key the card does not define is refused. | |
benefit_selections | object | Which vendor the member picked for a credit that locks to one, keyed by the credit's id from the card's benefits (airline_fees, splurge). Each value is a list of {choices, period, selected_on, source}, one per benefit window. choices is a list even for a credit that takes one pick; period is the window the pick governs -- 2026 on a calendar-year credit, 2026-05 on a cardmember-year one -- and is optional, derived from selected_on, needed explicitly only when it differs from the window selected_on falls in. Replaces the stored map: send the whole history. | |
original_card_name | string | The product the card was first opened as. Correctable here to fix history; a change happening now goes through product_change instead. | |
product_history | object[] | The full list of past product changes, oldest first, each {from_card, to_card, changed_date, direction, note}. REPLACES the stored list, which is how a wrong or missing changed_date on a recorded change is corrected. To record a new change, use product_change=true instead. | |
cardholder | string | The household member this card belongs to, by name as it appears in Household Profiles; "" unassigns. A supporter feature: an ungated member's update still applies, minus the attribution, and says so in a note. | |
holder_type | string | Whether the cardholder is the primary account holder (the default) or an authorized_user on the card. | |
card_number_last4 | string | The last four digits of the account number, exactly four; set, correct or clear it here. Anything longer is refused rather than stored. | |
product_change | boolean | true records a product change happening now: the holding is renamed to new_card_name and a row is appended to product_history. Cannot be combined with clear_fields; make that two calls. | |
new_card_name | string | The product the card was changed to. Required with product_change=true. | |
changed_date | string | The date the product change happened, YYYY-MM-DD, with product_change=true. Omit it when unknown; Miles records unknown rather than stamping today. This is not the bonus acceptance date. | |
direction | string | upgrade or downgrade, with product_change=true. Inferred from the card family when omitted. | |
product_change_note | string | Why the product change was made, recorded with product_change=true. | |
new_anniversary_date | string | The new annual-fee date, YYYY-MM-DD, when the issuer reset it as part of a product change. | |
keep_bonus | boolean | Whether a product_change=true keeps the recorded or newly supplied sign-up bonus. Defaults to true on an upgrade -- an upgrade offer's bonus belongs to the new product -- or when this call supplies a new bonus; it is false otherwise. A kept bonus needs member-stated bonus_accepted_on. | |
expected_updated_at | string | The card's stored updated_at as you last read it, copied back character for character, microseconds included. If the card has changed since, nothing is written and the result is stale_precondition: re-read and retry. Omit it and the last writer wins. | |
clear_fields | string[] | Names of fields to reset to empty, e.g. ["nickname", "notes"], since a null argument is dropped and changes nothing. A field that cannot be cleared, or one named here while also given a value, is refused and nothing is written. Cannot ride along with product_change=true. |