Back to docs

Category: developer

Webhooks

In your survey settings you can set a webhook URL. If you set this URL and turn the webhook on, we will send a request to your application for every submitted response. This is a great way to integrate your customer feedback directly into your back-end and/or business logic.

Payload

Here is an example of what a payload will look like:

{
  "event": "survey.response.submitted",
  "survey": {
    "id": "d11d6a48-016c-406d-ae31-f8n296c5facf",
    "category": "score",
    "dashboard_url": "https://freddyfeedback.com/dashboard/survey/d11d6a48-016c-406d-ae31-f8n296c5facf",
    "title": "FAQ feedback",
    "score_min": 1,
    "score_max": 5
  },
  "response": {
    "id": "da1b8f8e-d7b9-465d-8bcb-5ce79463dc63",
    "score": 5,
    "comment": "All my questions were answered, nice work!",
    "screen_capture": {
        "has_screen_capture": true,
        "path": "https://cdn.freddyfeedback.com/surveys/d11d6a48-016c-406d-ae31-f8n296c5facf/screen-captures/da1b8f8e-d7b9-465d-8bcb-5ce79463dc63.jpeg"
    }
  },
  "response_meta": {
    "url": "https://example.com/contact",
    "user_agent": {
      "human": "Safari 13.1.2 on macOS Catalina 10.15",
      "browser": "Safari 13.1.2",
      "os": "macOS Catalina 10.15",
      "device": "",
      "device_type": "desktop" 
    }
  },
  "custom_fields": {
    "user_id": 42,
    "email": "customer@example.com"
  },
  "is_preview": false,
  "timestamp": 1596704505
}

Webhook URL

You can set the webhook URL in Survey settings > Advanced. Note that if you use a URL with https, the webhook will verify if the SSL certificate of the URL is valid and if not the request will fail (more on that below).

Requests and parameters

Requests are sent as POST in JSON format.

These are the request body parameters and their details:

event (type: string) The event name will be survey.response.submitted.

survey will contain the following parameters:

  • id (type: string). The id of the survey. You can find this in the Survey settings > Advanced.
  • category (type: string). This is either question-only for a question only survey, or score when it's a survey that collects a score via emojis or stars.
  • dashboard_url (type: string). The URL to the survey in the dashboard.
  • title (type: string). The internal title that you've set for your survey.
  • score_min (type: int). The minimum score a survey can receive. Note that this is 0 if survey.category = question-only.
  • score_max (type: int). The maximum score a survey can receive. Note that this is 0 if survey.category = question-only.

response will contain the following parameters:

  • id (type: string). The id of the response. Currently not used for any specific functionality but might be used in the future.
  • score (type: int). The score that the customer has submitted. Note that this is 0 if survey.category = question-only.
  • comment (type: string). The comment that the customer has submitted.
  • screen_capture within response has the follwing parameters
    • has_screen_capture (type: bool). Whether the response has a screencapture
    • path (type: string). Full path to the screen capture. If the response doesn't have a screen capture, this will be an empty string.

response_meta will contain the following parameters:

  • url (type: string). The URL from which the customer submitted the response.
  • user_agent within response_meta has parameters with the user agent information:
    • human (type: string). The human readable string with all the user agent information. This is the string you see in the dashboard under the response.
    • browser (type: string). User browser + version
    • os (type: string). User OS + version
    • device (type: string). User device, like iPhone. This will mostly be empty when device_type is desktop
    • device_type (type: string). User device type. Typically the value will be desktop, mobile or tablet
Please note that not all parameters within user_agent are guaranteed to have a value. User agent parsing is technically impossible to get 100% right, so make sure that you check whether a parameter is not empty.

custom_fields will contain any custom fields that you've passed. If there are no custom fields passed to the response, the value of this field will be null.

is_preview (type: boolean) Whether the response was sent via the survey preview from the dashboard.

timestamp (type: int) The Unix timestamp indicating when the response was submitted.

Signature verification

We will add a header called X-Freddy-Signature to every request. This signature is calculated using a secret and the payload.

Secret

You can find the secret in your dashboard. Click on your name in the top right, then select 'Workspace settings'.

We strongly recommend you verify the signature. Here are some examples:

PHP
$payloadJson = json_encode($payload); 
$signature = hash_hmac('sha256', $payloadJson, $secret);
Rails
signature = OpenSSL::HMAC.hexdigest(
  OpenSSL::Digest.new('sha256'), secret, request.body.read
)

Testing webhooks

You can do a simple end-to-end test by using the survey preview. Go to your survey and click on 'preview' below the survey title. Any responses that you submit in this preview mode will be sent to your webhook. As indicate above, you can distinguish between regular and preview responses using the is_preview parameter. You can read more about the survey preview here.

Responding to webhooks

The webhook expects a 2xx response. If it doesn't receive this response code, the following will happen:

  • The webhook will be retried for a maximum of 3 times
  • Between the first and the second fail, there will be a 10 second delay
  • Between the second and the third fail, there will be a 100 second delay
  • After the third fail the webhook won't be retried anymore

Start today

Collect feedback from your most valuable source: your visitors and customers.

Get started for free

Free 30 day trial • No credit card required

Subscribe to Freddy's updates

Get insights on how to best get feedback from your customers, updates on new features and maybe even a joke from Freddy.