Skip to main content

Webhooks

Webhooks let you receive events instantly instead of continuously polling your server. When an event occurs, Rabisu sends a signed POST request to your registered URL.

1. Register an Endpoint — POST /webhooks​

curl -X POST https://api.rabisu.com/api/v1/webhooks \
-u "rsk_live_xxx:rsks_yyy" \
-H "Content-Type: application/json" \
-d '{
"url": "https://reseller.com/modules/addons/rabisu/webhook.php",
"event_types": ["service.*", "credit.added"],
"description": "Production webhook"
}'

The HMAC secret is returned only once — store it securely:

{
"success": true,
"data": {
"id": 12,
"url": "https://reseller.com/.../webhook.php",
"event_types": ["service.*", "credit.added"],
"secret": "whsec_...ONE_TIME...",
"is_active": true
},
"meta": { "trace_id": "...", "timestamp": "..." }
}

URL Rules (SSRF Protection)​

  • https:// is required.
  • The URL may not contain user:pass@.
  • All resolved DNS IPs must be public (private/internal IPs are rejected).

2. Subscription Patterns​

The event_types array supports these forms:

PatternMeaning
*All events (catch-all)
service.*Namespace wildcard — all events starting with service
service.createdExact event name

Valid namespaces: service, product, credit. Sending an invalid pattern makes the registration fail with 422 (a clear error instead of silently "receiving no events").

3. Event Catalog​

EventWhenPayload fields (summary)
service.createdVPS provisioning completed (active)provision_id, service_id, order_id, product_id, status
service.suspendedService suspendedservice_id, reason
service.unsuspendedSuspension liftedservice_id
service.terminatedService terminatedservice_id
product.price_changedProduct price changed (notification)product_id
product.stock_changedProduct stock status changedproduct_id, stock_active
product.disabledProduct closed for saleproduct_id
credit.addedReseller credit added (refund/manual)reseller_id, amount, currency, reason, new_balance

Note: product.* events carry a notification only. Fetch the current data with GET /products/{id} (hybrid notification + pull).

Every payload includes a schema_version field at its root (currently 1).

4. Signature Verification (CRITICAL)​

Every delivery includes two signature headers:

HeaderContentUsage
X-Rabisu-Signature-V2t=<unix>,v1=<hex> — HMAC-SHA256(secret, "{t}.{X-Rabisu-Event-Type}.{raw body}")Recommended. Protects against replay and event-type swapping
X-Rabisu-Signaturesha256=<hex> — HMAC-SHA256 of the raw body onlyFor legacy receivers. No replay protection; do not use in new integrations

The receiver must verify that |now - t| <= 300 seconds and check the signed event type (X-Rabisu-Event-Type).

Verification (PHP, V2):

$raw = file_get_contents('php://input');
$eventType = $_SERVER['HTTP_X_RABISU_EVENT_TYPE'] ?? '';
$header = $_SERVER['HTTP_X_RABISU_SIGNATURE_V2'] ?? '';

parse_str(str_replace(',', '&', $header), $parts); // t=..., v1=...
$t = (int) ($parts['t'] ?? 0);
$v1 = (string) ($parts['v1'] ?? '');

if (abs(time() - $t) > 300) {
http_response_code(401); // Outside the time window (replay)
exit;
}

$expected = hash_hmac('sha256', $t . '.' . $eventType . '.' . $raw, $webhookSecret);
if (!hash_equals($expected, $v1)) {
http_response_code(401); // Invalid signature
exit;
}
// Safe: the payload can be processed
$payload = json_decode($raw, true);
  • Always verify the signature — otherwise you accept forged requests.
  • Use a constant-time comparison such as hash_equals.
  • Verify against the raw body before decoding to JSON (re-serialized JSON breaks the signature).

5. Delivery and Response Contract​

Your endpoint should return the following HTTP codes:

ResponseMeaningRabisu behavior
2xxProcessed successfullyDelivery complete
4xx (incl. 401)Permanent error (signature/format)Not retried
5xxTransient errorRetried with exponential backoff

Retry schedule: 1m → 5m → 15m → 1h → 6h → 24h. After 6 attempts the event is marked "dead letter". After 5 consecutive failures the endpoint is automatically deactivated (circuit breaker) — reactivate it with PATCH /webhooks/{id} once fixed.

6. Management Endpoints​

  • GET /webhooks — list registered endpoints (including inactive)
  • GET /webhooks/{id} — detail
  • PATCH /webhooks/{id} — reactivate / update event_types or description
  • DELETE /webhooks/{id} — delete (soft delete)