Update Listing

EIP-712 order signatures are cryptographically bound to specific pricing and nonce values — they cannot be mutated after signing. To update a listing (e.g. to change the price or extend the expiration), you must cancel the existing listing and create a new one.


Why You Can't Edit In-Place

When a listing is created, the seller signs a MakerOrder struct that commits to exact values for price, endTime, nonce, and all other fields. The orderHash is derived from this struct. Changing any field would produce a different hash and invalidate the original signature.


Step 1 — Get the Current orderHash

If you stored it at creation, use it directly. Otherwise look it up:

Text
GET /v1/listings?seller=0x9876...&tokenId=123
JSON
{
"listings": [
{
"orderHash": "0xabcde12345...",
"tokenId": "123",
"priceWei": "100000000000000000000",
"endTime": 1781874000
}
]
}

Step 2 — Cancel the Existing Listing

Sign and submit a cancellation for the current orderHash. See the Cancel Listing page for the full flow.

TypeScript
// Sign the cancellation message
const message = `Cancel Mintpad Listing: ${orderHash}`
const cancelSignature = await signer.signMessage(message)
// Cancel via DELETE
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: cancelSignature })
})

Step 3 — Create a New Listing

Build fresh typed data with the new price or expiration, get the user's signature, and ingest it. See the Create Listing page for the full flow.

TypeScript
// Build new typed data with updated price (requires partner key)
const typedDataRes = await fetch('https://partners-api.mintpad.app/v1/listings/typed-data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey
},
body: JSON.stringify({
seller: sellerAddress,
collectionAddress,
tokenId,
priceWei: newPriceWei, // Updated price
expiresAt: newExpiresAt // Updated expiration
})
})
const { orderHash: newOrderHash, typedData } = await typedDataRes.json()
// Get user signature for the new listing
const newSignature = await signer.signTypedData(
typedData.domain,
{ MakerOrder: typedData.types.MakerOrder },
typedData.message
)
// Submit the new listing
await fetch('https://partners-api.mintpad.app/v1/listings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey
},
body: JSON.stringify({
orderHash: newOrderHash,
isOrderAsk: true,
signer: sellerAddress,
collectionAddress,
...typedData.message,
signature: newSignature
})
})

Both the cancel and re-list require the user to sign. Present them as a single "Update Listing" flow in your UI — cancel first, then immediately prompt for the new listing signature.


Scoping & Ownership Rules for Updates

Because an update is executed as a cancellation followed by a new listing:

  1. Cancellation Scope: You can only cancel the active listing if it was originally created by your own partner API key. Attempting to update a listing created by another partner will fail at the cancellation stage with 403 Forbidden.
  2. Duplicate Creation Prevention: When requesting typed data and submitting the new listing, the API verifies that there is no other active listing for the same token. If you attempt to list the NFT without successfully cancelling the original one first, the creation endpoints will return a 409 Conflict error (ACTIVE_LISTING_EXISTS).

Full Update Flow

TypeScript
async function updateListing({
currentOrderHash,
collectionAddress,
tokenId,
sellerAddress,
newPriceWei,
newExpiresAt,
signer,
apiKey
}: UpdateListingParams) {
// 1. Cancel existing listing
const cancelMsg = `Cancel Mintpad Listing: ${currentOrderHash}`
const cancelSig = await signer.signMessage(cancelMsg)
await fetch(`https://partners-api.mintpad.app/v1/listings/${currentOrderHash}`, {
method: 'DELETE',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({ signature: cancelSig })
})
// 2. Build new typed data
const tdRes = await fetch('https://partners-api.mintpad.app/v1/listings/typed-data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey
},
body: JSON.stringify({
seller: sellerAddress,
collectionAddress,
tokenId,
priceWei: newPriceWei,
expiresAt: newExpiresAt
})
})
const { orderHash: newOrderHash, typedData } = await tdRes.json()
// 3. Get user signature for new listing
const listSig = await signer.signTypedData(
typedData.domain,
{ MakerOrder: typedData.types.MakerOrder },
typedData.message
)
// 4. Submit new listing
const submitRes = await fetch('https://partners-api.mintpad.app/v1/listings', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({
orderHash: newOrderHash,
isOrderAsk: typedData.message.isOrderAsk,
signer: typedData.message.signer,
collectionAddress: typedData.message.collection,
price: typedData.message.price,
tokenId: typedData.message.tokenId,
amount: typedData.message.amount,
strategy: typedData.message.strategy,
currency: typedData.message.currency,
nonce: typedData.message.nonce,
startTime: typedData.message.startTime,
endTime: typedData.message.endTime,
minPercentageToAsk: typedData.message.minPercentageToAsk,
params: typedData.message.params,
signature: listSig
})
})
return submitRes.json()
}