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

# Get a filtered aggregated portfolio snapshot

> **Rate limit:** 60 requests per 60 seconds. This is a **shared quota** — the same budget is consumed by a group of related endpoints, so calling any of them reduces what is left for the others (you cannot call each at the full rate independently). Endpoints sharing this quota:
- `GET /api/v1/trading/info/demo/aggregate-portfolio`

---

Returns the demo portfolio using aggregation levels and structured per-mirror instrument filters from the request body. This filter does not affect the account totals, that are still calculated based on the full portfolio.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/trading/info/demo/aggregate-portfolio
openapi: 3.0.1
info:
  title: eToro Api
  version: v1.375.0
  description: >-
    eToro’s public API provides access to real-time financial data, trading
    insights, and account management features, allowing developers to integrate
    eToro’s services into their applications. With access to market prices,
    historical data, and social trading information, the API empowers users to
    enhance their trading strategies. Designed for security and scalability, the
    eToro API ensures smooth and reliable integration for a variety of financial
    applications.


    For more details on integrating with eToro's public WebSocket service,
    please refer to the dedicated [WebSocket
    documentation](./websocket/websocket-doc.html).


    ## Authentication


    Every request must be authenticated with exactly one of two options: an
    OAuth 2.0 access token (`Authorization: Bearer <token>`), or the
    non-interactive credential pair (`x-api-key` + `x-user-key` headers). The
    two options are mutually exclusive — a request carrying both is rejected.
    Each operation lists the OAuth scopes that grant access as alternative
    security requirements: a bearer token needs only ONE of them, and the same
    permissions govern the credential pair.
servers:
  - url: https://public-api.etoro.com
    description: eToro Public API
security:
  - apiKeyAuth: []
    userKeyAuth: []
  - oauth2: []
tags:
  - name: Agent Portfolios
  - name: Social Feeds
  - name: Balances
  - name: Clubs
  - name: Watchlists
  - name: Data
  - name: Top Assets
  - name: App Data
  - name: Market Data
  - name: Identity
  - name: Cash Accounts
  - name: Transfer
  - name: Notifications
  - name: PI Data
  - name: PortfolioSearch
  - name: Price Alerts
  - name: SSO - Applications
  - name: SSO - Scopes
  - name: Sub-Accounts - eToro Trading
  - name: Sub-Accounts
  - name: Trading - Demo
  - name: Trading - Real
  - name: Users Info
  - name: Rankings
  - name: User Stats
  - name: Copy Trading
  - name: Copy Trading - Demo
paths:
  /api/v1/trading/info/demo/aggregate-portfolio:
    post:
      tags:
        - Trading - Demo
      summary: Get a filtered aggregated portfolio snapshot
      description: >-
        **Rate limit:** 60 requests per 60 seconds. This is a **shared quota** —
        the same budget is consumed by a group of related endpoints, so calling
        any of them reduces what is left for the others (you cannot call each at
        the full rate independently). Endpoints sharing this quota:

        - `GET /api/v1/trading/info/demo/aggregate-portfolio`


        ---


        Returns the demo portfolio using aggregation levels and structured
        per-mirror instrument filters from the request body. This filter does
        not affect the account totals, that are still calculated based on the
        full portfolio.
      operationId: postAggregatedPortfolioDemo
      parameters:
        - name: x-request-id
          in: header
          required: true
          schema:
            type: string
            format: uuid
            example: f0bfaf25-1252-4a64-b06d-8ab77ceb5202
          description: A unique request identifier.
          example: f0bfaf25-1252-4a64-b06d-8ab77ceb5202
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AggregatedPortfolioDemoPostRequest'
            example:
              conversionMode: eToroApp
              pnlLevel: pnl
              accountLevel: totals
              instrumentLevel: details
              mirrorLevel: details
              instrumentIds:
                - 1001
              mirrorFilters:
                - mirrorId: 0
                  instrumentMode: custom
                  instrumentIds:
                    - 1001
                - mirrorId: 123
                  instrumentMode: all
      responses:
        '200':
          description: Successfully retrieved aggregated portfolio data
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/TradingPortfolioDemoApi_AggregatedPortfolioResponse
          headers:
            RateLimit-Limit:
              description: >-
                Maximum number of requests allowed per window. This budget is
                SHARED across 2 endpoints (it is NOT per-endpoint): a request to
                any endpoint in the group spends the same budget. See this
                operation's description for the full list of endpoints sharing
                it.
              schema:
                type: integer
              example: 60
            RateLimit-Remaining:
              description: Requests remaining in the current window for this quota.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
            RateLimit-Policy:
              description: Quota policy in the form `<limit>;w=<window-seconds>`.
              schema:
                type: string
              example: 60;w=60
        '400':
          description: Invalid request body
        '404':
          description: User not found
        '429':
          description: >-
            Too Many Requests — the shared rate limit (60 requests / 60s) was
            exceeded.
          headers:
            RateLimit-Limit:
              description: >-
                Maximum number of requests allowed per window. This budget is
                SHARED across 2 endpoints (it is NOT per-endpoint): a request to
                any endpoint in the group spends the same budget. See this
                operation's description for the full list of endpoints sharing
                it.
              schema:
                type: integer
              example: 60
            RateLimit-Remaining:
              description: Requests remaining in the current window for this quota.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
            RateLimit-Policy:
              description: Quota policy in the form `<limit>;w=<window-seconds>`.
              schema:
                type: string
              example: 60;w=60
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
              example: 60
      security:
        - apiKeyAuth: []
          userKeyAuth: []
        - oauth2:
            - etoro-public:trade.demo:read
components:
  schemas:
    AggregatedPortfolioDemoPostRequest:
      type: object
      description: >-
        All aggregation levels are honored. Omitted properties use the same
        defaults as GET.
      properties:
        conversionMode:
          type: string
          enum:
            - eToroApp
            - realtime
          default: eToroApp
        pnlLevel:
          type: string
          enum:
            - none
            - pnl
            - dailyPnl
          default: pnl
        accountLevel:
          type: string
          enum:
            - none
            - totals
            - details
          default: totals
          description: >-
            Controls accountTotals. none omits it; totals and details include
            full-portfolio totals.
        instrumentLevel:
          type: string
          enum:
            - none
            - totals
            - details
          default: totals
          description: >-
            Controls per-instrument aggregates for both the manual (non
            copy-trading) portfolio and each mirror's positions — a single
            request-level setting, not scoped per mirror. none omits
            instrument-level aggregates; totals and details include them at the
            requested level.
        mirrorLevel:
          type: string
          enum:
            - none
            - totals
            - details
          default: totals
          description: >-
            Controls copy-trading data. none omits mirrors and requires
            mirrorFilters to be absent; totals includes mirrors without their
            instrument-level aggregates; details additionally includes each
            mirror's instrument-level aggregates, per instrumentLevel.
        instrumentIds:
          type: array
          items:
            type: integer
            format: int32
        mirrorFilters:
          type: array
          nullable: true
          description: >-
            Filters which copy-trading relationships to include, by mirror ID.
            Mirror ID 0 represents the manual (non copy-trading) part of the
            portfolio. When mirrorLevel is none, mirrorFilters must be absent —
            only the manual part of the portfolio is returned. When mirrorLevel
            is totals or details, an absent mirrorFilters returns all mirrors
            plus the manual part; an empty array returns none.
          items:
            $ref: '#/components/schemas/AggregatedPortfolioDemoMirrorFilter'
        dailyCutoffUtc:
          type: string
          format: date-time
          description: >-
            UTC timestamp representing the start of 'today' in the user's local
            timezone — normally the user's most recent local midnight, expressed
            in UTC. Required when pnlLevel is dailyPnl; rejected otherwise. Must
            not be more than 48 hours in the past or more than 5 minutes in the
            future.
    TradingPortfolioDemoApi_AggregatedPortfolioResponse:
      type: object
      description: >-
        Complete snapshot of the authenticated user's investment portfolio,
        organized by asset.
      properties:
        cid:
          type: integer
          format: int32
          description: Customer ID.
        timestamp:
          type: string
          format: date-time
          description: Time at which this portfolio snapshot was calculated.
        accountCurrency:
          type: string
          description: ISO 4217 code of the account's base currency (e.g. 'USD').
        accountTotals:
          $ref: >-
            #/components/schemas/TradingPortfolioDemoApi_AggregatedPortfolioAccountTotals
        instrumentAggregates:
          type: array
          description: >-
            Positions held directly (not via copy trading), grouped by
            instrument.
          items:
            $ref: >-
              #/components/schemas/TradingPortfolioDemoApi_AggregatedPortfolioInstrumentAggregate
        mirrors:
          type: array
          description: Copy-trading relationships the user has active.
          items:
            $ref: >-
              #/components/schemas/TradingPortfolioDemoApi_AggregatedPortfolioMirrorAggregate
    AggregatedPortfolioDemoMirrorFilter:
      type: object
      required:
        - mirrorId
      properties:
        mirrorId:
          type: integer
          format: int32
        instrumentMode:
          type: string
          nullable: true
          enum:
            - default
            - all
            - none
            - custom
          description: >-
            When omitted, or "default" is used, the top-level instrumentIds
            filter is used. custom requires a non-empty instrumentIds array;
            default, all, and none require instrumentIds to be omitted.
        instrumentIds:
          type: array
          nullable: true
          items:
            type: integer
            format: int32
    TradingPortfolioDemoApi_AggregatedPortfolioAccountTotals:
      type: object
      description: Account-level balance and equity totals.
      properties:
        accountAvailableCash:
          type: number
          format: double
          description: >-
            Cash available for new trades: accountBalance minus
            accountFrozenCash.
        accountFrozenCash:
          type: number
          format: double
          description: Cash reserved for pending open orders.
        accountCurrentPnl:
          type: number
          format: double
          description: >-
            Unrealized P&L across all manual positions and copy-trading mirrors
            in account currency.
        accountTotalValue:
          type: number
          format: double
          description: >-
            Total portfolio value: accountAvailableCash + accountTotalUsedMargin
            + accountCurrentPnl.
        accountTotalUsedMargin:
          type: number
          format: double
          description: >-
            Total margin in use: manual position margins + frozen order amounts
            + mirror active margins.
        accountBalance:
          type: number
          format: double
          description: Total cash balance (available + frozen), excluding invested amounts.
        dailyGainAccountCurrency:
          type: number
          format: double
          description: >-
            Today's unrealized gain in account currency. Present when
            pnlLevel=DailyPnl.
          example: -24.57
        yesterdayTotalValue:
          type: number
          format: double
          description: >-
            Total portfolio value as of yesterday's close. Present when
            pnlLevel=DailyPnl.
          example: 5179.05
        dailyGainAccountCurrencyPercent:
          type: number
          format: double
          description: >-
            Today's gain as a percentage of yesterday's total value. Present
            when pnlLevel=DailyPnl.
          example: -0.47
    TradingPortfolioDemoApi_AggregatedPortfolioInstrumentAggregate:
      type: object
      description: Aggregated data across all positions for a single instrument.
      properties:
        instrumentId:
          type: integer
          format: int32
          description: eToro instrument identifier.
        assetCurrency:
          type: string
          description: ISO 4217 code of the instrument's base currency (e.g. 'USD', 'EUR').
        totalMarginAccountCurrency:
          type: number
          format: double
          description: >-
            Sum of margins across all positions for this instrument, in account
            currency.
        totalFees:
          type: number
          format: double
          description: >-
            Sum of transaction fees taken on positions of this instrument, in
            asset currency.
        totalFeesAcctCcy:
          type: number
          format: double
          description: >-
            Sum of transaction fees taken on positions of this instrument, in
            account currency.
        totalTaxes:
          type: number
          format: double
          description: Sum of taxes for this instrument, in asset currency.
        totalTaxesAcctCcy:
          type: number
          format: double
          description: Sum of taxes for this instrument, in account currency.
        totalMarginAssetCurrency:
          type: number
          format: double
          description: >-
            Sum of margins across all positions for this instrument, in asset
            currency.
        pnlAssetCurrency:
          type: number
          format: double
          nullable: true
          description: >-
            Unrealized P&L for this instrument in asset currency. Null when P&L
            calculation is not requested.
        accountCurrencyRoePercent:
          type: number
          format: double
          description: >-
            Return on equity in account currency: accountCurrencyReturn /
            totalMarginAccountCurrency.
        netContracts:
          type: number
          format: double
          description: >-
            Net contracts across all positions (positive = net long, negative =
            net short).
        netUnits:
          type: number
          format: double
          description: >-
            Net units across all positions (positive = net long, negative = net
            short).
        netCurrentExposureAssetCurrency:
          type: number
          format: double
          description: Net current market exposure in asset currency.
        netCurrentExposureAccountCurrency:
          type: number
          format: double
          description: Net current market exposure in account currency.
        netInitialExposureAccountCurrency:
          type: number
          format: double
          description: Net initial exposure at open in account currency.
        accountCurrencyReturn:
          type: number
          format: double
          description: Unrealized P&L for this instrument in account currency.
        liquidationValueAccountCurrency:
          type: number
          format: double
          description: >-
            Current liquidation value in account currency:
            totalMarginAccountCurrency + accountCurrencyReturn.
        liquidationValueAssetCurrency:
          type: number
          format: double
          description: Current liquidation value in asset currency.
        avgLeverage:
          type: number
          format: double
          description: Average leverage across all positions for this instrument.
        avgOpenRate:
          type: number
          format: double
          description: Weighted average open rate across all positions for this instrument.
        netAvgOpenRate:
          type: number
          format: double
          description: >-
            Direction-aware weighted average open rate (long contributions minus
            short).
        avgConversionRate:
          type: number
          format: double
          description: >-
            Weighted average asset-to-account-currency conversion rate at
            position open.
        dailyGainAssetCurrency:
          type: number
          format: double
          description: >-
            Today's unrealized gain for this instrument in the portfolio, in
            asset currency. Present when pnlLevel=DailyPnl.
          example: -18.42
        dailyGainAccountCurrency:
          type: number
          format: double
          description: >-
            Today's unrealized gain for this instrument in the portfolio, in
            account currency. Present when pnlLevel=DailyPnl.
          example: -18.42
    TradingPortfolioDemoApi_AggregatedPortfolioMirrorAggregate:
      type: object
      description: Aggregated data for a single copy-trading relationship.
      properties:
        mirrorId:
          type: integer
          format: int32
          description: Mirror identifier. A value of 0 represents manually held positions.
        mirrorAvailableCash:
          type: number
          format: double
          description: Cash available within this mirror for new copy positions.
        mirrorDepositTotal:
          type: number
          format: double
          description: >-
            Total amount ever deposited into this mirror: initialInvestment +
            depositSummary.
        mirrorWithdrawalTotal:
          type: number
          format: double
          description: Total amount ever withdrawn from this mirror.
        mirrorStopLossPercentage:
          type: number
          format: double
          description: Stop-loss threshold as a percentage of the mirror's current value.
        mirrorStopLoss:
          type: number
          format: double
          description: >-
            Stop-loss threshold in account currency. The mirror liquidates when
            its value falls to this level.
        mirrorClosedPositionsPnl:
          type: number
          format: double
          description: Accumulated net profit from all closed positions within this mirror.
        mirrorTotals:
          $ref: >-
            #/components/schemas/TradingPortfolioDemoApi_AggregatedPortfolioMirrorTotals
        instrumentAggregates:
          type: array
          description: >-
            Positions held within this copy-trading mirror, grouped by
            instrument.
          items:
            $ref: >-
              #/components/schemas/TradingPortfolioDemoApi_AggregatedPortfolioInstrumentAggregate
    TradingPortfolioDemoApi_AggregatedPortfolioMirrorTotals:
      type: object
      description: Aggregated totals for a copy-trading mirror.
      properties:
        mirrorNetFunding:
          type: number
          format: double
          description: >-
            Net amount funded into the mirror: mirrorDepositTotal minus
            mirrorWithdrawalTotal.
        mirrorPositionsPnl:
          type: number
          format: double
          description: >-
            Total P&L from open and closed positions within the mirror, in
            account currency.
        mirrorLiquidationValue:
          type: number
          format: double
          description: 'Current mirror value: mirrorActiveMargin + mirrorPositionsPnl.'
        mirrorPositionsPnlPercent:
          type: number
          format: double
          description: mirrorPositionsPnl as a percentage of mirrorLiquidationValue.
        mirrorMarginPercent:
          type: number
          format: double
          description: >-
            This mirror's active margin as a percentage of the account's total
            used margin.
        mirrorValuePercent:
          type: number
          format: double
          description: >-
            This mirror's liquidation value as a percentage of the account's
            total value.
        mirrorActiveMargin:
          type: number
          format: double
          description: >-
            Total margin in active use within this mirror: mirrorAvailableCash +
            sum of position margins minus closed positions P&L.
        mirrorDailyGainAccountCurrency:
          type: number
          format: double
          description: >-
            Today's unrealized gain for this mirror in account currency. Present
            when pnlLevel=DailyPnl.
          example: -6.15
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key of the application. Only valid together with the x-user-key
        header — the pair is an alternative to OAuth bearer authentication,
        never sent alongside it. The pair is granted the same permissions the
        operation's OAuth scopes describe.


        Demo credential for trying the API from these docs:
        `lhgfaslk21490FAScVPkdsb53F9dNkfHG4faZSG5vfjndfcfgdssdgsdHF4663`
      x-default: lhgfaslk21490FAScVPkdsb53F9dNkfHG4faZSG5vfjndfcfgdssdgsdHF4663
    userKeyAuth:
      type: apiKey
      in: header
      name: x-user-key
      description: >-
        User-specific authentication key. Only valid together with the x-api-key
        header — the pair is an alternative to OAuth bearer authentication,
        never sent alongside it.


        Demo credential for trying the API from these docs:
        `eyJlYW4iOiJVbnJlZ2lzdGVyZWRBcHBsaWNhdGlvbiIsImVrIjoiOE5sZ2cwcW5EUVdROUFNWGpXT2lmOWktZnpidG5KcUlqWGJ3WHJZZkpZcldrbG90ZEhvLVBjSWhQaU8xU1ZtMW84aU1WZGZqN2xWNzFjLXFxLmcybXE1dnh4Q1hUT25xaWRUaTFlcEhmVk1fIn0_`
      x-default: >-
        eyJlYW4iOiJVbnJlZ2lzdGVyZWRBcHBsaWNhdGlvbiIsImVrIjoiOE5sZ2cwcW5EUVdROUFNWGpXT2lmOWktZnpidG5KcUlqWGJ3WHJZZkpZcldrbG90ZEhvLVBjSWhQaU8xU1ZtMW84aU1WZGZqN2xWNzFjLXFxLmcybXE1dnh4Q1hUT25xaWRUaTFlcEhmVk1fIn0_
    oauth2:
      type: oauth2
      description: >-
        eToro OAuth2 — send the access token as `Authorization: Bearer <token>`.
        Each operation lists the scopes that grant access as separate `security`
        requirements (OpenAPI OR semantics): the caller's token only needs ONE
        of them — you do NOT need all of them. Mutually exclusive with the
        x-api-key/x-user-key credential pair: never send both.
      flows:
        authorizationCode:
          authorizationUrl: https://www.etoro.com/sso
          tokenUrl: https://www.etoro.com/api/sso/v1/token
          scopes:
            etoro-public:agent-portfolio:read: Grants access to the 'etoro-public:agent-portfolio:read' scope.
            etoro-public:agent-portfolio:write: Grants access to the 'etoro-public:agent-portfolio:write' scope.
            etoro-public:club:read: Grants access to the 'etoro-public:club:read' scope.
            etoro-public:demo:read: Grants access to the 'etoro-public:demo:read' scope.
            etoro-public:demo:write: Grants access to the 'etoro-public:demo:write' scope.
            etoro-public:feed:read: Grants access to the 'etoro-public:feed:read' scope.
            etoro-public:feed:write: Grants access to the 'etoro-public:feed:write' scope.
            etoro-public:market-data:read: Grants access to the 'etoro-public:market-data:read' scope.
            etoro-public:money.balance:read: Grants access to the 'etoro-public:money.balance:read' scope.
            etoro-public:money.cash-transactions:read: >-
              Grants access to the 'etoro-public:money.cash-transactions:read'
              scope.
            etoro-public:money.transfer:read: Grants access to the 'etoro-public:money.transfer:read' scope.
            etoro-public:money.transfer:write: Grants access to the 'etoro-public:money.transfer:write' scope.
            etoro-public:money:transfer: Grants access to the 'etoro-public:money:transfer' scope.
            etoro-public:notifications:read: Grants access to the 'etoro-public:notifications:read' scope.
            etoro-public:notifications:write: Grants access to the 'etoro-public:notifications:write' scope.
            etoro-public:pi-data:read: Grants access to the 'etoro-public:pi-data:read' scope.
            etoro-public:price-alerts:read: Grants access to the 'etoro-public:price-alerts:read' scope.
            etoro-public:price-alerts:write: Grants access to the 'etoro-public:price-alerts:write' scope.
            etoro-public:real:read: Grants access to the 'etoro-public:real:read' scope.
            etoro-public:real:write: Grants access to the 'etoro-public:real:write' scope.
            etoro-public:sso-applications:read: Grants access to the 'etoro-public:sso-applications:read' scope.
            etoro-public:sso-applications:write: Grants access to the 'etoro-public:sso-applications:write' scope.
            etoro-public:sso-scopes:read: Grants access to the 'etoro-public:sso-scopes:read' scope.
            etoro-public:sso-scopes:write: Grants access to the 'etoro-public:sso-scopes:write' scope.
            etoro-public:sub-accounts:read: Grants access to the 'etoro-public:sub-accounts:read' scope.
            etoro-public:sub-accounts:write: Grants access to the 'etoro-public:sub-accounts:write' scope.
            etoro-public:trade.demo:read: Grants access to the 'etoro-public:trade.demo:read' scope.
            etoro-public:trade.demo:write: Grants access to the 'etoro-public:trade.demo:write' scope.
            etoro-public:trade.real:read: Grants access to the 'etoro-public:trade.real:read' scope.
            etoro-public:trade.real:write: Grants access to the 'etoro-public:trade.real:write' scope.
            etoro-public:user-info:read: Grants access to the 'etoro-public:user-info:read' scope.
            etoro-public:watchlist:read: Grants access to the 'etoro-public:watchlist:read' scope.
            etoro-public:watchlist:write: Grants access to the 'etoro-public:watchlist:write' scope.

````