Skip to main content
Every movement of money on a Fluz account produces a transaction record: gift card purchases, virtual card authorizations, deposits, withdrawals, internal transfers, wallet-to-wallet sends, bill payments, and cashback. One feed, one shape, one query. Records are account-level. There is no user-level filtering — a query returns everything on the account your token is scoped to.

Which query do I want?

Declines are not a transaction status. status is only ever PENDING or SETTLED — a declined authorization never becomes a settled transaction, so it won’t appear in getTransactions at all. If you’re debugging “the charge didn’t go through,” that’s getDeclinedTransactions and Decline Codes, not this feed.

Field naming is mixed, and you have to match it exactly.Most fields on the Transaction type are snake_case — record_id, transaction_type, created_at, cash_balance_available_balance. But newer additions are camelCase — memo, transactionCategory, attachmentUrl, connectedAppId, connectedAppName, expectedClearedDate.Everything around the record is camelCase: the filter input (createdGte, amountGte, virtualCardProgram) and the connection fields (totalCount, hasNextPage).Introspect the schema before writing queries rather than assuming a convention. → How the GraphQL API works

What’s in a record

Around fifty fields, in six groups. Request only what you need — the response is large if you ask for everything.
record_id, account_id, user_id, user, transaction_type, channel (WEB, MOBILE, API), connectedAppId and connectedAppName — which of your applications initiated it.
amount, fee, cashback, cashback_rate, bonus_cashback_rate, plus two directional fields worth understanding:
  • external_funding_source_activity — the change to external funding sources (bank cards and accounts)
  • fluz_balance_activity — the change to internal Fluz balances
Together these tell you whether money entered Fluz, left Fluz, or just moved around inside it.
See below — every record carries the after-state of every balance.
source and destination as display strings (“Visa ****1234”, “Amazon”), description, merchant_id, logo_url, card_last_four, card_display_name, virtual_card_program, source_type.Foreign transactions add original_currency_amount, original_currency_code, and conversion_rate.
memo, transactionCategory, attachmentUrl — see Annotating.
reference_id, transfer_id, liability_id, used_user_cash_balance_id, descriptor_id — the fields you reconcile against. See Reconciliation.

Balance snapshots

Every transaction carries the balance of every balance type as it stood after that transaction was applied. That makes the feed a replayable ledger — you can reconstruct the state of the account at any point in its history without a separate balance-history API.
seat_balance_* is the rewards balance. The naming is historical — don’t go looking for a separate seat concept.
Each comes in _available_balance and _total_balance. Paired is_*_affected booleans (is_cash_balance_affected, is_seat_balance_affected, is_gift_card_balance_affected, is_reserve_balance_affected) tell you which balances this transaction actually touched — cheaper to branch on than diffing snapshots. Wallet Overview for what each balance is.

Filtering

getTransactions takes a rich TransactionFilterInput. The families: amount is the base amount; finalAmount is amount plus fees — the total actually charged. Filter on finalAmount when reconciling against what a funding source was debited.
Confirm the accepted values for transactionType before relying on it. The reference page lists human-readable strings (Add Money, Gift Card Purchase, Transfer - Out) in one place and enum-style constants (GIFT_CARD_PURCHASE, DEPOSIT) in its examples and sample responses. These are not interchangeable. Query a small unfiltered page first and read the actual transaction_type values your account returns.

Pagination and throughput

limit maxes out at 20, and offset walks forward. Check hasNextPage rather than inferring from a short page; totalCount gives the full size of the filtered set. Rate limits are 100 queries per minute per user and 300 per minute per IP, with X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers on responses.
Do the arithmetic before building a sync job. 20 records per query × 100 queries per minute is a ceiling of roughly 2,000 transactions per minute. An account with 500,000 lifetime transactions takes over four hours to walk end to end.Design for incremental sync: bound every job with createdGte/updatedGte against your last successful watermark, and never re-walk history you already hold.

Annotating transactions

Attach a free-text memo (max 255 characters), a transactionCategory, and a file to any transaction — either at transaction time on deposits, purchases, and transfers, or afterwards with updateTransactionMetadata. Categories are created on first use and reused when the same name comes back.
attachmentUrl is a signed URL that expires. Never store it. Re-fetch the transaction when you need the file.This also breaks naive caching. Settled transactions look immutable, but memo, transactionCategory, and attachmentUrl are all mutable after settlement — so a cached SETTLED record will serve stale annotations and a dead attachment link. Cache the financial fields if you like; re-fetch the annotations.
Add Expense Details

Reconciling against your own system

Five fields do the joining: A workable pattern:
  1. Store record_id and reference_id against your own order at the time you create it. Don’t try to match on amount and timestamp later.
  2. Sync incrementally on updatedGte, not createdGte — a PENDING transaction that later settles changes updated_at, and a created-date sync will miss the transition.
  3. Expect settlement lag. ACH withdrawals sit PENDING for 1–3 business days; card authorizations settle on their own timeline. expectedClearedDate tells you when to look again.
  4. Reconcile balances against snapshots, not by summing amounts. The *_available_balance fields are authoritative and already account for fees, cashback, and pending holds.
externalReferenceId does not appear on transaction records. If you need your own user ID on a movement, join through the account or carry it in memo at transaction time. → Managing External Reference IDs

Scopes

getTransactions requires both LIST_PAYMENT and LIST_PURCHASES. Missing either returns a FORBIDDEN error naming the required scopes. Enable both on your app’s Permissions tab before you build — a requested scope that isn’t enabled is silently dropped rather than rejected. → Configure OAuth App

Next steps

Get all transactions

Full filter, field, and pagination reference.

Declined transactions

Authorizations that never became transactions.

Decline codes

What each decline reason means.

Virtual card transactions

Scoped to one or more cards.

Gift card purchases

Orders rather than ledger entries.

Add expense details

Memos, categories, and attachments.