---
title: "Swaps on every chain"
method: GET
path: "/portfolio/{wallet}/activity"
tags: ["Portfolio"]
---

# Swaps on every chain

`GET /portfolio/{wallet}/activity`

## Request

- Base URL: `https://api.getchord.xyz/v1`
- URL: `https://api.getchord.xyz/v1/portfolio/{wallet}/activity`
- Auth: none declared

The wallet's swaps on every chain in scope, merged newest first, one keyset page at a time. Each item is one side of a swap seen from the wallet: `buy` = it received `token`, `sell` = it gave it.

**Notes**
- Pass the page's `cursor` back as `cursor` for the next page; `cursor: null` = nothing older. One transaction's rows stay on one page, so a page can hold fewer than `limit` items.
- A chain that could not be read for a page is listed in `unavailable` and keeps its place: the next page asks it again. `items: []` with `unavailable` set is an outage, not an empty history.
- How far back: Monad, Robinhood Chain and Arc, their raw tape (45 days); Avalanche, Base, BNB Chain, Arbitrum One and Ethereum, their raw tape and then, where Chord's history lake holds older days, up to 5,000 older swaps; Solana, 45 days. EVM swaps under $0.10 are left out.
- `ts` is in milliseconds.
- Pages are not cached: without an API key (or an Ask session) each page counts against the budget it shares with `GET /portfolio/{wallet}` (10 new reads per IP every 10 minutes, a limited number a minute for every such caller together); past it 429 `RATE_LIMITED` or 503 `BUSY` with `Retry-After`.

## Path parameters

- `wallet` string, required: EVM address, hex, case-insensitive.

## Query parameters

- `sol` string: Solana address, base58, case-sensitive. Never lower-case it.
- `chains` string
- `cursor` string
- `limit` integer

## Response `200`

- object
  - `items` PortfolioActivityItem[], required: Newest first, every chain in scope merged.
    - `ts` integer: Unix time, milliseconds.
    - `chain` union: EVM chain id, or `solana`.
      - integer
      - string
    - `side` 'buy' | 'sell': `buy` = the wallet received `token`; `sell` = it gave it.
    - `token` object
      - `address` string, nullable: EVM token, lower-case. Null on a Solana row.
      - `mint` string: Solana only, case kept.
      - `symbol` string
      - `name` string, nullable
      - `logo` string, nullable
    - `amount` string: Whole tokens, decimal string.
    - `valueUsd` number, nullable
    - `priceUsd` number, nullable
    - `tx` string: Transaction hash, or the Solana signature (case kept).
    - `explorer` string, nullable: The transaction on the chain's explorer.
    - `venue` string, nullable: Venue display name.
  - `cursor` string, nullable, required: Opaque. Pass it back for the next page; null = nothing older.
  - `unavailable` object[]: Present only when a chain could not be read for this page.
    - `chain` union: EVM chain id, or `solana`.
      - integer
      - string
    - `reason` string

## Other responses

- `400`: `INVALID_ADDRESS`, `INVALID_SOL_ADDRESS`, `BAD_CHAINS`, `SOL_REQUIRED`, `BAD_LIMIT` (1 to 100) or `BAD_CURSOR` (not a cursor of this route).
- `429`: `RATE_LIMITED`: without an API key, this IP started its 10 new portfolio reads of the last 10 minutes, pages included (`Retry-After`). Or `RATE_LIMIT_EXCEEDED`, the per-minute limit of every route.
- `503`: `BUSY`: too many new portfolio reads are running for callers without a key right now (`Retry-After`). `UNAVAILABLE`: the page itself could not be built (a chain that cannot be read is listed in `unavailable` inside a 200).

---

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