Skip to main content

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.

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:
{
  "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.
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.
For a more detailed explanation of the denomination concept, check the Core Concepts page.

Fetch portfolio statements

Call 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.
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.
{
  "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 to retrieve a paginated list of completed transactions during the period, each with exchange rates captured at the time they completed.
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.
{
  "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. To retrieve all transactions, request each page in sequence and follow next until it’s absent. The following helper collects all pages upfront:
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.
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

Preparing data

Compute denominated values for holdings and transactions and build the report payload.

Generating report

Build a PDF from the processed data and run the generation pipeline in a background worker.