Pliant uses HTTPS callbacks (you can also call them webhooks) to inform partners about certain events which happen in our system.

A partner may subscribe to such callbacks via API. The partner will then be informed about the specific type of event they subscribed to.

  • The callbacks are HTTPS POST calls with a specific body which carries the information about the event happened.
  • The callbacks can use oAuth 2.0 to authenticate against the partners backend or no authentication.
  • Each callback request contains the following HTTP header to identify the callback and help you work with it:
    • X-Organization-Id: The organization this callback is triggered for. Example value: 54e6e7e7-0c23-4a54-bccb-2d3ff2fd02df.
    • X-Partner-Organization-Id: The optional partners organization this callback is triggered for. Example value: abcdf1234.
    • X-Payment-Program-Id: The payment program this callback is triggered for. Example value: 54e6e7e7-0c23-4a54-bccb-2d3ff2fd02df.
    • X-Callback-Id: A UUIDv4 unique to this specific callback. With this information you can think of a deduplication on your end. Due to the nature of distributed systems, callbacks may arrive more than once on your end. Example value: 12a03093-eaad-4ae5-9d8d-42e7f6f8b7c6.
    • X-Callback-Created-At: The UTC timestamp when the callback was created. You can re-order callbacks with this information if necessary. Due to network latency and the distributed nature of the system callbacks may not arrive in order at your servers. Example value: 2024-03-15T15:55:58.623375258Z.

Callback Semantics

Pliant sends callbacks with a at least once semantic. This means it can happen that one callback for the same business event is sent twice or more times to a partner. We do de-duplication of events were possible, but due to the nature of asynchronous systems and network communication, we cannot 100% ensure a only-once semantic. We recommend partners to consider this behaviour when implementing their business logic based on our callbacks. Idempotent endpoints are best suited for this style of communication.

Please also note the emphasis on sending. Since we cannot control how a partner consumes the callback payload, we cannot ensure its correct processing on partner side.

Retries

When we recognize an HTTP error on the receiver side of the callback, the partner side, we will retry the callback some minutes later again. We retry callbacks where the HTTP response code was not 2xx. This also means we do not follow redirects like a 301 or 302. We retry for about one day in total, with the backoff getting bigger in between calls. During the first hour we retry within minutes, from hour 2-23 we retry just once an hour. After that, the callback is marked as failed. It can be retried manually if needed, for instance on request by the partner. Providing which callbacks should be send again for which timeframe.

Important Notes

All business related events we have in our system behave inherently asynchronous. This means the order or exact timing of an event cannot be predicted. This is reflected in our API and the way the callbacks behave.

The time between an event happening on the business side and the time the actual callback is triggered to inform a partner is not deterministic. We strive to keep the delay as short as possible, which under normal circumstances means below one minute. But this timing is not guaranteed.

Also the order of callbacks can change and is not deterministic. Normally the order equals the occurrence of the related business event, but there might be deviations from that.

Authentication

Please read the documentation about how to authenticate callbacks.

Full Callbacks List

In order of appearance in the reference.

Event Type
ORGANIZATION_ADDED
ORGANIZATION_CONFIG_CHANGED
ORGANIZATION_DETAILS_CHANGED
ORGANIZATION_LIMIT_CHANGED
ORGANIZATION_STATE_CHANGED
ORGANIZATION_SYNCTYPE_CHANGED
ORGANIZATION_BALANCE_UPDATED
AUTHORIZATION_PENDING
AUTHORIZATION_GRANTED
AUTHORIZATION_REVOKED
REPRESENTATIVE_SUBMISSION_STATUS_CHANGED
REPRESENTATIVE_LEGITIMATION_STATUS_CHANGED
DOCUMENT_CUSTOMER_STATUS_CHANGED
DIRECT_DEBIT_STATUS_CHANGED
BANK_CONNECTION_STATUS_CHANGED
CARD_ACCOUNT_DETAILS_CHANGED
CARD_ACCOUNT_BALANCE_CHANGED
CARD_ACCOUNT_LIMIT_CHANGED
CARDHOLDER_CREATED
CARDHOLDER_DATA_CHANGED
CARDHOLDER_DEACTIVATED
CARDHOLDER_INVITED
CARDHOLDER_INVITED_NEED_ACTIVATION
CARDHOLDER_INVITED_NEED_REGISTRATION
CARDHOLDER_REGISTERED
CARD_CREATED
CARD_ISSUED
CARD_ACTIVATED
CARD_LOCKED
CARD_UNLOCKED
CARD_TERMINATED
CARD_EXPIRED
CARD_LIMIT_CHANGED
CARD_DETAILS_CHANGED
CARD_BALANCE_UPDATED
CARD_STATUS_CHANGED
CARD_SHIPPED
CARD_REQUEST_CREATED
CARD_REQUEST_APPROVED
CARD_REQUEST_REJECTED
CARD_LIMIT_REQUEST_CREATED
CARD_LIMIT_REQUEST_APPROVED
CARD_LIMIT_REQUEST_REJECTED
CARD_CONTROL_UPDATED
TRANSACTION_CREATED
TRANSACTION_UPDATED
TRANSACTION_TYPE_UPDATED
TRANSACTION_STATUS_CHANGED
TRANSACTION_AMOUNT_CHANGED
TRANSACTION_MERCHANT_UPDATED
TRANSACTION_AUTH_CODE
TRANSACTION_AUTHORIZED
TRANSACTION_CONFIRMED
TRANSACTION_COMMENT_UPDATED
TRANSACTION_RECEIPT_UPLOAD_ENABLED_UPDATED
RECEIPT_UPLOADED
RECEIPT_DELETED
RECEIPT_AUTOMATCHING_FINISHED
ACCOUNTING_TRANSACTION_CREATED
ACCOUNTING_TRANSACTION_UPDATED
ACCOUNTING_TRANSACTION_STATUS_CHANGED
PROJECT_CREATED
PROJECT_UPDATED
PROJECT_DELETED
PROJECT_STATUS_CHANGED
TEAM_CREATED
TEAM_UPDATED
TEAM_DELETED
TEAM_DEACTIVATED
CASHBACK_AMOUNT_CHANGED
PAYMENT_STATUS_CHANGED
PAYMENT_READY
STATEMENT_GENERATED
STATEMENT_UPDATED
STATEMENT_CSV_DOWNLOAD_READY
ACCOUNT_ENTRY_CREATED
CARD_TOKENIZATION_OTP
CARD_TOKENIZATION_STATUS_CHANGE