Skip to main content

Auction API

Auctions provide competitive bidding functionality where the highest bidder wins.

Get Auction

Retrieve auction details and current status. GET /api/v1/auctions/:auctionId

Authentication

  • Publishable key required
  • Consumer authentication not required

Path Parameters

ParameterTypeDescription
auctionIdstringThe auction ID

Response

interface Auction {
  id: string;
  name: string;
  sequenceId: string;
  openAt: string | null;
  closeAt: string | null;
  settleAt: string;
  timeZone: string | null;
  startingPrice: number;
  reservePrice: number | null;
  minimumBidIncrement: number;
  winnerCount: number;
  status: "PENDING" | "OPEN" | "CLOSED" | "SETTLED";
  currentHighBid: number | null;
  currencyCode: string;
}

Example

curl -X GET https://consumer.fanfare.io/api/v1/auctions/auction_01HXYZ123456789 \
  -H "X-Publishable-Key: pk_live_xxxxxxxxxxxx"
Response:
{
  "id": "auction_01HXYZ123456789",
  "name": "Exclusive Item Auction",
  "sequenceId": "seq_01HXYZ123456789",
  "openAt": "2024-12-01T09:00:00Z",
  "closeAt": "2024-12-01T18:00:00Z",
  "settleAt": "2024-12-01T18:30:00Z",
  "timeZone": "America/New_York",
  "startingPrice": 100.0,
  "reservePrice": 500.0,
  "minimumBidIncrement": 10.0,
  "winnerCount": 1,
  "status": "OPEN",
  "currentHighBid": 250.0,
  "currencyCode": "USD"
}

Error Responses

StatusErrorDescription
404Auction not foundThe auction ID does not exist

Place Bid

Place a bid on an auction. POST /api/v1/auctions/:auctionId/bid

Authentication

  • Publishable key required
  • Consumer authentication required

Headers

HeaderRequiredDescription
X-FingerprintRecommendedDevice fingerprint for bot mitigation

Path Parameters

ParameterTypeDescription
auctionIdstringThe auction ID

Request Body

interface BidRequest {
  amount: number;
}

Response

interface BidResponse {
  status: "ACTIVE" | "OUTBID" | "WINNING";
  lastBidAmount: number;
  lastBidTime: string;
  bidCount: number;
}

Example

curl -X POST https://consumer.fanfare.io/api/v1/auctions/auction_01HXYZ123456789/bid \
  -H "X-Publishable-Key: pk_live_xxxxxxxxxxxx" \
  -H "Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..." \
  -H "X-Fingerprint: fp_01HXYZ123456789" \
  -H "Content-Type: application/json" \
  -d '{"amount": 275.00}'
Response:
{
  "status": "WINNING",
  "lastBidAmount": 275.0,
  "lastBidTime": "2024-12-01T10:15:23Z",
  "bidCount": 3
}

Error Responses

StatusErrorDescription
400Consumer ID is requiredMissing consumer authentication
400Auction is closedAuction has ended
400Bid must be higher than current bidBid amount too low
400Bid must meet minimum incrementIncrement requirement not met
404Auction not foundThe auction ID does not exist
423Auction is not open yetAuction opens in the future

Special Headers on Error

HeaderValueDescription
Retry-AfterISO timestampWhen to retry (for 423)
X-Fingerprint-ErrortrueFingerprint validation failed

Get Bid Status

Get the current consumer’s bid status. GET /api/v1/auctions/:auctionId/status

Authentication

  • Publishable key required
  • Consumer authentication required

Path Parameters

ParameterTypeDescription
auctionIdstringThe auction ID

Response

interface BidderState {
  auctionId: string;
  consumerId: string;
  status: "ACTIVE" | "OUTBID" | "WINNING" | "WON" | "LOST";
  lastBidAmount: number | null;
  lastBidTime: string | null;
  bidCount: number;
  paymentToken?: string; // Only present if won
}

Example

curl -X GET https://consumer.fanfare.io/api/v1/auctions/auction_01HXYZ123456789/status \
  -H "X-Publishable-Key: pk_live_xxxxxxxxxxxx" \
  -H "Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
Response (Currently Winning):
{
  "auctionId": "auction_01HXYZ123456789",
  "consumerId": "cons_01HXYZ123456789",
  "status": "WINNING",
  "lastBidAmount": 275.0,
  "lastBidTime": "2024-12-01T10:15:23Z",
  "bidCount": 3
}
Response (Won Auction):
{
  "auctionId": "auction_01HXYZ123456789",
  "consumerId": "cons_01HXYZ123456789",
  "status": "WON",
  "lastBidAmount": 500.0,
  "lastBidTime": "2024-12-01T17:55:00Z",
  "bidCount": 5,
  "paymentToken": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
}

Get Highest Bid

Get the current highest bid amount. GET /api/v1/auctions/:auctionId/highest-bid

Authentication

  • Publishable key required
  • Consumer authentication required

Path Parameters

ParameterTypeDescription
auctionIdstringThe auction ID

Response

interface HighestBidResponse {
  amount: number;
  bidderId: string | null; // May be anonymized
}

Example

curl -X GET https://consumer.fanfare.io/api/v1/auctions/auction_01HXYZ123456789/highest-bid \
  -H "X-Publishable-Key: pk_live_xxxxxxxxxxxx" \
  -H "Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
Response:
{
  "amount": 350.0,
  "bidderId": null
}

Get Bid History

Get the consumer’s own bid history. GET /api/v1/auctions/:auctionId/bids/history

Authentication

  • Publishable key required
  • Consumer authentication required

Path Parameters

ParameterTypeDescription
auctionIdstringThe auction ID

Query Parameters

ParameterTypeDefaultDescription
limitnumber10Maximum number of bids to return

Response

interface BidHistoryItem {
  bidId: string;
  consumerId: string;
  amount: number;
  timestamp: string;
}

type BidHistoryResponse = BidHistoryItem[];

Example

curl -X GET "https://consumer.fanfare.io/api/v1/auctions/auction_01HXYZ123456789/bids/history?limit=5" \
  -H "X-Publishable-Key: pk_live_xxxxxxxxxxxx" \
  -H "Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
Response:
[
  {
    "bidId": "bid_01HXYZ123456789",
    "consumerId": "cons_01HXYZ123456789",
    "amount": 275.0,
    "timestamp": "2024-12-01T10:15:23Z"
  },
  {
    "bidId": "bid_01HXYZ123456788",
    "consumerId": "cons_01HXYZ123456789",
    "amount": 200.0,
    "timestamp": "2024-12-01T09:45:00Z"
  },
  {
    "bidId": "bid_01HXYZ123456787",
    "consumerId": "cons_01HXYZ123456789",
    "amount": 150.0,
    "timestamp": "2024-12-01T09:15:00Z"
  }
]

Get All Bids

Get all bids for the auction (requires authentication). GET /api/v1/auctions/:auctionId/bids

Authentication

  • Publishable key required
  • Consumer authentication required

Path Parameters

ParameterTypeDescription
auctionIdstringThe auction ID

Query Parameters

ParameterTypeDefaultDescription
limitnumber20Maximum number of bids to return

Response

Returns an array of BidHistoryItem objects (consumer IDs may be anonymized).

Example

curl -X GET "https://consumer.fanfare.io/api/v1/auctions/auction_01HXYZ123456789/bids?limit=10" \
  -H "X-Publishable-Key: pk_live_xxxxxxxxxxxx" \
  -H "Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."

Bidder Statuses

StatusDescription
ACTIVEConsumer has placed bids but is not currently winning
OUTBIDConsumer’s bid has been exceeded by another bidder
WINNINGConsumer currently has the highest bid
WONConsumer won the auction (after settlement)
LOSTConsumer did not win the auction (after settlement)

Auction Lifecycle

  1. Pending: Auction created but not yet open
  2. Open: Bidding is active
  3. Closed: Bidding has ended, awaiting settlement
  4. Settled: Winners determined, payment tokens issued

SDK Usage

React

import { useAuction } from "@fanfare/sdk-react";

function AuctionPage({ auctionId }: { auctionId: string }) {
  const {
    auction,
    bidderStatus,
    highestBid,
    placeBid,
    isLoading,
    error,
  } = useAuction(auctionId);

  const [bidAmount, setBidAmount] = useState("");

  if (isLoading) return <Loading />;
  if (error) return <Error message={error.message} />;

  const handleBid = async () => {
    try {
      await placeBid(parseFloat(bidAmount));
      setBidAmount("");
    } catch (e) {
      console.error("Bid failed:", e);
    }
  };

  return (
    <div>
      <h2>{auction?.name}</h2>
      <p>Current High Bid: ${highestBid?.amount}</p>
      <p>Your Status: {bidderStatus?.status}</p>
      <p>Your Last Bid: ${bidderStatus?.lastBidAmount}</p>

      {auction?.status === "OPEN" && (
        <div>
          <input
            type="number"
            value={bidAmount}
            onChange={(e) => setBidAmount(e.target.value)}
            placeholder={`Minimum: ${(highestBid?.amount || auction.startingPrice) + auction.minimumBidIncrement}`}
          />
          <button onClick={handleBid}>Place Bid</button>
        </div>
      )}

      {bidderStatus?.status === "WON" && (
        <div>
          <h3>Congratulations! You won!</h3>
          <a href={`/checkout?token=${bidderStatus.paymentToken}`}>
            Complete Purchase
          </a>
        </div>
      )}
    </div>
  );
}

Real-Time Updates

For live auction updates, consider using WebSockets or polling:
function useAuctionPolling(auctionId: string, intervalMs = 2000) {
  const [auction, setAuction] = useState(null);
  const [highestBid, setHighestBid] = useState(null);

  useEffect(() => {
    const poll = async () => {
      const [auctionRes, bidRes] = await Promise.all([
        fetch(`/api/v1/auctions/${auctionId}`, { headers }),
        fetch(`/api/v1/auctions/${auctionId}/highest-bid`, { headers }),
      ]);

      setAuction(await auctionRes.json());
      setHighestBid(await bidRes.json());
    };

    poll();
    const interval = setInterval(poll, intervalMs);
    return () => clearInterval(interval);
  }, [auctionId, intervalMs]);

  return { auction, highestBid };
}