Webhooks

Where do you want your typeform’s data to be sent? Get every submission sent straight to a compatible web app or URL as soon as it’s submitted.

Jump to:

What is a webhook?

In general terms, a webhook is simply a notification sent over the web, which is triggered automatically whenever a specific event occurs.

In this case, the event is a new typeform submission. Whenever a new typeform submission comes in, a notification containing the response data is immediately sent to your chosen destination — the Webhook URL which you set in the configuration panel.

Typeform webhook notifications are sent via HTTP POST request, and the request body (containing the response data) is in JSON format.

Setup guide

Please note that webhooks are a PRO+ feature.
Configuring webhooks for typeforms is easy.

  1. Open your typeform from your Workspace.
  2. Navigate to the Configure Panel.
  3. Choose the Webhooks section from the left-side menu.
  4. Enter a Webhook URL. (This is the endpoint which we will make HTTP POST requests to).
  5. Test your URL to see if it’s working. Note: this endpoint must respond with a 2XX HTTP status code — e.g. 200 (OK).
  6. Hit Update Settings to save the changes. Congratulations! Webhooks are now active on this typeform, and any new submissions will be automatically POSTed to the specified Webhook URL.

Using Requestb.in

If you want an easy way to capture and inspect the webhook HTTP requests while testing and developing, we recommend you use a quick-and-simple (free) tool like Requestb.in.

Visit http://requestb.in and click Create a RequestBin. You’ll be given a URL. This URL will capture all the HTTP requests which are sent to it, and present them for you to inspect.

So just enter your RequestBin’s URL as your typeform’s Webhook URL (and hit Update settings) and when the webhook fires — next time your typeform is submitted — the HTTP request + JSON payload will be in your RequestBin for you to take a look at.

Example payload (JSON)

{
  "event_id": "4fdb9fbb3b0f0dd34730621e4e0b38c6",
  "event_type": "form_response",
  "form_response": {
    "form_id": "abc123",
    "token": "4fdb9fbb3b0f0dd34730621e4e0b38c6",
    "submitted_at": "2016-03-23T13:37:00Z",
    "hidden": {
      "name": "Linus",
      "team": "Design",
      "beard_status": "epic"
    },
    "definition": {
      "id": "BpLnfg",
      "title": "Test Form Submission",
      "fields": [
        {
          "id": "9048084",
          "title": "What is your favorite meat?",
          "type": "short_text"
        },
        {
          "id": "12447898",
          "title": "How do you like your meat cooked?",
          "type": "multiple_choice"
        },
        {
          "id": "12511545",
          "title": "How would you rate this combo?",
          "type": "rating"
        },
        {
          "id": "9422804",
          "title": "Why does this combination taste so good?",
          "type": "long_text"
        },
        {
          "id": "12823744",
          "title": "Which meal is your favorite meal for this type of meat?",
          "type": "picture_choice"
        }
      ]
    },
    "answers": [
      {
        "type": "text",
        "text": "Beef.",
        "field": {
          "id": "9048084",
          "type": "short_text"
        }
      },
      {
        "type": "choice",
        "choice": {
          "label": "Roasted"
        },
        "field": {
          "id": "12447898",
          "type": "multiple_choice"
        }
      },
      {
        "type": "number",
        "number": 5,
        "field": {
          "id": "12511545",
          "type": "rating"
        }
      },
      {
        "type": "text",
        "text": "Can't explain, just so tasty.",
        "field": {
          "id": "9422804",
          "type": "long_text"
        }
      },
      {
        "type": "choices",
        "choices": {
          "labels": [
            "Breakfast",
            "Lunch",
            "Dinner"
          ],
          "other": "Brunch too. Who cares when? Just feed it to me."
        },
        "field": {
          "id": "12823744",
          "type": "picture_choice"
        }
      }
    ]
  }
}

Definition

The definition of the questions in your form is provided in a summarized form. The form definition can be used to match up your answers with the original questions.

  • id: the ID of the field, which will correlate to answers/field/id.
  • title: The text you defined when creating the form.
  • type: The type of field that you defined.

The order of the fields will match the order of the fields in the answers object.

Field types

  • Short text short_text
  • Long text long_text
{
  "type": "text",
  "text": "A big juicy steak.",
  "field": {
    "id": "12345",
    "type": "short_text"
  }
}
  • Email email
{
  "type": "email",
  "email": "somebody@somewhere.com",
  "field": {
    "id": "12345",
    "type": "email"
  }
}
  • Website (URL) website
{
  "type": "url",
  "url": "https://theinter.net/great-page",
  "field": {
    "id": "12345",
    "type": "website"
  }
}
  • Multiple Choice (Single Select) multiple_choice
  • Picture Choice (Single Select) picture_choice
  • Dropdown dropdown
{
  "type": "choice",
  "choice": {
    "label": "Medium rare"
  },
  "field": {
    "id": "12345",
    "type": "multiple_choice"
  }
}
  • For Single-Select Choice fields, “choice” is an object containing either “label” or “other”.
  • If the other option is disabled, “choice” will simply always contain “label”.
  • Multiple Choice (Multi Select) multiple_choice
  • Picture Choice (Multi Select) picture_choice
{
  "type": "choices",
  "choices": {
    "labels": ["Breakfast", "Lunch", "Dinner"],
    "other": "Brunch"
  },
  "field": {
    "id": "12345",
    "type": "picture_choice"
  }
}
  • For Multi-Select Choice fields, “choices” will contain both “labels” and “other” if the respondent uses the other option in their answer.
  • If the other option is either a) not used by the respondent, or b) disabled, “choices” will contain “labels” only.
  • Date date
{
  "type": "date",
  "date": "2016-12-25",
  "field": {
    "id": "12345",
    "type": "date"
  }
}
  • WARNING: Dates are always returned in ISO 8601 format (YYYY-MM-DD), irrespective of the input format you configured on the front-end for your typeform’s date field.
  • File Upload file_upload
{
  "type": "file_url",
  "file_url": "https://api.typeform.com/v1/form/abc123/fields/16843266/blob/aadd6592adb8-image.jpg",
  "field": {
    "id": "12345",
    "type": "file_upload"
  }
}
  • Number number
  • Rating rating
  • Opinion oreale opinion_scale
{
  "type": "number",
  "number": 5,
  "field": {
    "id": "12345",
    "type": "rating"
  }
}
  • Yes No yes_no
  • Legal legal
{
  "type": "boolean",
  "boolean": true,
  "field": {
    "id": "12345",
    "type": "yes_no"
  }
}
  • Payment payment
{
  "type": "payment",
  "payment": {
    "amount": "25",
    "last4": "4242",
    "name": "William Gates"
  },
  "field": {
    "id": "12345",
    "type": "payment"
  }
}

Score

If you added a score calculation to your form, you will have a calculations/score object. If no score calculation was added to the form, this field/object will not be included in your webhook payload.

{
...
"form_response": {
  // Definition, answers, etc
  "calculated":{
    "score": 0
  }
}

Unanswered questions (or “empty” answers)

The “answers” array is populated with answered questions only. If a question was not answered because either a) it’s not required, or b) it was skipped by a Logic Jump, it simply won’t be present in the webhook request. If no score calculation was added to the form, the score will not be included in your webhook payload.

Errors

If the webhook request fails for any reason, we will retry the request to your endpoint at 20 minute intervals for at least 1 full day (72 retries).

We check for successful requests by looking at the HTTP status code in the response. If your endpoint replies a non-2XX status code, we will continue retrying.

Any error messages will be displayed in the Error log inside the Webhooks Configure panel.

Security

Your Webhook URL can use either http or https.

Please note, your SSL certificate must be validated in order to use https — self-signed certificates will not work. We may introduce an option to use self-signed certificates in future, so if this is something you would be interested in, please let us know by submitting a ticket.

Was this article helpful?
Thanks!