Cancel Listing

There are two ways to cancel a listing: Gasless (Off-chain) and Secure (On-chain).

  • Gasless Cancel (Off-chain): Removes the listing from our database using an EIP-191 signature. This is free and fast, but the signed listing remains technically valid on-chain if a buyer possesses the original signature.
  • Secure Cancel (On-chain): Submits a transaction calling the exchange contract directly to cryptographically invalidate the order nonce. This requires a gas fee but guarantees the listing can never be fulfilled on-chain.

To completely invalidate the order on-chain, the seller submits a transaction to the MintpadExchange contract.

Step 1 — Obtain the listing's nonce

Query GET /v1/listings or GET /v1/listings/:orderHash (both require x-api-key) to retrieve the listing's nonce string.

Step 2 — Submit the contract transaction

Call the cancelMultipleMakerOrders function on the MintpadExchange contract from the user's wallet:

  • Exchange Address: 0xdFbE43b2c154B6a790158fa2696cDb32A86Efc78
  • Function: cancelMultipleMakerOrders(uint256[] nonces)
TypeScript
// ethers.js v6
const exchange = new Contract(EXCHANGE_ADDRESS, MINTPAD_EXCHANGE_ABI, signer)
const tx = await exchange.cancelMultipleMakerOrders([BigInt(nonce)])
await tx.wait()

Step 3 — Sync with the Database

After the transaction is confirmed on-chain, call the off-chain DELETE request (see below) to remove the listing from the database index.


Gasless Cancel (Off-chain)

To remove the listing from the marketplace without paying gas, have the seller sign a cancellation message and send it to the partner API.

Step 1 — Obtain the orderHash

The orderHash is the unique identifier for a listing. You need it to identify which listing to cancel.

Option A — Store it at creation time. The POST /v1/listings response always includes it:

JSON
{
"success": true,
"orderHash": "0xabcde12345...",
"status": "active"
}

Option B — Look it up by querying the active listing. Use GET /v1/listings (requires x-api-key) filtered by seller and token:

Text
GET /v1/listings?seller=0x9876...&tokenId=123

The orderHash field is present on every listing object in the response:

JSON
{
"listings": [
{
"orderHash": "0xabcde12345...",
"tokenId": "123",
"seller": "0x9876543210abcdef9876543210abcdef98765432",
"priceWei": "100000000000000000000",
"nonce": "1718274092"
}
]
}

Step 2 — Sign the Cancellation Message

The seller must sign an EIP-191 personal_sign message — not a typed data signature. The message is a plain string:

Text
Cancel Mintpad Listing: <orderHash>

Where <orderHash> is the full lowercase hex string (e.g. 0xabcde12345...).

TypeScript
// ethers.js v6
const message = `Cancel Mintpad Listing: ${orderHash}`
const signature = await signer.signMessage(message)
// viem
const signature = await walletClient.signMessage({
account: sellerAddress,
message: `Cancel Mintpad Listing: ${orderHash}`
})

The message format must be exact — including the colon and space before the hash. The API will reject signatures with any variation in the string.


Step 3 — Send the Cancel Request

DELETE /v1/listings/:orderHash

Headers:

  • x-api-key: mp_part_yourkey
JSON
{
"signature": "0xsignaturehex..."
}

Listing Ownership Requirement

A partner can only cancel listings that were created using their own API key. If the listing was created by another partner or directly on the Mintpad website, the API will reject the request with 403 Forbidden.

The API recovers the signer from the signature and verifies:

  1. The signature matches the original listing's signer address.
  2. The listing was originally created by the requesting partner (partnerId matches the authenticated API key).

If all checks pass, the listing is marked as cancelled immediately.

Error Responses

If the listing was created by another partner:

  • Status: 403 Forbidden
  • Body:
JSON
{
"error": "FORBIDDEN",
"message": "This listing was not created by your partner account."
}

Response

JSON
{
"success": true,
"orderHash": "0xabcde12345...",
"status": "cancelled"
}

Full Example (Gasless)

TypeScript
async function cancelListing(
orderHash: string,
sellerAddress: string,
signer: Signer, // ethers.js v6
apiKey: string
) {
// 1. Sign the cancellation message
const message = `Cancel Mintpad Listing: ${orderHash}`
const signature = await signer.signMessage(message)
// 2. Submit the cancel request
const res = await fetch(
`https://partners-api.mintpad.app/v1/listings/${orderHash}`,
{
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey
},
body: JSON.stringify({ signature })
}
)
const data = await res.json()
if (!data.success) throw new Error(`Cancel failed: ${data.error}`)
return data
}