Webhooks

At Evy, we use webhooks to keep your service in sync with real-time Evy data, ensuring instant updates after specific events.

What are webhooks?

A webhook is a way for one application to notify another about specific events, eliminating the need for constant polling and providing a more efficient and real-time data exchange. Instead of regularly checking for updates, an application can register a webhook to receive instant notifications when relevant events occur.

Create a webhook endpoint

  • Create a secure (HTTPS) POST endpoint to receive webhook payloads
  • Add validation of the secret x-evy-secret (see Webhook headers)
  • Process the data and take appropriate action based on the event type (see Event types description) (for example, handle a refund following a contract_cancellation_request.approved event)
  • Acknowledge that the event delivery was successful respond with a 200 HTTP status code. All other codes will be considered as a failure. Evy will retry delivering the event with exponential backoff (see Error Handling and retry policy).
    • It's important to ensure your API responds promptly, as timeouts are treated as failures. If you have long-running tasks to perform after receiving an event from us, acknowledge the event promptly and handle the tasks afterward.

Register a webhook

To start receiving webhook events, follow these steps after creating an endpoint:

  1. Share the endpoint URL and the list of desired event types with us.
  2. We'll provide you with the webhook secret for validation when events are sent to your endpoint.

Webhook headers

In addition to the message payload, each webhook message contains the following header:

  • x-evy-secret: the secret to validate. The validation consists in verifying that the secret in the header x-evy-secret is equal to the webhook secret.

Webhook payload

The event object received in the payload contains the following fields:

  • id: a unique UUID to identify the event
  • object: a string representing the received object (equals to event in the case of a webhook payload)
  • type: the type of the event (see Event types description )
  • data: the data related to the event type (see examples in Event types description )
  • created_at: a timestamp indicating the event creation date (formatted as a RFC 3339 timestamp)

Example:

{
  "id": "8500e9a1-336c-4333-86e1-1484f9bcc165",
  "object": "event",
  "created_at": "2023-11-14T08:55:27.024468Z",
  "type": "contract_cancellation_request.approved",
  "data": {
    "object": "contract_cancellation_request",
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",
    "status": "approved",
    "reason": "termination_upon_expiry",
    "final_reason": "insured_product_loss",
    "source": "policyholder",
    "refund_amount": 1000,  
    "refund_currency": "EUR",
    "created_at": "2023-11-14T08:55:27.024468Z",
    "updated_at": "2023-11-14T08:55:27.024468Z"
  }
}

Test a Webhook

  • Trigger a webhook event by using our test endpoint.
    • URL: POST /v1/webhook-test-events
    • payload example:
      {
        "type": "contract_cancellation_request.created",
        "store_id": "4dcf6e93-6143-4850-a51a-4c03ae7f5a4a"
      }
  • Tooling suggestions:
    • Beeceptor to create a publicly-available endpoint and test the webhook retrieval
    • smee.io

Ordering

We do not guarantee that you will receive events in the order they occurred. For the most up-to-date data, we recommend you to make direct calls to our API.

Uniqueness

While we cannot guarantee a single notification for each event, it's rare but possible to receive duplicates due to our at-least-once delivery pattern. To handle this, we recommend making your event processing idempotent. Logging processed events and skipping already logged ones is one effective approach.

Error Handling and retry policy

In case of failure to deliver the events, we will automatically retry the delivery with exponential backoff for 72 hours.

Event types description

event type

description

contract_cancellation_request.created

Occurs when a contract cancellation request is created.
Example of data:\

{  
"object": "contract_cancellation_request",  
"id": "f0bb3e61-2452-4ae8-b934-f17847e8e1c3",  
"contract_id": "28e0968e-2b44-42ca-ae51-4d31962b591c",  
"reason": "OTHER",  
"other_reason": "another reason",  
"reason_event_date": "2022-09-01T15:07:56.572316Z",  
"status": "pending",  
"created_at": "2022-12-19T08:28:32.387843Z",  
"updated_at": "2022-12-19T08:28:32.387843Z",  
"source": "policyholder",
"refund_amount": 1000,  
"refund_currency": "EUR" 
}

contract_cancellation_request.approved

Occurs when a contract cancellation request is approved.
Example of data:\

{
"object": "contract_cancellation_request",
"id": "f0bb3e61-2452-4ae8-b934-f17847e8e1c3",
"contract_id": "28e0968e-2b44-42ca-ae51-4d31962b591c",
"reason": "OTHER",
"other_reason": "another reason",
"reason_event_date": "2022-09-01T15:07:56.572316Z",
"final_reason": "policyholder_status_change",
"status": "approved",
"created_at": "2022-12-19T08:28:32.387843Z",
"updated_at": "2022-12-19T08:28:32.387843Z",
"source": "policyholder",  
"refund_amount": 1000,  
"refund_currency": "EUR"
}

claim.created

Occurs when a new claim is created.
Example of data:\

{  
    "object": "claim",  
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",  
    "store_id": "a8f7d740-f638-4c05-89b1-ff24ea9c85dc",  
    "physical_store_id": null,  
    "customer_contract_id": "R6ZZSSJV",  
    "contract_id": "9283e663-fe38-4c22-9e7f-0c500d082905",  
    "incident": {  
      "reported_cause": "stolen"  
    },  
    "investigated_cause": null,  
    "status": "new",  
    "settled_at": null,  
    "declined_at": null,  
    "withdrawn_at": null,  
    "submitted_at": "2024-02-15T13:24:46.711782Z",  
    "approved_at": null
  }

claim.approved

Occurs when a claim is approved.
Example of data:\

{  
    "object": "claim",  
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",  
    "store_id": "a8f7d740-f638-4c05-89b1-ff24ea9c85dc",  
    "physical_store_id": null,  
    "customer_contract_id": "R6ZZSSJV",  
    "contract_id": "9283e663-fe38-4c22-9e7f-0c500d082905",  
    "incident": {  
      "reported_cause": "stolen"  
    },  
    "investigated_cause": "stolen",  
    "status": "approved",  
    "settled_at": null,  
    "declined_at": null,  
    "withdrawn_at": null,  
    "submitted_at": "2024-02-15T13:24:46.711782Z",  
    "approved_at": "2024-02-16T12:12:18.711782Z"  
  }

claim.settled

Occurs when a claim is settled.
Example of data:\

{  
    "object": "claim",  
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",  
    "store_id": "a8f7d740-f638-4c05-89b1-ff24ea9c85dc",  
    "physical_store_id": null,  
    "customer_contract_id": "R6ZZSSJV",  
    "contract_id": "9283e663-fe38-4c22-9e7f-0c500d082905",  
    "incident": {  
      "reported_cause": "stolen"  
    },  
    "investigated_cause": "stolen",  
    "status": "settled",  
    "settled_at": "2024-02-16T13:24:46.711782Z",  
    "declined_at": null,  
    "withdrawn_at": null,  
    "submitted_at": "2024-02-15T13:24:46.711782Z",  
    "approved_at": "2024-02-16T12:12:18.711782Z"  
  }

claim.declined

Occurs when a claim is declined.
Example of data:\

{  
    "object": "claim",  
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",  
    "store_id": "a8f7d740-f638-4c05-89b1-ff24ea9c85dc",  
    "physical_store_id": null,  
    "customer_contract_id": "R6ZZSSJV",  
    "contract_id": "9283e663-fe38-4c22-9e7f-0c500d082905",  
    "incident": {  
      "reported_cause": "stolen"  
    },  
    "investigated_cause": "stolen",  
    "status": "declined",  
    "settled_at": null,  
    "declined_at": "2024-02-16T13:24:46.711782Z",  
    "withdrawn_at": null,  
    "submitted_at": "2024-02-15T13:24:46.711782Z",  
    "approved_at": null  
  }

claim.withdrawn

Occurs when a claim is withdrawn.
Example of data:\

{  
    "object": "claim",  
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",  
    "store_id": "a8f7d740-f638-4c05-89b1-ff24ea9c85dc",  
    "physical_store_id": null,  
    "customer_contract_id": "R6ZZSSJV",  
    "contract_id": "9283e663-fe38-4c22-9e7f-0c500d082905",  
    "incident": {  
      "reported_cause": "stolen"  
    },  
    "investigated_cause": "stolen",  
    "status": "withdrawn",  
    "settled_at": null,  
    "declined_at": null,  
    "withdrawn_at": "2024-02-16T13:24:46.711782Z",  
    "submitted_at": "2024-02-15T13:24:46.711782Z",  
    "approved_at": null  
  }

Resources definition

The contract cancellation request object

See the contract cancellation request object

The claim object

Example:

{  
    "object": "claim",  
    "id": "cbbcc434-1433-4b3b-881b-99709afe3db3",  
    "store_id": "a8f7d740-f638-4c05-89b1-ff24ea9c85dc",  
    "physical_store_id": null,  
    "customer_contract_id": "R6ZZSSJV",  
    "contract_id": "9283e663-fe38-4c22-9e7f-0c500d082905",  
    "incident": {  
      "reported_cause": "stolen"  
    },
    "investigated_cause": "stolen",  
    "status": "approved",  
    "settled_at": null,  
    "declined_at": null,  
    "withdrawn_at": null,  
    "submitted_at": "2024-02-15T13:24:46.711782Z",  
    "approved_at": "2024-02-16T12:16:33.711782Z"  
  }

Attributes:

fieldtypedescription
objectstring, value is claimString representing the object’s type. Objects of the same type share the same value.
idstringUnique identifier for the claim.
contract_idstringUnique identifier of the contract associated to the claim.
customer_contract_idstringThe customer contract ID is the contract reference displayed in the subscription certificate.
store_idstringThe unique identifier of the store this claim belongs to.
physical_store_idstringThe physical store ID of the contract this claim is related to.
incidentdictionaryA nested object containing details of the incident leading to the claim.
investigated_causestringThe actual claim incident cause, determined by the handler when the claim is investigated. It might be different from the cause initially reported by the claimant in incident.reported_cause.
statusenum, possible values are new, approved, settled, declined, withdrawnThe status of the claim.
submitted_attimestampTime at which the claim was submitted. Formatted as a RFC 3339 timestamp, with up to nanosecond precision.
approved_attimestampTime at which the claim was approved. Formatted as a RFC 3339 timestamp, with up to nanosecond precision.
settled_attimestampTime at which the claim was settled. Formatted as a RFC 3339 timestamp, with up to nanosecond precision.
declined_attimestampTime at which the claim was declined. Formatted as a RFC 3339 timestamp, with up to nanosecond precision.
withdrawn_attimestampTime at which the claim was withdrawn. Formatted as a RFC 3339 timestamp, with up to nanosecond precision.

Incident dictionary

fieldtypedescription
reported_causestringThe claim incident cause reported by the customer when the claim is submitted.