> ## Documentation Index
> Fetch the complete documentation index at: https://developer.uphold.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Fetching data

This guide covers how to set a period and denomination, fetch portfolio holdings and transactions, and pull it all together into a multi-month report.

## Prerequisites

* The user is onboarded and verified (KYC is complete).

## Set the period

All statements are scoped to a specific period, defined by three required query parameters:

* `period` — the period type. Currently only `one-month` is supported.
* `year` — the calendar year (e.g. `2025`).
* `month` — the calendar month as a number from `1` to `12`.

The `period` object in the response reflects the exact UTC start and end timestamps of the requested period:

```json theme={null}
{
  "period": {
    "from": "2025-03-01T00:00:00.000Z",
    "to": "2025-03-31T23:59:59.999Z"
  }
}
```

Valid periods range from the month the user's account was created to the last fully completed calendar month. Requests outside this range, or with an unsupported denomination asset, return a `409` error. A valid period with no user activity still returns a successful response — holdings and transactions will have no entries.

## Set the denomination

The `denomination` query parameter accepts a single asset code (e.g. `denomination=GBP`). If not provided, `USD` is used by default. Exchange rates use USD as the base pair. When the denomination is not USD, the response also includes a `USD-{denomination}` rate to complete the conversion.

<Note>Supported assets include some of the major fiat currencies and BTC. If you need a particular asset added to this list, please reach out to your Account Manager.</Note>

For a more detailed explanation of the denomination concept, check the [Core Concepts](/rest-apis/core-api/concepts#denomination) page.

## Fetch portfolio statements

Call [Get portfolio statement](/rest-apis/core-api/statements/get-portfolio-statement) to retrieve the user's holdings at the end of the requested period, along with exchange rates in the requested denomination. Rates are a period-end snapshot.

```http theme={null}
GET /core/statements/portfolio?period=one-month&year=2025&month=3&denomination=GBP
```

Holdings are returned per asset. Assets already held in the denomination currency (GBP in this case) have no rate entry — their value is their amount directly.

```json theme={null}
{
  "statement": {
    "holdings": [
      { "asset": "BTC", "total": "0.02" },
      { "asset": "ETH", "total": "0.5" },
      { "asset": "GBP", "total": "250.00" }
    ],
    "period": {
      "from": "2025-03-01T00:00:00.000Z",
      "to": "2025-03-31T23:59:59.999Z"
    },
    "rates": {
      "BTC-USD": "68106.26",
      "ETH-USD": "2094.45",
      "USD-GBP": "0.75629"
    }
  }
}
```

## Fetch transaction statements

Call [Get transactions statement](/rest-apis/core-api/statements/get-transactions-statement) to retrieve a paginated list of completed transactions during the period, each with exchange rates captured at the time they completed.

```http theme={null}
GET /core/statements/transactions?period=one-month&year=2025&month=3&denomination=GBP&page=1&perPage=50
```

Each entry contains the transaction details and a `rates` object with exchange rates captured at the time that transaction completed.

```json theme={null}
{
  "statement": {
    "period": {
      "from": "2025-03-01T00:00:00.000Z",
      "to": "2025-03-31T23:59:59.999Z"
    },
    "transactions": [
      {
        "rates": {
          "BTC-USD": "68106.26",
          "USD-GBP": "0.75629"
        },
        "transaction": {
          "id": "8daa6dbd-21a0-4305-93c3-bd1d04bc575c",
          "status": "completed",
          "completedAt": "2025-03-23T12:06:55.116Z",
          "denomination": {
            "amount": "100",
            "asset": "GBP",
            "target": "origin"
          },
          "origin": {
            "amount": "100",
            "asset": "GBP"
          },
          "destination": {
            "amount": "0.00186036",
            "asset": "BTC",
            "rate": "0.00001869711794070723"
          },
          "fees": [
            { "amount": "0.5", "asset": "GBP", "type": "deposit" }
          ]
        }
      }
    ]
  },
  "pagination": {
    "first": "https://api.enterprise.uphold.com/core/statements/transactions?period=one-month&year=2025&month=3&denomination=GBP&page=1&perPage=50",
    "next": "https://api.enterprise.uphold.com/core/statements/transactions?period=one-month&year=2025&month=3&denomination=GBP&page=2&perPage=50"
  }
}
```

### Handling pagination

The response includes a `pagination` object with `first` and `next` URL links. `next` points to the next page and is absent on the last page. For a full overview of how pagination works across the API, see [Pagination in responses](/rest-apis/pagination#pagination-in-responses).

To retrieve all transactions, request each page in sequence and follow `next` until it's absent. The following helper collects all pages upfront:

```javascript theme={null}
async function fetchAllTransactions({ token, userId, year, month, denomination }) {
  const transactions = [];
  let page = 1;
  const perPage = 50;

  while (true) {
    const params = new URLSearchParams({ period: 'one-month', year, month, denomination, page, perPage });
    const response = await fetch(
      `https://api.enterprise.uphold.com/core/statements/transactions?${params}`,
      { headers: { Authorization: `Bearer ${token}`, 'X-On-Behalf-Of': userId } }
    );

    if (!response.ok) {
      throw new Error(`Failed to fetch transactions: ${response.status}`);
    }

    const { statement, pagination } = await response.json();
    transactions.push(...statement.transactions);

    if (!pagination.next) break;
    page++;
  }

  return transactions;
}
```

## Build a quarterly statement

To generate a quarterly report, use the helpers above: fetch the portfolio snapshot at the end of the last month of the quarter and aggregate transactions across all three months.

```javascript theme={null}
const QUARTER_MONTHS = {
  Q1: [1, 2, 3],
  Q2: [4, 5, 6],
  Q3: [7, 8, 9],
  Q4: [10, 11, 12]
};

async function fetchQuarterlyData({ token, userId, year, quarter, denomination }) {
  const months = QUARTER_MONTHS[quarter];

  const { statement: portfolio } = await fetchPortfolioStatement({ token, userId, year, month: months[2], denomination });

  const allTransactions = [];
  for (const month of months) {
    const monthTransactions = await fetchAllTransactions({ token, userId, year, month, denomination });
    allTransactions.push(...monthTransactions);
  }

  return { portfolio, transactions: allTransactions };
}
```

## Next steps

<CardGroup cols={2}>
  <Card title="Preparing data" icon="coins" href="/developer-guides/statements/preparing-data">
    Compute denominated values for holdings and transactions and build the report payload.
  </Card>

  <Card title="Generating report" icon="file-lines" href="/developer-guides/statements/generating-report">
    Build a PDF from the processed data and run the generation pipeline in a background worker.
  </Card>
</CardGroup>
