AIARCOASC Docs

Webhooks

HMAC-SHA256 signed webhooks with replay protection. Rotate secrets without downtime.

What it is

Every webhook delivery includes:

  • X-AIARCO-Timestamp: <unix> — Unix seconds.
  • X-AIARCO-Signature: t=<unix>,v1=<hex> — HMAC-SHA256 of <unix>.<raw-body> using the webhook's signing secret.

Reject any delivery where |now - timestamp| > 300 s to prevent replay. Compute the signature with the raw body — don't parse and re-serialise.

Secrets can be rotated via POST /v1/webhooks/{id}/rotate-secret. The previous secret stays valid for 24 h so you can roll receivers.

When to use it

  • Get notified when a training run completes.
  • Receive Shield workflow events for downstream automation.
  • React to billing events (budget threshold crossed).

Quickstart

asc webhooks create training-done --url https://my-app/hooks/asc --events training.run.completed,training.run.failed
# returns: { id, secret: 'whsec_…' }  — store it, you can't see it again
# Verify in your receiver
import hmac, hashlib, time
def verify(body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split('=', 1) for p in header.split(','))
    ts = int(parts['t'])
    if abs(time.time() - ts) > 300: return False
    expected = hmac.new(secret.encode(), f'{ts}.'.encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts['v1'])
import { createHmac, timingSafeEqual } from 'crypto';
export function verify(body: Buffer, header: string, secret: string): boolean {
  const parts = Object.fromEntries(header.split(',').map(p => p.split('=', 2)));
  const ts = parseInt(parts.t, 10);
  if (Math.abs(Date.now() / 1000 - ts) > 300) return false;
  const expected = createHmac('sha256', secret).update(`${ts}.`).update(body).digest('hex');
  return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Limits & quotas

LimitDefaultBurstNotes
Replay window±300 s
Retry policy5 retries, exp. backoffUp to 24 h
Delivery timeout10 sRespond 2xx within this window

API surface

  • POST /v1/webhooks — create
  • POST /v1/webhooks/{id}/rotate-secret — rotate (24 h grace)
  • GET /v1/webhooks/{id}/deliveries — delivery log
  • POST /v1/webhooks/{id}/deliveries/{d}/replay — manual replay

Security

All access is authenticated and scoped. See Auth & scopes and Network controls.