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

# Get Trading Activity Feed

> Returns trading activity from the last 24 hours for one audience: everyone (all), the profiles the signed-in viewer follows (following), or a curated set of featured traders (featured). Entries are Bought, Sold, Resolved, Parlay placed, and Parlay resolved events, newest first.

Returns a feed of trading activity from the last 24 hours, newest first. Entries cover buys, sells, market resolutions, and pack (parlay) placements and resolutions. Public for the `all` and `featured` audiences; the `following` audience requires authentication.

## When to use

Use this endpoint to render an activity feed of what traders are doing on the platform right now. Choose a global stream, a curated list of featured traders, or a personal stream of the profiles the signed-in viewer follows. The API filters out small activity server-side so the feed stays meaningful.

## Audiences

The `audience` query parameter selects which profiles the feed reads:

* `all` (default): activity from every profile. Public.
* `featured`: activity from a curated set of featured traders. Public.
* `following`: activity from the profiles the viewer follows. Requires authentication; an unauthenticated request returns `401 Unauthorized`.

If the first `featured` page has no entries, the API serves the `all` stream instead and sets `effectiveAudience: "all"` in the response. A new viewer never lands on an empty screen. The returned cursor carries the effective audience, and continuation requests keep paging that same stream.

On the `following` audience, `emptyReason` distinguishes two empty states without a second request: `NO_FOLLOWS` when the viewer follows nobody, `NO_RECENT_ACTIVITY` when the followed profiles have been quiet. It is `null` everywhere else.

## Entry types

Each entry carries an `entryType` and a `facts` object with immutable event-time values:

* `BOUGHT` / `SOLD`: side, outcome, contracts, execution price, notional, and collateral symbol. `SOLD` entries also carry `realizedPnl`, `averageEntryPrice`, and `roi` when close data fully covers the fill; otherwise those fields are `null` and the entry shows the fill only.
* `RESOLVED`: the aggregated result (`WON`, `LOST`, or `BREAK_EVEN`) for a profile in one market or group, with realized PnL, cost basis, payout, and a per-market position breakdown.
* `PARLAY_PLACED` / `PARLAY_RESOLVED`: the pack's legs, stake, multiplier, and potential payout, plus the payout, realized PnL, and result once resolved.

## Display fields

Beyond `facts`, each entry carries display data that the API resolves at read time, when you fetch the page:

* `profile`: the trader's account, display name, username, profile picture, rank name, and connected X handle (`xHandle`, `null` when no X account is connected).
* `subject`: the market or group the entry is about, including its `imageUrl` card image and a `tradable` flag that turns `false` once the subject can no longer be traded. `null` on parlay entries.
* `parlay` (parlay entries only): the source pack's name (`null` for a custom parlay or a deleted pack) and ordered leg details, including crest image, named outcomes, league, teams, live score, and fixture kickoff. Use `parlay.legs[].startsAt` for match times; `facts.legs[].startsAt` is the market deadline, not the kickoff.
* `positionNow`: the trader's live position in the subject market as of when the page was fetched, with contracts, average entry price, current value, payout if the position wins, and unrealized PnL. `null` when there is no open position or no usable price mark.

## Pagination

* `limit` accepts 1-30 and defaults to 30.
* Pass `nextCursor` from the previous page as `cursor` to fetch the next page. `nextCursor` is `null` on the last page.
* The cursor is opaque and pinned to the audience that issued it. A malformed or tampered cursor returns `400` with code `TRADING_FEED_CURSOR_INVALID`; a cursor sent with a different audience returns `400` with code `TRADING_FEED_CURSOR_AUDIENCE_MISMATCH`.

## Availability

The feed fails closed rather than serving incomplete data:

* `503` with code `TRADING_FEED_INITIALIZING` while the API is still building the first 24-hour window after a deployment.
* `503` with code `TRADING_FEED_STALE` when the feed is temporarily behind.

Both are transient; retry later.

## Caching

Responses for `all` and `featured` carry `Cache-Control: public, s-maxage=60, stale-while-revalidate=30`, so CDN edges may serve a shared cached copy for up to a minute. `following` responses are per-viewer and carry `private, no-store`.

## Example

```bash theme={null}
curl "https://api.limitless.exchange/feed/trading?audience=all&limit=10"
```

```json theme={null}
{
  "requestedAudience": "all",
  "effectiveAudience": "all",
  "events": [
    {
      "id": "clob:123456:42",
      "entryType": "BOUGHT",
      "occurredAt": "2026-09-02T14:03:11.482910Z",
      "facts": {
        "side": "BUY",
        "outcome": "YES",
        "contracts": "120",
        "price": "0.540000",
        "notional": "64.800000",
        "symbol": "USDC"
      },
      "profile": {
        "id": 42,
        "account": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        "displayName": "Alice",
        "username": "alice",
        "pfpUrl": "https://...",
        "rankName": "Expert",
        "xHandle": "alice_trades"
      },
      "subject": {
        "kind": "MARKET",
        "id": 9876,
        "slug": "will-x-happen-123",
        "groupSlug": null,
        "title": "Will X happen?",
        "status": "FUNDED",
        "imageUrl": "https://...",
        "tradable": true
      },
      "parlay": null,
      "positionNow": {
        "contracts": "120",
        "averageEntryPrice": "0.540000",
        "currentValue": "68.400000",
        "payoutIfWins": "120.000000",
        "unrealizedPnl": "3.600000"
      }
    }
  ],
  "hasMore": true,
  "nextCursor": "eyJ2IjoxLCJhIjoi...",
  "emptyReason": null
}
```


## OpenAPI

````yaml GET /feed/trading
openapi: 3.0.0
info:
  title: Limitless Exchange API
  description: >-

    # Limitless Exchange Trading API


    *Production-ready API for prediction market trading, portfolio management,
    and market data*


    > 🎯 **Quick Navigation**: [Authentication](#tag/authentication) |
    [Markets](#tag/markets) | [Trading](#tag/trading) |
    [Portfolio](#tag/portfolio)


    ---
      


    ## 🚀 Quick Start


    Choose your preferred programming language for complete end-to-end
    implementation:


    ### Overview


    The Limitless Exchange API offers both REST and WebSocket integration:


    **REST API (Trading)**:

    1. **🔐 Authentication**: Use API key for all programmatic access

    2. **📊 Fetch Market Data**: Get market info including venue contract
    addresses (once per market)

    3. **📋 Order Creation**: Build and sign orders using EIP-712 structured
    data

    4. **🚀 Order Submission**: Submit signed orders and receive confirmations


    **WebSocket API (Real-Time Data)**:

    1. **🔌 Connection**: Connect to `/markets` namespace for real-time updates

    2. **📊 Subscriptions**: Subscribe to market prices and position changes

    3. **📡 Events**: Handle live market data and transaction updates


    ### 🔐 Authentication for API Users


    > **⚠️ DEPRECATION NOTICE**: Cookie-based session authentication is
    deprecated and will be removed within weeks. Please migrate to API keys
    immediately.


    | Method | Header | Status |

    |--------|--------|--------|

    | **API Key** | `X-API-Key: lmts_...` | ✅ Required for programmatic access |

    | Cookie Session | `Cookie: limitless_session=...` | ⚠️ Deprecated (removal
    imminent) |


    **Getting an API Key**


    API keys can only be created via the Limitless Exchange UI:

    1. Log in to [limitless.exchange](https://limitless.exchange) using your
    wallet

    2. Click your profile menu (top right)

    3. Select "Api keys"

    4. Generate a new key


    **Using Your API Key**


    Include in all requests via the `X-API-Key` header:


    ```bash

    # REST API

    curl -H "X-API-Key: lmts_your_key_here"
    https://api.limitless.exchange/markets


    # WebSocket - pass X-API-Key header during connection handshake

    ```


    ### Migration from Cookie to API Key


    If you're currently using cookie-based authentication, migrate by:


    1. **Generate an API key** via the UI (profile menu → Api keys)

    2. **Replace cookie header** with API key header:


    ```diff

    # Before (deprecated)

    - Cookie: limitless_session=your_session_token


    # After

    + X-API-Key: lmts_your_key_here

    ```


    3. **Remove session management code** - no more login flow or cookie
    handling needed


    ### Important: Venue System for CLOB Markets


    CLOB markets use a **venue system** where each market is associated with
    specific contract addresses. Before placing orders:


    1. **Fetch market data once**: `GET /markets/:slug` returns venue
    information

    2. **Use venue.exchange**: This is the `verifyingContract` for EIP-712 order
    signing

    3. **Cache the venue**: Venue data is static per market - fetch once and
    reuse


    **Sample venue response:**

    ```json

    {
      "venue": {
        "exchange": "0xA1b2C3...",
        "adapter": "0xD4e5F6..."
      }
    }

    ```


    ### Required Approvals


    Before trading, set up token approvals based on order type:


    | Order Type | Market Type | Approve To |

    |------------|-------------|------------|

    | BUY | All CLOB | USDC → `venue.exchange` |

    | SELL | Simple CLOB | CT → `venue.exchange` |

    | SELL | NegRisk/Grouped | CT → `venue.exchange` AND `venue.adapter` |


    ### Checksummed Addresses


    All addresses must use **checksummed format** (EIP-55 mixed-case):

    - Authentication: `x-account` header

    - Orders: `maker` and `signer` fields

    - Example: `0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed`


    ### Implementation Guides


    **[🐍 Python Quick Start](#description/-python-quick-start)**

    - REST API: eth-account, requests, and web3.py libraries

    - WebSocket: python-socketio, asyncio integration


    **[☕ Java Quick Start](#description/-java-quick-start)**  

    - REST API: Web3j, OkHttp3, and Jackson libraries


    **[📦 Node.js/TypeScript Quick
    Start](#description/-nodejs-typescript-quick-start)**

    - REST API: viem, ethers, and cross-fetch libraries

    - WebSocket: socket.io-client for real-time trading

    - Full TypeScript support with end-to-end examples


    **[🔌 WebSocket Integration](#description/-websocket-integration)**

    - Real-time market data and position updates

    - Production-ready Python client with authentication


    ---
      


    ## 🐍 Python Quick Start


    Complete end-to-end Python implementation for Limitless Exchange API
    integration.
      


    ### 🐍 Python E2E Order Creation Guide


    Complete Python implementation guide is being loaded from external
    documentation...


    **Guide Contents:**

    - 🔐 Complete authentication flow with eth-account

    - 📋 Order construction with Web3.py calculations

    - ✍️ EIP-712 structured data signing

    - 🚀 Order submission with requests library

    - ⚠️ Comprehensive error handling

    - 🛠️ Production deployment considerations


    *For the complete Python guide, ensure the file is available at
    docs/scripts-samples/python-e2e-order-creation.md*
        


    ## ☕ Java Quick Start


    Complete end-to-end Java implementation for Limitless Exchange API
    integration.
      


    ### ☕ Java E2E Order Creation Guide


    Complete Java enterprise implementation guide is being loaded from external
    documentation...


    **Guide Contents:**

    - 🔐 Complete authentication flow with Web3j

    - 📋 Order construction with BigInteger precision

    - ✍️ EIP-712 structured data signing

    - 🚀 Order submission with OkHttp3

    - ⚠️ Enterprise error handling patterns

    - 🏗️ Production Maven project structure


    *For the complete Java guide, ensure the file is available at
    docs/scripts-samples/java-e2e-order-creation.md*
        


    ## 📦 Node.js/TypeScript Quick Start


    Complete end-to-end Node.js/TypeScript implementation for trading and
    WebSocket subscriptions.
      


    ### 📦 Node.js/TypeScript Trading & WebSocket Guide


    Complete Node.js/TypeScript implementation guide is being loaded from
    external documentation...


    **Guide Contents:**

    - 🔐 **Authentication**: Wallet-based auth with ethers and viem

    - 📋 **Order Creation**: EIP-712 signing with viem WalletClient

    - 🚀 **Order Submission**: REST API integration with cross-fetch

    - 🔌 **WebSocket Subscriptions**: socket.io-client for real-time updates

    - 📊 **Market Data**: AMM prices and CLOB orderbook subscriptions

    - ⚠️ **Type Safety**: Full TypeScript support with proper types

    - 🛠️ **Production Ready**: Complete end-to-end working example


    **Key Features:**

    - **Combined Subscriptions**: Subscribe to both AMM and CLOB markets
    simultaneously

    - **Authentication Flow**: Complete wallet-based authentication with session
    management

    - **Trading Integration**: Place orders and receive real-time updates

    - **TypeScript First**: Type-safe implementation with proper interfaces


    *For the complete Node.js guide, ensure the file is available at
    docs/scripts-samples/node-socket-trading-and-subscribe.md*
        


    ## 🔌 WebSocket Integration


    Real-time market data and position updates using WebSocket connections.
      


    ### 🔌 WebSocket Real-Time Integration Guide


    Complete WebSocket implementation guide is being loaded from external
    documentation...


    **Guide Contents:**

    - 🔌 **WebSocket Connection**: python-socketio client with async support

    - 🔐 **Authentication**: JWT session cookie integration

    - 📊 **Market Subscriptions**: Real-time price updates and position changes

    - ⚡ **Event Handling**: Comprehensive event processing patterns

    - 🔄 **Auto-Reconnection**: Production-ready reconnection logic

    - 🛠️ **Error Recovery**: Robust error handling and fallback strategies


    **Key Features:**

    - **Public Mode**: Market price updates without authentication

    - **Authenticated Mode**: Full access to positions and transactions

    - **Multi-Market Support**: Subscribe to multiple markets simultaneously

    - **Production Ready**: Tested patterns for production deployment


    *For the complete WebSocket guide, ensure the file is available at
    docs/scripts-samples/python-socket-subscribe.md*
        
  version: '1.0'
  contact:
    name: API Support
    url: https://limitless.exchange
    email: hey@limitless.network
servers:
  - url: https://api.limitless.exchange
    description: Production API
security: []
tags:
  - name: Authentication
    description: User authentication and session management
  - name: Markets
    description: Browse, search, and analyze prediction markets
  - name: Market Navigation
    description: Navigation tree, market pages, and property filters
  - name: Trading
    description: Create, manage, and cancel orders
  - name: Portfolio
    description: Position tracking, trade history, and performance
  - name: Feed
    description: Public trading activity feeds
paths:
  /feed/trading:
    get:
      tags:
        - Feed
      summary: Get the public trading activity feed
      description: >-
        Returns trading activity from the last 24 hours for one audience:
        everyone (all), the profiles the signed-in viewer follows (following),
        or a curated set of featured traders (featured). Entries are Bought,
        Sold, Resolved, Parlay placed, and Parlay resolved events, newest first.
      operationId: TradingFeedController_getTradingFeed
      parameters:
        - name: audience
          required: false
          in: query
          description: >-
            Which set of profiles to read. `following` requires authentication.
            Defaults to `all`.
          schema:
            type: string
            enum:
              - all
              - following
              - featured
            default: all
        - name: limit
          required: false
          in: query
          description: Entries per page (1-30).
          schema:
            type: number
            default: 30
            minimum: 1
            maximum: 30
        - name: cursor
          required: false
          in: query
          description: >-
            Opaque cursor from `nextCursor` on the previous page. A cursor is
            pinned to the audience that issued it; sending it with a different
            audience returns 400.
          schema:
            type: string
      responses:
        '200':
          description: One page of trading activity, newest first
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TradingFeedResponseDto'
        '400':
          description: >-
            Malformed or tampered cursor (`TRADING_FEED_CURSOR_INVALID`), or a
            cursor issued for a different audience
            (`TRADING_FEED_CURSOR_AUDIENCE_MISMATCH`)
        '401':
          description: The `following` audience was requested without authentication
        '503':
          description: >-
            Feed unavailable: `TRADING_FEED_INITIALIZING` while the first
            24-hour window is still being built, or `TRADING_FEED_STALE` when
            the feed is temporarily behind. Retry later; the feed never serves
            stale data as if it were fresh.
components:
  schemas:
    TradingFeedResponseDto:
      type: object
      properties:
        requestedAudience:
          type: string
          enum:
            - all
            - following
            - featured
          description: The audience the request asked for
        effectiveAudience:
          type: string
          enum:
            - all
            - following
            - featured
          description: >-
            The audience actually served. Differs from requestedAudience only
            when a first featured page was empty and fell back to all; the
            cursor carries this value so continuation requests keep paging the
            same stream.
        events:
          type: array
          items:
            $ref: '#/components/schemas/TradingFeedEntryDto'
        hasMore:
          type: boolean
        nextCursor:
          type: string
          nullable: true
          description: >-
            Pass as `cursor` with the same audience to fetch the next page; null
            on the last page
        emptyReason:
          type: string
          nullable: true
          enum:
            - NO_FOLLOWS
            - NO_RECENT_ACTIVITY
            - null
          description: >-
            Only meaningful on the following audience: distinguishes a viewer
            who follows nobody from followed profiles that have been quiet
      required:
        - requestedAudience
        - effectiveAudience
        - events
        - hasMore
        - nextCursor
        - emptyReason
    TradingFeedEntryDto:
      type: object
      description: >-
        One feed entry. `facts` holds immutable event-time values whose shape
        depends on `entryType`; live state is hydrated separately into
        `positionNow` and `parlay`.
      properties:
        id:
          type: string
        entryType:
          type: string
          enum:
            - BOUGHT
            - SOLD
            - RESOLVED
            - PARLAY_PLACED
            - PARLAY_RESOLVED
        occurredAt:
          type: string
          description: When the underlying event happened (ISO 8601)
        facts:
          type: object
          description: >-
            Immutable event-time values. BOUGHT/SOLD carry side, outcome,
            contracts, price, notional, and symbol, with realizedPnl,
            averageEntryPrice, and roi populated on SOLD entries when close data
            fully covers the fill. RESOLVED carries result (WON, LOST, or
            BREAK_EVEN), realizedPnl, costBasis, payout, and per-market position
            breakdowns. PARLAY_PLACED and PARLAY_RESOLVED carry legs, stake,
            multiplier, potentialPayout, and, once resolved, payout,
            realizedPnl, and result.
          additionalProperties: true
        profile:
          $ref: '#/components/schemas/TradingFeedProfileDto'
        subject:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TradingFeedSubjectDto'
        parlay:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TradingFeedParlayDisplayDto'
        positionNow:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TradingFeedPositionNowDto'
      required:
        - id
        - entryType
        - occurredAt
        - facts
        - profile
        - subject
        - parlay
        - positionNow
    TradingFeedProfileDto:
      type: object
      description: >-
        Public profile fields for the trader on a feed entry. A profile with no
        display name can be rendered as its truncated account address.
      properties:
        id:
          type: number
          description: Profile id, the same id used by the follow endpoints
        account:
          type: string
          description: Ethereum address of the trader
        displayName:
          type: string
          nullable: true
        username:
          type: string
          nullable: true
        pfpUrl:
          type: string
          nullable: true
          description: Profile picture URL
        rankName:
          type: string
          nullable: true
          description: Leaderboard rank name, if the trader has one
        xHandle:
          type: string
          nullable: true
          description: >-
            The trader's connected X (Twitter) handle, or null when no X account
            is connected
      required:
        - id
        - account
        - displayName
        - username
        - pfpUrl
        - rankName
        - xHandle
    TradingFeedSubjectDto:
      type: object
      description: The market or group the entry is about. Null on parlay entries.
      properties:
        kind:
          type: string
          enum:
            - MARKET
            - GROUP
        id:
          type: number
        slug:
          type: string
        groupSlug:
          type: string
          nullable: true
          description: Slug of the parent group when the subject market belongs to one
        title:
          type: string
        status:
          type: string
        imageUrl:
          type: string
          nullable: true
          description: Card image for the market or group
        tradable:
          type: boolean
          description: >-
            Whether a Trade action should be offered; false once the subject can
            no longer be traded
      required:
        - kind
        - id
        - slug
        - groupSlug
        - title
        - status
        - imageUrl
        - tradable
    TradingFeedParlayDisplayDto:
      type: object
      description: >-
        Display block for parlay entries, hydrated at read time. Null for every
        other entry type.
      properties:
        name:
          type: string
          nullable: true
          description: >-
            Name of the pack the parlay was bought from; null for a custom
            parlay or a deleted pack
        legs:
          type: array
          items:
            $ref: '#/components/schemas/TradingFeedParlayLegDisplayDto'
      required:
        - name
        - legs
    TradingFeedPositionNowDto:
      type: object
      description: >-
        Live position state for the trader who made this entry, as of when the
        page was fetched. Null when there is no open position or no usable price
        mark.
      properties:
        contracts:
          type: string
        averageEntryPrice:
          type: string
        currentValue:
          type: string
        payoutIfWins:
          type: string
        unrealizedPnl:
          type: string
      required:
        - contracts
        - averageEntryPrice
        - currentValue
        - payoutIfWins
        - unrealizedPnl
    TradingFeedParlayLegDisplayDto:
      type: object
      description: >-
        Read-time display metadata for one parlay leg, in the parlay's leg
        order.
      properties:
        marketId:
          type: number
        imageUrl:
          type: string
          nullable: true
          description: Crest or market image for the leg
        outcomeLabels:
          type: array
          nullable: true
          description: Named outcome labels as a [yes, no] pair
          items:
            type: string
          minItems: 2
          maxItems: 2
        outcomeImageUrls:
          type: array
          nullable: true
          description: Outcome images as a [yes, no] pair; individual entries can be null
          items:
            type: string
            nullable: true
          minItems: 2
          maxItems: 2
        leagueName:
          type: string
          nullable: true
        homeTeam:
          type: string
          nullable: true
        awayTeam:
          type: string
          nullable: true
        homeScore:
          type: number
          nullable: true
          description: >-
            Live score as of when the page was fetched; 0 is a real score, null
            means no score
        awayScore:
          type: number
          nullable: true
          description: >-
            Live score as of when the page was fetched; 0 is a real score, null
            means no score
        startsAt:
          type: string
          nullable: true
          description: >-
            Fixture kickoff time. Note that facts.legs[].startsAt is the market
            deadline, not the kickoff; use this field for match times.
      required:
        - marketId
        - imageUrl
        - outcomeLabels
        - outcomeImageUrls
        - leagueName
        - homeTeam
        - awayTeam
        - homeScore
        - awayScore
        - startsAt

````