Skip to main content
All survey endpoints live under the admin REST API and use its authentication:
The API host depends on the data region of your project:
The examples on this page use the EU host. If your project lives in another region, replace https://api.gleap.io with your region’s host. API tokens are per project and only valid in the project’s region.
{id} below is the survey’s Gleap id (the _id returned by GET /v3/engagement/surveys). The id you pass to Gleap.showSurvey is the survey’s SDK id (actionType) — a different value. Every endpoint is project-scoped and checks the same survey permissions as the dashboard (viewers can read, members and admins can edit).

Surveys

Delete a survey

DELETE /v3/engagement/surveys/{id} deletes the survey at once. Everything stored for it follows in the background, usually within a minute and at the latest after about ten: every response (including the files respondents uploaded, and the survey tickets of a survey created before Surveys 2.0), its published versions, stats, analytics events and search entries. Conversations started from a response stay (without the link to it). Live email campaigns that send the survey are paused right away (their pending sends are dropped) and kept, without the survey. GET /v3/engagement/surveys/{id}/delete-preview returns what a deletion affects besides the survey’s own data: { liveEmailCampaigns: [{ id, name }], legacyTickets }. This cannot be undone: export the responses first if you need them.

Create a draft

The definition format is described in Survey definition. New surveys are always drafts; nothing is shown to anyone until the survey is published and set live.

Save the draft

Returns { definition, warnings }. Drafts may contain invalid logic — warnings lists what publishing would reject. Saving the draft of a live survey doesn’t change what respondents see.

Validate

POST /validate with { "definition": { … } } returns { ok, errors: [{ path, code, message }] } and saves nothing.

Publish

POST /publish validates the draft, stores it as the next immutable version and makes it the version respondents see. Invalid drafts return 422 with errors. Publishing doesn’t start the survey in your app: that is the survey’s status (live shows it to the in-app audience, Share → In the app in the dashboard), or send { "goLive": true } to publish and start it in one call. The survey page and emails use the published version whatever the status.
Requests made by AI agents (the Gleap MCP server, Kai) don’t publish: they receive 403 with requiresApproval: true. A teammate publishes from the dashboard (Publish changes).

Survey page settings

PUT /page takes:
slug is unique per project (^[a-z0-9-]{2,60}$). access is anyone or personal_links_only. afterSubmit.mode is ending or redirect.

Results

Stats

GET /v3/engagement/surveys/{id}/stats?from=2026-09-01&to=2026-09-30&version=3 Computed from stored counters, so it is cheap at any volume. nps (score and distribution) is present when the survey has an NPS question; perBlock is keyed by answer key, edges counts the paths between blocks (from>to).

Analytics

GET /v3/engagement/surveys/{id}/analytics?from=2026-09-01&to=2026-09-30 — views, starts, submissions, the question funnel with drop-off, timing, breakdowns and the previous period for comparison, from survey events. See Survey analytics.

Responses

GET /v3/engagement/surveys/{id}/responses Returns { responses: [...], nextCursor }, newest first. Response objects are described in Survey definition → Responses.
Compatibility for existing pollers. Integrations that page through this endpoint with skip / limit keep receiving the previous shape — an array of { _id, formData, session, createdAt, updatedAt }, where formData holds the answers keyed by answer key (for a survey created before Surveys 2.0: by its old field names). Switch to cursor to get the new fields (status, path, version, channel, themes).

Survey answers on the ticket API (until January 5, 2027)

Before Surveys 2.0 every answer was a ticket of type SURVEY. Until January 5, 2027 the ticket API keeps returning them, without creating tickets:
  • GET /v3/tickets?type=SURVEY, GET /v3/tickets/export?type=SURVEY and GET /v3/tickets/csv-export?type=SURVEY list survey answers in the ticket shape, newest first (skip / limit, outbound, session and date filters work). An answer from before the upgrade is its original ticket (same _id, bugId, formData); a newer one is a ticket view with _id = the response id, formData under the old field names (choices as their text), the contact’s fields in session, createdAt = when it was completed, and surveyResponse. Merged pages go up to 25,000 rows deep.
  • GET /v3/sessions/{sessionId}/activities?surveyResponses=include adds the contact’s survey responses to its tickets; surveyResponses=only lists only them (with surveyName, outbound and responseStatus).
From January 5, 2027 type=SURVEY returns tickets only. Move to GET /v3/engagement/surveys/{id}/responses, the survey webhooks or automations before then.

Reach out to a respondent

POST /v3/engagement/surveys/{id}/responses/{responseId}/reach-out
channel is messenger or email (with an optional subject); message is plain text or a TipTap document. Gleap starts a normal conversation with the contact, links it to the response and returns { ticketId, ticketShareToken }.

AI insights

GET /insights returns the links as links and per theme as themes[].links, each with the ticket’s number, title, status and type or the Kai Code session’s title and status. Links to deleted tickets or sessions are left out. Insights are generated on demand: GET /insights always answers at once with what is stored. When responses came in since the last update and that update is more than 5 minutes old, the read also starts one update in the background (tagging new answers with themes, recounting, and rewriting the summary after 25 newly tagged answers or 10% more responses). generation tells you its state:
Read again in a minute or two while status is updating. Without new responses, reading the insights uses no AI. Each project has a daily budget for survey AI (2,000 answers tagged and 20 summaries or theme lists a day); when it is used up, capped is true and updates resume at resumesAt (the next midnight UTC). A survey nobody opens is never analyzed. POST /insights/ask:
AI usage (themes, insights, ask) is billed as token usage.