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 whose indexed metadata matches what you specify. A metadata bid can either target a group of tokens that share the same metadata ID (e.g. tokens minted from the same template), or it can match tokens by field-level criteria on the top-level metadata fields (name, image, description, animation_url, external_url, youtube_url) and individual attributes.
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 or ERC-1155 collection buy item.
  • You attach exactly one matching spec:
    • metadataId — a UUID that identifies a group of tokens sharing the same metadata definition in Immutable’s indexer. The bid fills only on tokens whose indexed metadata_id equals this UUID.
    • metadataCriteria — an array of field-level filters. Each filter has a fieldName (a top-level metadata field, or an attribute prefixed with attribute:) and a list of allowed values.
  • Matching semantics for metadataCriteria: every filter you specify must be matched (filters AND). For a given filter, the token matches if its value is one of the allowed values (values OR). Matching is case-insensitive.
  • Matching semantics for metadataId: the token’s indexed metadata_id must equal the supplied UUID exactly.
  • 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 purely by individual trait attributes (e.g. Background is Blue) without any top-level metadata fields, a trait bid is a simpler choice. A metadata bid in metadataCriteria mode supports the same attribute filters plus top-level fields.

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 against your matching spec. That requires the NFT’s metadata to be available through Immutable’s indexer. If metadata is missing or out of date, fulfillment can fail even if the token exists on-chain.

Choosing between metadataId and metadataCriteria

ModeUse it when
metadataIdThe marketplace already knows the metadata stack UUID, e.g. “all tokens minted from template a1b2c3...”. One stable identifier, no field-level reasoning.
metadataCriteriaYou want to bid on tokens whose metadata satisfies a logical AND of human-readable conditions, e.g. “name is Cool Dragon AND background is Blue or Red”.
Exactly one of the two must be set; supplying both, or neither, is rejected at the SDK and API levels.

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,
});
The prepare, approval, and signing steps are identical for both modes. The third step — calling createMetadataBid — is where you pick the matching spec.
// 3) Create a metadata bid that fills on any token with this metadata_id
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);

Supported fieldName values

In metadataCriteria mode, fieldName must be one of:
PatternMeaning
nameMatches the NFT’s top-level name field
imageMatches the NFT’s top-level image field
descriptionMatches the NFT’s top-level description field
animation_urlMatches the NFT’s top-level animation_url field
external_urlMatches the NFT’s top-level external_url field
youtube_urlMatches the NFT’s top-level youtube_url field
attribute:<trait_type>Matches the value of the attribute whose trait_type equals <trait_type> (e.g. attribute:Background)
Each fieldName may appear at most once per bid. The SDK rejects duplicates client-side — combine multiple acceptable values into a single filter’s values array (OR) instead.

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 indexed metadata does not match the bid’s matching spec — metadata_id mismatch in metadataId mode, or any filter unsatisfied in metadataCriteria mode — 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) {
  if (bid.metadataId) {
    console.log(bid.id, 'by id:', bid.metadataId);
  } else {
    console.log(bid.id, 'by criteria:', bid.metadataCriteria);
  }
}

Get one metadata bid

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

console.log({
  id: bid.id,
  status: bid.status,
  // Exactly one of these is populated for any given bid:
  metadataId: bid.metadataId,
  metadataCriteria: bid.metadataCriteria,
  sell: bid.sell,
  buy: bid.buy,
});
The response shape is the same for both modes — metadataId is undefined for criteria-mode bids, and metadataCriteria is an empty array for id-mode bids.

Comparison: collection bid vs trait bid vs metadata bid

AspectCollection bidTrait bidMetadata bid
Buy targetAny token in the collectionAny token whose attributes satisfy traitCriteriaAny token matching metadataId or metadataCriteria
Filter mechanismNoneArray of attribute filtersUUID or field-level filters spanning top-level metadata fields and attributes
Fulfillment validationToken exists in collectionToken attributes satisfy all trait filtersToken metadata_id matches (id mode) or token metadata satisfies all field filters (criteria mode)
Typical useFloor sweep / any itemOffers on attribute-filtered sets (e.g. legendary + blue)Offers on tokens from a specific template (id mode) or on human-readable metadata conditions (criteria mode)

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