Webhooks
Computers use webhooks to communicate with each other about events. Like notifications, webhooks let you know when something you're interested in happens with your integration.
Overview
You're aware of events you request or that your user's request directly from you. Consider the basic API flow for reference. However, not all events are under your control; some events are triggered by external parties. When external events occur, resources are updated in Swan, but you aren't notified by default.
If you subscribe to webhooks for these external events, Swan initiates a request on your endpoint and you receive webhook notifications. Requests to your endpoint must be answered with a 200 OK HTTP response.
Response time
Webhooks operate with a near-real-time efficiency, typically delivering responses within seconds of the event.
It's worth clarifying that webhooks don't actively respond but autonomously send information to your system, potentially introducing delays of up to 10 minutes after the actual action occurs.
Automatic retry
If Swan encounters an error during a webhook request, the request is retried every 30 seconds and up to 7 times.
If all retries fail, you can retry it manually by selecting Retry from your Dashboard > Developers > Webhooks. You can also trigger the webhook manually at any time.
Subscription limits
In order to avoid overconsumption caused by too many subscriptions to the same webhook event, there's a limit on how many subscriptions you can enable per event. Please consider unsubscribing if you have multiple subscriptions to the same event.
The following limits apply:
- Sandbox: 10 subscriptions per event
- Live: 5 subscriptions per event
All webhook subscriptions enabled before these limits were established remain intact. However, you won't be able to add additional subscriptions for the same event.
For example, if you had 12 subscriptions to a Sandbox event:
- All 12 subscriptions remain active.
- To add a new subscription to that event, delete 3 existing subscriptions first.
Security
Webhooks aren't the most secure communication method, and banking data can be sensitive. Therefore, Swan never uses webhooks to send sensitive information that requires authentication to view.
If an event involves sensitive information, the webhook only includes a notification that an event occurred. You need to use your Dashboard or the API to actually review the information.
If you have security restrictions in your infrastructure, you might need to add the following IPs to your allowlist for both Sandbox and Live environments.
- 52.210.172.90
- 52.51.125.72
- 54.194.47.212
Event handling
Handling webhooks is important to make sure your integration's business logic works as expected.
Delivery method
Swan webhooks are designed following the at-least once
delivery method.
Taking transactions as an example, the at-least once
delivery means that for the same eventId
, you might receive more than one notification.
Swan chose at-least once
delivery deliberately over the at-most once
delivery; it's better you receive the information multiple times instead of not at all, which can occur with at-most once
in case of technical error.
Notification content
Webhook notifications contain the following information in a POST
request:
{
"eventType": "Transaction.Booked",
"eventId": "$YOUR_EVENT_ID",
"eventDate": "2021-08-18T09:35:46.673Z",
"projectId": "$YOUR_PROJECT_ID",
"resourceId": "$YOUR_RESOURCE_ID"
}
Note that eventType
is the action performed on which resource type, eventId
is a unique ID for this event, and resourceId
is a unique ID for the resource.
For security reasons, webhook notifications include limited information. You can always query the API for more information about these events.
Idempotent process
Due to at-least once
delivery, a webhook endpoint might receive the same event notification multiple times.
Therefore, Swan strongly suggests making your event processing idempotent, essentially making sure your response to webhook notifications can be repeated multiple times without producing different outcomes.
For example, you might log the events you've processed, and then not process events that are already logged.
Manage webhooks with the API
You can manage your webhooks with the API.
- Add a new webhook subscription:
addWebhookSubscription
. - Update a webhook subscription:
updateWebhookSubscription
. - Remove a webhook subscription:
removeWebhookSubscription
. - Trigger a retry of a failed webhook:
replayWebhookEvent
. - Subscriptions:
- Get a single subscription:
webhookSubscription
. - Get a list of all subscriptions:
webhookSubscriptions
.
- Get a single subscription:
- Event logs:
- Get one event log:
webhookEventLog
. - Get a log of all events:
webhookEventLogs
.
- Get one event log:
Event order
Webhook notifications aren't always delivered in the order the events occur. If you want to receive webhooks in a specific order, you'll need to implement logic on your end.
For example, consider the regular card payment flow, which is always Authorization to Debit to Released. The flow generates the following webhook events:
- Authorization:
Transaction.Pending
- Debit:
Transaction.Booked
- Released:
Transaction.Released
You'll receive the Transaction.Pending
as soon as the authorization is created.
However, you can receive Transaction.Booked
and Transaction.Released
webhooks in any order, even though the flow is always Debit, then Released.
List of webhook events
The first part of the eventType
will tell you what resources to query in an API call. In the following table, you will find all the event types and examples of their functional triggers.
Account holders
eventType | Explanation |
---|---|
AccountHolder.Created | Onboarding was finalized |
AccountHolder.Updated | Swan updated a banking verification status |
Account onboarding
eventType | Explanation |
---|---|
Onboarding.Created | New onboarding was created either through the API or the no-code interface |
Onboarding.Updated | Onboarding was either finalized, or changed because new data was added to it |
Account memberships
eventType | Explanation |
---|---|
AccountMembership.Bound | User was bound with the account membership |
AccountMembership.Created | New account membership was created |
AccountMembership.Disabled | Account membership was disabled |
AccountMembership.Resumed | Suspended account membership was resumed |
AccountMembership.Suspended | Account membership was suspended |
AccountMembership.Updated | Account membership was updated by an action |
Accounts
eventType | Explanation |
---|---|
Account.Created | Onboarding was finalized |
Account.Updated | Account attribute was changed |
Account.Closing | Account is closing |
Account.Closed | Account was closed |
AccountStatement.Generated | Account statement was generated and available for download |
Billing
eventType | Explanation |
---|---|
AccountInvoice.Generated | New invoice was generated and available for download |
AccountInvoice.Updated | Invoice or refund note was updated |
Capital deposits
eventType | Explanation |
---|---|
CapitalDepositCaseEvent.Created | Capital deposit case was created |
CapitalDepositCaseEvent.Updated | Capital deposit case was updated |
CapitalDepositDocument.Created | Document for a capital deposit case or a shareholder was created |
CapitalDepositDocument.Updated | Document for a capital deposit case or a shareholder was updated |
Shareholder.Created | Shareholder was created |
Shareholder.Updated | Shareholder was updated |
Cards
eventType | Explanation |
---|---|
Card.Created | New virtual card was created |
Card.Updated | Physical card was printed, spending limit was updated, and more (doesn't not include PIN notifications) |
Consent
eventType | Explanation |
---|---|
Consent.Canceled | Consent was canceled by the Partner |
Consent.Created | Consent was created for a sensitive operation |
Consent.Expired | Consent expired without being refused or granted |
Consent.Granted | User accepted a sensitive operation |
Consent.Refused | User refused a sensitive operation |
Consent.Started | ConsentURL was opened |
Funding
eventType | Explanation |
---|---|
FundingLimitSettingsChangeRequest.Created | Funding limit settings change request was created |
FundingLimitSettingsChangeRequest.Updated | Funding limit settings change request was updated |
FundingSource.Created | Funding source was created |
FundingSource.Updated | Funding source was updated |
Merchants
eventType | Explanation |
---|---|
MerchantProfile.Created | Merchant profile was created |
MerchantProfile.Updated | Merchant profile was updated |
Payments
eventType | Explanation |
---|---|
ReceivedDirectDebitMandate.Created | Received direct debit mandate was created either through the API or automatically by Swan |
ReceivedDirectDebitMandate.Updated | Received direct debit mandate was updated |
StandingOrder.Canceled | Standing order was canceled |
StandingOrder.Scheduled | Standing order was scheduled |
Supporting documents
eventType | Explanation |
---|---|
SupportingDocumentCollection.Created | A new supporting document collection was created |
SupportingDocumentCollection.Updated | A supporting document collection was either finalized or updated |
Transactions
eventType | Explanation |
---|---|
Transaction.Booked | Transaction was completed and will appear on the account statement |
Transaction.Canceled | Upcoming direct debit was canceled |
Transaction.Deleted | Scheduled direct debit was deleted |
Transaction.Enriched | Enriched transaction information was received for a card transaction outside of a status update |
Transaction.Pending | Outgoing SEPA Credit Transfer was processed and is waiting for the next SEPA batch, a card authorization was accepted, and more |
Transaction.Rejected | Transaction was rejected for compliance reasons |
Transaction.Released | Transaction was released |
Transaction.Upcoming | Transaction was booked for a future date |
TransactionStatement.Generated | Transaction statement was generated successfully |
Users
eventType | Explanation |
---|---|
User.Joined | User joins your project |
User.Updated | User's information was updated, such as their phone number |
User.Deactivated | User was deactivated The phone number associated with the deactivated user's Swan account can now be used to sign up a different user. |