Create webhook
POST/v2/config/webhook
This endpoint creates a webhook. The webhook sends the events that you subscribe to, to an external IT system. The payload URL must start with http:// or https://, and it must be unique for the organisation. Subscribe to a minimum of 1 event type.
The service sends each event as an HTTP POST to the payload URL. The body holds 5 fields: deliveryID, webhookID, timestamp, type and data. The type field holds 1 of the subscribed event types, and the data field holds the event object. For an OID4VC event, data holds organisationId, an optional sandboxOrgId, and the credential or the presentation record.
The service signs each delivery with the X-IGrant-Signature header. The value is t=<timestamp>,sig=<hex>, where <hex> is the lowercase hexadecimal HMAC-SHA256 of <timestamp>.<json-payload> with the secret key. The service always signs the JSON payload, also when the content type is application/x-www-form-urlencoded. In that case, URL decode the payload form field before you check the signature.
The service makes 1 delivery attempt for each event. There is no automatic retry.
The response status code of this operation is 200, not 201. The response holds the secret key in clear text.
Request
Header Parameters
Optional. Unique identifier of the sandbox organisation to use for this request. When you send this header, the service runs the operation in the context of the named sandbox organisation, that is, against the wallet of that sandbox organisation and not against the main wallet of the organisation. Leave the header out to use the main wallet.
The service reads this header only when you authenticate with a bearer access token. When you authenticate with an API key, the service takes the sandbox organisation from the API key and ignores this header. To run an API-key call in a sandbox organisation, bind the key to the sandbox organisation with PUT /v2/config/admin/apikey/{apiKeyId}/sandbox-org instead.
X-SubwalletId is the deprecated name of this header. The service continues to accept it, but X-SandboxOrgId wins if you send both headers.
The sandbox organisation must exist, must belong to your organisation and must be deployed. An unknown identifier, an identifier of a sandbox organisation that is not deployed, and an identifier that belongs to a different organisation all make the call fail with HTTP 400.
- application/json
Body
required
The webhook configuration.
webhook object
The webhook configuration to create or to update. The service ignores id, orgId, sandboxOrgId and timestamp if you send them. It takes the organisation from the organizationId header.
The HTTPS or HTTP URL that receives the webhook payload. The value must start with http:// or https:// and must be unique for the organisation.
Possible values: [application/json, application/x-www-form-urlencoded]
The content type of the webhook payload. For application/x-www-form-urlencoded, the JSON payload is sent in a single form field named payload.
subscribedEvents objectrequired
The event types that the webhook receives, in 3 groups. A minimum of 1 of the 3 arrays must hold a minimum of 1 event type. The service refuses an event type that is not in the list of its group. The service does not remove duplicate values.
Possible values: [data.update.initiated, data.update.cancelled, consent.allowed, consent.disallowed, consent.auto_expiry, data.delete.initiated, data.download.initiated, data.delete.cancelled, data.download.cancelled]
Consent management event types. These events occur when an individual gives or refuses consent, or asks to delete, download or update their data.
Possible values: [digitalwallet.connection.init, digitalwallet.connection.invitation, digitalwallet.connection.request, digitalwallet.connection.response, digitalwallet.connection.active, digitalwallet.connection.error, digitalwallet.connection.inactive, digitalwallet.connection.delete, digitalwallet.credential.proposal_sent, digitalwallet.credential.proposal_received, digitalwallet.credential.offer_sent, digitalwallet.credential.offer_received, digitalwallet.credential.request_sent, digitalwallet.credential.request_received, digitalwallet.credential.credential_issued, digitalwallet.credential.credential_received, digitalwallet.credential.credential_acked, digitalwallet.presentation.proposal_sent, digitalwallet.presentation.proposal_received, digitalwallet.presentation.request_sent, digitalwallet.presentation.request_received, digitalwallet.presentation.presentation_sent, digitalwallet.presentation.presentation_received, digitalwallet.presentation.verified, digitalwallet.presentation.presentation_acked, openid.credential.offer_sent, openid.credential.offer_received, openid.credential.credential_issued, openid.credential.credential_acked, openid.credential.credential_accepted, openid.credential.credential_deleted, openid.credential.issuance_denied, openid.credential.token_issued, openid.holder.credential.credential_pending, openid.holder.credential.credential_acked, openid.holder.credential.credential_accepted, openid.presentation.request_sent.v3, openid.presentation.request_received.v3, openid.presentation.presentation_acked.v3, openid.presentation.presentation_pending.v3]
Digital wallet event types. Every OID4VC event uses this group; the openid.* values are the only values that an OID4VCI or OpenID4VP integration needs. The digitalwallet.* values belong to the older DIDComm protocol.
The openid.credential.* events follow the issuer side of an OID4VCI exchange. The openid.holder.credential.* events follow the holder side. The openid.presentation.*.v3 events follow an OpenID4VP exchange: request_sent, request_received and presentation_acked come from the verifier side, and presentation_pending and presentation_acked come from the holder side.
Possible values: [datamarketplace.data_disclosure_agreement_record]
Data marketplace event types. These events occur when the service creates or updates a data disclosure agreement record.
Default value: false
When true, the webhook does not receive event deliveries. Optional. Defaults to false.
Secret key used to compute the X-IGrant-Signature HMAC-SHA256 header for each delivery. The receiver uses it to check the authenticity of the payload. Do not use a value of spaces only: the service accepts it but then sends no signature header.
Default value: false
When true, the server does not verify the TLS certificate of the payload URL. Optional. Defaults to false.
Responses
- 200
- 400
- 401
- 500
OK
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
webhook object
A webhook configuration of the organisation. The service always sends every field of this object, except sandboxOrgId.
Unique identifier of the webhook.
Unique identifier of the organisation that owns the webhook.
Unique identifier of the sandbox organisation. The service sends this field only for a webhook that belongs to a sandbox deployment. A webhook receives only the events of its own scope.
URL that receives the webhook payload.
Possible values: [application/json, application/x-www-form-urlencoded]
Content type of the webhook payload.
subscribedEvents objectrequired
The event types that the webhook receives, in 3 groups. A minimum of 1 of the 3 arrays must hold a minimum of 1 event type. The service refuses an event type that is not in the list of its group. The service does not remove duplicate values.
Possible values: [data.update.initiated, data.update.cancelled, consent.allowed, consent.disallowed, consent.auto_expiry, data.delete.initiated, data.download.initiated, data.delete.cancelled, data.download.cancelled]
Consent management event types. These events occur when an individual gives or refuses consent, or asks to delete, download or update their data.
Possible values: [digitalwallet.connection.init, digitalwallet.connection.invitation, digitalwallet.connection.request, digitalwallet.connection.response, digitalwallet.connection.active, digitalwallet.connection.error, digitalwallet.connection.inactive, digitalwallet.connection.delete, digitalwallet.credential.proposal_sent, digitalwallet.credential.proposal_received, digitalwallet.credential.offer_sent, digitalwallet.credential.offer_received, digitalwallet.credential.request_sent, digitalwallet.credential.request_received, digitalwallet.credential.credential_issued, digitalwallet.credential.credential_received, digitalwallet.credential.credential_acked, digitalwallet.presentation.proposal_sent, digitalwallet.presentation.proposal_received, digitalwallet.presentation.request_sent, digitalwallet.presentation.request_received, digitalwallet.presentation.presentation_sent, digitalwallet.presentation.presentation_received, digitalwallet.presentation.verified, digitalwallet.presentation.presentation_acked, openid.credential.offer_sent, openid.credential.offer_received, openid.credential.credential_issued, openid.credential.credential_acked, openid.credential.credential_accepted, openid.credential.credential_deleted, openid.credential.issuance_denied, openid.credential.token_issued, openid.holder.credential.credential_pending, openid.holder.credential.credential_acked, openid.holder.credential.credential_accepted, openid.presentation.request_sent.v3, openid.presentation.request_received.v3, openid.presentation.presentation_acked.v3, openid.presentation.presentation_pending.v3]
Digital wallet event types. Every OID4VC event uses this group; the openid.* values are the only values that an OID4VCI or OpenID4VP integration needs. The digitalwallet.* values belong to the older DIDComm protocol.
The openid.credential.* events follow the issuer side of an OID4VCI exchange. The openid.holder.credential.* events follow the holder side. The openid.presentation.*.v3 events follow an OpenID4VP exchange: request_sent, request_received and presentation_acked come from the verifier side, and presentation_pending and presentation_acked come from the holder side.
Possible values: [datamarketplace.data_disclosure_agreement_record]
Data marketplace event types. These events occur when the service creates or updates a data disclosure agreement record.
When true, the webhook receives no event delivery.
Secret key that the service uses to calculate the X-IGrant-Signature header of each delivery. The service sends this value in clear text in every webhook response, so protect the response as you protect the key.
When true, the service does not verify the TLS certificate of the payload URL.
UTC time when the service created the webhook, in YYYY-MM-DDThh:mm:ssZ format. The service does not change this value on an update.
{
"webhook": {
"id": "68a1f2c3d4e5f6a7b8c9d0e1",
"orgId": "string",
"sandboxOrgId": "string",
"payloadUrl": "https://example.com/hooks/igrant",
"contentType": "application/json",
"subscribedEvents": {
"consentManagementWebhook": [
"data.update.initiated"
],
"digitalWalletWebhook": [
"digitalwallet.connection.init"
],
"dataMarketplaceWebhook": [
"datamarketplace.data_disclosure_agreement_record"
]
},
"disabled": true,
"secretKey": "string",
"skipSslVerification": true,
"timestamp": "2026-08-09T10:11:12Z"
}
}
Bad request. The server sends this error if a mandatory field is missing, if the payload URL does not start with http:// or https://, if a webhook with the same payload URL exists, if you subscribe to no event type, or if an event type or a content type is not valid.
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
{
"errorCode": 400,
"errorDescription": "Bad input parameter"
}
Unauthorized
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
{
"errorCode": 400,
"errorDescription": "Bad input parameter"
}
Internal server error
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
{
"errorCode": 400,
"errorDescription": "Bad input parameter"
}