Skip to content

GET /v3/bidder/my-activity

GET
/v3/bidder/my-activity
curl --request GET \
--url 'https://api-ha-prod-p8.handbid.dev/v3/bidder/my-activity?whitelabelKey=handbid&limit=20' \
--header 'Authorization: Bearer <token>'

NEW (HAN-1848, 2026-05-21). Live-event dashboard. Bundled bids[] + purchases[] for the user’s currently-visible auctions, with derived 4-state lifecycle on each bid row. Replaces /v3/bidder/active-bids.

HAN-1865 update (2026-05-21): adds top-level statusCounts block with per-bucket counts + representative thumbnails.

Auth: required.

Response shape:

{
  "bids": [
    {
      // ItemCard base fields...
      "itemType": "silent",          // granular DB enum
      "auctionName": "Spring Gala",  // auction context (5 fields)
      "auctionStatus": "open",        // mapped label
      "auctionEndTime": 1716232000,
      "isCurrent": true,              // a.statusId IN (2,3,4,5,8)
      "myLastBidAmount": "250.00",
      "myLastBidAt": 1716220900,
      "myBidStatus": "winning",       // raw bids.status
      "myActivityStatus": "Winning"   // DERIVED: Winning | Losing | Won | Lost
    }
  ],
  "purchases": [
    {
      // ItemCard base + auction context...
      "itemType": "ticket",
      "purchaseId": 998877,
      "purchaseAmount": "150.00",
      "purchasedAt": 1716221000,
      "purchaseQuantity": 2,
      "receiptId": 778899,
      "isPaid": true
    }
  ],
  "bidsCount": 8,
  "purchasesCount": 3,
  "statusCounts": {
    "winning": { "count": 5,  "imageUrl": "https://cdn.handbid.com/item/42/img.jpg" },
    "losing":  { "count": 12, "imageUrl": "https://cdn.handbid.com/item/87/img.jpg" },
    "won":     { "count": 3,  "imageUrl": "https://cdn.handbid.com/item/156/img.jpg" },
    "lost":    { "count": 7,  "imageUrl": "https://cdn.handbid.com/item/201/img.jpg" }
  }
}

Bucketing (by items.itemType):

  • bids[]: silent, live, sealedBid, competitiveBid, bidBox
  • purchases[]: ticket, forSale, customDonation, dafDonation, appeal, raffle, puzzle, gram, contest

myActivityStatus derivation (PHP-side):

  1. bid.status='purchase'Won (regardless of item state)
  2. winning + item sold + EXISTS purchase by current user → Won
  3. winning + item in-flight → Winning
  4. losing + item sold + EXISTS purchase by another user → Lost
  5. losing + item in-flight → Losing
  6. anything else → null (client falls back to raw myBidStatus)

statusCounts (HAN-1865, 2026-05-21):

  • Counts are accurate across the full visible auction set (pre-pagination) up to a hard cap of 500 rows (prod audit shows max active-user bid count < 200 — power-user buffer).
  • Representative imageUrl per bucket is the most-recent bid row in that bucket (myLastBidAt DESC, i.id DESC — matches the row-level tiebreaker).
  • Empty bucket returns {count: 0, imageUrl: null} — iOS reads either as empty without null-handling.
  • Aggregation runs in PHP (same deriveMyActivityStatus precedence) so row-level + aggregated states stay byte-identical. Same JOIN graph as bids[] but lean SELECT.
  • Empty-set response includes the all-zeros statusCounts block for shape stability.
  • Lets iOS drop the limit=50 home-screen workaround — read tile counts + thumbnails from statusCounts, page bids[] at the visible row count (3, typically).

Item-status filter: (1, 2, 4, 5, 7, 8) — INCLUDES sold (2) so Won/Lost surface.

Sort: FIELD(a.statusId, 4, 8, 3, 2, 5, 6) ASC, myLastBidAt DESC, i.id DESC — clustered by auction status priority then recency within each cluster.

Auction scope: auctions where the user is registered as a bidder, on the resolved whitelabel, not test, not in deleted-events org, status in visible set, AND (status != closed OR closed within closedAuctionGraceDays).

Empty-set guard: returns {bids:[], purchases:[], bidsCount:0, purchasesCount:0, statusCounts: {winning, losing, won, lost all zero}} without issuing SQL when the user has no visible auctions.

Cache: 15s TTL. Tags: userActiveBids, userMyItems, userMyAuctions, plus auction(:id) for every auctionId in the response — a status flip on any contributing auction drops the cache (including the statusCounts block).

whitelabelKey
string

Defaults to ‘handbid’ when omitted. Legacy whitelabelId also accepted.

Example
handbid
limit
integer

Default reads from whitelabels.myActivityPageSize (typically 20); range 1-100

Example
20

Successful response

Media type application/json