Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.immutable.com/llms.txt

Use this file to discover all available pages before exploring further.

Place bids on NFTs in a collection that have a specific metadata ID. A metadata bid targets a group of tokens linked by the same metadata definition in Immutable’s indexer.
See Getting Started for prerequisites and installation.

What is a metadata bid?

  • You offer ERC-20 tokens to buy one or more NFTs from a collection, identified by an ERC-721 collection buy item.
  • You attach a metadataId: a UUID that identifies a group of tokens sharing the same metadata definition in Immutable’s indexer.
  • Matching semantics: when a seller fills your bid with a specific tokenId, Immutable validates that the token’s metadata_id in the indexer matches the metadataId on the bid.
  • Orders appear as METADATA_BID in API responses alongside listings, bids, collection bids, and trait bids. Use the order type field when branching in your app or webhooks.
If you want to filter by individual trait attributes (e.g. Background is Blue) rather than a metadata ID, use a trait bid instead.

Prerequisites

  • Same setup as other orderbook flows (Passport or wallet, fees, etc.).
  • Metadata for fulfillment: when a seller fills your bid with a specific tokenId, Immutable validates that token’s metadata_id against the bid’s metadataId. That requires the NFT metadata to be available through Immutable’s indexer. If metadata is missing or the metadata_id does not match, fulfillment will fail.

Creating a metadata bid

The flow mirrors collection bids: prepare (builds orderComponents, orderHash, and actions) → run any approval transactions → sign the EIP-712 order from the SIGNABLE action → create.
import { Orderbook, ActionType } from '@imtbl/orderbook';

const prepared = await orderbook.prepareMetadataBid({
  makerAddress: address,
  buy: {
    type: 'ERC721_COLLECTION',
    contractAddress: NFT_CONTRACT,
    amount: '1',
  },
  sell: {
    type: 'ERC20',
    contractAddress: PAYMENT_TOKEN,
    amount: '1000000000000000000', // wei
  },
});

// 1) Submit approval txs from prepared.actions (if any)
for (const action of prepared.actions) {
  if (action.type === ActionType.TRANSACTION) {
    const tx = await action.buildTransaction();
    await walletClient.sendTransaction(tx);
  }
}

// 2) Sign the CREATE_ORDER payload from the SIGNABLE action (EIP-712)
const signable = prepared.actions.find((a) => a.type === ActionType.SIGNABLE);
if (!signable) throw new Error('Missing signable order action');

const orderSignature = await walletClient.signTypedData({
  account: address,
  domain: signable.message.domain,
  types: signable.message.types,
  primaryType: 'OrderComponents',
  message: signable.message.value,
});

// 3) Create the metadata bid on Immutable
const { result } = await orderbook.createMetadataBid({
  orderComponents: prepared.orderComponents,
  orderHash: prepared.orderHash,
  orderSignature,
  makerFees: [],
  metadataId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', // UUID from the indexer
});

console.log('Metadata bid created:', result.id);

Filling a metadata bid (seller)

Sellers call fulfillOrder with the metadata bid order id and the token ID they are selling into the bid. Pass undefined for amountToFill (standard ERC-721 fill) and supply tokenId as a string.
import { Orderbook } from '@imtbl/orderbook';

const { actions } = await orderbook.fulfillOrder(
  metadataBidId,
  sellerAddress,
  [], // taker fees
  undefined, // amountToFill — omit for standard ERC-721 fills
  '123', // tokenId — required: the NFT the seller is selling into the bid
);

// Execute actions (approvals + fulfill) in order
for (const action of actions) {
  if (action.type === 'TRANSACTION') {
    const unsignedTx = await action.buildTransaction();
    const hash = await walletClient.sendTransaction(unsignedTx);
    await publicClient.waitForTransactionReceipt({ hash });
  }
}
If the token’s metadata_id in the indexer does not match the bid’s metadataId, the orderbook will not return valid fulfillment data for that token.
For more context on actions, fees, and expiry, see Fill orders.

Querying metadata bids

List metadata bids

Filter by collection contract, status, maker, and pagination.
import { Orderbook, OrderStatusName } from '@imtbl/orderbook';

const { result, page } = await orderbook.listMetadataBids({
  buyItemContractAddress: NFT_CONTRACT,
  status: OrderStatusName.ACTIVE,
  pageSize: 50,
});

for (const bid of result) {
  console.log(bid.id, bid.metadataId, bid.sell.amount);
}

Get one metadata bid

const { result: bid } = await orderbook.getMetadataBid(metadataBidId);

console.log({
  id: bid.id,
  status: bid.status,
  metadataId: bid.metadataId,
  sell: bid.sell,
  buy: bid.buy,
});

Comparison: collection bid vs trait bid vs metadata bid

AspectCollection bidTrait bidMetadata bid
Buy targetAny token in the collectionAny token whose metadata matches traitCriteriaAny token whose metadata_id matches metadataId
Filter mechanismNoneArray of trait type/value filtersSingle metadata ID (UUID)
Fulfillment validationToken exists in collectionToken attributes satisfy all trait filtersToken metadata_id matches bid
Typical useFloor sweep / any itemOffers on filtered sets (e.g. legendary + blue)Offers on tokens from a specific template or blueprint

Fees and cancellation

  • Fees: same maker/taker concepts as other orders — see Fees.
  • Cancel: use the bid’s order id with Cancel orders (soft or hard cancel patterns apply to open orders).

Next steps

Collection bids

Bids on any NFT in a collection without filters

Trait bids

Bids filtered by metadata trait attributes

Fill orders

Fulfillment, actions, and approvals

Cancel orders

Cancel metadata bids you created