Karauti API documentation
/
Sign in

Payload

We POST this when an API order's status changes to 1, 2, 11, 23 or 24. A 24 is always followed by one more callback once we have confirmed the outcome. Reply 2xx within 10 seconds; otherwise we retry after 1 minute and after 5. Console orders get no webhook.

POST https://yoursite.com/api/notify Content-Type: application/json X-Karauti-Signature: t=1786686460,v1=8f2c… { "event": "order.updated", "data": { "order_id": "ORD-1001", "trx_id": "K260816YULHW3", "status": 1, "failure_code": null, "message": "The order completed.", "sku": "UNIFF25", "target": "9003278192", "nickname": "Rafi", "sn": "10721447482238481657", "fee": 2, "balance": 4976, "created_at": "2026-08-14T05:46:40+00:00", "voucher": null }, "meta": { "unix_timestamp": 1786686455 } }

Fields

From order_id down, the fields are inside data: the same object Check a status returns, plus voucher.

eventAlways order.updated here. Product changes are product.updated and product.removed.
meta.unix_timestampWhen the order reached this status. Keep the newest per order_id and ignore anything older.
order_idYour reference.
trx_idOur reference. Always present.
statusWhat to do next: 0, 1, 2, 11, 23 or 24. See Order status.
failure_codeWhy it failed. Null unless it failed.
messageOne sentence you can show a person.
skuThe product ordered.
targetThe player account. Empty string on a gift card, which is delivered to nobody.
nicknameThe player name the supplier returned, when it returned one.
snSupplier serial. Null unless delivered. Proof an order happened — not something to redeem.
feeCharged for this order, NPR.
balanceKarauti balance after the fee, NPR.
created_atWhen the order was placed, ISO 8601.
voucherA gift card's redeemable code, when the order produced one. Null on every other order. Webhook only. This is money — see Gift cards.
Warning

Test payloads carry "test": true. Reject those before delivering goods.

Info

Callbacks come from 103.235.196.125. Allowlist it if you like, but verify the signature regardless.

Note

This is the order callback. The catalogue has its own stream — product updates — signed the same way, and pointable at a different URL.

Verifying

X-Karauti-Signature: t=<unix timestamp>,v1=<lowercase hex>

v1 is HMAC-SHA256 of timestamp . "." . raw body, keyed with the whsec_ signing secret from Settings → Webhook. Not the API secret key.

// PHP [$t, $v1] = sscanf($_SERVER['HTTP_X_KARAUTI_SIGNATURE'], 't=%d,v1=%s'); $raw = file_get_contents('php://input'); $ok = hash_equals(hash_hmac('sha256', $t.'.'.$raw, $secret), $v1) && abs(time() - $t) <= 300; if (! $ok) { http_response_code(401); exit; }
Warning

Hash the raw body as received. Decoding and re-encoding the JSON changes the bytes and valid callbacks will fail the check.

Warning
  • Reject a t more than 5 minutes old, so a captured callback cannot be replayed later.
  • The same order can arrive twice (a retry, or a manual Resend). Act once per order_id and status.
Note

Every callback failing the check usually means the two copies of the secret have drifted apart. An owner can read the current one back under Show secret on the Webhooks page — compare it with what your own config holds before changing anything else. Rotating issues a new one and signs with it immediately, so your site rejects every callback until the new value is deployed.