Agent skill
Orb Webhooks Skill
Receive and verify Orb webhooks. Use when setting up Orb webhook handlers, debugging Orb signature verification, or handling usage-based billing events like invoice.issued, subscription.created, or customer.credit_balance_dropped.
Install this skill
npx skills add hookdeck/webhook-skills --skill orb-webhooks
When to Use This Skill
- Setting up Orb webhook handlers
- Debugging Orb signature verification failures
- Understanding Orb event types and payloads
- Handling usage-based billing, subscription, or invoice events
Verification (core)
Orb signs every webhook with HMAC-SHA256 over the literal string v1:{X-Orb-Timestamp}:{rawBody}. The hex digest is delivered in X-Orb-Signature prefixed with v1= (e.g. v1=abc123…). The ISO 8601 timestamp arrives separately in X-Orb-Timestamp. Use the raw request body — don't JSON.parse first.
The orb-billing SDK does expose webhook helpers — webhooks.verifySignature(), plus webhooks.unwrap() and webhooks.unwrapStandard() which verify and parse (verified against orb-billing@6.33.0). The manual HMAC above is the dependency-free path and is what the examples use; either is fine.
Payload shape (important)
Orb serializes the event's resource under a key matching the resource_name prefix of type — invoice.issued carries it under invoice, subscription.created under subscription. The resource ID lives there, not in properties, which holds only the extra fields specific to the event and is an empty object for many types.
Every payload also carries payload_style: "standard" or "expanded", configured per endpoint. Standard payloads summarize subscriptions and invoices (no line items, related objects as references); expanded payloads carry them in full. New endpoints default to standard, and retries of older events keep the style they were created with — so branch on payload_style rather than assuming one. See references/overview.md.
Node:
const crypto = require('crypto');
function verifyOrbSignature(rawBody, signatureHeader, timestamp, secret) {
if (!signatureHeader || !timestamp) return false;
const provided = signatureHeader.startsWith('v1=') ? signatureHeader.slice(3) : signatureHeader;
const expected = crypto
.createHmac('sha256', secret)
.update(`v1:${timestamp}:${rawBody}`)
.digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(provided, 'hex'), Buffer.from(expected, 'hex'));
} catch {
return false;
}
}
Python:
import hmac, hashlib
def verify_orb_signature(raw_body: bytes, signature_header: str, timestamp: str, secret: str) -> bool:
if not signature_header or not timestamp:
return False
provided = signature_header[3:] if signature_header.startswith("v1=") else signature_header
expected = hmac.new(
secret.encode(), f"v1:{timestamp}:".encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(provided, expected)
For complete handlers with route wiring, event dispatch, and tests, see:
- examples/express/ — Full Express implementation
- examples/nextjs/ — Next.js App Router implementation
- examples/fastapi/ — Python FastAPI implementation
Common Event Types
| Event | Description |
|---|---|
customer.created | New customer created |
customer.credit_ | Prepaid credit balance fell below a threshold |
subscription.created | New subscription created |
subscription.started | Subscription's billing period started |
subscription.ended | Subscription ended |
subscription.plan_ | Subscription moved to a different plan |
subscription.usage_ | Usage crossed a configured threshold |
invoice.issued | Invoice finalized and issued to customer |
invoice.payment_ | Invoice paid successfully |
invoice.payment_failed | Invoice payment attempt failed |
data_ | Scheduled data export delivered |
For full event reference, see Orb Webhook Documentation
Environment Variables
ORB_WEBHOOK_SECRET=your_webhook_signing_secret # Per-endpoint secret from Orb dashboard
The webhook signing secret is configured per webhook endpoint in the Orb dashboard — it is not your account API key.
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 orb --path /webhooks/orb
Reference Materials
- references/overview.md — Orb webhook concepts and events
- references/setup.md — Dashboard configuration
- references/verification.md — Signature verification details and gotchas