The Transactions API surfaces every monetary movement that touches the accounts your business holds on Rho - card spend, ACH, wires, internal transfers, interest, and refunds. Use it to feed your data warehouse, drive reconciliation, or trigger workflows the moment money lands.
The Transactions API is part of the stable v1 contract: additive-only, with breaking changes reserved for a new API version. See Versioning and compatibility.
A single transaction record models one ledger event against one account. The fields below are grouped by what they are useful for; the API Reference remains the authoritative contract for types and nullability.
| Field | What it tells you |
|---|---|
id | The transaction's identifier. Stable across re-fetches, but not guaranteed unique per row - the entries of one money movement can share an id. See Idempotent ingestion. |
money_movement_id | Identifier shared by every transaction entry belonging to the same money movement. Group on it to treat the entries of one movement as a unit rather than as unrelated events. |
account_id | The account the event posted against. |
account_name | That account's display name, denormalized onto the record so reconciliation rarely needs a second call to Accounts. |
account_type | The account's type: checking, savings, credit, investment, or rewards. |
transaction_type | The kind of event: card, credit-line, ACH, wire (domestic and international), check, internal transfer, savings, treasury, rewards, fee, and adjustment activity, including the refund and return variants of each. See the API Reference for the full list of values. |
status | One of pending, settled, failed, or awaiting_approval. Most events pass through pending before they settle. |
amount | An object, not a scalar: amount.amount is a signed integer in minor units (cents for USD), where negative values are debits, and amount.currency is an ISO 4217 code. Treat the value as an integer rather than a decimal. |
initiated_at | When the event was created. Always present. |
posted_at | When the event cleared the ledger. Null while the status is pending. |
attachments | Stable file descriptors containing file_id and file_name. The array is empty when no files are attached. See Downloading attachments. |
When available, user and card attribution is returned directly on the transaction, supporting per-employee and per-card reporting.
| Field | What it tells you |
|---|---|
user_id | The user the transaction is attributed to. Null for system-initiated activity such as interest. |
user_full_name | That user's display name, denormalized onto the record. Null for the same system-initiated activity as user_id. |
card_id | The card the spend was made on. Null for every non-card transaction type. |
card_name | That card's display name. Card transactions only. |
user_id and card_id are also filters on the list endpoint - see Attributing card spend by employee.
| Field | What it tells you |
|---|---|
counterparty_name | The merchant, or the other side of the money movement. Always present, though it can be an empty string. |
counterparty_logo_url | A logo for the counterparty when Rho has one on file. Null otherwise. |
memo | Original text describing the transaction, supplied by a bank or payment provider or generated by Rho. Unlike note, it is not user-editable. Omitted when unavailable. |
note | A user or system annotation on the transaction. Omitted when unset. |
The list endpoint's search parameter matches free text across counterparty_name, memo, and note, so a single query covers all three.
| Field | What it tells you |
|---|---|
tracking_number | The payment network identifier for tracing an outbound transaction: an ACH NACHA trace number, or a wire IMAD/OMAD. MT103 reference numbers are not returned. Null for transaction types that carry no network identifier. |
Transaction responses contain stable attachment metadata but never signed URLs. Request a fresh, short-lived URL only when the file is needed:
curl "https://rhoapi.rho.co/api/v1/transactions/{transaction_id}/files/{file_id}" \
-H "Authorization: Bearer $RHO_API_TOKEN"Set {transaction_id} to the transaction's id, and {file_id} to an attachments[].file_id value. A transaction id identifies one transaction.
Transaction responses carry stable attachment metadata but never signed URLs, so each request to this endpoint issues a fresh, short-lived link. Follow it straight away, without an Authorization header, and request another one whenever a new URL is needed instead of reusing or persisting the last. The response contains file_id, file_name, and download_url.
Sandbox downloads contain non-empty representative fictional documents, but their contents are not guaranteed to reproduce every field of the transaction fixture.
status reports where a transaction stands: pending, settled, failed, or awaiting_approval. Most events are created pending and settle once funds clear, and initiated_at is always present. The amount can shift between an initial card authorization and final clearing. Failed transactions - insufficient funds, a returned ACH, a declined card - remain queryable for audit purposes. An awaiting_approval transaction is held pending action on your side - a payment waiting on an approver, or a debit waiting on your authorization - and no funds have moved while it sits in that state.
posted_at is nullable, and the contract describes it as null while the status is pending. Beyond that it is not coupled to status: v1 does not guarantee that a failed transaction has an empty posted_at, so read the field as nullable whatever the status. Nor does v1 guarantee a transition order, so reconcile on the status and timestamps a response actually carries rather than on an assumed progression.
Iterate the list endpoint with posted_after and posted_before set to the boundaries of your accounting day, and status=settled to skip in-flight items:
curl 'https://rhoapi.rho.co/api/v1/transactions?status=settled&posted_after=2026-05-21T00:00:00Z&posted_before=2026-05-22T00:00:00Z&page_size=100' \
-H "Authorization: Bearer $RHO_API_TOKEN"Follow the cursor (see Pagination) until next_page_token is null.
Filter on transaction_type=card_refund and transaction_type=card_credit against the account_type=credit slice to surface refunds and credits against the card line of credit. Each one carries counterparty_name, plus card_id, card_name, and user_id when that attribution is available, so you can often attribute it without a second call. Entries sharing a money_movement_id belong to the same movement. A refund or credit is not by itself a dispute - v1 exposes no dispute indicator.
Pass user_id to break card activity out per employee, composed with the date and type filters:
curl 'https://rhoapi.rho.co/api/v1/transactions?user_id=<uuid>&transaction_type=card_debit&posted_after=2026-01-01T00:00:00Z&page_size=100' \
-H "Authorization: Bearer $RHO_API_TOKEN"user_id accepts repeats, so one call can cover several employees.
Attribution fields are nullable. When aggregating an unfiltered window, handle missing user fields on system-initiated activity and missing card fields on non-card transactions. Substitute card_id for user_id to scope the request by card.
Re-fetching a day's window returns the same id values, so ingestion can be made naturally idempotent. Do not assume id is unique per row, though: the entries of a single money movement can share an id, so a warehouse keyed on id alone silently drops a leg. Either key on id together with the fields that distinguish entries of the same movement, such as account_id, or group on money_movement_id and treat the movement as your unit.
Full endpoint catalogue - paths, parameters, response shapes, and required scopes - lives in the API Reference.