Creating and Filling Orders

Reservoir gives you access to a fully functional Aggregated Orderbook that strives to be a global pool of NFT liquidity. You can both create orders (list for sale, make an offer) or fill orders (buy token, accept offer).


We recommend using Reservoir SDK

Reservoir SDK includes helpers that abstract the process of iterating through steps, and returning callbacks that can be used to update your UI.

Importantly, because it's a shared order book, tools can specialize on different parts of the market. For example, a market maker could generate bids and feed them directly into the order book, while a wallet could place a sell button next to every NFT in a user's wallet, giving them access to those bids. As more integrations get built, the network effects of the shared order book grow stronger.


When executing orders, there are often multiple steps, like approving an exchange to access your NFTs, or wrapping WETH for a bid. These steps differ for every different type of liquidity that Reservoir supports. To make this simple, you can use the Router endpoints, which return the exact steps that you need to follow, including descriptions that you can display to users.

The flow looks like this:

  1. Call the Router API with the action you want to take (create or fill)
  2. Iterate through the steps and the items within a step, taking the necessary actions. Steps with no items, or an empty array of items, should be skipped.

As mentioned above each step contains an array of one or more items. These items need to be iterated and completed depending on the kind of step. There are two kinds of steps:


A transaction that needs to be submitted on-chain. After this item is complete you can poll the Transaction Status API to ensure that the transaction was successfully picked up by the indexer. Depending on the router api, if it's a sale or a buy transaction, you can additionally poll the Sales API to ensure that the sale event was indexed correctly. The step item can then be successfully marked as complete.


A message that needs to be signed. Every signature comes with sign data and post data. The first action we need to take is to sign the message, keep in mind the signatureKind and use the appropriate signing method. After the message is signed the second action is to submit the post body to the endpoint provided in the post data. If the request is successful we can mark the step item as complete.

The API returns the exact data that you need to sign/submit, so it can be fed directly into an Ethereum library like ethers.js. What's nice about this design pattern is that it is completely generic. As new types of liquidity are added, you can support them automatically without needing to update your app.

Supported Actions

The following actions are possible with the Router API: