Skip to main content
Please note: this API is currently in beta and is subject to change based on testing and feedback. By using these endpoints you agree to adhere to HubSpot’s Developer Terms & Developer Beta Terms. You also acknowledge and understand the risk associated with testing an unstable API.
If you have a Service Hub Professional or Enterprise account, the surveys API allows you to create, retrieve, and delete shareable link custom surveys with a single CSAT or NPS question in a HubSpot account. It also provides the ability to programmatically send or remove feedback submission data associated with an existing custom survey. If you need to retrieve feedback submission data, check out the feedback submissions API instead.

Scope requirements

The following scopes are required for the survey API endpoints, based on the endpoint you plan on using:
  • surveys.read: provides access to retrieve survey overview data.
  • surveys.write: provides access to create, edit, and delete surveys, as well as create and delete survey submission data.

Create a survey

To create a survey, make a POST request to /surveys/v3/surveys, and include the name, language, and fields parameters for the survey in the body of your request, which are documented in the table below. At this time, you can only create a custom survey with a single CSAT or NPS question via this endpoint. You can create up to 100 total custom surveys in a HubSpot account.
ParameterTypeDescription
nameStringAn internal name for the survey that will appear in your HubSpot account. This name is not visible to respondents.
languageStringThe language of the survey that will be used to translate default survey content (e.g., NPS label, default survey title, and introduction).
fieldsArrayAn array of JSON objects that specifies each field in the survey. Each object should include the following properties:
  • type: the question type (either CSAT or NPS).
  • label: if you’re creating a custom survey with a CSAT question, you can specify a custom label as a string. If you’re creating a custom survey with a NPS question, this field cannot be customized, and will default to “How likely is it that you would recommend {{brand_name}} to a friend or colleague?”.
  • required: whether the question is required to submit the survey. This property defaults to true.
On success, the response will include the id of the newly created survey, along with a shareableLink you can use to send to a customer. For example, if you made a POST request to https://api.hubapi.com/surveys/v3/surveys with the following request body:
{
  "name": "Spring CSAT survey",
  "language": "en",
  "fields": [
    {
      "type": "CSAT",
      "label": "How satisfied are you with our recent service?",
      "required": true
    }
  ]
}
The response would resemble the following:
{
  "id": "10",
  "name": "Spring CSAT survey",
  "shareableLink": "https://survey.hsforms.com/1wYDHSyRWStWjWaWaB_0dUg123499",
  "createdAt": "2025-02-05T18:19:34.948Z"
}

Retrieve a survey

To retrieve a specific survey, make a GET request to /surveys/v3/surveys/{surveyId}, providing the ID of the survey as the surveyId. The response will include key information about the survey, such as the name, fields, shareableLink, createdAt, and lastUpdatedAt properties, along with the sourceType property that will specify whether the survey was created via the API (api) or via the feedback tool in HubSpot (ui). For example, if you made a request to retrieve a survey with an ID of 10, you’d make a GET request to https://api.hubapi.com/surveys/v3/surveys/10, and the response would resemble the following:
{
  "id": 10,
  "name": "Spring CSAT survey",
  "fields": [
    {
      "type": "CSAT",
      "label": "How satisfied are you with our recent service?",
      "required": true
    }
  ],
  "sourceType": "api",
  "shareableLink": "https://survey.hsforms.com/1wYDHSyRWStWjWaWaB_0dUg123499",
  "createdAt": "2025-02-05T18:19:34.948Z",
  "lastUpdatedAt": "2025-02-05T18:19:34.948Z"
}

Search for survey overview data

To get a list of existing surveys, you can make a POST request to /surveys/v3/surveys/search, and provide the limit or after query parameters to paginate the results. You can also provide an array of filterGroups and sorts in the request body to filter the results further. Learn more about how to use the search API. The response will include the following fields:
FieldTypeDescription
resultsArrayAn array of results, each of which will include the following survey properties:
  • id: The ID of the survey.
  • name: The internal name of the survey.
  • type: The survey type, which is distinct from the question type in the context of CUSTOM surveys. The possible survey types are CUSTOM, CES, CSAT, NPS, and KNOWLEDGE. All API-created surveys are CUSTOM surveys.
  • createdBy: the ID of the user who created the survey.
  • integratorId: the appId of the integrator associated with survey creation.
  • sourceType: whether the survey was created in the UI or via the API.
  • surveyedCount: The number of times the survey was viewed.
  • responseCount: The number of times a survey was submitted.
  • publishedAt: The timestamp of when the survey was published.
  • createdAt: The timestamp of when the survey was created.
  • updatedAt: The timestamp of when the survey was last updated.
totalNumberThe total number of results.
pagingObjectAn object that provides pagination information. This will not be included if no further results remain. If present, this field will contain a next field, which itself contains an after field you can use to request the next page of results. Learn more about paginating results.
For example, if you wanted to search for all surveys created directly through the feedback tool (i.e., through the UI instead of via the API), limit your results to the first two matching surveys, and sort the results alphabetically, you’d make a POST request to https://api.hubapi.com/surveys/v3/surveys/search?limit=2, and your request body would resemble the following:
{
  "filterGroups": [
    {
      "filters": [
        {
          "property": "sourceType",
          "operator": "EQ",
          "value": "ui"
        }
      ]
    }
  ],
  "sorts": [
    {
      "property": "name",
      "order": "ASC"
    }
  ]
}
The resulting response would be:
{
  "total": 10,
  "results": [
    {
      "id": "230",
      "name": "February NPS survey",
      "type": "CUSTOM",
      "createdBy": "905076099",
      "integratorId": "759076010",
      "sourceType": "ui",
      "surveyedCount": 2,
      "responseCount": 2,
      "publishedAt": "2025-02-11T20:37:22.686Z",
      "createdAt": "2025-02-11T20:37:20.131Z",
      "lastUpdatedAt": "2025-02-11T20:38:58.264Z"
    },
    {
      "id": "229",
      "name": "Spring CSAT survey",
      "type": "CUSTOM",
      "createdBy": "905076099",
      "integratorId": "759076010",
      "sourceType": "ui",
      "surveyedCount": 2,
      "responseCount": 2,
      "publishedAt": "2025-02-11T20:37:22.686Z",
      "createdAt": "2025-02-11T20:37:20.131Z",
      "lastUpdatedAt": "2025-02-11T20:38:58.264Z"
    }
  ],
  "paging": {
    "next": {
      "after": "Ng%3D%3D"
    }
  }
}

Delete a survey

To delete a survey, make a DELETE request to /surveys/v3/surveys/{surveyId}, providing the ID of the survey you want to delete as the surveyId. If successfully deleted, the response will include a status code of 204 No content.

Create a feedback submission associated with a survey

To create a feedback submission to a custom survey you’ve created via the API, make a POST request to /surveys/v3/surveys/{surveyId}/submissions, providing the ID of the survey as the surveyId, and providing details for the submission in the body of your request. The following fields are supported in the request body:
FieldTypeDescription
emailStringA required field indicating the email address associated with the submission.
submissionFieldsArrayA list of populated fields associated with the submission. For a valid submission, the order and type of these fields must match those on the submitted survey. Each object in the array must include the following properties:
  • type: The question type of the custom survey (either NPS or CSAT), provided as a number.
  • value: The response value submitted. For custom surveys with a single CSAT question, 0 (detractor), 1 (neutral), or 2 (promoter) is supported. For custom surveys with a single NPS question, any number between 0 and 10 is supported.
  • followUpResponse: the text response associated with the submission, corresponding to the follow-up questions that appear in the UI once a user selects a value for a CSAT or NPS field.
    For a CSAT question, the follow-up questions are:
    • 0: “Can you tell us more about your experience, so we can get it right the next time?”
    • 1: “Can you tell us more about your experience, so we can do even better next time?”
    • 2: “Can you tell us why you scored us so highly?”
    For an NPS question, the follow-up questions are:
    • 0 to 6: “Can you tell us more about your experience, so we can get it right the next time?
    • 7 or 8: “Can you tell us more about your experience, so we can do even better next time?”
    • 9 or 10: “Can you tell us why you scored us so highly?”
For example, if you had an existing survey with an ID of 10, you’d make a POST request to https://api.hubapi.com/surveys/v3/surveys/10/submissions and the request body would resemble the following:
{
  "email": "alice@example.com",
  "submissionFields": [
    {
      "type": "NPS",
      "value": "10",
      "followUpResponse": "Thanks so much for all of your help during our last call!"
    }
  ]
}
The response will include an ID that corresponds to the form submission along with the date it was submitted:
{
  "id": "470cab4c-be1b-4b00-866c-30aeab104999",
  "createdAt": "2025-02-05T17:39:13.562Z"
}

Delete a feedback submission associated with a survey

To delete an existing feedback submission, you can make a DELETE request to /surveys/v3/surveys/{surveyId}/submissions/{feedbackSubmissionId}, providing the ID of the survey as the surveyId and the ID of the feedback submission you want to delete as the feedbackSubmissionId. If successfully deleted, the response will include a status code of 204 No content.