Your user just purchased an NFT using Crossmint. Now what? You may want to...

  • Store a receipt of it in your database
  • Associate a user wallet account with their account in your system
  • Show some celebratory confetti UI 🎊

You can do this easily with webhooks!

Setting up a webhook to log purchases

Step 1: Register your webhook endpoint

First, navigate to and click on "Add Endpoint"

Next, fill in your webhook details: Enter the URL where you'd like to receive the webhook, and the events for which you'd like to receive updates, and that's it! When an event occurs, you'll receive a POST request to the designated URL.

Step 2: Listen to webhook events

Whenever a customer purchases an NFT using Crossmint, Crossmint will make an HTTPS request to the webhook URL you have configured. Example JSON for each request is below:



Please be aware that purchase.failed is currently in alpha and is subject to change.

    "type": "purchase.succeeded",
    "status": "success",
    "walletAddress": "<EVM_ADDRESS>",
    "projectId": "<PROJECT_ID>",
    "collectionId": "<COLLECTION_ID>",
    "clientId": "<CLIENT_ID>",
    "txId": "<TX_ID>",
    "contractAddress": "<CONTRACT_ADDRESS>",
    "tokenIds": [<TOKEN_IDS>], // only present for EVM collections (eth/polygon)
    "passThroughArgs": "<YOUR_ARGS_JSON>" // only present if you set whPassThroughArgs
    "type": "purchase.succeeded",
    "status": "success",
    "walletAddress": "<SOL_ADDRESS>",
    "clientId": "<CLIENT_ID>",
    "txId": "<TXID>",
    "mintAddress": "<MINT_HASH>",
    "passThroughArgs": "<YOUR_ARGS_JSON>"
    "type": "export.succeeded",
    "status": "success",
    "fromAddress": "<FROM_ADDRESS>", // crossmint custodial wallet
    "toAddress": "<TO_ADDRESS>", 		 // user external wallet
    "mintAddress": "<CONTRACT_OR_MINT_HASH>", // evm nft contract / solana mintHash
    "txId": "<TX_ID>",
    "tokenId": "<TOKEN_ID>"
 type: "purchase.failed",
 status: "failure",
 walletAddress?: "<WALLET_ADDRESS>",  // wallet address being minted to
 chain?: "<CHAIN>", // Ethereum/Polygon/Solana/Cardano/BSC
 errorMessage: "<ERROR_MESSAGE>", 
 clientId: "<CLIENT_ID>", 
 contract?: "<CONTRACT_ADDRESS>",
 txId?: "<TX_HASH>",
 email?: "<EMAIL_ADDRESS>",
 mintArgs: "<MINT_ARGS>", // the minting arguments passed in the Crossmint button

Your server must return a 2xx HTTP status quickly such that the webhook is marked as delivered successfully.

Step 3: (Optional) Set custom pass-through arguments

When a user initiates the Crossmint flow, you can optionally set some custom arguments that will get passed through to your server webhook at the time of purchase.

Some useful information that you could pass here includes:

  • The user's id in your system. For additional security, sign this ID with a custom key, or send it as a signed JWT, and verify its integrity later on your server.
  • The time of purchase
  • A product SKU

You can pass multiple arguments by serializing them into a single string.

Example of handling the pass-through arguments

You can pass the arguments on the client-side:

function NFTSalePage() {

  const whArgs = {
    uid: 123424,
    sku: 123123123,
    monkey: true
  const whArgsSerialized = JSON.stringify(whArgs);

  return (

Then, extract the arguments on the server-side:

// NextJS
export default function handler(req, res) {
  const { whPassThroughArgs } = req.body;
  if (whPassThroughArgs) {
    const whArgsDeserialized = JSON.parse(whPassThroughArgs);




If someone mints multiple tokens at once on an EVM chain, we currently only fire a webhook with the first token ID.

Here's the full table of webhook events you can subscribe to:

export.succeededCalled when an NFT from a collection has been successfully transferred to another wallet
purchase.succeededCalled when an NFT from a collection has been successfully purchased
purchase.failedCalled if an NFT from a collection has failed to mint
mint.succeededCalled when an API NFT mint has completed
prepay.succeededCalled when a prepay transaction is successful