Skip to main content

Webhooks — list of endpoints

Every endpoint in the Webhooks section of the API Reference →. Click any row to open the full reference page with the request body, response body, examples, and the Try it widget.

These endpoints are the management surface for the webhooks we send you. They do not deliver webhooks — they configure and inspect them. How a webhook is signed and delivered is covered in the Webhooks guide.

At a glance​

MethodEndpointWhat it does
GET/webhooks/public-keyThe public key you verify every webhook signature with.
PUT/webhooks/secretSet or rotate the secret your webhooks are signed with.
GET/webhooks/eventsEvery supported event type and whether it is currently on.
PATCH/webhooks/eventsSwitch one or more events on or off.
GET/logs/webhooksYour own delivery history — one row per delivery attempt.

All paths are relative to the Partner API base URL (https://api.card-management-staging.paynovus.com/api/partner). Every endpoint is scoped to the partner whose JWT you sent — you can never read or change another partner's configuration.

The other direction

These endpoints are what you call. The webhook itself arrives at your url as a POST — see the Webhooks guide for the body you receive, the signature scheme, and the guarantee that one final outcome produces one webhook.

Get the public key​

GET /webhooks/public-key

Fetches the Ed25519 public key your receiver verifies signatures with. Cache it by keyId; the X-Payload-Key-Id header on each webhook tells you which key signed it, so you can pick the right one after a rotation.

Request body: none.

Response body

{
"success": true,
"keyId": "9f86d081884c7d65",
"algorithm": "ed25519",
"publicKey": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n"
}

Validation

FieldTypeRequiredRules
successboolean—Always true on success.
keyIdstring—The signing key id, matching X-Payload-Key-Id.
algorithmstring—Always ed25519.
publicKeystring—SPKI PEM.

Errors: 401 when the JWT is missing or invalid; 503 when signing is not configured on the environment (no webhooks are sent there either).

Set or rotate the secret​

PUT /webhooks/secret

Sets the secret your webhooks are signed with. The secret is stored encrypted and is write-only — no endpoint returns it again, so store it when you set it. Rotation applies to webhooks sent after the call, with no grace period for the old secret.

Request body

{
"secretKey": "my-own-long-random-secret"
}

Omit the body entirely and we generate a strong random secret and return it once in the response.

Request validation

FieldTypeRequiredRules
secretKeystringNo8–200 characters. Trimmed before it is stored. Unknown properties are rejected.

secretKey is the only accepted property. A misspelled field (for example secret) is rejected with 400 rather than being silently ignored, so you always know which secret is in force.

Response body

{
"success": true,
"hasSecret": true,
"secretKeyGenerated": false
}
FieldTypeRules
successbooleanAlways true on success.
hasSecretbooleanAlways true — a secret is stored either way.
secretKeyGeneratedbooleantrue when we generated the secret, false when we used the value you supplied.
secretKeystringPresent only when secretKeyGenerated is true, and only this once.

Errors: 400 for an invalid length or an unknown request property; 401 when the JWT is missing or invalid.

Validation error body

A failed validation returns the offending field and the reason:

{
"message": "Validation failed",
"details": [{ "field": "secretKey", "message": "secretKey must be at least 8 characters" }],
"type": "validation error"
}

List the event subscriptions​

GET /webhooks/events

Returns every event type the platform can send, with its current on/off state. An event you have never touched is on — webhooks are opt-out, so a newly introduced event type reaches you without any change.

Request body: none.

Response body

{
"success": true,
"count": 8,
"data": [
{ "event": "b2b_account_created", "isActive": true },
{ "event": "b2b_cardholder_approved", "isActive": false }
]
}
FieldTypeRules
successbooleanAlways true on success.
countintegerThe number of supported event types.
dataarrayOne entry per event type, each { event, isActive }.

The supported event types

eventMeaning
individual_onboarding_applicant_createdAn individual onboarding was created.
individual_onboarding_applicant_declinedThe individual onboarding ended without a usable account.
b2b_account_createdA B2B account request was approved.
b2b_account_declinedA B2B account request was declined.
b2b_cardholder_approvedA B2B cardholder request was approved.
b2b_cardholder_declinedA B2B cardholder request was declined.
b2b_iban_settings_updatedAn IBAN settings change was applied or declined.
b2b_iban_linkedAn IBAN link request was linked or declined.

Errors: 401 when the JWT is missing or invalid.

Switch event subscriptions​

PATCH /webhooks/events

Sets the state of one or more events at once. Events you do not mention keep their current state, so the request is safe to repeat.

Request body

{
"events": [
{ "event": "b2b_cardholder_approved", "isActive": false },
{ "event": "b2b_iban_linked", "isActive": true }
]
}

Request validation

FieldTypeRequiredRules
eventsarrayYesAt least one entry. Unknown properties are rejected.
events[].eventstringYesOne of the supported event types listed above.
events[].isActivebooleanYestrue to receive the event, false to skip it.

isActive must be a real JSON boolean — the string "false" is rejected, not coerced. Unknown fields, in the body or inside an event entry, are rejected too.

Response body: the same shape as the list endpoint — the full event list after the change.

Errors: 400 for an empty array, an unknown event type, or a non-boolean isActive; 401 when the JWT is missing or invalid.

Validation error body

A failed validation returns the offending field and the reason:

{
"message": "Validation failed",
"details": [{ "field": "events", "message": "events must include at least one event" }],
"type": "validation error"
}
The master switch

Delivery also requires the master webhook switch (webhooks.isActive), which your PayNovus administrator controls. Switching an event off here does not change the master switch or your url.

Read the delivery history​

GET /logs/webhooks

Every webhook we send to you leaves a delivery log row. This endpoint returns those rows so you can see what was sent, to which url, and whether it arrived. It is read-only — there is no resend or modify action here.

Query parameters

ParameterTypeDefaultRules
pageinteger1Page number.
limitinteger50Rows per page.

Response body

{
"success": true,
"count": 2,
"data": [
{
"_id": "6adf2f5bfe545da555d81245",
"event": "b2b_cardholder_approved",
"webhookUrl": "https://your-domain.example/webhooks/cip",
"payloadSent": { "status": "success", "type": "b2b_cardholder_approved" },
"responseStatus": 200,
"responseBody": { "received": true },
"error": null,
"createdAt": "2026-01-15T10:30:00.000Z"
}
],
"pagination": { "total": 2, "page": 1, "limit": 50, "pages": 1, "hasNextPage": false, "hasPrevPage": false }
}
FieldTypeRules
eventstringThe event type — the same value as the body's type.
webhookUrlstringThe url we delivered to.
payloadSentobjectThe exact body we sent, or null.
responseStatusintegerThe HTTP status your endpoint returned, or null if it never answered.
responseBodyobjectThe body your endpoint returned.
errorobjectThe error details, when the delivery failed, otherwise null.
createdAtstringWhen the attempt was made (ISO 8601).

The signing secret is never included.

Errors: 401 when the JWT is missing or invalid.