> ## 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.

# Metadata bids

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.

<Info>
  See [Getting Started](/docs/products/orderbook/overview#getting-started) for prerequisites and installation.
</Info>

## 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](/docs/products/indexer/overview). 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.

<Tip>
  If you want to filter purely by **individual trait attributes** (e.g. `Background` is `Blue`) without any top-level metadata fields, a **[trait bid](/docs/products/orderbook/trait-bids)** is a simpler choice. A metadata bid in `metadataCriteria` mode supports the same attribute filters plus top-level fields.
</Tip>

## Prerequisites

* Same setup as other orderbook flows ([Passport](/docs/products/passport/authentication) or wallet, [fees](/docs/products/orderbook/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](/docs/products/indexer/overview). If metadata is missing or out of date, fulfillment can fail even if the token exists on-chain.

## Choosing between `metadataId` and `metadataCriteria`

| Mode               | Use it when                                                                                                                                                    |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadataId`       | The marketplace already knows the metadata stack UUID, e.g. "all tokens minted from template `a1b2c3...`". One stable identifier, no field-level reasoning.    |
| `metadataCriteria` | You 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](/docs/products/orderbook/collection-bids): **prepare** (builds `orderComponents`, `orderHash`, and `actions`) → run any **approval** transactions → **sign** the EIP-712 order from the `SIGNABLE` action → **create**.

```typescript theme={null}
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.

<Tabs>
  <Tab title="By metadata ID">
    ```typescript theme={null}
    // 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);
    ```
  </Tab>

  <Tab title="By criteria">
    ```typescript theme={null}
    // 3) Create a metadata bid that fills on any token whose metadata satisfies
    //    all of the following:
    //      - name is "Cool Dragon"
    //      - background trait is one of "Blue" or "Red"
    //      - rarity trait is "Legendary"
    const { result } = await orderbook.createMetadataBid({
      orderComponents: prepared.orderComponents,
      orderHash: prepared.orderHash,
      orderSignature,
      makerFees: [],
      metadataCriteria: [
        { fieldName: 'name', values: ['Cool Dragon'] },
        { fieldName: 'attribute:Background', values: ['Blue', 'Red'] },
        { fieldName: 'attribute:Rarity', values: ['Legendary'] },
      ],
    });

    console.log('Metadata bid created:', result.id);
    ```
  </Tab>
</Tabs>

### Supported `fieldName` values

In `metadataCriteria` mode, `fieldName` must be one of:

| Pattern                  | Meaning                                                                                                   |
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
| `name`                   | Matches the NFT’s top-level `name` field                                                                  |
| `image`                  | Matches the NFT’s top-level `image` field                                                                 |
| `description`            | Matches the NFT’s top-level `description` field                                                           |
| `animation_url`          | Matches the NFT’s top-level `animation_url` field                                                         |
| `external_url`           | Matches the NFT’s top-level `external_url` field                                                          |
| `youtube_url`            | Matches 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.

```typescript theme={null}
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 });
  }
}
```

<Warning>
  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.
</Warning>

For more context on actions, fees, and expiry, see [Fill orders](/docs/products/orderbook/fill-orders).

## Querying metadata bids

### List metadata bids

Filter by collection contract, status, maker, and pagination.

```typescript theme={null}
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

```typescript theme={null}
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

| Aspect                     | Collection bid              | Trait bid                                                 | Metadata bid                                                                                                 |
| -------------------------- | --------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| **Buy target**             | Any token in the collection | Any token whose attributes satisfy `traitCriteria`        | Any token matching `metadataId` **or** `metadataCriteria`                                                    |
| **Filter mechanism**       | None                        | Array of attribute filters                                | UUID **or** field-level filters spanning top-level metadata fields and attributes                            |
| **Fulfillment validation** | Token exists in collection  | Token attributes satisfy all trait filters                | Token `metadata_id` matches (id mode) **or** token metadata satisfies all field filters (criteria mode)      |
| **Typical use**            | Floor sweep / any item      | Offers 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](/docs/products/orderbook/fees).
* **Cancel:** use the bid's order id with [Cancel orders](/docs/products/orderbook/cancel-orders) (soft or hard cancel patterns apply to open orders).

## Next steps

<CardGroup cols={2}>
  <Card title="Collection bids" icon="gavel" href="/docs/products/orderbook/collection-bids">
    Bids on any NFT in a collection without filters
  </Card>

  <Card title="Trait bids" icon="filter" href="/docs/products/orderbook/trait-bids">
    Bids filtered by metadata trait attributes
  </Card>

  <Card title="Fill orders" icon="cart-shopping" href="/docs/products/orderbook/fill-orders">
    Fulfillment, actions, and approvals
  </Card>

  <Card title="Cancel orders" icon="xmark" href="/docs/products/orderbook/cancel-orders">
    Cancel metadata bids you created
  </Card>
</CardGroup>
