Card VaultAI← Home

Webhooks

Get notified when cards are identified, listed, or sold without polling the API.

Last updated May 11, 2026

Webhooks let the vault push events to your server in real time. Instead of polling GET /cards?updated_since=... every minute, register a webhook URL and we'll POST to it as events happen.

Status note. Webhooks are documented here as part of the Wave 5 KB rollout. The dashboard UI for registering webhooks at /settings/webhooks is coming soon. Until then, contact us and we'll register one for you by hand.

What events fire

EventWhen
card.identifiedA card moves from imported to identified (AI or manual)
card.pricedA card gets an asking price for the first time
card.workflow_status_changedAny workflow status transition
listing.publishedAn eBay listing successfully goes live
listing.soldAn eBay listing closes with a sale
listing.endedAn eBay listing ends without selling
batch.completedA batch is marked complete
identify.failedBoth CardSight and Gemini fail to identify a card

Payload format

Every webhook POSTs JSON with a stable shape:

{
  "id": "evt_01HX9...",
  "event": "card.identified",
  "created_at": "2026-05-11T15:32:01Z",
  "account_id": "acc_01HX8...",
  "data": {
    "card_id": "card_01HX...",
    "title": "2023 Crown Zenith Charizard VMAX",
    "set": "Crown Zenith",
    "number": "20/20"
  }
}

The data payload varies by event. Full schemas will live at /help/api/webhook-events once Wave 5 closes.

Signing

Every webhook is signed with an HMAC-SHA256 of the raw body using a secret unique to your endpoint. The signature is in the X-Vault-Signature header:

X-Vault-Signature: t=1715442721,v1=5257a869e7ecebeda32affa62cdca3fa...

Verify by computing HMAC_SHA256(secret, "{t}.{body}") and constant-time-comparing to v1. Reject any request older than 5 minutes (the t timestamp) to prevent replay.

Delivery

We POST your endpoint with a 10-second timeout. Any non-2xx response (or a timeout) triggers retry with exponential backoff: 30s, 2m, 10m, 1h, 6h, 24h. After 24 hours of failures the event is dropped and surfaced in the dashboard.

Idempotency is your responsibility — the same event ID may arrive twice during a retry storm. Store the event.id on first receipt and skip duplicates.

When to use webhooks vs polling

  • Webhooks: you have an externally-reachable HTTPS endpoint and want low-latency updates (a custom dashboard, a Slack notifier, your own ERP).
  • Polling: you don't have an endpoint, or your workload is daily/weekly batch reconciliation. GET /cards?updated_since=... works fine.