About KYG webhooks

How KYG notifies you when an asynchronous batch finishes.

A batch can take minutes to finish. Instead of making you poll, we call you: when a batch reaches a final state, KYG sends one POST to the URL registered for your account.

The webhook is a notification, not a delivery. It tells you which batch finished and how it finished. It never carries player profiles — those are always read with GET /api/v1/batches/{batch_id}.


Configuration

Webhooks are configured per account, once — not per batch. Every batch you submit is delivered to the same registered URL and signed with the same secret; the submission body has no webhook_url field.

Send us, through your usual support channel:

  1. The URL that should receive notifications.
  2. Who on your side should receive the signing secret.

We register it and hand you a signing secret, which you store wherever you keep credentials. It is the key to every signature we send you — see Signature verification.

Until the URL is registered, batches run normally. You simply get no notification, and read results with GET /api/v1/batches/{batch_id}.

The secret is not recoverable. We cannot look it up and re-send it. If it is lost, we re-register the account, which mints a new secret and invalidates the old one at that instant — there is no window where both are accepted, so the swap has to be scheduled.


Endpoint requirements

Your endpoint must accept POST with Content-Type: application/json and reply with any 2xx status. Anything else — 4xx, 5xx, a timeout or a dropped connection — counts as a failed attempt and is retried.

Answer quickly. The request times out after 10 seconds, so acknowledge first and do the heavy work afterwards: enqueue the batch_id, return 200, and fetch the result pages in the background. An endpoint that downloads a thousand results before replying will time out, be retried, and make you process the same batch twice.


Signature Verification

Every request carries an x-paag-webhook-signature header: the HMAC-SHA256 of the raw request body keyed with your signing secret, rendered as hexadecimal and then Base64-encoded. No sha256= prefix.

Important: use exactly the bytes of the received raw body in the calculation. Re-serializing the JSON may alter spacing and key order and invalidate the comparison.

The full procedure, a test vector to check your implementation against, and working examples in six languages are on Signature verification.

Same scheme as the Payments API — same header name, same algorithm, same encoding. If you already verify Paag payment webhooks, reuse that code as-is. Only the secret differs: each product has its own.