Skip to content

Subscriber Auction Detail — REST & WebSocket Integration Guide

Complete contract for the subscriber auction detail screen: the REST read endpoint GET /v2/subscribers/me/auctions/:auctionId plus the realtime WebSocket events that keep that screen in sync.

Prebid is split across two transports:

  • REST — all reads and writes (auction detail, prebid place/edit/cancel).
  • WebSocket (/ws) — the live room: state snapshots, prebid/bid lifecycle events, announcements, presence, and phase transitions.

The WebSocket never creates or modifies prebids — REST is the source of truth for every write. The socket tells the UI what changed.

Related docs: Auction — Frontend Integration Guide · Subscriber Prebid REST · Auction participant presence and counts · WebSocket auction events · WebSocket prebid events · WebSocket protocol


1. The endpoint

GET /v2/subscribers/me/auctions/:auctionId
Aspect Value
Auth Authorization: Bearer <access-token>
Role SUBSCRIBER (403 otherwise)
Purpose Auction detail + prebid context for one auction the subscriber is enrolled in

1.1 Path parameter

Param Type Notes
auctionId string CUID. Invalid id → 400.

1.2 Query parameters

Param Type Default Notes
participantPageNumber integer 1 Minimum 1.
participantPageSize integer 10 Between 1 and 100.

1.3 Response envelope

Every successful response uses the standard envelope:

{
  "status": "success",
  "code": 200,
  "message": "Auction fetched successfully.",
  "data": {}
}

1.4 Error responses

Status Message (abridged) When
400 Invalid auctionId auctionId is not a valid CUID.
400 Auction is not enabled for this program. Program bid type is not auction-based.
401 — Missing/invalid bearer token.
403 — Authenticated user is not a SUBSCRIBER.
404 Auction not found. Auction does not exist, or the subscriber is not part of the auction's program.

2. Response data — field reference

2.1 Top level

Field Type Description
auctionId string Auction id.
cycleId string Cycle the auction belongs to.
cycleNumber number Cycle number within the program.
cycleStatus string CycleStatus enum (ACTIVE, UPCOMING, …).
programId string Program id.
programName string Program display name.
prebidDocumentRequired boolean Whether a prebid document + signature are required.
prebidDocumentTemplateVersionId string | null Pinned prebid document template version (form fields source).
chitId string | null Program chit id.
companyId string Operating company user id.
companyName / companyAvatar string | null Company branding.
companyBranch string | null Company branch.
totalAmount number | null Cycle total amount.
auctionStatus string AuctionStatus enum (SCHEDULED, LIVE, PAUSED, ENDED, …).
prebidPhase string Derived prebid phase: NONE | OPEN | CLOSED. OPEN drives prebid placement; live participation is driven by auctionStatus (LIVE/PAUSED/ENDED).
currentPhase string Always present — lifecycle summary (e.g. PENDING, PREBID_OPEN, PREBID_CLOSED, READY_TO_START, LIVE, PAUSED, ENDED). Render directly as a phase badge.
liveStartedAt string | null Always present — ISO-8601 live-start marker (null until the auction actually goes live; set once, never cleared).
prebidEndAt string | null Prebid window close (ISO-8601).
auctionStartAt string | null Scheduled live start (ISO-8601).
auctionEndAt string | null Computed end time (ISO-8601).
auctionDurationSeconds number | null Live auction duration.
prebidAmountsRevealed boolean True after staff reveal prebid amounts.
prebidAmountsRevealedAt string | null Reveal timestamp, or null before reveal.
minimumBidAmount number | null Floor for the bid amount.
settings object Auction config snapshot (below).
joinWindow object Current versioned join-window state.
audience object | null null until the persisted join window opens; afterward contains audience counts and conditionally visible participant identities.
liveBids array Visible live bids (auction-wide; empty unless LIVE/PAUSED/ENDED).
announcements array Room announcements (max 50).
enrollments array The subscriber's enrollments in this program (one per enrollment).
winners array Declared winners; populated once the auction has ended.

Note: leadingBidAmount and per-enrollment hasPlacedBid / bidCount / isLeadingBidder were removed from this endpoint. Live-bid leading state is served by the WebSocket snapshot and the cycle-scoped overview (GET /v2/subscribers/me/cycles/:cycleId/auction/:enrolledSubscriberId).

audience stays visible after the join window closes or the auction ends. Its counts are available to every enrolled subscriber once the window has opened:

interface SubscriberAuctionAudience {
  viewerCount: number;
  joinedParticipantCount: number;
  presentParticipantCount: number;
  bidderCount: number;
  participants: PaginatedResponse<{
    subscriberId: string;
    enrolledSubscriberId: string;
    name: string | null;
    avatar: string | null;
    joinSource: 'ONLINE' | 'FLOOR';
    joinedAt: string;
    presenceStatus: 'PRESENT' | 'LEFT';
    lastSeenAt: string | null;
  }> | null;
}

participants is populated only when at least one of the requesting subscriber's enrollments has joined the auction. It includes all durable joined participants, including the requester. joinSource records how participation was created, while joinedAt is the durable admission time. presenceStatus reflects current online or floor presence. lastSeenAt is always null for a present participant; for a participant who left, it is the most recent present-to-left transition time, or null if they have never been observed present.

2.2 settings

Field Type Description
hasPrebid boolean Whether prebid is enabled.
auctionBidMode string TOTAL_VALUE_DECREASING | DISCOUNT_INCREASING.
auctionClosingMode string DURATION_MODE | CALL_MODE.
auctionDurationSeconds number | null Live auction duration.
auctionExtensionSeconds number Per-bid extension.
auctionFirstCallSeconds / auctionSecondCallSeconds / auctionThirdCallSeconds number Call-mode timing.
subscriberJoinGraceSeconds number Late-join grace window.
subscriberJoinLeadSeconds number Seconds before start when the join window opens.
allowStaffOfflineBids boolean Offline bid support.
prebidMutabilityPolicy string MUTABLE_UNTIL_CLOSE | IMMUTABLE_CANCEL_ONLY.
auctionJoiningRule string BEFORE_START | …

2.3 liveBids[] (visible, auction-wide)

Field Type Description
id string Bid id.
enrolledSubscriberId string Bidder enrollment id.
subscriberName string | null Bidder display name.
subscriberAvatar string | null Bidder avatar URL.
amount number Bid amount.
createdAt string ISO-8601.

2.4 announcements[]

Field Type Description
id string Announcement id.
auctionId string —
cycleId string —
actorId string | null Author user id.
message string Announcement text.
tone string Tone marker (e.g. INFO).
createdAt string ISO-8601.

2.5 joinWindow

Field Type Description
status string SCHEDULED, OPEN, or CLOSED.
version number Increments on every reschedule.
opensAt / openedAt string | null Configured opening boundary and actual opening time.
closesAt / closedAt string | null Predicted and actual closing time.
joiningRule string BEFORE_START, GRACE_PERIOD, or ANYTIME.

Participant identities follow the conditional audience.participants rules above. Viewer identities and session audit data remain staff-only.

2.6 enrollments[]

One entry per enrollment of the subscriber in the program's cycle. Pick the one matching your enrolledSubscriberId — every prebid write must pass that id (see Subscriber Prebid REST).

Field Type Description
enrolledSubscriberId string Enrollment id — used for prebid place/edit/cancel.
invoiceStatus string | null InvoiceStatus enum (PAID, DRAFT, …).
currentUser object Eligibility for this enrollment (below).
liveBids array This subscriber's own live bids.
prebids array This subscriber's own prebids (max 20).

currentUser

Field Type Description
canViewDetails boolean True after the endpoint authorizes this subscriber and enrollment, including for a PENDING auction.
canSubscribeRealtime boolean True only for SCHEDULED, READY, LIVE, or PAUSED; use this before opening the auction WebSocket room.
accessMode string VIEWER or PARTICIPANT; restored from durable admission on reconnect.
hasJoined / joinedAt boolean / string | null Durable admission state and original join time.
canJoin / joinBlockedReason boolean / string | null Authoritative join-button state.
isPrebidDisqualified boolean Disqualified from the PREBID phase.
isLiveBidDisqualified boolean Disqualified from the LIVE phase.
canPrebid / prebidBlockedReason boolean / string | null Authoritative prebid-form state and stable reason when disabled. See the values below.
canBid / bidBlockedReason boolean / string | null Requires LIVE, durable admission, no prior win, and no live disqualification. Payment reversal after admission does not revoke bidding.
hasAlreadyWonProgram boolean One-win-per-program gate.
isPaymentCompletedForCycle boolean Cycle invoice paid — prebid gate.

prebidBlockedReason is one of:

Value Meaning
PREBID_DISABLED The auction configuration has prebid disabled.
CYCLE_NOT_ACTIVE Prebid operations require an active cycle.
AUCTION_NOT_ACCEPTING_PREBIDS The auction is no longer PENDING, SCHEDULED, or READY.
PREBID_NOT_OPEN No active prebid window is available.
PREBID_CLOSED The prebid deadline has passed.
PAYMENT_REQUIRED The cycle invoice has not been paid.
PRIOR_WINNER This enrollment already won in the program.
PREBID_DISQUALIFIED This enrollment is disqualified specifically from prebidding.
ACTIVE_PREBID_EXISTS One active prebid already exists; edit or cancel it according to policy.
null canPrebid is true.

Viewing details does not require payment and does not require joining the live auction. Prebid placement also does not require live-auction participation. The backend rechecks eligibility when the prebid mutation is submitted.

liveBids[] (own)

Field Type Description
id string Bid id.
amount number Bid amount.
status string LEADING when this bid is the auction's current leader, otherwise OUTBID.
createdAt string ISO-8601.

prebids[] (own)

Field Type Description
id string Prebid id — used for prebid edit/cancel.
amount number Prebid amount.
status string AuctionPrebidStatus: ACTIVE, CANCELLED, DISQUALIFIED, APPLIED, SUPERSEDED.
createdAt string ISO-8601.

2.7 winners[]

Field Type Description
id string Winner record id.
subscriberId string Winner user id.
enrolledSubscriberId string Winner enrollment id.
subscriberName / subscriberAvatar string | null Winner info.
amount number | null null for prebid-sourced winners until prebid amounts are revealed.
division number | null Winner division.
status string CYCLE_WINNER_STATUSES (e.g. DECLARED).
type string | null CycleWinningType (AUCTION, …).
selectionSource string | null AUCTION_WINNER_SELECTION_SOURCES: PREBID_REVIEW, LIVE_BID_REVIEW, MANUAL_SELECTION, LOT_SELECTION
auctionBidId / auctionPrebidId string | null Source bid/prebid id.
selectedAt string | null ISO-8601.

3. Example response

{
  "status": "success",
  "code": 200,
  "message": "Auction fetched successfully.",
  "data": {
    "auctionId": "auction-id",
    "cycleId": "cycle-id",
    "cycleNumber": 3,
    "cycleStatus": "ACTIVE",
    "programId": "program-id",
    "programName": "Monthly Chit",
    "prebidDocumentRequired": true,
    "prebidDocumentTemplateVersionId": "tv-id",
    "chitId": "chit-id",
    "companyId": "company-id",
    "companyName": "Dichit",
    "companyAvatar": null,
    "companyBranch": "Kochi",
    "totalAmount": 1000000,
    "auctionStatus": "SCHEDULED",
    "prebidPhase": "OPEN",
    "currentPhase": "PREBID_OPEN",
    "liveStartedAt": null,
    "prebidEndAt": "2026-08-10T18:30:00.000Z",
    "auctionStartAt": "2026-08-11T10:00:00.000Z",
    "auctionEndAt": "2026-08-11T10:30:00.000Z",
    "auctionDurationSeconds": 1800,
    "prebidAmountsRevealed": false,
    "prebidAmountsRevealedAt": null,
    "leadingBidAmount": 20000,
    "minimumBidAmount": 25000,
    "settings": {
      "hasPrebid": true,
      "auctionBidMode": "TOTAL_VALUE_DECREASING",
      "auctionClosingMode": "DURATION_MODE",
      "auctionDurationSeconds": 1800,
      "auctionExtensionSeconds": 120,
      "auctionFirstCallSeconds": 30,
      "auctionSecondCallSeconds": 20,
      "auctionThirdCallSeconds": 10,
      "subscriberJoinGraceSeconds": 0,
      "subscriberJoinLeadSeconds": 600,
      "allowStaffOfflineBids": true,
      "prebidMutabilityPolicy": "MUTABLE_UNTIL_CLOSE",
      "auctionJoiningRule": "BEFORE_START"
    },
    "joinWindow": {
      "status": "OPEN",
      "version": 2,
      "opensAt": "2026-08-11T09:50:00.000Z",
      "openedAt": "2026-08-11T09:50:00.012Z",
      "closesAt": "2026-08-11T10:00:00.000Z",
      "closedAt": null,
      "joiningRule": "BEFORE_START"
    },
    "audience": {
      "viewerCount": 4,
      "joinedParticipantCount": 3,
      "presentParticipantCount": 2,
      "bidderCount": 1,
      "participants": null
    },
    "liveBids": [],
    "announcements": [],
    "enrollments": [
      {
        "enrolledSubscriberId": "enrolled-id",
        "invoiceStatus": "PAID",
        "currentUser": {
          "canViewDetails": true,
          "canSubscribeRealtime": true,
          "accessMode": "VIEWER",
          "hasJoined": false,
          "joinedAt": null,
          "canJoin": true,
          "joinBlockedReason": null,
          "isPrebidDisqualified": false,
          "isLiveBidDisqualified": false,
          "canPrebid": false,
          "prebidBlockedReason": "ACTIVE_PREBID_EXISTS",
          "canBid": false,
          "bidBlockedReason": "PARTICIPATION_REQUIRED",
          "hasAlreadyWonProgram": false,
          "isPaymentCompletedForCycle": true
        },
        "liveBids": [],
        "prebids": [
          {
            "id": "prebid-id",
            "amount": 25000,
            "status": "ACTIVE",
            "createdAt": "2026-08-10T12:00:00.000Z"
          }
        ]
      }
    ],
    "winners": []
  }
}

Method Path Purpose
GET /v2/subscribers/me/auctions Discover auctionId / enrolledSubscriberId.
POST /v2/subscribers/me/auctions/:auctionId/prebid Place a prebid (body: enrolledSubscriberId, amount, signatureAssetId?).
PUT /v2/subscribers/me/auctions/:auctionId/prebid/:prebidId Edit prebid (MUTABLE_UNTIL_CLOSE only).
DELETE /v2/subscribers/me/auctions/:auctionId/prebid/:prebidId?enrolledSubscriberId=… Cancel prebid (both policies).
GET /v2/subscribers/me/cycles/:cycleId/auction/:enrolledSubscriberId Cycle-scoped overview — primary live room screen payload (leadingBid, activePrebidCount, currentUser.isLeadingBidder, latestBid, activePrebid).
GET /v2/subscribers/me/documents/signatures List READY signature assets for signatureAssetId.

Full prebid write contract: Subscriber Prebid REST.


5. WebSocket — realtime contract

5.1 Connect & authenticate

wss://api.example.com/ws

Browser: Sec-WebSocket-Protocol: websocket.v1, bearer.<access-token> Native/mobile: Authorization: Bearer <access-token> header. Invalid/missing token → socket closes with code 1008.

5.2 Subscribe to the auction room

{
  "id": "sub-001",
  "type": "auction.subscribe",
  "version": "1.0",
  "source": "web-client",
  "data": {
    "auctionId": "auction-id",
    "enrolledSubscriberId": "enrolled-id",
    "lastSequence": 0
  }
}

enrolledSubscriberId is required for subscriber sockets. Optional lastSequence (last seen auction-level data.serverSequence) requests replay.

The server then sends, in order:

  1. ack — echo with eventType, auctionId, cycleId, room.
  2. auction.connected — confirmation + connectionId + heartbeatIntervalMs.
  3. auction.state.snapshot — full subscriber-scoped state (initial source of truth).
  4. auction.audience.snapshot — current participants and authoritative counters.

Leave with auction.unsubscribe (data.auctionId) when the screen closes.

5.3 Common envelope

{
  "type": "auction.state.snapshot",
  "id": "evt-1",
  "version": "1.0",
  "source": "auction-service",
  "timestamp": "2026-08-10T10:00:00.000Z",
  "sequence": 2,
  "data": {}
}

5.4 Server → Client events for this screen

Event When What to do
auction.connected On subscribe Store connectionId / heartbeatIntervalMs.
auction.state.snapshot On subscribe, on reconnect Render initial state from data.payload.
auction.audience.snapshot + auction.audience.changed Aggregate audience changes Replace the four audience counters.
auction.state.changed Phase/schedule transitions (schedule_changed, started, paused, resumed, extended, closed, winner_selected, prebids_revealed) Switch UI mode, update countdowns, re-check canPrebid.
auction.settings.updated Settings edited Refresh settings display.
auction.prebid.created Staff-only; subscribers do not receive this event Update own prebid state from the REST response/snapshot.
auction.prebid.deleted Staff/admin deleted a prebid (targeted) Clear own activePrebid if ids match.
auction.bidder.disqualified Bidder disqualified (phase: "PREBID" blocks prebid) Lock form / treat in-flight prebid as void.
auction.bid.created · updated · rejected · deleted Live bidding activity Update live bid list + own bid state.
auction.announcement.created · updated · deleted Room announcements Refresh announcements.

5.5 Snapshot fields that matter for prebid

data.payload contains:

Field Type Notes
auction.auctionId, auction.cycleId string Room identity.
auction.prebidPhase string Same phases as the REST detail (NONE/OPEN/CLOSED).
auction.prebidStartAt / prebidEndAt string Prebid window.
auction.activePrebidCount number Only surfaced once live.
auction.minimumBidAmount / totalAmount number Amounts.
auction.settings.hasPrebid / prebidMutabilityPolicy object Prebid gates.
currentUser.canPrebid boolean Server-computed eligibility, including payment, prior winner, PREBID disqualification, and active-prebid state. It does not validate a submitted amount or signature asset.
currentUser.prebidBlockedReason string | null Stable reason to display when canPrebid is false.
currentUser.isPrebidDisqualified / isLiveBidDisqualified boolean Separate phase-specific restrictions.
currentUser.activePrebid / latestPrebid object | null Own prebid state (id, amount, status, documentSubmissionId, generatedPdfUrl, …).
currentUser.isLeadingBidder boolean Live-phase lead flag.
currentUser.latestBid object | null Own latest live bid.
currentUser.isPaymentCompletedForCycle / hasAlreadyWonProgram boolean Prebid gates.
currentUser.disqualifications array phase: "PREBID" blocks prebid.

Frontend rule: render from currentUser.canPrebid, currentUser.prebidBlockedReason, activePrebid, and auction.prebidPhase. Never decide eligibility client-side.

5.6 Prebid lifecycle events

auction.prebid.created — persisted and delivered only to staff. Subscriber clients do not receive it. After the REST POST, update the current user's prebid state from the response and reconcile from a snapshot/detail fetch when needed.

auction.prebid.deleted — staff/admin deletion path only, targeted at the affected subscriber. Payload: metadata.prebidId / metadata.enrolledSubscriberId. The subscriber's own REST cancel (DELETE …/prebid/:prebidId) publishes no event — the REST response (status: "CANCELLED") is the source of truth.

auction.state.changed — schedule_changed (window open/close) recomputes the prebid form state; started means the prebid window is over.


  1. Fetch GET /v2/subscribers/me/auctions/:auctionId → render auction + prebid context (fields, settings, own prebids, admission state, and audience counts).
  2. Open /ws, auction.subscribe with auctionId + enrolledSubscriberId (fetch auctionId via REST first; auction row guaranteed before READY/LIVE) (+ lastSequence on reconnect).
  3. On auction.state.snapshot → adopt as the live source of truth (phase, canPrebid, activePrebid, isLeadingBidder).
  4. User places a prebid: REST POST …/prebid with enrolledSubscriberId + amount (+ signatureAssetId when prebidDocumentRequired). Update UI from the REST response (prebidId, status: "ACTIVE"); reconcile from a fresh detail fetch when needed.
  5. User cancels: REST DELETE …/prebid/:prebidId?enrolledSubscriberId=… — response is truth; no socket event follows.
  6. Apply auction.state.changed transitions to switch prebid ⇄ live modes and update countdowns; update canPrebid from auction.bidder.disqualified.
  7. During LIVE: render liveBids from REST or socket bid events; own-bid leading state from currentUser.isLeadingBidder (socket) or the cycle overview.
  8. auction.unsubscribe when leaving the screen.

Reconnection

  • Persist the last seen auction-level data.serverSequence (present on bid-activity events) and pass it back as lastSequence on resubscribe.
  • Prebid events are not persisted in the replay log — after a gap, re-read own prebid state from the REST detail response or the fresh snapshot.
  • The envelope-level sequence is per-connection only.