Skip to main content
The survey export copies your survey campaigns and every native survey response into two tables in your own warehouse, so you can join them with product and revenue data. This page is the schema reference. Responses carry most of the same fields as the survey response webhook and the Surveys API, in snake_case.

Who can use it

  • Workspaces on the Enterprise plan with a BigQuery or Snowflake connection. Redshift, Postgres and S3 connections aren’t supported.
  • Admins with the permission to change sync settings turn it on. Turning it off works on any plan.

Turn it on

Create the destination first, then switch export on in GainTrace.
  1. Create a dataset in the same location as your connection. The default name is gaintrace.
  2. Give the connection’s service account BigQuery Data Editor on that dataset. It keeps BigQuery Job User on the project.
Then open Integrations, choose the connection, and go to the Survey export tab. Enter the dataset (BigQuery) or schema (Snowflake) and turn on Export survey responses. GainTrace creates both tables and checks that it can write to them. Names can use letters, numbers and underscores only, up to 128 characters.

How it runs

  • The first export copies everything. Consumers can see a partial table until it finishes.
  • After that it runs every hour with the connection’s sync, which needs auto sync on and billing not locked. Export now runs it on demand.
  • Rows are upserted by id, so you never get duplicates. Edits, follow-up changes and responses a respondent finishes later update the row. A row never moves to an older version.
  • Responses that are deleted in GainTrace get a deleted_at value, and every answer and personal column on the row is cleared. A deleted response keeps only id, workspace_id, survey_id, measure, updated_at and deleted_at. Its updated_at becomes the deletion time. A deleted campaign gets deleted_at on its surveys row.
  • Anonymous campaigns, and responses whose personal details were removed (anonymized_at is set), never carry person_id, respondent_email or respondent_name.
  • Private reviewer notes and GainTrace’s internal answer keys are never exported.
  • Responses imported from other tools (Typeform, SurveyMonkey, Qualtrics, Retently, Delighted and CSV files) and NPS sent to /nps-responses aren’t included.
  • Turning export off keeps the tables. Turning it on again, or changing the dataset, empties the tables and reloads them.
Every table has one more column, _gaintrace_synced_at, a timestamp of when GainTrace last wrote the row.

Table survey_responses

One row per response. Types are shown for BigQuery and Snowflake. id, workspace_id, survey_id and updated_at are never empty.

The answers column

answers has the same shape as answers on the API and in webhooks. Keys are question positions, q0, q1 and so on, counted from zero. A comment key holds the comment. Values you saved with hidden fields are under hidden, and an AI follow-up is under _probe with question and answer.

The question_answers column

question_answers is a list with one entry per answered question. Statements and unanswered questions are left out.
number is the question’s position counted from one. value is the stored answer. display is the same answer as text.

Table surveys

One row per campaign. id, workspace_id and updated_at are never empty. Survey settings aren’t exported, because they hold alert destinations and in-app origins.

Example queries

Monthly NPS by campaign. Leave out deleted and unfinished responses.
Read one answer out of the JSON column:

Troubleshooting

Surveys API

Read the same responses over REST.

Webhooks

Get responses as they arrive.
Last modified on October 20, 2026