Skip to content

Sales

Sales are managed through methods on the client.collection sub-client. The canonical route schema is at REST API → Collection — this page is a usage overlay focused on SDK patterns and constraints.

See support matrix for which collection + sale + access combinations are valid. Anything outside it is rejected.

const res = await client.collection.getSales({ highlightId });

Returns every sale currently attached (draft or live).

await client.collection.addSale({
highlightId,
type: "FIXED_PRICE",
accessMode: "PUBLIC",
startAt: new Date().toISOString(),
price: "0.01",
currency: "ETH",
maxPerTransaction: 5,
maxPerWallet: 10,
maxTotal: 1000,
paymentRecipient: "0x...",
// Optional:
// endAt: "2026-12-31T00:00:00Z",
// gateId: "gate-uuid", // required when accessMode = "GATED"
// gasSponsored: true, // only FIXED_PRICE + PUBLIC
// mechanicId: "mech-uuid", // only type = "CUSTOM"
// typeConfig: { ... }, // required for DUTCH_AUCTION, RANKED_AUCTION, CUSTOM
// collectorMessage: "Welcome!",
// customMintFee: "0.0001",
// name: "Early access",
});

Rules:

  • Draft collection — one sale at a time. Delete the existing draft before adding a new one.
  • Live collection — only gated sales can be added (they have no on-chain component). Public sales on live collections aren’t yet implemented.
await client.collection.addSale({
// ... base fields ...
type: "DUTCH_AUCTION",
typeConfig: {
scheduledPrices: ["1.0", "0.75", "0.5", "0.25"],
priceDropInterval: { hours: 1, minutes: 0 },
},
});

1–5 price levels. Price drops on the interval until it reaches the floor.

await client.collection.addSale({
// ... base fields ...
type: "RANKED_AUCTION",
typeConfig: {
reserveBidAmount: "0.1",
rebateWinningBids: true,
},
});

Gated ranked auctions are rejected. See ranked auctions guide.

await client.collection.addSale({
// ... base fields ...
type: "CUSTOM",
mechanicId: "your-mechanic-uuid",
typeConfig: { /* whatever the mechanic expects */ },
});

Register mechanics with client.mechanic.create — see sdk/mechanics.

await client.collection.updateSale({
highlightId,
saleId,
price: "0.02",
paused: true,
// ...other mutable fields
});

Immutable (need delete + re-add to change): type, accessMode, gateId, gasSponsored, mechanicId, typeConfig.

On a live public sale, only name, collectorMessage, customMintFee, and paused can be updated. On-chain fields (price, startAt, endAt, currency, limits, paymentRecipient) can’t be changed yet.

await client.collection.deleteSale({ highlightId, saleId });

Only draft sales. Live sales must be paused or end-dated via update.

const res = await client.collection.claimSale({
highlightId,
saleId,
amount: 1,
// tokenIds: [7, 42], // only for choose-token Series sales
});

Returns a signed contract execution (res.data.tx). The caller submits the transaction on-chain.

const res = await client.collection.bidSale({
highlightId,
saleId,
bidAmount: "0.5",
// bidId: existingBidId, // to update an existing bid
});

See ranked auctions guide for the full flow including settlement.

Called after each bid tx confirms on-chain (not at auction end) to record the bid in the backend’s ranked-auction ledger so it’s eligible to win. Pass the hash of the bid transaction:

await client.collection.confirmBid({ highlightId, saleId, txHash });

The end-of-auction claim uses claimSale — see ranked auctions guide.

client.collection.confirmSale exists in the SDK surface but returns 400 until on-chain vector registration for live-collection public sales is implemented.