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

# Get portfolio summary

> The total value and cost basis of all your open positions, in one call. Use it for a portfolio headline without paging through [List positions](/predictions/reference/positions/list-positions).

`value` marks each open position at the current ask on the side you hold (contracts held times that ask), summed. `cost_basis` is what those same contracts cost plus the fees on every executed order on each open position, including sells and earlier round trips in the same market. The difference, `value` minus `cost_basis`, is your unrealized profit or loss; profit already locked in by sales and settlements is `realized_pnl` on each position, not part of this summary. Both are dollars rounded to cents, and both are 0 when you hold nothing.



## OpenAPI

````yaml /predictions/openapi.json get /portfolio/summary
openapi: 3.1.0
info:
  title: Splash Predictions API
  version: 1.0.0
  description: >-
    Splash prediction markets: leagues, games, game lines, futures and player
    props, and the signed routes to place orders, read your orders, positions
    and transactions, and read your account's fee settings and cash balance. The
    market endpoints need no authentication; the order, position, account and
    balance endpoints are [signed with an API key](/predictions/authentication).
servers:
  - url: https://api.splashsports.com/predictions-service/api
    description: Production
security: []
tags:
  - name: Discover
    description: The home feed.
  - name: Sub-categories
    description: Leagues, their availability and their tabs.
  - name: Markets
    description: Market group listings and single groups.
  - name: Events
    description: One game's markets, shaped for the game page.
  - name: Orders
    description: Place orders and read them. Signed requests.
  - name: Positions
    description: Read your positions. Signed requests.
  - name: Activity
    description: 'Your transaction history: fills and settlement payouts. Signed requests.'
  - name: Account
    description: Your fee settings, maximum trade and cash balance. Signed requests.
paths:
  /portfolio/summary:
    get:
      tags:
        - Positions
      summary: Get portfolio summary
      description: >-
        The total value and cost basis of all your open positions, in one call.
        Use it for a portfolio headline without paging through [List
        positions](/predictions/reference/positions/list-positions).


        `value` marks each open position at the current ask on the side you hold
        (contracts held times that ask), summed. `cost_basis` is what those same
        contracts cost plus the fees on every executed order on each open
        position, including sells and earlier round trips in the same market.
        The difference, `value` minus `cost_basis`, is your unrealized profit or
        loss; profit already locked in by sales and settlements is
        `realized_pnl` on each position, not part of this summary. Both are
        dollars rounded to cents, and both are 0 when you hold nothing.
      operationId: getPortfolioSummary
      responses:
        '200':
          description: The summary of your open positions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PortfolioSummaryResponse'
              examples:
                Open positions:
                  summary: Open positions
                  value:
                    status: success
                    summary:
                      value: 42.5
                      cost_basis: 38.74
                  description: >-
                    The positions are worth $42.50 now against $38.74 paid, fees
                    included.
                No open positions:
                  summary: No open positions
                  value:
                    status: success
                    summary:
                      value: 0
                      cost_basis: 0
                  description: Both amounts are 0, never absent.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/Unavailable'
      security:
        - SplashAccessKey: []
          SplashAccessTimestamp: []
          SplashAccessSignature: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            KEY="your-key-id"

            SECRET="your-secret"

            METHOD="GET"

            URLPATH="/predictions-service/api/portfolio/summary"

            BODY=""


            TS=$(( $(date +%s) * 1000 ))

            SIG=$(printf '%s' "$TS$METHOD$URLPATH$BODY" | openssl dgst -sha256
            -hmac "$SECRET" -binary | base64)


            curl -X "$METHOD" "https://api.splashsports.com$URLPATH" \
              -H "SPLASH-ACCESS-KEY: $KEY" \
              -H "SPLASH-ACCESS-TIMESTAMP: $TS" \
              -H "SPLASH-ACCESS-SIGNATURE: $SIG"
        - lang: python
          label: Python
          source: >-
            import base64, hashlib, hmac, json, time

            import requests


            KEY = "your-key-id"

            SECRET = "your-secret"

            HOST = "https://api.splashsports.com"



            def sign(secret, timestamp, method, path, body):
                message = (timestamp + method + path + body).encode("utf-8")
                digest = hmac.new(secret.encode("utf-8"), message, hashlib.sha256).digest()
                return base64.b64encode(digest).decode("ascii")


            def request(method, path, payload=None):
                body = json.dumps(payload, separators=(",", ":")) if payload is not None else ""
                timestamp = str(int(time.time() * 1000))
                headers = {
                    "Content-Type": "application/json",
                    "SPLASH-ACCESS-KEY": KEY,
                    "SPLASH-ACCESS-TIMESTAMP": timestamp,
                    "SPLASH-ACCESS-SIGNATURE": sign(SECRET, timestamp, method, path, body),
                }
                return requests.request(method, HOST + path, headers=headers, data=body.encode("utf-8"))


            response = request("GET",
            "/predictions-service/api/portfolio/summary")

            print(response.status_code, response.json())
        - lang: typescript
          label: TypeScript
          source: >-
            import { createHmac } from "node:crypto";


            const KEY = "your-key-id";

            const SECRET = "your-secret";

            const HOST = "https://api.splashsports.com";


            function sign(secret: string, timestamp: string, method: string,
            path: string, body: string): string {
              return createHmac("sha256", secret).update(timestamp + method + path + body, "utf8").digest("base64");
            }


            const method = "GET";

            const path = "/predictions-service/api/portfolio/summary";

            const body = "";

            const timestamp = Date.now().toString();


            const response = await fetch(HOST + path, {
              method,
              headers: {
                "SPLASH-ACCESS-KEY": KEY,
                "SPLASH-ACCESS-TIMESTAMP": timestamp,
                "SPLASH-ACCESS-SIGNATURE": sign(SECRET, timestamp, method, path, body),
              },
            });

            console.log(response.status, await response.json());
        - lang: go
          label: Go
          source: "package main\n\nimport (\n\t\"bytes\"\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"time\"\n)\n\nconst (\n\tkey    = \"your-key-id\"\n\tsecret = \"your-secret\"\n\thost   = \"https://api.splashsports.com\"\n)\n\nfunc sign(secret, timestamp, method, path string, body []byte) string {\n\tmac := hmac.New(sha256.New, []byte(secret))\n\tmac.Write([]byte(timestamp + method + path))\n\tmac.Write(body)\n\treturn base64.StdEncoding.EncodeToString(mac.Sum(nil))\n}\n\nfunc main() {\n\tmethod := \"GET\"\n\tpath := \"/predictions-service/api/portfolio/summary\"\n\n\tvar body []byte // no body: the signature covers the empty string\n\ttimestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)\n\n\treq, err := http.NewRequest(method, host+path, bytes.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treq.Header.Set(\"SPLASH-ACCESS-KEY\", key)\n\treq.Header.Set(\"SPLASH-ACCESS-TIMESTAMP\", timestamp)\n\treq.Header.Set(\"SPLASH-ACCESS-SIGNATURE\", sign(secret, timestamp, method, path, body))\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\tout, _ := io.ReadAll(resp.Body)\n\tfmt.Println(resp.StatusCode, string(out))\n}"
components:
  schemas:
    PortfolioSummaryResponse:
      type: object
      title: PortfolioSummaryResponse
      description: The summary of your open positions.
      required:
        - status
        - summary
      properties:
        status:
          type: string
          const: success
          description: Always `success` on a 200.
          example: success
        summary:
          $ref: '#/components/schemas/PortfolioSummary'
          description: Value and cost basis of your open positions.
      example:
        status: success
        summary:
          value: 42.5
          cost_basis: 38.74
    PortfolioSummary:
      type: object
      title: PortfolioSummary
      description: >-
        Your open positions added up. Both amounts are in dollars, rounded to
        cents.
      required:
        - value
        - cost_basis
      properties:
        value:
          type: number
          description: >-
            Current value of everything you hold: for each open position, the
            contracts held times the current ask on the side you hold, summed. 0
            when you hold nothing.
          example: 42.5
        cost_basis:
          type: number
          description: >-
            For each open position, the cost of the contracts you hold now plus
            the fees on every executed order on that position, summed. The fees
            include sells and orders from earlier times you opened and closed
            the same market, so after trading in and out of a market this is
            more than the open contracts cost. Compare with `value` for
            unrealized profit or loss. 0 when you hold nothing.
          example: 38.74
      example:
        value: 42.5
        cost_basis: 38.74
    TradingError:
      type: object
      title: TradingError
      description: >-
        The error body of the signed order and position routes. Same shape as
        the public `Error`, with the codes those routes can return. Branch on
        `error`; `message` is for people. See
        [Errors](/predictions/trading#errors).
      required:
        - status
        - error
        - message
      properties:
        status:
          type: string
          const: error
          description: Always `error` on an error response.
          example: error
        error:
          type: string
          description: >-
            Machine-readable code; branch on this. A string: the values below
            are the ones these routes return today, and a code not listed here
            should be handled by its HTTP status. See [Trading error
            codes](/predictions/enums#trading-error-codes-error).


            - `BAD_REQUEST` (400): invalid body or query, or an order check
            failed.

            - `NOT_AUTHORIZED` (401): the signature check failed, the request
            had no `SPLASH-ACCESS-KEY` header, or `user_id` was passed to `GET
            /orders`, `GET /orders/{id}`, `GET /positions`, `GET
            /positions/{id}` or `GET /transactions`.

            - `FOBIDDEN` (403): `Not authorized to trade`, the account may not
            trade. `FOBIDDEN` is the literal value the API returns (not
            `FORBIDDEN`); match it exactly.

            - `NOT_FOUND` (404): no such order, position or market on your
            account.

            - `DUPLICATE_REQUEST_ID` (409): another account used this
            `request_id`.

            - `UNSUPPORTED_MEDIA_TYPE` (415): a signed body that is not JSON.

            - `INTERNAL_ERROR` (500): the request could not be handled. On `POST
            /trading/orders` the order was not placed; poll the `request_id`,
            then try again with a new one.

            - `TRADING_API_UNAVAILABLE` (503): the Trading API is not taking
            signed requests; retry later.

            - `EXCHANGE_UNAVAILABLE`, `SERVICE_UNAVAILABLE` (503): the order
            could not be placed right now; retry later with a new `request_id`.
            On `GET /balance`, `SERVICE_UNAVAILABLE` means your balance could
            not be read; retry shortly.


            A `429 Too Many Requests` is the rate limit, not one of these codes;
            see [Rate limits](/predictions/rate-limits). Whether an order's
            `request_id` can be reused after an error: see [Order outcomes and
            retries](/predictions/trading#order-outcomes-and-retries).
          example: FOBIDDEN
        message:
          type: string
          description: >-
            Human-readable detail. For `BAD_REQUEST` and `NOT_AUTHORIZED` it
            names the cause, e.g. `Invalid price` or `Invalid signature`. Do not
            branch on it.
          example: Not authorized to trade
      example:
        status: error
        error: FOBIDDEN
        message: Not authorized to trade
    TooManyRequestsError:
      type: object
      title: TooManyRequestsError
      description: >-
        The body of a `429 Too Many Requests`: more than 10 requests per second
        from your IP address. It is not a `TradingError`; branch on the `429`
        status. See [Rate limits](/predictions/rate-limits).
      required:
        - status
        - error
        - message
      properties:
        status:
          type: string
          const: error
          description: Always `error`.
          example: error
        error:
          type: string
          const: TOO_MANY_REQUESTS
          description: Always `TOO_MANY_REQUESTS` on a rate-limited request.
          example: TOO_MANY_REQUESTS
        message:
          type: string
          description: Human-readable detail. Do not branch on it.
          example: Too many requests, try again later
      example:
        status: error
        error: TOO_MANY_REQUESTS
        message: Too many requests, try again later
    Error:
      type: object
      required:
        - status
        - error
        - message
      properties:
        status:
          type: string
          const: error
          description: Always `error` on an error response.
          example: error
        error:
          type: string
          enum:
            - BAD_REQUEST
            - NOT_FOUND
            - INTERNAL_ERROR
          description: >-
            Machine-readable code; branch on this. `BAD_REQUEST` (400),
            `NOT_FOUND` (404) or `INTERNAL_ERROR` (500). See [Error
            codes](/predictions/enums#error-codes-error).
          example: BAD_REQUEST
        message:
          type: string
          description: >-
            Human-readable detail for logs and people. Wording can change; do
            not branch on it.
          example: Invalid request parameters
      title: Error
      example:
        status: error
        error: BAD_REQUEST
        message: Invalid request parameters
  responses:
    Unauthorized:
      description: >-
        The signature check failed, or the request had no `SPLASH-ACCESS-KEY`
        header. A failed check's `message` is one of `Unknown API key`, `API key
        revoked`, `Timestamp outside the allowed window` or `Invalid signature`.
        `API key revoked` is reported only when the signature is correct, so a
        wrong secret always reads `Invalid signature`. A request without the
        `SPLASH-ACCESS-KEY` header is not an API request and is refused with
        `You are not authorized to perform the requested action.` See
        [Authentication
        errors](/predictions/authentication#authentication-errors).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TradingError'
          examples:
            Invalid signature:
              summary: Invalid signature
              value:
                status: error
                error: NOT_AUTHORIZED
                message: Invalid signature
              description: >-
                The signature does not match what Splash computed. Check that
                you signed the exact body bytes and the full path including
                `/predictions-service/api` and the query string.
            Timestamp outside the allowed window:
              summary: Timestamp outside the allowed window
              value:
                status: error
                error: NOT_AUTHORIZED
                message: Timestamp outside the allowed window
              description: >-
                `SPLASH-ACCESS-TIMESTAMP` is more than 30 seconds from server
                time. Check your clock.
            Unknown API key:
              summary: Unknown API key
              value:
                status: error
                error: NOT_AUTHORIZED
                message: Unknown API key
            API key revoked:
              summary: API key revoked
              value:
                status: error
                error: NOT_AUTHORIZED
                message: API key revoked
            Missing or misspelled key header:
              summary: Missing or misspelled key header
              value:
                status: error
                error: NOT_AUTHORIZED
                message: You are not authorized to perform the requested action.
              description: >-
                The request carried no `SPLASH-ACCESS-KEY` header, because it
                was not signed or the header name is misspelled. A request
                without the `SPLASH-ACCESS-KEY` header is not an API request and
                is refused. Send all three `SPLASH-ACCESS-*` headers.
    RateLimited:
      description: >-
        Too Many Requests: more than 10 requests per second from your IP
        address. The request was not handled and nothing was recorded. If the
        response has a `Retry-After` header, wait that many seconds; otherwise
        back off (about 1 second, with jitter). Then send the same request
        again; on `POST /trading/orders` reuse the same `request_id`. See [Rate
        limits](/predictions/rate-limits).
      headers:
        Retry-After:
          description: >-
            Optional, and may be absent. When present, the number of seconds to
            wait before retrying; when absent, back off about 1 second with
            jitter.
          required: false
          schema:
            type: integer
          example: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TooManyRequestsError'
          examples:
            Over the limit:
              summary: Over the limit
              value:
                status: error
                error: TOO_MANY_REQUESTS
                message: Too many requests, try again later
              description: >-
                More than 10 requests per second from your IP address. Nothing
                was recorded; wait about a second (or the `Retry-After` seconds
                when that header is present) and send the same request again.
    InternalError:
      description: >-
        The request could not be handled. On `POST /trading/orders` the order
        was not placed: poll `GET /orders?request_id=` before trying again. If
        the poll returns the order, follow it; otherwise send the order again
        with a new `request_id`, because this one now reads `cancelled`. See
        [Order outcomes and
        retries](/predictions/trading#order-outcomes-and-retries).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            The request could not be handled:
              summary: The request could not be handled
              value:
                status: error
                error: INTERNAL_ERROR
                message: >-
                  An internal error has occured and the request could not be
                  handled.
              description: >-
                The message is spelled `occured` on the wire. On `POST
                /trading/orders`, poll the `request_id` before trying again,
                then send the order with a new `request_id`.
    Unavailable:
      description: >-
        The Trading API cannot take signed requests right now
        (`TRADING_API_UNAVAILABLE`). Nothing was read or recorded. Retry later.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TradingError'
          examples:
            The Trading API is not available:
              summary: The Trading API is not available
              value:
                status: error
                error: TRADING_API_UNAVAILABLE
                message: The trading API is not available.
  securitySchemes:
    SplashAccessKey:
      type: apiKey
      in: header
      name: SPLASH-ACCESS-KEY
      description: >-
        Your API key id. Keys are issued by Splash on request, never expire, and
        stay valid until Splash revokes them, which it does on request. See
        [Authentication](/predictions/authentication).
    SplashAccessTimestamp:
      type: apiKey
      in: header
      name: SPLASH-ACCESS-TIMESTAMP
      description: Unix milliseconds, within 30 seconds of server time.
    SplashAccessSignature:
      type: apiKey
      in: header
      name: SPLASH-ACCESS-SIGNATURE
      description: >-
        `base64(HMAC-SHA256(secret, timestamp + METHOD + path + body))`. See
        [Authentication](/predictions/authentication).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.