Webhooks
Receive real-time notifications when events occur in your workspace.
Overview
Webhooks allow your application to receive HTTP POST callbacks whenever significant events happen — new buyer requests, match completions, trade state transitions, and more. Each delivery is signed with HMAC-SHA256 so you can verify authenticity.
Event Types
buyer_request.createdNew buyer request submittedbuyer_request.matchedBuyer request matched with inventorybuyer_request.archivedBuyer request archivedmatch.completedMatch engine run completedoffer.createdNew offer sentoffer.acceptedOffer accepted by buyeroffer.rejectedOffer rejectedoffer.counteredCounter-offer receivedtrade.initiatedNew trade createdtrade.paidPayment receivedtrade.shippedTrade marked as shippedtrade.completedTrade completed successfullytrade.cancelledTrade cancelledhold.createdNew hold placedhold.expiredHold expired without conversionhold.deposit_paidHold deposit payment receivedinventory.createdNew inventory item addedinventory.updatedInventory item updatedinventory.deletedInventory item removedlive_session.startedLive selling session startedlive_session.endedLive session endedreserve.placedReserve placed on live lotRegistering a Webhook
const webhook = await ciq.webhooks.create({
url: 'https://your-app.com/webhooks/collectiq',
events: ['trade.completed', 'offer.accepted', 'match.completed'],
});
if (webhook.success) {
// Save this secret securely — it is shown only once
console.log('Signing secret:', webhook.data.secret);
}curl -X POST https://collectiqhq.com/api/v1/webhooks \
-H "Authorization: Bearer ciq_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/collectiq",
"events": ["trade.completed", "offer.accepted"]
}'Signature Verification
Every webhook delivery includes a X-CollectIQ-Signature header containing an HMAC-SHA256 signature of the request body using your webhook secret.
import { createHmac, timingSafeEqual } from 'crypto';
function verifyWebhookSignature(
body: string,
signature: string,
secret: string,
): boolean {
const expected = createHmac('sha256', secret)
.update(body)
.digest('hex');
const sig = signature.replace('sha256=', '');
return timingSafeEqual(
Buffer.from(sig, 'hex'),
Buffer.from(expected, 'hex'),
);
}
// In your webhook handler:
app.post('/webhooks/collectiq', (req, res) => {
const signature = req.headers['x-collectiq-signature'];
const isValid = verifyWebhookSignature(
req.rawBody,
signature,
process.env.COLLECTIQ_WEBHOOK_SECRET,
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = req.body;
console.log('Event type:', event.type);
console.log('Event data:', event.data);
res.status(200).json({ received: true });
});⚠ Always verify signatures before processing webhook payloads. Use timingSafeEqual to prevent timing attacks.
Payload Format
{
"id": "evt_a1b2c3d4e5f6",
"type": "trade.completed",
"created_at": "2025-01-15T10:30:00Z",
"workspace_id": "ws_...",
"data": {
"trade_id": "trd_...",
"offer_id": "ofr_...",
"amount": 299.99,
"status": "completed"
}
}Retry Policy
If your endpoint returns a non-2xx status code or times out (30s), CollectIQ will retry the delivery with exponential backoff:
Testing Webhooks
Send a test event to verify your endpoint is working:
// Send a test delivery via SDK
const test = await ciq.webhooks.test('<webhook-id>');
if (test.success) {
console.log('Status:', test.data.status);
console.log('Response:', test.data.body);
}View delivery history in Portal → Webhooks to inspect payloads and response codes.