---
title: "List treasury transfers"
method: GET
path: "/v1/multisig-wallets/{walletId}/intents"
tags: ["Multisig Wallets"]
---

# List treasury transfers

`GET /v1/multisig-wallets/{walletId}/intents`

## Request

- Base URL: `https://api.prod.keyban.io`
- URL: `https://api.prod.keyban.io/v1/multisig-wallets/{walletId}/intents`
- Auth: one of:
  - API key in header `X-Api-Key`
  - `bearer` (a scheme the document does not define)

Transfer history of the treasury, most recent first: what is awaiting signatures, what executed, and what failed or expired. Reading also repairs the live transfer, exactly as the detail endpoint does: an `unknown` one is reconciled against the chain, a `broadcasting` one with no relay behind it is queued again.

## Path parameters

- `walletId` string, uuid, required

## Response `200`

List of transfers retrieved successfully

- PaginatedMultisigIntentDtoOutput
  - `data` object[], required: Array of items for the current page
    - `id` string, uuid, required: Entity UUID
    - `createdAt` string, date-time, required: Creation date (ISO 8601)
    - `updatedAt` string, date-time, required: Last update date (ISO 8601)
    - `status` 'pending' | 'broadcasting' | 'unknown' | 'executed' | 'failed' | 'cancelled' | 'expired', required: Lifecycle: `pending` (collecting signatures), `broadcasting` (threshold reached, relay in progress), `executed` (mined, `txHash` set), `failed` (reverted or never broadcast), `unknown` (outcome undetermined — the transfer may have landed, and no new intent is accepted until it is reconciled), `cancelled`, `expired`.
    - `transfers` object[], required: Legs of the lot, in the exact order they were signed — the order is part of the signed preimage. The signer app displays the full list and re-derives every calldata from it.
      - `agentWalletId` string, uuid, nullable, required: Agent wallet this leg credits, as resolved at creation. Null when the leg targets a contact of the treasury instead, and on rows migrated from the single-transfer era whose agent wallet had already been deleted.
      - `targetAddress` string, required: On-chain address of that agent wallet, snapshotted so the destination stays what the signers saw even if the wallet row is later renamed or deleted.
      - `amount` string, required: Amount in USDC sub-units (6 decimals), as a positive integer string. "1500000" is 1.50 USDC.
      - `destinationLabel` string, nullable, required: Display name of this destination, resolved from the frozen `targetAddress` **at read time and never stored on the intent** — an agent wallet of the organization, else a contact of this treasury (archived ones included, so the history keeps its names). Null when the address resolves to neither. It is the frozen address above, not this label, that a signer verifies against.
      - `destinationKind` 'agent' | 'contact' | 'unknown', required: What the frozen address turned out to be: `agent` (a wallet of your own fleet — the leg is internal), `contact` (a named third party), `unknown` (neither, e.g. a wallet deleted since). Resolved from the address, so it stays true whatever path created the leg.
      - `destinationFirstUse` boolean, nullable, required: True when no transfer to this contact has ever EXECUTED — the signal the signer app puts in front of the signers, since a brand-new destination is where a compromised-channel address lands. **Null on an `agent` or `unknown` destination**: a refill toward one’s own fleet needs no such warning.
    - `totalAmount` string, required: Sum of the leg amounts in USDC sub-units, as a decimal string. Derived, never stored.
    - `fiat` object, nullable, required: Indicative rate for display only, resolved **at read time and never stored on the intent**: it is outside the signed preimage and must never enter its computation. Null when the organization has no display currency or the rate oracle is unavailable — the lot is still fully served and signable.
      - `currency` 'EUR' | 'USD' | 'JPY', required: Display currency of the organization at read time.
      - `centiPerUsdc` integer, required: Centi-units of `currency` per 1 USDC when the lot was served. A leg converts as floor(amount × centiPerUsdc / 1e6) centi-units.
    - `relayNonce` string, required: Account relay nonce the signatures are bound to, as a decimal string. One nonce covers the whole lot. If the account moves past it, the intent fails without broadcasting.
    - `relayHash` string, required: What each signer signs. Single-leg lot: `keccak256(abi.encode(chainId, account, nonce, dest, value, keccak256(data)))`. Two legs or more: `keccak256(abi.encode(chainId, account, nonce, keccak256(abi.encode(calls))))` over the ordered `(dest, value, data)` legs. The app must recompute it locally from the other fields and refuse to sign on a mismatch.
    - `approvalCount` integer, required: Signatures collected so far, out of the wallet threshold.
    - `expiresAt` string, date-time, required: End of the signing window. Past it the intent expires on its next touch and the collected signatures are purged.
    - `txHash` string, nullable: Hash of the relayed transaction. Null until executed — and can stay null on an intent reconciled as `executed` after an ambiguous broadcast, where only the consumed account nonce proves execution.
    - `error` string, nullable: Why the transfer failed, or what made its outcome undetermined. Null while pending or once executed.
  - `total` integer, required: Total count of items matching the query

## Other responses

- `404`: Multisig wallet not found

---

[API](https://skmtc.dev/keyban/apis/keyban-rest-apis.md) · [All operations](https://skmtc.dev/keyban/apis/keyban-rest-apis/llms.txt) · [OpenAPI document](https://skmtc.dev/keyban/apis/keyban-rest-apis/revisions/0bb79a1da961?raw)
