---
title: "Search transactions"
method: POST
path: "/v1/tools/betteroff_search_transactions"
tags: ["tools"]
---

# Search transactions

`POST /v1/tools/betteroff_search_transactions`

## Request

- Base URL: `https://api.betteroff.finance`
- URL: `https://api.betteroff.finance/v1/tools/betteroff_search_transactions`
- Auth: one of:
  - OpenID Connect (`https://app.betteroff.finance/api/auth/.well-known/openid-configuration`, scopes: `transactions:read`)
  - HTTP bearer

Use this when the user asks to find transactions or total a filtered set of transactions. Search transactions by date, merchant, category, trait, type/class, account, or amount; a summary totals all matches. Brokerage deposits/withdrawals: transactionClass `brokerage`, transactionTypes `transfer_in`/`transfer_out`/`deposit`/`withdrawal`.

## Request body

- object
  - `allTime` boolean, nullable: Use true for all synced merchant history; dates are ignored. Use it when the answer may be older than the default 30 days: the last or first time, ever, annual or one-off charges, or 'did I pay X before'.
  - `cursor` object, nullable
    - `offset` integer, required
    - `revision` integer, required
  - `startDate` string, date, nullable, required: Start date (ISO format, e.g. 2025-01-01). Use null for 30 days ago.
  - `endDate` string, date, nullable, required: End date (ISO format). Use null for today.
  - `merchant` string, nullable, required: Merchant name to search for (partial match).
  - `traits` string[], nullable, required: Only transactions whose merchant has every listed trait. Use for purposes a category does not capture. discretionary: optional spending: dining out, entertainment, hobbies, shopping for wants; travel: trips: flights, hotels, rental cars, cruises, travel booking; health: medical care: doctors, dentists, pharmacies, vision, therapy; kids: children: childcare, schools, tutoring, toys, kids' activities; gifts: gifts: florists, gift shops, gift cards; charity: donations: charities, nonprofits, religious organizations, fundraisers; business: work expenses: software, office supplies, coworking, professional services; crypto: crypto: exchanges, on-ramps, wallets, crypto cards. Person-to-person payments and unrecognized merchants carry no traits. Use null for no trait filter.
  - `category` string, nullable, required: Category code (e.g. FOOD_AND_DRINK, TRANSPORTATION, ENTERTAINMENT).
  - `transactionTypes` string[], nullable, required: Filter by transaction type. For investment account deposits/withdrawals, use transfer_in/deposit/bank_deposit for deposits and transfer_out/withdrawal/bank_withdrawal for withdrawals.
  - `transactionClass` 'bank' | 'brokerage' | 'crypto_exchange' | 'blockchain_wallet', nullable, required: Filter by normalized transaction class. Use brokerage for investment accounts.
  - `accountId` string, nullable, required: Filter to a specific account by ID. Use null to search all accounts.
  - `minAmount` number, nullable, required: Minimum transaction amount.
  - `maxAmount` number, nullable, required: Maximum transaction amount.
  - `limit` integer, nullable, required: Max results to return (default 25, max 50). Use null for 25.

## Response `200`

Tool result

- union
  - object
    - `ok` false, required
    - `requestId` string
    - `error` string, required
    - `code` string, required
    - `retryable` boolean, required
    - `nextStep` string, required
    - `field` string
    - `missingInputs` object[]
      - `id` string, required
      - `name` string, required
      - `balanceMissing` boolean, required
      - `interestRateMissing` boolean, required
      - `minimumPaymentMissing` boolean, required
  - object
    - `ok` true, required
    - `requestId` string
    - `schemaVersion` '4', required
    - `data` object, required
      - `summary` object, required
        - `count` integer, required
        - `returnedCount` integer, required
        - `signConvention` 'positive_is_outflow', required
        - `netAmount` string, required: Decimal text, e.g. "-12.50". Read the currency beside it or on the result.
        - `totalSpent` string, required: Decimal text, e.g. "-12.50". Read the currency beside it or on the result.
        - `totalReceived` string, required: Decimal text, e.g. "-12.50". Read the currency beside it or on the result.
        - `outflowCount` integer, required
        - `inflowCount` integer, required
        - `averageOutflow` string, nullable, required: Decimal text, e.g. "-12.50". Read the currency beside it or on the result.
        - `totalCurrency` string, required
        - `unconvertedRowCount` integer, required
        - `truncated` boolean, required
      - `transactions` object[], required
        - `id` string, uuid, required
        - `name` string, nullable, required
        - `amount` string, required: Decimal text in the row's currency. Positive is an outflow; negative is an inflow.
        - `currency` string, nullable, required
        - `date` string, required
      - `period` object, required
        - `start` string, nullable, required
        - `end` string, nullable, required
      - `page` object, required
    - `currency` string, nullable, required
    - `timezone` string, required
    - `asOf` string, nullable, required
    - `revision` integer, required
    - `householdRevision` integer, required
    - `quality` object, required
      - `state` 'complete' | 'partial' | 'unavailable', required
      - `reasons` string[], required
    - `evidence` object[], required
      - `source` string, required
      - `id` string
      - `observedAt` string, nullable, required
    - `page` object, required
      - `returnedCount` integer, required
      - `totalCount` integer, nullable, required
      - `truncated` boolean, required
      - `nextCursor` Schema1, required (unresolved $ref)
    - `warnings` string[], required
    - `notes` string

## Other responses

- `400`: INVALID_INPUT (a missing, unknown, or invalid argument, named in `fields`), TOOL_CALL_REJECTED, or a body that is not JSON.
- `401`: AGENT_TOKEN_INVALID: the token is missing, expired, or revoked.
- `402`: AGENT_SUBSCRIPTION_INACTIVE or FEATURE_NOT_INCLUDED: needs BetterOff Core.
- `403`: INSUFFICIENT_SCOPE, ACCESS_DENIED, or AGENT_GRANT_REVOKED.
- `404`: TOOL_NOT_FOUND, or NOT_FOUND for a record the org does not have.
- `409`: CONFLICT: the record's state rules this call out. Read it again.
- `422`: INCOMPLETE_DATA or RESULT_TOO_LARGE. Narrow the request; don't retry as is.
- `429`: RATE_LIMITED. Retry after Retry-After seconds.
- `503`: DATA_UNAVAILABLE, DEPENDENCY_UNAVAILABLE (including the 25-second tool deadline), or AGENT_AUTHZ_UNAVAILABLE. Retryable.
- `default`: Problem details

---

[API](https://skmtc.dev/betteroff/apis/betteroff-api.md) · [All operations](https://skmtc.dev/betteroff/apis/betteroff-api/llms.txt) · [OpenAPI document](https://skmtc.dev/betteroff/apis/betteroff-api/revisions/bc858c8d428d?raw)
