Skip to content

Transactions

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.

Stable contract

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.

What a transaction represents

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.

FieldWhat it tells you
idThe 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_idIdentifier 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_idThe account the event posted against.
account_nameThat account's display name, denormalized onto the record so reconciliation rarely needs a second call to Accounts.
account_typeThe account's type: checking, savings, credit, investment, or rewards.
transaction_typeThe 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.
statusOne of pending, settled, failed, or awaiting_approval. Most events pass through pending before they settle.
amountAn 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_atWhen the event was created. Always present.
posted_atWhen the event cleared the ledger. Null while the status is pending.
attachmentsStable file descriptors containing file_id and file_name. The array is empty when no files are attached. See Downloading attachments.

Attribution

When available, user and card attribution is returned directly on the transaction, supporting per-employee and per-card reporting.

FieldWhat it tells you
user_idThe user the transaction is attributed to. Null for system-initiated activity such as interest.
user_full_nameThat user's display name, denormalized onto the record. Null for the same system-initiated activity as user_id.
card_idThe card the spend was made on. Null for every non-card transaction type.
card_nameThat 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.

Counterparty and annotations

FieldWhat it tells you
counterparty_nameThe merchant, or the other side of the money movement. Always present, though it can be an empty string.
counterparty_logo_urlA logo for the counterparty when Rho has one on file. Null otherwise.
memoOriginal 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.
noteA 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.

Payment tracing

FieldWhat it tells you
tracking_numberThe 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.

Downloading attachments

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.

Lifecycle

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.

Common workflows

Reconciling daily activity

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.

Finding card refunds and credits

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.

Attributing card spend by employee

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.

Idempotent ingestion

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.

Reference

Full endpoint catalogue - paths, parameters, response shapes, and required scopes - lives in the API Reference.