API documentation

Webhooks

Use webhooks to trigger requests to your own application when survey responses are created or updated.

Webhook structure

Webhooks are always sent as an HTTP POST request to the webhook URLs you’ve configured via your Webhooks integration. The details of the activity that triggered the webhook are sent as the body of the HTTP request in JSON format. Every webhook will include an event_type property that describes what kind of activity triggered the event.

Event types

We currently support sending webhook notifications for the following event types:

Type Description
survey_response.created This occurs the moment a customer provides a score. It can take a few minutes to write a comment, so it is unlikely one will be present in this initial payload.
survey_response.updated This occurs any time the score or comment on a survey response is changed. Responses usually only contain a score when they are first created, so most of the time comments will only appear in a survey_response.updated event.

Example request body

{
  "event_type": "survey_response.updated",
  "event_id": "b8d057c59327541d7ec2104c0a9a255ad1997fb00831b9c6bbf09561e6d5cbd0",
  "event_data": {
    "id": "5435",
    "person": {
      "id": "5975",
      "email": "charlie_gravis@example.com",
      "name": "Charlie Gravis",
      "created_at": 1516128468
    },
    "survey_type": "nps",
    "score": 9,
    "comment": "Your service is fast and flawless!",
    "permalink": "https://delighted.com/r/5pFDpmlyC8GUc5oxU6USto5VonSKAqOa",
    "created_at": 1516128528,
    "updated_at": 1516129128,
    "person_properties": null,
    "notes": [],
    "tags": []
  }
}

Webhook request body parameters

Name Type Description
event_type String This describes what kind of event triggered this webhook. It is composed of an object type and an action, separated by a period: survey_response.created.
event_id String The event_id can be used to deduplicate notifications that may be delivered more than once when it’s hard for us to be sure that earlier attempts succeeded. You can ensure that you don’t unnecessarily process requests multiple times by logging each event_id as you process it and checking each event_id is new to ensure you haven’t already processsed it.
event_data Map/Dictionary

This describes the details of the object that triggered the webhook.

For an event related to a survey response it will include the survey response’s id, person, survey_type, score, comment, permalink, created_at, updated_at, person_properties, notes, and tags.

The person object will contain the person’s id, email, name, and created_at.

For more information on the contents of the person_properties, see the Sending to people section of the API guide for more details.

Example request headers

Name Example Value
Content-Type application/json
User-Agent Delighted Webhook Notifier
X-Delighted-API-Version v1
X-Delighted-Webhook-Signature
sha256=5ccf874cdc518138f08f0e5d0ba6f8b4fd1d7a78372d0b858571204b99c0b094

Responding to webhooks

You should respond with an HTTP status code in the 200 range to indicate that you successfully received the webhook. Any response with a status code outside the 200-299 range, including a redirect, will be treated as a failure, and we will try to deliver the webhook again multiple times over several days.

Signature verification

Every webhook includes an X-Delighted-Webhook-Signature header that can optionally be used to verify that the request did indeed come from us. The value of this header is composed of two parts, separated by an equal sign: the signature algorithm, and the signature itself.

To validate the signature, you should take the exact HTTP request body as originally transmitted (before decoding the JSON), use your private Delighted API key, and generate an HMAC digest over the request body, using the signature algorithm specified in the header.

Here’s an example in Ruby:

def webhook_signature_valid?(request)
  private_api_key = ENV['DELIGHTED_API_KEY']
  signature_header = request.headers['X-Delighted-Webhook-Signature']
  algorithm, received_signature = signature_header.split('=', 2)
  if algorithm != 'sha256'
    raise Exception, "Invalid algorithm"
  end
  expected_signature = OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest.new(algorithm), private_api_key, request.body.read
  )
  return SecurityUtils.secure_compare(received_signature, expected_signature)
end

Data security

We recommend that your webhooks use HTTPS URLs so that the customer information delivered to you via webhooks is encrypted while traveling over the internet.