You register webhook endpoints in the dashboard. From then on, every qualifying event in your workspace is delivered to that endpoint as an HTTPDocumentation Index
Fetch the complete documentation index at: https://docs.kwugwo.africa/llms.txt
Use this file to discover all available pages before exploring further.
POST. This page explains the request shape, how to verify
it, and how retries work.
Endpoint management — creating, listing, regenerating secrets — is
done from the dashboard. The
/v1/* merchant API does not expose
webhook CRUD.Event types
| Event | Fires when |
|---|---|
nzube.onye.created | A customer record is created. |
nzube.onye.updated | A customer record is updated. |
nzube.onye.deleted | A customer record is deleted. |
ugwo.created | A new ugwo is created. |
ugwo.updated | An ugwo changes state (e.g. requires_ugwo → processing → ugwo_successful). |
ugwo.activity.created | An activity is created against an ugwo. |
ugwo.activity.updated | An activity changes state (requires_action → successful, etc). |
Delivery request
Every webhook is sent as an HTTPPOST with a JSON body.
Headers
| Header | Purpose |
|---|---|
Content-Type | Always application/json. |
X-Kwugwo-Signature | HMAC-SHA256 of the raw body, hex-encoded, computed with your endpoint’s secret. Empty string if you never set a secret. |
X-Kwugwo-Delivery-Id | UUID identifying this delivery attempt. Re-delivery on retry uses a new id. Useful for idempotency on your side. |
Body envelope
The body is an envelope wrapping the resource that triggered the event:uid— the event id. It follows Kwugwo’s standard ID format with theevtprefix and is stable across redelivery attempts — use it as your idempotency key.event— the event type from the table above.data— the resource snapshot, in the same shape the correspondingGETendpoint returns.
Verifying the signature
ComputeHMAC-SHA256(secret, raw_body) and compare it constant-time
against the X-Kwugwo-Signature header. Verify against the raw
body bytes, not a re-encoded JSON string — re-serializing will
change whitespace and break the signature.
Retries
Kwugwo treats any2xx response from your endpoint as success. Any
other status, a redirect, a network error, or a timeout is a failure.
| Setting | Value |
|---|---|
| Max attempts | 3 (the initial delivery + 2 retries) |
| Retry interval | 30 minutes between attempts |
| Backoff | Fixed (no exponential growth) |
| Per-event status | pending → success on a 2xx, or pending again until the cap, then failed |
failed and is
not retried again. Re-delivery is not yet exposed in the dashboard;
if you need an event replayed, contact support with the event uid.
Best practices
- Respond quickly. Return
200as soon as you’ve persisted the event UID. Do the heavy work asynchronously — webhook delivery treats any timeout as a failure and burns one of your three attempts. - Be idempotent on
event.uid. Two attempts of the same event share the sameuid. Two events for the same state change (e.g.ugwo.updatedfollowed byugwo.activity.updated) do not. - Re-fetch on the merchant API for the source of truth. The
datasnapshot is what the resource looked like at the moment the event fired. If your handler runs minutes later (or after a retry), pull the latest from the merchant API before acting. - Don’t enforce a list of allowed event types in code. New events get added over time — just skip the ones you don’t care about.

