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

# Ingest behavioural feed signals

> Authenticated. When UserSettings.analyticsPersonalization is false (#614), the payload is dropped at this endpoint and never persisted. Opted-in bodies are validated (zod) and stored as FeedSignal rows (#685): at most 50 events per request plus a 64KB body ceiling enforced before JSON parsing; unknown kind/filter rejected per event; dwellMs must be a finite positive number (booleans/numeric strings rejected), minimum normalized 1, clamped to 60s; opted-in writes are capped at 30 batches/min/user (429 RATE_LIMITED); client `at` clamped into the previous 24 hours ending at createdAt (future pinned to now). `accepted` counts the rows that survived validation (0 on the opt-out path). Rows older than FEED_SIGNAL_RETENTION_DAYS (default 90) are hard-deleted by the daily /api/cron/feed-signal-retention cron.



## OpenAPI

````yaml /api-reference/openapi.json post /api/feed/signals
openapi: 3.1.0
info:
  title: D-Sports API
  description: >-
    Public API for the D-Sports fan engagement platform (PWA backend). Most
    endpoints require Clerk Bearer authentication.
  version: 1.0.0
servers:
  - url: https://app.d-sports.org
    description: Production
  - url: http://localhost:3004
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Auth
    description: Authentication and token exchange
  - name: Logout
    description: Session logout
  - name: Mobile auth
    description: OAuth flow for native apps
  - name: Teams
    description: Teams list and follow/unfollow
  - name: Leaderboard
    description: Leaderboards, seasons, winners, stats
  - name: Locker room
    description: Social feed posts, comments, reactions
  - name: Packs
    description: Packs list, purchase, open
  - name: User
    description: Profile, onboarding, follow, search, privacy
  - name: Quests
    description: Quests and progress
  - name: Rewards
    description: Rewards claim and redeem
  - name: Wallets
    description: Wallets and coin prices
  - name: Checkout
    description: Crypto and D-Sports Cash checkout
  - name: D-Sports Cash
    description: D-Sports Cash balance
  - name: Dashboard
    description: Dashboard stats and balance
  - name: Products
    description: Products and packs catalog
  - name: Webhooks
    description: RevenueCat webhook
  - name: Misc
    description: Image proxy, crypto prices, upload, feedback
  - name: Auth and onboarding
    description: Domain grouping for auth, profile, onboarding, and identity flows
  - name: Social and locker room
    description: Domain grouping for social feed, follows, and community interactions
  - name: Gamification
    description: >-
      Domain grouping for quests, leaderboards, points-facing outcomes, and
      rewards
  - name: Commerce and purchases
    description: >-
      Domain grouping for checkout, cash balance, webhooks, and store purchase
      flows
  - name: Collectibles and packs
    description: Domain grouping for pack lifecycle and collectible inventory
  - name: Wallet and web3
    description: Domain grouping for wallet and crypto-support operations
  - name: Moderation and reporting
    description: >-
      Domain grouping for user-facing report submission and moderation-adjacent
      endpoints
  - name: Platform and infrastructure
    description: >-
      Domain grouping for utility, infrastructure, and platform support
      endpoints
  - name: Rep
    description: Fan / Club / Player / Direct Rep earn, breakdown, and ledger
  - name: Engage
    description: Engage-domain Rep and related mobile contracts
  - name: Admin
    description: Staff-only admin operations
  - name: Binders
    description: Digital binder inventory, PIN, and card transfer
  - name: Games
    description: Team mini-game catalog and play routes
  - name: Game Engine
    description: Engage native catalog and server-authoritative daily session lifecycle
  - name: Events
    description: Game schedule, Game Center, chat, presence, and ratings
  - name: Notifications
    description: Authenticated in-app inbox
  - name: Config
    description: Public catalogs and support matrices
  - name: Discovery
    description: Suggested fans and teams
  - name: Leagues
    description: League metadata and branding
  - name: Marketplace
    description: Listings, bids, offers, cart, and shop merchandising
  - name: KYC
    description: Identity verification session helpers
paths:
  /api/feed/signals:
    post:
      tags:
        - Feed
      summary: Ingest behavioural feed signals
      description: >-
        Authenticated. When UserSettings.analyticsPersonalization is false
        (#614), the payload is dropped at this endpoint and never persisted.
        Opted-in bodies are validated (zod) and stored as FeedSignal rows
        (#685): at most 50 events per request plus a 64KB body ceiling enforced
        before JSON parsing; unknown kind/filter rejected per event; dwellMs
        must be a finite positive number (booleans/numeric strings rejected),
        minimum normalized 1, clamped to 60s; opted-in writes are capped at 30
        batches/min/user (429 RATE_LIMITED); client `at` clamped into the
        previous 24 hours ending at createdAt (future pinned to now). `accepted`
        counts the rows that survived validation (0 on the opt-out path). Rows
        older than FEED_SIGNAL_RETENTION_DAYS (default 90) are hard-deleted by
        the daily /api/cron/feed-signal-retention cron.
      responses:
        '200':
          description: '{ success, data: { ingested: boolean, accepted: number } }'
        '401':
          description: Unauthenticated
        '413':
          description: Body exceeds the 64KB ingest ceiling (PAYLOAD_TOO_LARGE)
        '429':
          description: Per-user batch rate limit exceeded (RATE_LIMITED)
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Clerk session token. Use Authorization: Bearer <token>.'

````