Skip to main content

Overview

The Portfolio API gives you the account-level view after users deposit, withdraw, trade, transfer funds, or earn rewards. Use it to show current portfolio value, per-asset balances, an activity feed, and historical performance. Subscribe to Portfolio transaction webhooks when you want change notifications without continuous polling. All Portfolio endpoints are scoped to a specific account_id. Pass the same quote_symbol and quote_type across the current portfolio, history, and transaction calls when you want their monetary values to use the same quote asset.

Prerequisites

  • Payward Services API credentials (see the Authentication guide)
  • A verified user with at least one account
  • Base URL: https://api.services.payward.com

Portfolio workflow

Use this flow when you build a portfolio dashboard or reconcile user activity after payments and trades.
1

Show the current portfolio

Fetch account-level values and the per-asset balance breakdown in one snapshot.GET /v1/accounts/{account_id}/portfolio
2

Build the activity feed

Fetch transaction history for deposits, withdrawals, transfers, swaps, price trigger swaps, and earn rewards.GET /v1/accounts/{account_id}/portfolio/transactions
3

Subscribe to transaction changes

Register for transaction.* webhook events. Retrieve the complete transaction from Portfolio after each notification.POST /v1/webhooks
4

Chart portfolio performance

Fetch historical balances and valuations for a selected time window.GET /v1/accounts/{account_id}/portfolio/history

Step 1: get the current portfolio

Call GET /v1/accounts/{account_id}/portfolio to get the account totals and per-asset balances in one consistent snapshot. Set with_zero_balances=true when you also need assets with zero balances, such as when you display every supported asset.
Use these account-level fields for the dashboard header: For each item in assets, use these fields: Quote-denominated monetary amounts end in _in_quote. Native asset amounts omit that suffix. For example, balances.total is an amount in the asset itself; it is not a price. Use balances.total_in_quote when you need its value in data.quote. The nested balance sources use the same total and total_in_quote naming. Account-level availability is an aggregate in data.quote; it does not belong inside balances.main. Per-asset availability.trade and availability.transfer are native amounts for those actions. The pnl objects are optional. A PnL status can be in_progress while its corresponding value is absent or not final. Numeric PnL fields ending in _in_quote use data.quote. pnl.reference_currency identifies Portfolio’s calculation basis; it does not change the display currency. See the Get portfolio API reference for every query parameter and response field.

Step 2: build the activity feed

Call GET /v1/accounts/{account_id}/portfolio/transactions to list user-visible portfolio activity. Use it after a deposit, withdrawal, swap, price trigger swap, or earn reward to show what changed and support reconciliation.
Common filters: Each returned transaction includes the required fields id, timestamp, type, and status. It can include spend, receive, or both. Failed transactions can omit movement details. Transactions without a defined lifecycle status are not returned. Deposits and withdrawals can also carry details with type: "funding" and a crypto_transaction_id you can use to link to a block explorer. It appears once the transaction settles on a blockchain, and is omitted for fiat funding. Successful swap and price_trigger_swap transactions include details.quote_id. Use it to correlate the transaction with the quote that executed it. Failed swap attempts appear with status: "failed". Their details use type: "failed_swap" or type: "failed_price_trigger_swap" and include failure_reason. The reason is one of insufficient_funds, card_issue, user_account_issue, or other. Use next_page_token as page_token to fetch more transactions. See the List Portfolio Transactions API reference for all filters and response fields.

Step 3: subscribe to transaction changes

Register a webhook to receive change notifications for the Portfolio transaction categories you use. One webhook can subscribe to any combination of these events: Every payload contains type, transaction_id, user_id, account_id, and timestamp. It can also contain status. Treat the webhook as a change notification. Use transaction_id as the ids filter on GET /v1/accounts/{account_id}/portfolio/transactions to retrieve the complete ledger entry. The same transaction can emit more than one event as its status changes. Deduplicate delivery retries with the svix-id header.
Failed swap and price trigger swap execution attempts do not emit transaction.* events because they do not contain ledger movements. Use the relevant quote or price trigger swap failure event instead.
See the Register webhook API reference to create a subscription and review the event payload schemas.

Step 4: chart portfolio performance

Call GET /v1/accounts/{account_id}/portfolio/history to draw a portfolio value chart or show how balances changed over time.
Use the history endpoint for:
  • Portfolio value charts with timestamp and value.
  • Historical PnL views with total_pnl, when available.
  • Historical asset-balance charts when you request assets filters with both symbol and type.
  • Quote-aware charts with top-level quote_symbol, quote_type, start_timestamp, and end_timestamp.
The history endpoint returns a maximum of 365 data points per request. Use a narrower time window when you need fewer points.
A missing asset balance at the start of the range means the user did not hold that asset at that time. A zero balance means the user may have held the asset previously, but did not hold it at that snapshot. The latest daily balance can be delayed by up to about five hours after UTC midnight while data is processed.
See the List Portfolio History API reference for all query parameters and response fields.

API reference