Getting Started
Webhooks

Webhooks

Webhooks let Spectra push events to your server in near-real-time — orders placed, shipments delivered, inventory changes, and more. This is faster and cheaper than polling.

How webhooks work

  1. You register an HTTPS URL and the events you care about
  2. Spectra saves an HMAC secret and returns it once
  3. When a matching event happens, Spectra POSTs JSON to your URL with the signature in the X-Webhook-Signature header
  4. You verify the signature and process the event
  5. Spectra fires and forgets — no retries on failure (keep your endpoint reliable)

Register a webhook

curl -X POST https://api.spectradiag.com/api/v1/webhooks \
  -H "Authorization: Bearer spk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://myapp.com/spectra-webhook",
    "events": ["order.created", "order.shipped", "order.delivered"]
  }'

Response:

{
  "success": true,
  "data": {
    "id": 42,
    "url": "https://myapp.com/spectra-webhook",
    "events": ["order.created", "order.shipped", "order.delivered"],
    "secret": "f9a3d7..." 
  }
}

Save the secret immediately — it's only returned once and you need it to verify signatures.

Subscribing to all events

Use "*" to subscribe to everything:

{ "url": "https://myapp.com/spectra-webhook", "events": ["*"] }

Available events

EventWhen it fires
order.createdNew order placed
order.status_changedOrder status updated
order.shippedOrder marked shipped
order.deliveredOrder marked delivered
order.cancelledOrder cancelled
return.requestedCustomer requested return
return.approvedReturn approved by admin
return.refundedRefund issued
inventory.receivedDevice checked into inventory
inventory.updatedDevice fields updated
inventory.soldDevice marked sold
buyback.quote.createdNew buyback quote
buyback.quote.approvedBuyback quote accepted
buyback.quote.declinedBuyback quote rejected
repair.createdRepair ticket opened
repair.completedRepair ticket closed
customer.createdNew customer account
customer.updatedCustomer profile changed

Event payload format

{
  "event": "order.shipped",
  "timestamp": "2026-05-15T14:23:00+00:00",
  "data": {
    "id": 1234,
    "order_number": "ORD-20260515-0042",
    "tracking_number": "1Z999AA10123456789",
    "shipping_carrier": "UPS"
  }
}

Verifying signatures

Every request includes:

X-Webhook-Event: order.shipped
X-Webhook-Signature: sha256=f4e2...
User-Agent: Spectra-Webhook/1.0

The signature is HMAC-SHA256(body, secret). Verify it to confirm the request is genuinely from Spectra:

Node.js

const crypto = require('crypto');
 
function verifySignature(rawBody, signatureHeader, secret) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}

PHP

function verifySignature(string $rawBody, string $signatureHeader, string $secret): bool {
  $expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
  return hash_equals($expected, $signatureHeader);
}

Python

import hmac, hashlib
 
def verify_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Handling events

  • Respond with 2xx quickly — within 5 seconds, or the request times out
  • Acknowledge before processing — return 200 immediately, then do work in the background
  • Idempotency matters — if you receive the same event twice, don't double-process
  • Be resilient to outages — Spectra does NOT retry. For critical events, reconcile via the API periodically

Delivery log

Check delivery attempts:

curl https://api.spectradiag.com/api/v1/webhooks/42/deliveries \
  -H "Authorization: Bearer spk_live_xxx"

Returns the last 50 deliveries with status codes, response bodies, and errors.

Removing a webhook

curl -X DELETE https://api.spectradiag.com/api/v1/webhooks/42 \
  -H "Authorization: Bearer spk_live_xxx"