← Back to product·Simulmedia VAMOS Docs·API reference / Webhooks
API reference

Webhooks

Push delivery for events: register a notify URL, verify every signature, and treat every delivery as a hint. Buyers and sellers use the same machinery. Concept and receiver guidance: Webhooks.

Register a notify URL

POST/v1/webhooks/endpointswebhooks:manage

Register an HTTPS endpoint to receive event deliveries.

Request body

FieldTypeDescription
url requiredstringHTTPS URL that receives deliveries. Must be on your organization's allowlist; registering a non-allowlisted URL returns 422.
eventsarray of stringFilter to specific event types. Omit to receive every event for your role.
statusesarray of stringFilter order.status_changed deliveries to transitions landing in these order statuses, e.g. ["seller_review", "canceled"]. This is the replacement for what the retired per-audience type names used to select: a seller's old order.needs_review subscription is events: ["order.status_changed"], statuses: ["seller_review"], and it is strictly more precise, because any status can be filtered, not only the ones that once had their own name. Ignored for the non-lifecycle types, which have no status to filter. Omit for every transition you are eligible for: filters narrow within the audience-eligibility matrix, never widen past it, and a registration stored under a retired type name is migrated at read time per the same section.
labelstringFree-text name shown in Settings.

Response

The endpoint starts as pending_verification: the platform sends a signed ping, and verifying its signature confirms the endpoint. signing_key_id names the key that signs your deliveries.

201 Response
{
  "endpoint_id": "whe_4c1a",
  "url": "https://yourapp.example.com/webhooks/vamos",
  "events": ["order.status_changed", "catalog.stale_rate_card"],
  "label": "production-buyer-webhook",
  "status": "pending_verification",
  "signing_key_id": "key_2026q4"
}

Errors

StatusCodeWhen
422INVALID_INPUTurl is not HTTPS or is not on your organization's allowlist.

Remove an endpoint

DELETE/v1/webhooks/endpoints/{id}webhooks:manage

Deregister a notify URL. Delivery stops immediately; events keep accruing on your orders and stay replayable.

Response

204 with an empty body.

Errors

StatusCodeWhen
404NOT_FOUNDThe endpoint id does not exist within your organization.

Verifying the signature

Every delivery is signed: HMAC-SHA256 over the timestamp and the raw body, carried in X-Signature as t={unix_ts},v1={hex_digest}. Verify before trusting the payload, and reject stale timestamps. X-Delivery-Attempt carries 1, 2, or 3. Signing keys rotate; the signing_key_id on your registration names the active key.

// Python
import hmac, hashlib, time
def verify(secret, header, body):
    parts = dict(p.split('=',1) for p in header.split(','))
    ts, sig = parts['t'], parts['v1']
    if abs(time.time() - int(ts)) > 300:
        raise ValueError("stale timestamp")
    expected = hmac.new(secret.encode(), f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

// Node
const crypto = require('crypto');
function verify(secret, header, rawBody) {
  const {t, v1} = Object.fromEntries(header.split(',').map(p => p.split('=')));
  if (Math.abs(Date.now()/1000 - +t) > 300) throw new Error('stale');
  const expected = crypto.createHmac('sha256', secret)
    .update(`${t}.${rawBody}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Receiver pattern

Verify, ack fast, process async, dedup on (order_id, seq).

app.post('/webhooks/vamos', (req, res) => {
  verify(process.env.VAMOS_SIGNING_KEY, req.headers['x-signature'], req.rawBody);
  const { order_id, seq } = req.body;
  if (seen(order_id, seq)) return res.status(204).end();  // dedup: retries reuse seq
  enqueue(req.body);                                       // ack fast, process async
  res.status(200).end();
});

After any outage, replay with GET /v1/events?order={id}&after_seq={last_seen}. The full receiver and recovery pattern: Webhooks.

Delivery semantics

  • Up to 3 attempts per event, exponential backoff (roughly 5s, then 25s). After that: log and drop; recover via the snapshot plus replay.
  • Your endpoint must respond within 10 seconds; slow responses are treated as failures.
  • Non-2xx responses trigger a retry. 204 on dedup is the correct response; it stops retries.
  • An allowlisted endpoint that becomes unreachable for more than 1 hour is marked degraded; you receive a platform notification and can re-verify under Settings.
Deliveries are hints, not truth: a push can be dropped, delayed, or retried, while the order snapshot is the platform's own fold of the order's complete event log, which is what makes it authoritative. Replay and the event feed close any gap; nothing depends on your uptime.

Shared-queue delivery (SQS)

Request a shared SQS queue per counterparty for event delivery without a public endpoint. Same envelope, same seq semantics, AWS-native access control: grant sqs:SendMessage on your queue to the VAMOS service principal and provide the queue ARN under Settings → Delivery.