Webhooks
Overview
Webhooks allows you to notify your downstream systems when relevant events are raised by Socotra. Here are some examples how webhooks can be used:
Triggering integration processes, such as printing and sending an invoice after it is issued
Enabling automated processes, such as a renewal process after a policy nears expiration
Capturing data changes for maintaining an external database that includes Socotra data
Create a a webhook using an External Service Integration for each external system to be notified. Each webhook will listen for a set of events and notify the associated external system when any event in the webhook event set is raised.
Setting Up External Service Integrations
External service integrations (ESIs) provide a gateway for Socotra to communicate with external systems. Each webhook will use an ESI, so you’ll need to establish those first. To establish and manage webhook integration points, use the External Service Integration API and create an integration with type webhook
.
After you establish your ESI, you can begin to create and use webhooks.
Note
The names for each event will be the name as shown elsewhere in the documentation, such as policy.create or endorsement.update. See External Service Integration API
Setting Up Webhooks
You can create as many webhook instances as you need. Each instance will listen for a set of events and notify its associated ESI when any of those events are raised.
This endpoint will create (or update, if a webhook exists with that name) a webhook definition:
PUT /webhooks
Name | Position | Type | Required |
---|---|---|---|
request | body | WebhookRequest | required |
requiredname stringoptionalalertIntegrationName stringdisplayName stringenabled booleanevents [string cancellation.create | cancellation.update | cancellation.rescind | cancellation.issue | cancellation.effective | claim.close | claim.create | claim.discard | claim.open | claim.update | policy.gracePeriod | policy.gracePeriod.update | invoice.issue | invoice.invalidate | invoice.pastDue | invoice.writtenOff | payment.pay | policy.cancel | policy.create | policy.discard | policy.endorse | policy.finalize | policy.issue | policy.lapse | policy.reinstatement.close | policy.reinstatement.invoice | policy.reinstatement.issue | policy.reinstatement.open | policy.renew | policy.update | policy.upgrade | subClaim.open | subClaim.update | subClaim.close | subClaim.reopen | subClaim.updateReserve | policy.end.reminder | subClaim.createPayable | subClaim.reversePayable | endorsement.create | endorsement.update | endorsement.quote | endorsement.accept | endorsement.issue | endorsement.invalidate | endorsement.discard | endorsement.effective | reinstatement.accept | reinstatement.create | reinstatement.issue | reinstatement.invalidate | reinstatement.deadlineReached | reinstatement.effective | renewal.create | renewal.update | renewal.quote | renewal.accept | renewal.issue | renewal.invalidate | renewal.discard | renewal.effective | policy.effective | policy.end | policy.quote.create | policy.quote.discard | policy.quote.update | policy.quote.quoted | policy.quote.accept | policy.quote.declined | policy.quote.invalidate | premiumReport.create | premiumReport.update | premiumReport.issue | premiumReport.discard | premiumReport.reverse | premiumReport.replace | premiumReport.effective | premiumReport.pay | login.success | login.failure | policyholder.create | policyholder.update | payment.reverse | payment.update | payment.ready | payment.discard | payment.return | payment.decline | payment.draft | policy.gracePeriod.satisfied | disbursement.issue | disbursement.create | disbursement.update | catchUp.issue | catchUp.writtenOff | catchUp.pay | catchUp.pay.reverse | catchUp.invalidate | catchUp.pastDue | cash.transfer]failureHandling FailureHandlingRequestintegrationName stringresetAlertIntegrationName booleanretryStrategy string none | one | three
The alertIntegrationName
, if provided, will be used to POST
the FailureMessage
object. See Failure Handling for details.
requiredname stringenabled booleanevents [string cancellation.create | cancellation.update | cancellation.rescind | cancellation.issue | cancellation.effective | claim.close | claim.create | claim.discard | claim.open | claim.update | policy.gracePeriod | policy.gracePeriod.update | invoice.issue | invoice.invalidate | invoice.pastDue | invoice.writtenOff | payment.pay | policy.cancel | policy.create | policy.discard | policy.endorse | policy.finalize | policy.issue | policy.lapse | policy.reinstatement.close | policy.reinstatement.invoice | policy.reinstatement.issue | policy.reinstatement.open | policy.renew | policy.update | policy.upgrade | subClaim.open | subClaim.update | subClaim.close | subClaim.reopen | subClaim.updateReserve | policy.end.reminder | subClaim.createPayable | subClaim.reversePayable | endorsement.create | endorsement.update | endorsement.quote | endorsement.accept | endorsement.issue | endorsement.invalidate | endorsement.discard | endorsement.effective | reinstatement.accept | reinstatement.create | reinstatement.issue | reinstatement.invalidate | reinstatement.deadlineReached | reinstatement.effective | renewal.create | renewal.update | renewal.quote | renewal.accept | renewal.issue | renewal.invalidate | renewal.discard | renewal.effective | policy.effective | policy.end | policy.quote.create | policy.quote.discard | policy.quote.update | policy.quote.quoted | policy.quote.accept | policy.quote.declined | policy.quote.invalidate | premiumReport.create | premiumReport.update | premiumReport.issue | premiumReport.discard | premiumReport.reverse | premiumReport.replace | premiumReport.effective | premiumReport.pay | login.success | login.failure | policyholder.create | policyholder.update | payment.reverse | payment.update | payment.ready | payment.discard | payment.return | payment.decline | payment.draft | policy.gracePeriod.satisfied | disbursement.issue | disbursement.create | disbursement.update | catchUp.issue | catchUp.writtenOff | catchUp.pay | catchUp.pay.reverse | catchUp.invalidate | catchUp.pastDue | cash.transfer]failureHandling FailureHandlingResponseintegrationName stringretryStrategy string none | one | threesuspended booleanoptionalsuspendedTimestamp timestampalertIntegrationName stringdisplayName string
The webhook name
must not be longer than 128 characters, and may contain only letters, numbers, and symbols as follows:
Alphanumeric characters – the arabic numerals (
0
to9
)Latin letters (
A
toZ
,a
toz
) – and theThe hyphen, underscore, and tilde symbols (
-
,_
,~
)
The webhook displayName
must not be longer than 256 characters and may contain only the following:
Alphanumeric characters and latin characters (with the same allowed characters as for the
name
)The hyphen, underscore, and tilde, just as the
name
may use, and additionally these characters are allowed:
Exclamation points
!
Periods
.
Asterisks
*
Parentheses
(
or)
Spaces
GET /webhooks
requiredwebhooks [WebhookResponse]
GET /webhooks/{name}
Name | Position | Type | Required |
---|---|---|---|
name | path | string | required |
DELETE /webhooks/{name}
Name | Position | Type | Required |
---|---|---|---|
name | path | string | required |
void
Note
Webhooks can also be created and managed through the admin user interface. All the webhooks endpoints require admin user access. This requirement is the same as the requirement for setting up the external service integrations that the webhooks will use.
Behavior
After each event is fired, the application will scan all webhooks, and for each one that is enabled, and for which the event is included in the events
property, the application will POST the WebhookPayload object to the associated External Service Integration for that webhook.
The data
property contains the same information as is returned in the Event Stream API.
On time out or non-200 responses from the call, error handling will be used, as discussed below.
requiredid stringtimestamp timestampdata EventStreamDatatransactionId stringtype stringusername string
Startup
When a webhook is first enabled (or when it is re-enabled after being suspended), the webhook will not attempt to catch up on old messages.
Event ordering
Events sent for a specific webhook will be ordered based on the timestamp on the event response. Multiple events for the same webhook will be sent in sequence.
If there are multiple webhooks for a single event type, the webhooks may or may not be triggered in at the same time. The order and timing is not guaranteed.
For example, if two webhooks, CancelEventHandlerA
and CancelEventHandlerB
, handle cancellation.issue
events, when several cancellation.issue
events occur, CancelEventHandlerB
may receive some or all of the cancellation.issue
events before the first cancellation.issue
event is sent to CancelEventHandlerA.
Failure Handling
If an ESI responds with anything other than a 2xx
HTTP response, or times out (does not respond within 120 seconds), the message will be considered failed.
The WebhookRequest.alertIntegrationName
, if provided, will be used to POST
the FailureMessage
object.
If resetAlertIntegrationName
is true
, the application will reset alertIntegrationName
to null
.
requiredactualStatus stringeventData EventStreamDataexpectedStatus stringurl stringwebhookName object
optionalactOnStatusCodes [string]actOnTimeout booleanmode string none | divert | suspend
requiredactOnStatusCodes [string]actOnTimeout booleanmode string none | divert | suspend
Failure handling will be invoked based on the response (or non-response) from the webhook target.
The FailureHandlingRequest
properties, actOnTimeout
and actOnStatusCodes
control which failures and time outs are handled as errors:
The
actOnStatusCodes
property takes an array of strings, where each string is three characters long and can have the following values:4xx
(to act on all 400 Errors)5xx
(to act on all 500 Errors)Specific 400 or 500 error codes such as
403
,501
,504
If the
actOnStatusCodes
property is empty, Socotra will invoke failure-handling for all failures.
If
actOnTimeout
istrue
, failure handling will be invoked for time outs. Otherwise, ifactOnTimeout
isfalse
, time outs will be ignored.
Retry Strategy
On failure, the webhook retryStrategy
property will be used to determine the course of action:
none
: The failure will be silently ignored and the system will act as if the message had succeeded.one
: The system will try one more time, after 60 seconds. If this succeeds, the operation will be considered to have succeeded.three
: The system will try three more times, each 60 seconds apart. If any of these succeed, the operation will be considered to have succeeded. Note: subsequent messages will not be sent once one succeeds.
The default value of failureHandling.mode
is suspend
, unless retryStrategy
is none
.
If retryStrategy
is none
, the default value of value of failureHandling.mode
is also none
.
Failure Handling Mode
If no message succeeds during the retry attempts, the webhook FailureHandlingRequest.mode
property will be used to determine the course of action:
none
: The failure will be silently ignored and the system will act as if the message had succeeded.suspend
: The webhooksuspended
property will be set totrue
, and the event stream will emit awebhook.suspended
event. The webhook will not receive or process events, and will remain inactive until the webhook is reactivated.divert
: TheWebhookPayload
will be stored for 90 Days and can be retrieved withGET /webhooks/{name}/diverted
.
Use suspend
to handle failures when you would like to pause handling these events until the failure is resolved.
Use divert
if you need to collect these events that occur while you are resolving the failure, for retrieval and reuse after the failure is resolved.
Suspended Events
When a webhook is suspended, a webhook.suspended
event will fire, with the following payload:
requiredevent string cancellation.create | cancellation.update | cancellation.rescind | cancellation.issue | cancellation.effective | claim.close | claim.create | claim.discard | claim.open | claim.update | policy.gracePeriod | policy.gracePeriod.update | invoice.issue | invoice.invalidate | invoice.pastDue | invoice.writtenOff | payment.pay | policy.cancel | policy.create | policy.discard | policy.endorse | policy.finalize | policy.issue | policy.lapse | policy.reinstatement.close | policy.reinstatement.invoice | policy.reinstatement.issue | policy.reinstatement.open | policy.renew | policy.update | policy.upgrade | subClaim.open | subClaim.update | subClaim.close | subClaim.reopen | subClaim.updateReserve | policy.end.reminder | subClaim.createPayable | subClaim.reversePayable | endorsement.create | endorsement.update | endorsement.quote | endorsement.accept | endorsement.issue | endorsement.invalidate | endorsement.discard | endorsement.effective | reinstatement.accept | reinstatement.create | reinstatement.issue | reinstatement.invalidate | reinstatement.deadlineReached | reinstatement.effective | renewal.create | renewal.update | renewal.quote | renewal.accept | renewal.issue | renewal.invalidate | renewal.discard | renewal.effective | policy.effective | policy.end | policy.quote.create | policy.quote.discard | policy.quote.update | policy.quote.quoted | policy.quote.accept | policy.quote.declined | policy.quote.invalidate | premiumReport.create | premiumReport.update | premiumReport.issue | premiumReport.discard | premiumReport.reverse | premiumReport.replace | premiumReport.effective | premiumReport.pay | login.success | login.failure | policyholder.create | policyholder.update | payment.reverse | payment.update | payment.ready | payment.discard | payment.return | payment.decline | payment.draft | policy.gracePeriod.satisfied | disbursement.issue | disbursement.create | disbursement.update | catchUp.issue | catchUp.writtenOff | catchUp.pay | catchUp.pay.reverse | catchUp.invalidate | catchUp.pastDue | cash.transferintegrationName stringwebhookName string
The suspended webhook will not receive or process events, and will remain inactive until you reactivate the webhook. Enable (reactivate) a suspended webhook using the following endpoint:
PATCH /webhooks/{name}/unsuspend
Name | Position | Type | Required |
---|---|---|---|
name | path | string | required |
Diverted events
The WebhookPayload
will be stored for 90 Days and can be retrieved with GET /webhooks/{name}/diverted
.
GET /webhooks/{name}/diverted
Name | Position | Type | Required |
---|---|---|---|
limit | query | integer | optional |
name | path | string | required |
offset | query | integer | optional |
The limit
and offset
properties are used to page through the list of results, getting batches of diverted events of size limit
. Increase the offset
property with each query, to skip the events you have already retrieved.
The default value of limit
is 100
, and the default value of offset
is 0
, so the first call to GET /webhooks/{name}/diverted
will return the first 100
diverted events (or fewer if there are less than 100
events).
requiredevents [WebhookDivertedEventResponse]webhookName string
requiredeventType string cancellation.create | cancellation.update | cancellation.rescind | cancellation.issue | cancellation.effective | claim.close | claim.create | claim.discard | claim.open | claim.update | policy.gracePeriod | policy.gracePeriod.update | invoice.issue | invoice.invalidate | invoice.pastDue | invoice.writtenOff | payment.pay | policy.cancel | policy.create | policy.discard | policy.endorse | policy.finalize | policy.issue | policy.lapse | policy.reinstatement.close | policy.reinstatement.invoice | policy.reinstatement.issue | policy.reinstatement.open | policy.renew | policy.update | policy.upgrade | subClaim.open | subClaim.update | subClaim.close | subClaim.reopen | subClaim.updateReserve | policy.end.reminder | subClaim.createPayable | subClaim.reversePayable | endorsement.create | endorsement.update | endorsement.quote | endorsement.accept | endorsement.issue | endorsement.invalidate | endorsement.discard | endorsement.effective | reinstatement.accept | reinstatement.create | reinstatement.issue | reinstatement.invalidate | reinstatement.deadlineReached | reinstatement.effective | renewal.create | renewal.update | renewal.quote | renewal.accept | renewal.issue | renewal.invalidate | renewal.discard | renewal.effective | policy.effective | policy.end | policy.quote.create | policy.quote.discard | policy.quote.update | policy.quote.quoted | policy.quote.accept | policy.quote.declined | policy.quote.invalidate | premiumReport.create | premiumReport.update | premiumReport.issue | premiumReport.discard | premiumReport.reverse | premiumReport.replace | premiumReport.effective | premiumReport.pay | login.success | login.failure | policyholder.create | policyholder.update | payment.reverse | payment.update | payment.ready | payment.discard | payment.return | payment.decline | payment.draft | policy.gracePeriod.satisfied | disbursement.issue | disbursement.create | disbursement.update | catchUp.issue | catchUp.writtenOff | catchUp.pay | catchUp.pay.reverse | catchUp.invalidate | catchUp.pastDue | cash.transfertimestamp timestampdata EventStreamDataeventId stringtransactionId stringoptionalusername string
After you resolve the webhook failure and re-enable the diverted webhook, you can process the list of diverted events, and POST
or DELETE
any or all of these events.
DELETE /webhooks/{name}/diverted/{transactionId}
Name | Position | Type | Required |
---|---|---|---|
name | path | string | required |
transactionId | path | string | required |
void
POST /webhooks/{name}/diverted/{transactionId}/resend
Name | Position | Type | Required |
---|---|---|---|
name | path | string | required |
transactionId | path | string | required |
void