# Survicate for Developers > Official developer documentation for Survicate, the customer feedback and survey platform: the JavaScript SDK for websites and web apps, the Mobile SDKs (iOS, Android, React Native, Flutter, Unity) and their integrations, the Data Export API (REST), Webhooks, and Survicate MCP, the Model Context Protocol server that lets AI assistants such as Claude and ChatGPT work with Survicate. This file contains every page of https://developers.survicate.com as Markdown. Each page starts with a level-one heading followed by a "Source:" line with the URL of the original page. --- # Overview Source: https://developers.survicate.com/ Survicate is a customer feedback platform: targeted surveys on websites and web apps, in mobile apps, by email and shareable link, and inside Intercom Messenger and Braze, plus Research Hub, which gathers feedback from surveys and other sources and analyzes it with AI. This page defines the concepts the developer documentation builds on and shows how the SDKs, the Data Export API, Webhooks and Survicate MCP fit together. Surveys are created, targeted, launched and analyzed in the Survicate panel at [panel.survicate.com](https://panel.survicate.com/). Developers come in where Survicate meets your own code and systems: installing the SDKs, identifying respondents, reporting events, and getting responses out. Using the panel itself (building surveys, targeting, integrations, billing) is documented in the [Help Center](https://help.survicate.com/en/). - [Getting started](/getting-started) - [JavaScript SDK](/javascript) - [Mobile SDK](/mobile-sdk) - [Data Export API](/data-export) - [Webhooks](/webhooks) - [Survicate MCP](/mcp) ## Survey types A survey has exactly one type, chosen when it is created. The type decides where the survey is shown, which question types are available and what, if anything, a developer has to install. It cannot be changed later, except between Website or in-product and Braze in-app message. | Survey type | Where respondents see it | What it needs from a developer | | --- | --- | --- | | Website or in-product | A pop-up widget, a Feedback Button that stays on the page, or an iframe embed on a website or web app | The tracking code or an npm package on every page where surveys may appear ([JavaScript SDK](/javascript)). Attributes, events and methods are optional additions | | Mobile app | Inside native iOS and Android apps, including apps built with React Native, Flutter or Unity | The [Mobile SDK](/mobile-sdk) initialized with the workspace key; screens and events reported from the app code | | Email or shareable link | A hosted page under survey.survicate.com, opened from a link, a QR code or the first question embedded in an email; emails can be sent from Survicate or from your email tool | No code. Respondents are identified through URL parameters (merge tags) added to the survey link | | In-platform: Intercom Messenger, Braze in-app message | Inside an Intercom Chat or Post, or a Braze in-app message | No Survicate code. The survey is delivered by the [Intercom](https://help.survicate.com/en/articles/3935537-intercom-messenger-surveys) or [Braze](https://help.survicate.com/en/articles/11087508-braze-in-app-message-surveys) integration | Question types: welcome message, single answer selection, multiple answer selection, text answer (up to 1,000 characters), rating scale (2 to 10 points, used for CSAT), smiley scale (3 or 5 points), NPS (fixed 0 to 10), dropdown list, matrix (up to 13 rows and 7 columns), contact form, ranking, date, and a thank-you screen with an optional call to action. Not every type is available in every survey type; the Help Center has the [full matrix](https://help.survicate.com/en/articles/3933677-question-and-action-types), and [Webhooks: Answer types](/webhooks/answer-types) shows how each answer arrives in your systems. ## How a survey is delivered 1. Your page or app loads the SDK with the **workspace key**. The SDK assigns the visitor a UUID, kept in the browser's Local Storage or on the device, so the same person is recognized on later visits. 2. Your code can pass **attributes** about the visitor (such as `user_id` or `plan`) and report **events** and **screens**. Everything else about who sees which survey is configured in the panel and takes effect without a deployment. 3. The SDK works out which surveys the visitor is eligible for. For a *Visitors* audience the conditions are evaluated in the browser or app from data stored there. For *Users* and *Manual* audiences Survicate evaluates them on its servers, keyed by `user_id`, and the result is cached for about five minutes. 4. When the survey's trigger fires (page or screen load, a delay, exit intent, or an event), the SDK renders the survey. Each answer is sent to Survicate as soon as it is given, so partial responses are stored as well. 5. Survicate records the response, notifies the survey's integrations and webhooks, and shows it in the survey's Analyze tab, from where it also feeds Boards and Research Hub. ## Concepts - **Organization and workspace.** An organization is a company's account. It holds one or more workspaces, and each workspace has its own surveys, integrations, teammate permissions and workspace key. - **Workspace key.** The identifier the tracking code and the Mobile SDKs use to load the workspace's surveys, as in `https://survey.survicate.com/workspaces//web_surveys.js`. It is embedded in your pages and apps, so it is not a secret. It is shown under [Settings → Organization → Access Keys](https://panel.survicate.com/o/0/w/0/settings/organization/access-keys) in the panel. - **Access keys.** Besides the workspace key, a workspace has an **API key** for the Data Export API and an optional **secret key** used to sign user identities for logged-in user targeting. Webhooks use their own verification token and signing secret. [Getting started](/getting-started#2-find-your-keys) lists where each one lives and who can see it. - **Teammates and roles.** Four roles: Guest (view results), User (create and edit surveys, connect integrations, export results), Admin (also invites teammates and manages folder access) and Owner (also adds workspaces, deletes teammates and manages the subscription). Choosing roles per workspace is available on some plans; otherwise every teammate is a User. Access to Research Hub is granted separately from the role. Survey folders can be open to everyone or limited to chosen teammates and teams. - **Survey, question and answer.** A survey is identified by a 16-character hexadecimal ID that appears in the panel's address bar when the survey is open, for example `f658c90277553239`. Questions (called points in the JavaScript SDK) and answer choices have numeric IDs. A survey is enabled or disabled, can be scheduled to start and stop, can cap its responses, and can be archived. - **Respondent and response.** A respondent, also called a visitor, is one person identified by a UUID plus any attributes you passed. A response is one respondent's submission to one survey; complete and partial submissions are both stored and counted, test responses included, and any response can be deleted in the Analyze tab. Submitting only the welcome screen is shown in the analysis but not counted. - **Attributes (user traits).** Name-value pairs describing a respondent, set from your code, an integration, a CSV upload or the survey URL. Values are strings, numbers, booleans or dates. Attributes identify respondents, define audiences, filter results and can be recalled in question text. Four names are special: `user_id` marks the respondent as logged in and enables server-side targeting, and `first_name`, `last_name` and `email` make a response identified instead of anonymous. Names are case-sensitive, names and values are limited to 255 characters, and a workspace can hold up to 2,000 distinct attribute names. **Response attributes** belong to a single response rather than the respondent, for example the order a review refers to. - **Events.** Named actions your code reports with `invokeEvent`, optionally with string properties. In the panel an event can trigger a survey the moment it happens (counted in the browser or app) or filter a Users audience by the user's server-side event history, which follows the user across devices. - **Audience.** The group of respondents a survey targets; *All visitors* is the default and *All logged-in users* is everyone with a `user_id`. A *Visitors* audience is evaluated in the browser or app from attributes stored there. *Users* and *Manual (CSV upload)* audiences are evaluated on Survicate's servers by `user_id`, so the same person is recognized across browsers and devices and cannot answer twice. A survey uses either browser-side or server-side targeting, not both. - **Targeting.** Everything else that decides when a survey shows, set in the panel: pages or screens (URL rules, regular expressions), triggers (on load, after a delay, on exit intent, on an event), device, browser language, visit frequency and depth, sampling, how often a respondent may answer again, schedule and response caps. - **Integrations.** Native connections that send responses to other tools, sync respondent data, or pull feedback into Research Hub: Slack, Microsoft Teams, Google Sheets, HubSpot, Intercom, Salesforce, Segment, RudderStack, Amplitude, Mixpanel, Google Analytics, Google BigQuery, Zendesk, Jira, Productboard, Zapier and others. Availability depends on the plan and the survey type; the Help Center's [Connect integrations](https://help.survicate.com/en/collections/36481-connect-integrations) collection covers each one. - **Research Hub.** Survicate's research and analysis product. It collects feedback pieces from surveys, review sites (App Store, Google Play, G2, Google Reviews), support tools (Intercom, Zendesk, Front, LiveChat), call and meeting transcripts (Gong, Google Meet, tl;dv, uploaded recordings), Slack, email and uploaded files. A Research Project runs an AI analysis of chosen sources against a research question and produces a report whose conclusions link to the source quotes, plus Insights, the recurring themes found in the data. The Research Agent answers questions inside a project. - **Boards.** Dashboards within a workspace that combine widgets from several surveys and from Research Hub: single question, combined score, and Research Hub breakdowns by sentiment, insight or attribute. - **Survicate AI.** The AI features across the product: creating a survey from a description, AI follow-up questions to text answers, Insights that summarize text answers, Research Hub's analysis and Research Agent, and [Survicate MCP](/mcp). Text analysis uses OpenAI's Enterprise API, which does not train models on customer data. ## Developer surfaces | Surface | Use it to | How it runs | Authentication | | --- | --- | --- | --- | | [JavaScript SDK](/javascript) | Show website and in-product surveys, identify visitors, pass attributes, report events, show or close a survey from code, listen to survey events, submit answers without showing a survey | `web_surveys.js` loaded by the tracking code, or the `@survicate/survicate-web-package` and `@survicate/survicate-web-surveys-wrapper` npm packages | Workspace key | | [Mobile SDK](/mobile-sdk) | The same for iOS, Android, React Native, Flutter and Unity apps: screens, events, user traits, listeners, locale and theme | Native libraries and bindings for each platform | Workspace key | | [Data Export API](/data-export) | Pull surveys, questions, responses and respondents into your database, warehouse or CRM; delete a person's data for GDPR requests | REST and JSON at `https://data-api.survicate.com/v2/`, paginated with a `next_url` | `Authorization: Basic ` | | [Webhooks](/webhooks) | Receive every answer, or every completed response, at your HTTPS endpoint as it happens | HTTPS POST from Survicate to your endpoint | A verification token and an HMAC signature in the request headers | | [Survicate MCP](/mcp) | Let AI assistants (Claude, ChatGPT, Cursor, Slack) list surveys, read results, ask questions about feedback, draft surveys and use Research Hub | Remote MCP server at `https://mcp.survicate.com/`, Streamable HTTP | OAuth 2.1; every call runs as the signed-in user | | Integrations | Move responses to other tools and pull feedback into Research Hub without code | Configured in the panel, per survey in its Connect tab or per workspace | Per tool, usually OAuth | ### Getting data in - Respondent attributes and events, from the SDKs, Google Tag Manager, Segment, RudderStack, or URL parameters on a survey link. - Respondent profiles, from integrations such as HubSpot, Intercom or Clearbit. - Audiences, from a CSV upload of user IDs. - Feedback from other sources into Research Hub, through integrations, transcribed recordings and file uploads. ### Getting data out - As it happens, per answer or per response: Webhooks, or a native integration (Slack, Google Sheets, HubSpot, Amplitude, Mixpanel and others). - In bulk or as a backfill: the Data Export API, or the Google BigQuery and Fivetran integrations for a warehouse. - On demand: CSV and XLSX exports and PDF or PNG charts from the Analyze tab. - In conversation: Survicate MCP, which answers with citations to the underlying responses. ## Limits and defaults | Item | Value | | --- | --- | | Attribute name and value length | 255 characters; longer values are truncated | | Distinct attribute names per workspace | 2,000 | | Attribute filters in one audience | 50 | | Event name length and property values | 255 characters; property values must be strings | | Text answer length | 1,000 characters | | Server-side audience cache | 5 minutes, or 90 seconds once a survey is available to the user | | Time for survey changes to reach visitors | Up to 15 minutes for website surveys, a couple of minutes for mobile surveys | | Data Export API rate limits | 5 concurrent requests; 1,000 requests per minute per workspace; 1 to 100 items per page | | Webhook source IP addresses | 3.248.104.12 and 54.171.69.70 | | Browsers supported for surveys | Chrome 85+, Firefox 79+, Opera 71+, Safari 14+, Edge 85+ | | What counts as a response | One submission by one respondent, complete or partial; a welcome screen on its own does not count | ## Plans Survicate has a free plan (25 responses a month, up to 3 teammates, no data export) and paid plans: Starter (monthly), Growth, Pro and Enterprise (yearly). A new account starts with a 10-day trial of the Growth features. Installing the tracking code or a Mobile SDK, identifying respondents with `setVisitorTraits` and URL targeting work on every plan; the developer features below are tied to plans. The [pricing page](https://survicate.com/pricing/) and its Compare plans table are authoritative; this list reflects them as of September 2026. - Attribute-based audiences, recurring surveys and multilingual surveys: Growth and above. - Event-based targeting, JavaScript targeting (the SDK methods other than `setVisitorTraits`, and event listeners), sampling, A/B testing and custom CSS: Pro and Enterprise. - Webhooks and the Data Export API: Pro and Enterprise. - Survicate MCP: all paid plans. - SAML SSO, access logs, HIPAA and DORA terms: Enterprise. ## Security and compliance - Hosted on AWS in Ireland. Backups are encrypted and stored in at least three regions in Ireland. - Data is encrypted in transit (TLS 1.2 or higher only) and at rest (AWS KMS for databases and file stores). - Product development and maintenance are ISO 27001 certified; the infrastructure is covered by AWS's ISO 27001 and SOC 2 programs. Penetration tests run at least yearly, and there is a [bug bounty program](https://survicate.com/bug-bounty/). Security issues go to security@survicate.com. - GDPR: a data processing agreement is available, and the Data Export API's [personal data endpoints](/data-export/personal-data) retrieve or delete one person's data across services. HIPAA (with a BAA) and a DORA addendum are available on the Enterprise plan; HIPAA-regulated workspaces cannot be connected to AI assistants through MCP. - Account security: two-factor authentication for every account, SAML 2.0 single sign-on (Okta, Microsoft Entra ID, OneLogin and other SAML providers) on Enterprise. - Respondent data: Survicate sets no cookies on respondents' devices. The web SDK keeps the respondent UUID, survey status, tags, queued answers and attributes in Local Storage, or only in Session Storage when `disableSensitiveDataPersistence` is set. IP addresses are processed for CDN delivery and abuse protection and are not stored. - Accessibility: surveys work with screen readers (VoiceOver, NVDA, TalkBack), full keyboard navigation and zoom up to 400%, with the goal of WCAG 2.1 A and AA and Section 508 conformance. - Service status: [status.survicate.com](https://status.survicate.com/). ## Docs for AI agents Every page of this site is also published as plain Markdown for AI agents and tools: append `.md` to a page URL (for example `https://developers.survicate.com/getting-started.md`; this page is `https://developers.survicate.com/index.md`), fetch [llms.txt](https://developers.survicate.com/llms.txt) for an index of all pages with one-line descriptions, or [llms-full.txt](https://developers.survicate.com/llms-full.txt) for the whole documentation in one file. The AI tools beside each article copy the page as Markdown or open it in ChatGPT or Claude. For questions about your own surveys and responses, connect your assistant to [Survicate MCP](/mcp). - [Getting started](/getting-started) --- # Getting started Source: https://developers.survicate.com/getting-started/ This guide takes a developer from a new Survicate account to a survey that collects identified responses from a website or app and delivers them to your own systems. Steps 1 and 2 apply to everyone; in step 3 pick the channel your customers use. Each step links to the reference page with the full details. ## 1. Before you start - **Create an account** at [panel.survicate.com/signup](https://panel.survicate.com/signup) with a business email address, or accept the invitation a teammate sent you. A new account starts with a 10-day trial of the Growth plan's features and continues on the free plan afterwards; the [pricing page](https://survicate.com/pricing/) lists what each plan includes. - **Split the work.** Developers install the SDK once and pass attributes and events. From then on, whoever owns feedback creates, targets and launches surveys in the panel, with no further release needed. Agree early on the attribute and event names both sides will use; they are case-sensitive. - **Know where to get help.** Support answers on the live chat in the panel and at [support@survicate.com](mailto:support@survicate.com). The [Help Center](https://help.survicate.com/en/) covers everything that happens in the panel and this site covers the code; both can be read by your AI assistant, see [Docs for AI agents](/#docs-for-ai-agents). ## 2. Find your keys | Key | Used by | Where in the panel | Handle as | | --- | --- | --- | --- | | Workspace key | Tracking code, npm packages, Mobile SDKs | [Access Keys](https://panel.survicate.com/o/0/w/0/settings/organization/access-keys) | A public identifier; it ships in your pages and apps | | API key | Data Export API | [Access Keys](https://panel.survicate.com/o/0/w/0/settings/organization/access-keys) (owners and admins) | Secret; server side only | | Secret key | Signing user IDs for logged-in user targeting (`user_key`) | [Access Keys](https://panel.survicate.com/o/0/w/0/settings/organization/access-keys), Secret Key section | Secret; never in frontend or app code | | Verification token and signing secret | Verifying webhook deliveries | [Webhooks settings](https://panel.survicate.com/o/0/w/0/integrations/webhooks?tab=settings) | Secret; can be regenerated at any time | | Survey ID | `showSurvey`, `hiddenSurveys`, Data Export API paths | Address bar while the survey is open | Not secret | ## 3. Install Survicate ### Website or web app Add the tracking code before the closing `` tag of every page where a survey may appear, or install one of the npm packages. One installation serves every survey in the workspace, and the same snippet can be installed on any number of domains; which pages a survey shows on is decided by its targeting. ```html title="Tracking code" ``` ```javascript title="Web package" // npm install @survicate/survicate-web-package --save import Survicate from '@survicate/survicate-web-package/survicate_widget'; Survicate.init({ workspaceKey: 'YOUR WORKSPACE KEY HERE' }); ``` ```javascript title="Web surveys wrapper" // npm install @survicate/survicate-web-surveys-wrapper --save import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; await initSurvicate({ workspaceKey: 'YOUR WORKSPACE KEY HERE' }); ``` The snippet with your key already filled in is under [Settings → Surveys → Web](https://panel.survicate.com/o/0/w/0/settings/surveys/web) in the panel. The tracking code and the wrapper always load the current SDK version; the web package is a dependency you update yourself. To verify the installation, open your site and run `_svc` in the browser console: it prints the workspace key when the code is installed. Google Tag Manager, WordPress, Segment and Braze installations are covered on the [Installation](/javascript/installation) page. ### Mobile app Install the SDK for [iOS](/mobile-sdk/ios/installation), [Android](/mobile-sdk/android/installation), [React Native](/mobile-sdk/react-native/installation), [Flutter](/mobile-sdk/flutter/installation) or [Unity](/mobile-sdk/unity/installation), put the workspace key in the app configuration (`Info.plist` on iOS, `AndroidManifest.xml` on Android, or `setWorkspaceKey` in code) and initialize the SDK when the app starts. The key and the per-platform instructions are also under [Settings → Surveys → Mobile](https://panel.survicate.com/o/0/w/0/settings/surveys/mobile) in the panel. Steps 4 and 5 add user attributes, screens and events. ### Email Nothing to install. To identify the respondents of email and link surveys, add parameters to the survey link. When you pick a supported email tool in the survey's Configure step, Survicate generates the link with that tool's merge tags; with any other tool, or in your own emails, append the parameters yourself. Every parameter becomes a respondent attribute. ```text title="Survey link with respondent attributes" https://survey.survicate.com//?email={{contact.email}}&first_name={{contact.first_name}}&plan={{contact.plan}} ``` ## 4. Identify respondents Responses are anonymous until your code says who the respondent is. Pass a `user_id` plus the attributes you want to target or filter by, at a point where you know the user, for example after login. Attributes are cached on the device, so once is enough, and changing one may make a survey eligible immediately. ### Website or web app Set the traits in the `opts.traits` object before the tracking code loads, or call `setVisitorTraits` at any time. ```javascript title="Tracking code" // Before the tracking code (function (opts) { opts.traits = { user_id: 'u_12345', email: 'ada@example.com', first_name: 'Ada', plan: 'pro', signed_up: '2026-01-15T09:30:00Z', }; })(window._sva = window._sva || {}); // Later, for example after login window._sva.setVisitorTraits({ user_id: 'u_12345', plan: 'pro' }); ``` ```javascript title="Web package" Survicate.setVisitorTraits({ user_id: 'u_12345', email: 'ada@example.com', first_name: 'Ada', plan: 'pro', signed_up: '2026-01-15T09:30:00Z', }); ``` The Installation page covers [user identification](/javascript/installation#users-identification) and [user attributes](/javascript/installation#user-attributes) for each installation method; the method itself is documented under [Set visitor attributes](/javascript/methods#set-visitor-attributes). ### Mobile app Call `setUserTrait`, or `setUserTraits` for several at once, once the SDK is initialized. ```swift title="iOS (Swift)" SurvicateSdk.shared.setUserTrait(UserTrait(withName: "user_id", value: "u_12345")) SurvicateSdk.shared.setUserTraits(traits: [ UserTrait(withName: "email", value: "ada@example.com"), UserTrait(withName: "plan", value: "pro"), UserTrait(withName: "subscription_active", value: true), ]) ``` ```kotlin title="Android (Kotlin)" Survicate.setUserTrait(UserTrait("user_id", "u_12345")) Survicate.setUserTraits(listOf( UserTrait("email", "ada@example.com"), UserTrait("plan", "pro"), UserTrait("subscription_active", true) )) ``` The same call exists in every SDK: [iOS](/mobile-sdk/ios/using-sdk#user-identification-and-attributes), [Android](/mobile-sdk/android/using-sdk#user-identification-and-attributes), [React Native](/mobile-sdk/react-native/using-sdk#passing-user-attributes), [Flutter](/mobile-sdk/flutter/using-sdk#passing-user-attributes) and [Unity](/mobile-sdk/unity/using-sdk#passing-user-attributes). ### Email Every parameter on a survey link becomes a respondent attribute, as shown in step 3: `email`, `first_name`, `last_name` and any custom name such as `plan`. When you send the survey through a supported email tool, Survicate generates the link with that tool's merge tags. For Intercom Messenger and Braze in-app message surveys, respondent identification is set up in the integration; see the Help Center articles on [Intercom Messenger surveys](https://help.survicate.com/en/articles/3935537-intercom-messenger-surveys) and [Braze in-app message surveys](https://help.survicate.com/en/articles/11087508-braze-in-app-message-surveys). ### Attribute rules - `user_id` can be any string that is unique per user. It marks the respondent as logged in, and it is required for the *All logged-in users*, *Users* and *Manual* audiences. - `first_name`, `last_name` and `email` make a response identified in the panel; without them it is marked Anonymous. - Values can be strings, numbers, booleans or dates (ISO 8601). Attribute names are case-sensitive, and names and values are limited to 255 characters. Strings must not contain `{}`, `*`, `[]`, `%`, `~`, `--` or `$`. - A workspace can hold up to 2,000 distinct attribute names, and an audience filter up to 50 attributes. An attribute becomes available as a filter in the Analyze tab once a response carrying it has arrived. - Keep sensitive personal data (health, political opinions and similar) out of attributes used for targeting; stick to plan, role, company size and the like. **Sign user IDs for server-side targeting.** With a *Users* or *Manual* audience, anyone who can run JavaScript on your page could pretend to be another user. To prevent it, create a secret key in the Secret Key section of [Settings → Organization → Access Keys](https://panel.survicate.com/o/0/w/0/settings/organization/access-keys), compute an HMAC-SHA256 of the `user_id` with it on your server, pass the result as `user_key` next to `user_id` (in the web traits, or as a user trait in a mobile app), and turn on **Enforce secret keys for logged-in user targeting**. Once enforced, a `user_id` without a valid `user_key` gets no server-side targeted surveys. Details are in the Help Center article [Securing surveys with secret and user keys](https://help.survicate.com/en/articles/12470514-securing-surveys-with-secret-user-keys). ## 5. Report events Report the actions you want surveys to react to and, in mobile apps, the screens users move through. Event names, property names and values are case-sensitive and must match the panel exactly; property values are strings, and names are up to 255 characters. ### Website or web app ```javascript title="Event with properties" _sva.invokeEvent('checkout_completed', { plan: 'pro', currency: 'EUR' }); ``` Other methods you will reach for: `showSurvey(surveyId)` to show a specific survey regardless of its targeting (with `{ forceDisplay: true }` even to a visitor who already answered it), `closeSurvey()`, `retarget()` to re-run targeting after an asynchronous change in a single-page app (page loads, survey completions and route changes already do), and `addEventListener` for the `survey_displayed`, `question_answered`, `survey_completed` and `survey_closed` events, so your app can react to answers. Wait for the `SurvicateReady` window event before calling methods on `_sva`. For a fully custom UI, hide a survey with `hiddenSurveys` and record answers with `getSurveyPointsMetadata` and `submitAnswer`. All of them are on the [Methods](/javascript/methods) and [Event Listeners](/javascript/events) pages. Methods other than `setVisitorTraits`, and the event listeners, require a plan with JavaScript targeting. ### Mobile app Report each screen when it appears and when it disappears, so surveys can be targeted to screens, and report events the same way as on the web. Listeners for `survey_displayed`, `question_answered`, `survey_completed` and `survey_closed` are available as well. ```swift title="iOS (Swift)" // When the screen appears and disappears SurvicateSdk.shared.enterScreen(value: "checkout") SurvicateSdk.shared.leaveScreen(value: "checkout") // When the user does something a survey should react to SurvicateSdk.shared.invokeEvent(name: "checkout_completed", with: ["plan": "pro", "currency": "EUR"]) ``` ```kotlin title="Android (Kotlin)" // When the screen appears and disappears Survicate.enterScreen("checkout") Survicate.leaveScreen("checkout") // When the user does something a survey should react to Survicate.invokeEvent("checkout_completed", mapOf("plan" to "pro", "currency" to "EUR")) ``` The same calls, with the same names (PascalCase in Unity), on every platform: - iOS: [screens](/mobile-sdk/ios/using-sdk#targeting-a-survey-by-the-screen-name), [events](/mobile-sdk/ios/using-sdk#events-based-survey-targeting), [attributes](/mobile-sdk/ios/using-sdk#user-identification-and-attributes), [listeners](/mobile-sdk/ios/using-sdk#listeners) - Android: [screens](/mobile-sdk/android/using-sdk#targeting-a-survey-by-screen-name), [events](/mobile-sdk/android/using-sdk#events-based-survey-targeting), [attributes](/mobile-sdk/android/using-sdk#user-identification-and-attributes), [listeners](/mobile-sdk/android/using-sdk#event-listeners) - React Native: [screens](/mobile-sdk/react-native/using-sdk#targeting-a-survey-by-screen-name), [events](/mobile-sdk/react-native/using-sdk#events-based-survey-targeting), [attributes](/mobile-sdk/react-native/using-sdk#passing-user-attributes), [listeners](/mobile-sdk/react-native/using-sdk#event-listeners) - Flutter: [screens](/mobile-sdk/flutter/using-sdk#targeting-a-survey-by-screen-name), [events](/mobile-sdk/flutter/using-sdk#events-based-survey-targeting), [attributes](/mobile-sdk/flutter/using-sdk#passing-user-attributes), [listeners](/mobile-sdk/flutter/using-sdk#event-listeners) - Unity: [screens](/mobile-sdk/unity/using-sdk#targeting-a-survey-by-screen-name), [events](/mobile-sdk/unity/using-sdk#events-based-survey-targeting), [attributes](/mobile-sdk/unity/using-sdk#passing-user-attributes), [listeners](/mobile-sdk/unity/using-sdk#event-listeners) ### Triggers and audiences An event can be used in two ways. As a **trigger** (Target → Triggers) the survey fires the moment the event happens, and occurrence counts are kept on the device. As an **audience filter** on a *Users* audience, Survicate stores the event history per `user_id` on its servers, so the filter follows the user across devices; the eligibility check is cached for about five minutes, so the survey may appear with a delay. ## 6. Launch a survey In the panel, whoever owns the survey does the rest, without a deployment: 1. **Create new survey**: start from scratch, a template, a description for the AI, or imported questions, then choose the survey type. It cannot be changed afterwards. 2. **Create**: add questions, branch logic, translations and the design theme. Website surveys can switch between a pop-up and the Feedback Button in the Format tab. 3. **Target**: choose pages (URL rules or regular expressions) or screens, a trigger (on load, after a delay, on exit intent, on an event), the audience (All visitors, All logged-in users, or a Visitors, Users or Manual audience), the frequency (once per respondent by default, or recurring), sampling and, for mobile surveys, the device language, operating system or orientation. 4. **Connect**: turn on integrations and Webhooks for this survey. 5. **Launch**: start now or on a date, optionally with an end date or a response cap. Testing a website survey: use the panel's preview, or test live in a private browsing window, because a website survey is shown to a visitor once by default and the visitor is remembered in Local Storage. Changes to a survey take up to 15 minutes to reach visitors (a couple of minutes for mobile surveys), and server-side audiences add the five-minute cache. `showSurvey(surveyId, { forceDisplay: true })` skips both the targeting and the once-per-visitor rule for a quick check. ## 7. Get the data out - **Webhooks**: in the survey's Connect tab, add your endpoint URL and choose delivery per answer (`questionAnswered`) or per completed response (`surveyCompleted`). Use **Send sample request** to test. A `questionAnswered` delivery carries one question and its answer; a `surveyCompleted` delivery carries all of them in a `questionsAnswered` array. Both include the survey, `responseUuid`, timestamp, page URL and the respondent's attributes. Verify the signature with your [verification token or signing secret](/webhooks/security), and allow the source IPs 3.248.104.12 and 54.171.69.70. Payloads are documented under [Events](/webhooks/events) and [Answer types](/webhooks/answer-types). - **Data Export API**: authenticate with the API key and page through results by following `next_url` until `has_more` is `false`. Responses can be filtered by date range and enriched with the attributes you name in `attributes[]`. Limits: 5 concurrent requests and 1,000 requests per minute per workspace. [Setup](/data-export/setup) explains pagination and attributes; [Survey](/data-export/survey), [Response](/data-export/response), [Respondent](/data-export/respondent) and [Personal Data](/data-export/personal-data) list the endpoints. ```shell title="First requests" curl -H 'Authorization: Basic {{apiKey}}' 'https://data-api.survicate.com/v2/surveys' curl -H 'Authorization: Basic {{apiKey}}' 'https://data-api.survicate.com/v2/surveys/{survey_id}/responses?items_per_page=100' ``` - **Integrations**: for Slack, Microsoft Teams, Google Sheets, HubSpot, Salesforce, Intercom, Amplitude, Mixpanel, BigQuery and other tools, connect the integration in the panel instead of writing code; the Help Center's [Connect integrations](https://help.survicate.com/en/collections/36481-connect-integrations) collection has the setup for each. - **Exports**: CSV and XLSX from a survey's Analyze tab, and PDF or PNG charts. - **Survicate MCP**: connect Claude, ChatGPT, Cursor or Slack to `https://mcp.survicate.com/` to ask questions about the responses, pull scores and draft surveys with your own permissions. See [Connect](/mcp/connect). Webhooks and the Data Export API are included in the Pro and Enterprise plans; the [pricing page](https://survicate.com/pricing/) lists what each plan includes. ## Next steps - [JavaScript SDK installation](/javascript/installation) - [JavaScript SDK methods](/javascript/methods) - [Mobile SDK](/mobile-sdk) - [Data Export API setup](/data-export/setup) - [Webhooks](/webhooks) - [Connect Survicate MCP](/mcp/connect) --- # Survicate MCP Source: https://developers.survicate.com/mcp/ Survicate MCP lets you use Survicate from inside the AI assistant you already work in. Ask Claude what customers said about onboarding and get an answer grounded in your real survey responses, with citations. Say "draft a CSAT survey for the support team" and find the draft waiting in Survicate for you to review and launch. Pull an NPS trend, read what detractors wrote, or check what your research team has already found, all without switching tabs or exporting a single file. It works with Claude, ChatGPT, Cursor, Claude Code, assistants running inside Slack, and any other tool that supports remote MCP servers. MCP (Model Context Protocol) is the open standard that lets AI assistants connect to tools like Survicate. You connect once by signing in to Survicate. There are no API keys to copy. The assistant can only see what you can see in Survicate, and it can never launch a survey or delete anything. ```text title="Server URL" https://mcp.survicate.com/ ``` ## Before you start You need: - A Survicate account with the **User** role or higher in the workspace you want to connect. Guests cannot connect. Only workspaces where you have that role appear when you connect. - An AI assistant that supports custom or remote MCP connectors. Availability can depend on your plan with that assistant. - If your company uses Claude for Teams or Enterprise, or ChatGPT for Teams or Enterprise, an admin on that side usually has to add the connector once before members can use it. The [Connect](/mcp/connect) steps say who does what. - [Connect](/mcp/connect) - [What you can do](/mcp/what-you-can-do) - [Permissions and security](/mcp/security) - [FAQ](/mcp/faq) - [Technical overview](/mcp/technical-overview) --- # Connect Source: https://developers.survicate.com/mcp/connect/ Use the server URL `https://mcp.survicate.com/` wherever your assistant asks for a custom connector, remote MCP server, plugin, or app URL. Then sign in to Survicate when prompted. ## Claude **Personal plan (Pro or Max)** 1. Open **Settings**, then **Connectors**. 2. Choose **Add custom connector**, paste `https://mcp.survicate.com/`, and save. 3. Click **Connect** next to Survicate. A Survicate sign-in window opens. 4. Sign in, pick the workspace you want to connect, and approve. **Team or Enterprise plan** 1. The Claude account **Owner** adds the connector once: **Organization settings**, then **Connectors**, then **Add**, then **Custom**, then **Web**, and pastes `https://mcp.survicate.com/`. 2. Each member then goes to **Customize**, then **Connectors**, finds Survicate, and clicks **Connect**. 3. Each member signs in to Survicate with their own account, picks a workspace, and approves. Full guide with screenshots: [Connect Survicate MCP to Claude](https://help.survicate.com/en/articles/16271857-connect-survicate-mcp-to-claude). ## Claude Code ```bash claude mcp add --transport http survicate https://mcp.survicate.com/ ``` Then run `/mcp` inside Claude Code and follow the sign-in prompt for Survicate. ## ChatGPT 1. An **Owner** or admin turns on **Developer mode** under **Settings**, then **Security and login**. 2. They create a new app, name it **Survicate MCP**, paste `https://mcp.survicate.com/`, and choose **OAuth** as the authentication method. 3. They authorize it: a Survicate sign-in window opens, they sign in and approve. If the list of actions looks empty, refresh it after signing in. 4. They test it in a new chat by enabling **Survicate MCP** in the tools picker and asking about a survey, then click **Publish** so everyone in the workspace can use it. 5. Members then go to **Customize**, then **Plugins**, find Survicate MCP, click **+**, and sign in to Survicate with their own account. Full guide with screenshots: [Connect Survicate MCP to ChatGPT](https://help.survicate.com/en/articles/16271815-connect-survicate-mcp-to-chatgpt). ## Cursor 1. Open **Cursor Settings**, then **MCP**, then **Add new MCP server**. 2. Add the server with this configuration, or paste it into your `mcp.json`: ```json title="mcp.json" { "mcpServers": { "survicate": { "url": "https://mcp.survicate.com/" } } } ``` 3. Click the sign-in prompt that appears next to the server, sign in to Survicate, pick a workspace, and approve. ## Slack The Survicate agent for Slack is set up from Survicate rather than from Slack. Open the **Integrations** tab in your Survicate workspace and follow the Slack steps there. Once it is added to your Slack workspace, anyone in a channel can ask it questions, but each person connects their own Survicate account before it acts on their behalf. ## Other assistants and tools Any tool that supports remote MCP servers with sign-in works the same way: paste `https://mcp.survicate.com/` where it asks for the server URL and complete the Survicate sign-in. Tools that only accept a local command can usually bridge to a remote server with `mcp-remote`: ```text Command: npx Arguments: -y mcp-remote https://mcp.survicate.com/ ``` If you cannot add custom connectors in your tool, ask your internal admin. Most assistants let an administrator allow specific connectors for the whole organization. ## What happens when you connect 1. Your assistant opens a Survicate page in your browser. If you are not signed in to Survicate, you sign in first. 2. You pick **one workspace**. The connection is tied to that workspace. If you work across several, connect again and pick another; most assistants let you keep more than one connection. 3. You see exactly what the assistant will be able to do, grouped into read permissions and the four write actions (draft a survey, start a research project, save a note, archive surveys). Approve to finish. 4. Back in the assistant, Survicate appears as a connected tool. The first time you mention surveys or feedback, the assistant may ask whether it should use Survicate. Say yes. Not sure which workspace is connected? Ask the assistant: "Which Survicate workspace are you connected to?" --- # What you can do Source: https://developers.survicate.com/mcp/what-you-can-do/ Talk to your assistant the way you would talk to a colleague who has Survicate open. It works out which surveys, questions, and research to look at. Here is what people use it for most. ## Find out what customers are actually saying Ask a question in plain language. The answer is built from your collected feedback and cites the responses it draws on. This can take a few minutes for a big workspace; the assistant will keep you posted. > - "What frustrates users most about onboarding?" > - "Why do customers say they cancel? Give me the top three reasons with quotes." > - "Has feedback about pricing changed since we raised prices in June?" ## Get a score or a number > - "What is our NPS for the last 90 days?" > - "How did the checkout survey do last month? Responses, completion rate, and the average rating." > - "Compare the CSAT for support in Q2 and Q3." The assistant can pull one question at a time, so on a long survey it works in batches of about five questions and asks before continuing. Numbers reflect the date range you asked for; say "all time" if that is what you mean. ## Read what detractors, passives, or promoters wrote > - "What did detractors write in the follow-up question of the Q3 NPS survey?" > - "Show me promoter comments that mention the mobile app." ## Check whether you already asked > - "Do we have a survey running about onboarding right now?" > - "Which surveys ask about pricing, and how are the questions worded?" > - "List surveys that have not had a response in the last year." ## Bring your research into the conversation If your team uses Research Hub, the assistant can read your research projects, their cited reports, and the insights extracted from them, and search your saved notes. > - "What does our research say about why trial users do not convert?" > - "Summarize the onboarding research report and list the insights with the strongest evidence." > - "Are there research notes tagged 'pricing' from this year?" It can also start a new research project for you. The analysis runs in Survicate and usually takes 5 to 25 minutes; the assistant gives you a link where you can watch progress and read the report when it is ready. > - "Start a research project on what enterprise customers want from reporting." ## Save what you learned > - "Save this conclusion as a note in Research Hub, tagged 'churn' and 'Q3', with the NPS survey as the source." The note is attributed to you and shows up in Research Hub straight away, so teammates can find it. ## Draft a survey Describe the survey and the assistant creates it in Survicate as a draft, with a link to review it. Nothing is sent. You open it in Survicate, adjust targeting and design if you like, and launch it yourself. > - "Draft a 3-question CSAT survey for our support team." > - "Write a short survey to validate interest in a Slack integration, with one open question at the end." > - "Turn the gaps we just found into a survey for trial users." ## Tidy up your survey list > - "Find surveys with no responses since last year and archive them." The assistant lists the candidates and asks you to confirm before archiving anything. Surveys that are still collecting responses are skipped unless you say to include them, because archiving a live survey stops it collecting. Archived surveys are not deleted; you can restore them from the Survicate panel. ## What it can and cannot do **It can** - Find surveys and questions, and show how a survey is built. - Read results, scores, averages, and the individual answers to open-text questions. - Answer questions across all your feedback, with citations. - Read research projects, reports, insights, and notes in Research Hub. - Draft a new survey, start a research project, save a research note, and archive surveys. **It cannot** - Launch, edit, or delete an existing survey. Drafts wait for you in Survicate. - Delete responses, notes, insights, or research projects. - See surveys or folders you cannot open yourself. - Export files, manage webhooks, or handle data requests. - Change workspace, teammate, plan, or billing settings. - Do anything on your website or in your app. --- # Permissions and security Source: https://developers.survicate.com/mcp/security/ **It acts as you, and only as you.** Every request runs with your Survicate permissions. If you cannot open a folder in Survicate, the assistant cannot see the surveys in it. If your Research Hub role is read-only, the assistant cannot save notes or start projects for you. **One workspace per connection.** You choose the workspace when you approve, and the connection stays bound to it. To work with another workspace, connect again. **No API keys.** You sign in to Survicate and approve on a Survicate screen. Nothing is pasted into the assistant. **Access follows your account.** If you leave the workspace or your account is blocked, the connection stops working within an hour. Changing your password, email, or two-factor setting also ends the connection, and you simply approve it again. For safety, every connection asks for re-approval after 90 days. **Disconnect any time.** Remove Survicate in your assistant's connector or plugin settings. In Claude that is **Customize**, then **Connectors**, then **Connected**; in ChatGPT it is **Customize**, then **Plugins**, then **Uninstall**. **Regulated workspaces stay out.** Workspaces flagged as HIPAA-regulated cannot be connected to AI assistants. **Your data goes to the assistant you chose.** Survicate does not filter or redact what the assistant asks for. It receives the same data you would see in the panel, which can include personal details a respondent typed into an answer. What the assistant's provider does with that data is governed by your agreement with them, so check your company's policy before connecting. **Admin controls.** Survicate does not yet offer a switch to stop members from connecting. Most assistants let an administrator decide which connectors are available, so use that to manage access for now. --- # FAQ Source: https://developers.survicate.com/mcp/faq/ Common questions about connecting and using Survicate MCP. ## Good to know - **Long questions take time.** "Ask across all feedback" can run for a few minutes. Keep the chat open; the assistant shows progress. - **Research projects run in the background.** Creating one returns straight away with a link; the report takes 5 to 25 minutes. - **Confirm before it writes.** Most assistants ask before drafting, archiving, saving, or starting a project. That is by design. - **Fair use.** Each workspace can make about 30 requests a minute across everyone connected. If the assistant says it needs to pause, wait a minute and continue. - **Answers to a question versus responses to a survey.** Fewer people answer any given question than start the survey, because people skip questions. The two numbers are meant to differ. - **Names can be ambiguous.** If two surveys share a name, the assistant lists both and asks which one you mean. ## The assistant does not show Survicate, or the tool list is empty If you are on a Team or Enterprise plan, an admin has to add the connector first. In ChatGPT, refresh the list of actions after signing in to Survicate. If you cannot add custom connectors at all, ask your internal admin to allow it. ## It keeps asking me to sign in to Survicate again That is expected after 90 days, after you change your password, email, or two-factor setting, or if your access to the workspace changed. Approve again and carry on. If it happens repeatedly within minutes, contact support. ## I got "access denied" while connecting The workspace you picked is not one you belong to with the User role or higher, it is a HIPAA-regulated workspace, or MCP is not enabled for it. Try another workspace, or write to support. ## It is looking at the wrong workspace Ask "Which Survicate workspace are you connected to?" Then disconnect and connect again, choosing the right one. Most assistants also let you keep a second connection for another workspace. ## It says it cannot find my survey Give the exact name, or ask it to list surveys first and pick from the list. Surveys in folders you cannot access, and archived surveys, are not shown unless you ask for them. ## The numbers do not match what I see in Survicate Check the date range. Results are bounded by the period you asked about, while the survey list shows all-time totals. Ask again with explicit dates, or say "all time". ## It says it hit a limit or needs to pause Each workspace can make about 30 requests a minute. Wait a moment and ask it to continue. If the assistant mentions a chats limit on the feedback question feature, your organization has used its Research Assistant allowance for the billing period. ## Does it send surveys to my customers? No. It creates drafts only. A person launches the survey from Survicate. ## Can it change or delete my data? It writes in four places: a drafted survey, a new research project, a saved note, and archiving a survey. Archiving is reversible from the Survicate panel. Nothing is ever deleted, and results, responses, reports, and insights stay read-only. ## Can I connect two workspaces? Yes. Each connection is bound to one workspace, so connect once per workspace. Whether you can keep both active at the same time depends on your assistant. ## Does it work with my AI tool? It works with any assistant that supports remote MCP servers with sign-in, including Claude, ChatGPT, Cursor, Claude Code, and assistants inside Slack. Availability may depend on your plan with that assistant. ## Need help? - [What is Survicate MCP?](https://help.survicate.com/en/articles/16271576-what-is-survicate-mcp) - [What can I do with Survicate MCP?](https://help.survicate.com/en/articles/16271782-what-can-i-do-with-survicate-mcp) - [Survicate MCP FAQ](https://help.survicate.com/en/articles/16307629-survicate-mcp-faq) - Email [support@survicate.com](mailto:support@survicate.com) or use the chat in Survicate. --- # Technical overview Source: https://developers.survicate.com/mcp/technical-overview/ Server details and the tools Survicate MCP exposes to AI assistants. ## Server | Property | Value | |---|---| | Server URL | `https://mcp.survicate.com/` | | Transport | MCP Streamable HTTP | | Authentication | OAuth 2.1 with PKCE and dynamic client registration; no API keys | | Scope | One workspace per connection; every call runs as the authorizing user | ## Tools Tools available to the assistant: | Area | Tools | |---|---| | Connection | `get_connection_info` | | Surveys and questions | `list_surveys`, `get_survey`, `list_questions`, `get_question` | | Results | `get_survey_results`, `get_question_results` | | Feedback questions | `ask_feedback` | | Survey management | `create_survey`, `archive_surveys` | | Research Hub | `list_research_projects`, `get_research_project`, `get_research_project_report`, `create_research_project`, `list_research_insights`, `get_research_insight`, `list_research_notes`, `create_research_note` | Survicate MCP does not replace the [REST API](/data-export), [webhooks](/webhooks), or the native integrations, which remain the right tools for exports, synchronization, and automation. --- # Mobile SDK Source: https://developers.survicate.com/mobile-sdk/ The Survicate Mobile SDK allows you to collect feedback from your mobile app users. Installed in your app, the SDK allows you to trigger targeted micro-surveys to understand your users better and collect feedback about product or service you provide. Survicate maintains and supports iOS, Android, React Native, Unity, and Flutter apps. Language bindings are available in Kotlin, Java, Swift and Objective-C. The SDK is maintained and supported by [Survicate - The Customer Experience & Survey Software](https://survicate.com/mobile-surveys/). The documentation walks you through the key features of the SDK, helping you become familiar with what’s available before you begin integrating it with your app. - [iOS SDK](/mobile-sdk/ios) - [Android SDK](/mobile-sdk/android) - [React Native SDK](/mobile-sdk/react-native) - [Flutter SDK](/mobile-sdk/flutter) - [Unity SDK](/mobile-sdk/unity) - [Segment](/mobile-sdk/segment-integration) - [UXCam](/mobile-sdk/uxcam-integration) - [FullStory](/mobile-sdk/full-story-integration) --- # iOS SDK Source: https://developers.survicate.com/mobile-sdk/ios/ The iOS SDK is distributed in a binary version and developed using Swift 5.10. For apps downloaded from the App Store, the Survicate iOS SDK adds ~ 7.2MB to your uncompressed app size on device. Note that the SDK features a Time To Live (TTL) mechanism of 60 seconds. This means any modifications made to your survey will be reflected on your respondents' devices after a delay of up to 60 seconds. ## Requirements - Using Survicate Mobile SDK requires an account at [survicate.com](https://survicate.com). You can create your account [here](https://panel.survicate.com/signup) for free, or become invited to your company account by one of your colleagues. - Survicate SDK version 6.0.0 or higher. - Xcode 16 is required to build iOS SDK. - Respondent's device running iOS 15.0 or above. - [Installation](/mobile-sdk/ios/installation) - [Configuration](/mobile-sdk/ios/configuration) - [Using SDK](/mobile-sdk/ios/using-sdk) - [Changelog](/mobile-sdk/ios/changelog) --- # iOS SDK installation Source: https://developers.survicate.com/mobile-sdk/ios/installation/ There are three ways to install the Survicate Mobile SDK in the iOS applications: ## Installing as Swift Package The recommended installation method. 1. Once your iOS application project is ready, open it in the Xcode and select your project’s Package Dependencies tab 2. Copy the Survicate SDK Swift package repository URL `https://github.com/Survicate/survicate-ios-sdk` into the search field 3. Under the Dependency Rule, select the version of your preference. ![Add Swift Package step 1](/add_package_0.png) 4. After the package download completes, select Add Package. ![Add Swift Package step 2](/add_package_1.png) Survicate SDK should now be listed under Swift Package Dependencies in the Xcode Project Navigator. ## Installing using CocoaPods Define pod in your `Podfile` and run `pod install`. ```ruby title="Podfile" platform :ios, '15.0' target 'MyApp' do pod 'Survicate' end ``` ## Installing manually 1. [Download and extract the Survicate for iOS](https://repo.survicate.com/latest/ios/Survicate.zip) 2. Drag Survicate.framework into your project. Make sure "Copy items if needed" is selected and click Finish. 3. In the target settings for your app, set the Survicate.framework to “Embed & Sign”. You'll find it in the “Frameworks, Libraries, and Embedded Content” section of the “General” tab. --- # iOS SDK configuration Source: https://developers.survicate.com/mobile-sdk/ios/configuration/ The following configuration will require a Workspace Key. You can get your workspace key in the [Access Keys section](https://panel.survicate.com/o/0/w/0/settings/access-keys) of the Survicate panel. 1. Add workspace key to your `Info.plist` file. - Create `Survicate` _Dictionary_. - Define `WorkspaceKey` _String_ in `Survicate` _Dictionary_. This is how your `Info.plist` file should look like: ![Info.plist example](/ios-infoplist.png) As an alternative to the main way of specifying the Workspace Key, you can also use the `setWorkspaceKey()` method. Important: - Using `setWorkspaceKey()` method overrides the Workspace Key defined in the configuration. - `setWorkspaceKey()` method must be used before `init()` method is called. ```swift title="Swift" try? SurvicateSdk.shared.setWorkspaceKey("your_workspace_key") ``` ```objective-c title="Objective-C" NSError *error; [SurvicateSdk shared] setWorkspaceKey:@"your_workspace_key" error: &error]; ``` 2. Initialize the SDK using the `initialize` method. Choose an initialization method described below based on whether your project utilizes 'AppDelegate' class. Make sure that `import Survicate` line exists in all classes where you call SDK methods. ```swift title="Swift" // ... import Survicate class AppDelegate: UIResponder, UIApplicationDelegate { // ... func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { SurvicateSdk.shared.initialize() return true } } ``` ```objective-c title="Objective-C" // ... @import Survicate; @implementation AppDelegate // ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[SurvicateSdk shared] initialize]; return YES; } @end ``` Survicate iOS SDK can be used in SwiftUI projects. If your SwiftUI project doesn't use the `AppDelegate` class, the initialization of the Survicate Mobile SDK can be done in the constructor of the main application class: ```swift title="Initialization in SwiftUI projects, with no AppDelegate class" // ... import Survicate @main struct SwiftUIApp: App { init() { SurvicateSdk.shared.initialize() } // ... } ``` **Enable debug messaging** To enable debug console messages from the SDK, use the `setDebuggable(log:)` method with the desired log level. The SDK provides four log levels: - `.none` - `.error` - `.info` - `.verbose` ```swift title="Swift" SurvicateSdk.shared.setDebuggable(log: .verbose) ``` ```objective-c title="Objective-C" [[SurvicateSdk shared] setDebuggableWithLog:LogLevelVerbose]; ``` This is useful for development and debugging purposes. Make sure to disable it (`.none`) in production builds. --- # Using the iOS SDK Source: https://developers.survicate.com/mobile-sdk/ios/using-sdk/ Survicate allows you to launch precisely targeted surveys inside your app. In Survicate Panel, you'll be able to define conditions that your users have to meet for the surveys to appear. Users matching conditions defined in the Survicate panel will see the survey automatically. Here's a list of conditions you can use to target your surveys: - Name of the screen that a user currently sees - Any application event - User attributes and identities - Device language - Operating system Make sure to list all the screens and events described in your application. Once you got this covered, you or any person responsible for creating and managing surveys will be able to trigger surveys from the Survicate panel with no need for you to update the application. **Warning** The SDK utilizes [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults) to store information used by the targeting engine described in this section. Clearing UserDefaults will cause the targeting system to malfunction; f.e. by showing the same survey twice to a single user. ## Targeting a survey by the screen name A survey can appear when a user is viewing a specific screen. For example, a survey can be triggered to show up on the application's home screen after a user spends more than ten seconds there. To achieve that, you need to send information to Survicate about the user entering and leaving a screen. ```swift title="Swift" // UIKit version class PurchaseSuccessViewController: UIViewController { let SCREEN_KEY: String = "purchaseSuccess" override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) SurvicateSdk.shared.enterScreen(value: SCREEN_KEY) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) SurvicateSdk.shared.leaveScreen(value: SCREEN_KEY) } } // SwiftUI version struct ContentView: View { // ... var body: some View { VStack { // ... } .onAppear { SurvicateSdk.shared.enterScreen(value: "Showcase") } } } ``` ```objective-c title="Objective-C" @implementation PurchaseSuccessViewController - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [[SurvicateSdk shared] enterScreenWithValue:@"purchaseSuccess"]; } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[SurvicateSdk shared] leaveScreenWithValue:@"purchaseSuccess"]; } @end ``` _Screen name is case sensitive. If there's any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Events-based survey targeting You can log custom user events throughout your application. They can later be used in the Survicate panel to trigger your surveys. Your survey will show instantly after an event occurs in your app. ```swift title="Swift" // UIKit version @IBAction func didPressButton(_ sender: Any) { SurvicateSdk.shared.invokeEvent(name: "userPressedPurchase") } // SwiftUI version struct ContentView: View { var body: some View { VStack { Button(action: { // event without properties SurvicateSdk.shared.invokeEvent(name: "userPressedPurchase") // event with properties SurvicateSdk.shared.invokeEvent(name: "userPressedPurchase", with: [ "property1": "value1", "property2": "value2" ]) }) } } } ``` ```objective-c title="Objective-C" - (IBAction)didPressButton:(id)sender { // event without properties [[SurvicateSdk shared] invokeEventWithName:@"userPressedPurchase"]; // event with properties [[SurvicateSdk shared] invokeEventWithName:@"userPressedPurchase" withProperties: @{ @"property1": @"value1", @"property2": @"value2" }]; } ``` _Event name and property keys are case sensitive. If there is any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## User identification & attributes You can pass user attributes to Survicate as an additional layer of information about your users. Attributes can be used to: - Identify respondents (by default survey responses are anonymous). - Target surveys to specific users with Audience filters. - Filter survey results. - Recall information in survey questions (e.g. include user name). ```swift title="Swift" // set a single trait SurvicateSdk.shared.setUserTrait(UserTrait(withName: "userId", value: "YourUserId")) let trait = UserTrait(withName: "firstName", value: "John") SurvicateSdk.shared.setUserTrait(trait) // or multiple traits at once let traits: [UserTrait] = [ UserTrait(withName: "subscription_active", value: true), UserTrait(withName: "my_custom_attribute", value: "value"), UserTrait(withName: "age", value: 18), UserTrait(withName: "purchase_date", value: Date()) ] SurvicateSdk.shared.setUserTraits(traits: traits) ``` ```objective-c title="Objective-C" // Set a single trait [[SurvicateSdk shared] setUserTraitWithName:@"userId" value:@"YourUserId"]; // Set multiple traits at once [[SurvicateSdk shared] setUserTraitsWithNamesAndValues:@{ @"subscription_active": @"true", @"my_custom_attribute": @"value", @"age": @"18", @"purchase_date": @"2024-02-01T11:04:48+01:00"} ]; ``` _Bear in mind that user attributes are cached, you only have to provide them once, e.g. when user logs in, not after each `initialize()`. You can also change their values at any time (which may potentially trigger showing the survey)._ **Attribute types** - **String**: any text, e.g. user name or e-mail. - **Double**: a decimal value. - **Boolean**: a logic value. - **Date**: a `Date` that can be used in date or time interval filters. **Special attributes** - **user_id**: This corresponds to the "Logged-in status" in the panel's Audience filter. A user is considered logged-in when a trait with the "user_id" key has been set on the device, regardless of the value. - **first_name**, **last_name**, **email**: If none of these is specified, a response will be marked as Anonymous in the panel. **Additional notes** - You can freely use custom attribute keys without the need to register them anywhere. - In some panel functionalities (e.g. autocompletion), the attribute key will be available only after a survey response with the given attribute is uploaded (unless the key was added in the panel manually). By that time, the trait is saved only locally on the user's device. - Note that the predefined attribute classes (`UserTrait.userId`, `UserTrait.firstName`, etc.) have been deprecated in version 4.0. Instead, you should use the `UserTrait(withName, value)` constructor. You will find migration details in the deprecation messages. - In objective-c implementation you should use string values for every attribute type (e.g. `@"true"` for boolean attribute). ## Response attributes Response attributes are session-scoped attributes attached to survey responses. Unlike user attributes, they are cleared at the start of each new app session and are sent to Survicate along with the user's survey answers. To update a response attribute, call the method again with the same name and a new value. To clear an attribute, pass an empty string as the value. ```swift title="Swift" // set a single attribute SurvicateSdk.shared.setResponseAttribute(ResponseAttribute(name: "promo_code", value: "SAVE20")) // or multiple attributes at once let attributes: [ResponseAttribute] = [ ResponseAttribute(name: "campaign_id", value: "summer-2024"), ResponseAttribute(name: "age", value: 18.0), ResponseAttribute(name: "subscription_active", value: true), ResponseAttribute(name: "trial_started_at", value: Date()) ] SurvicateSdk.shared.setResponseAttributes(attributes) ``` ```objective-c title="Objective-C" // set a single attribute [[SurvicateSdk shared] setResponseAttribute:[[ResponseAttribute alloc] initWithName:@"promo_code" value:@"SAVE20" provider:nil]]; // or multiple attributes at once NSArray *attributes = @[ [[ResponseAttribute alloc] initWithName:@"campaign_id" value:@"summer-2024" provider:nil], [[ResponseAttribute alloc] initWithName:@"age" value:@"18" provider:nil], [[ResponseAttribute alloc] initWithName:@"subscription_active" value:@"true" provider:nil], [[ResponseAttribute alloc] initWithName:@"trial_started_at" value:@"2024-02-01T11:04:48+01:00" provider:nil] ]; [[SurvicateSdk shared] setResponseAttributes:attributes]; ``` `ResponseAttribute` accepts the following parameters: - **name** (required): The key that identifies the attribute. - **value** (required): The attribute value. Pass an empty string to clear an existing attribute. - **provider** (optional): The name of the external service where this data comes from (e.g., "hubspot", "intercom"). This helps integrations identify and match your survey respondents with their profiles in that service. **Attribute types** - **String**: any text value. - **Double**: a decimal value. - **Boolean**: a logic value. - **Date**: a `Date`. _Note: In Objective-C, `ResponseAttribute` only accepts `String` values._ ## Setting the locale Survicate SDK automatically detects the device locale using `NSLocale.preferredLanguages` and uses it both to choose the translation of a survey and to evaluate any Device language targeting filters. If your app allows users to change the locale independently of the system settings, you can override the default by calling: ```swift title="Swift" SurvicateSdk.shared.setLocale(languageTag) ``` ```objective-c title="Objective-C" [[SurvicateSdk shared] setLocale:@"languageTag"]; ``` The argument must be a valid IETF language tag such as: - A two‑letter ISO 639 code (e.g., "en", "fr") - A three-letter code for languages without the two-letter equivalent (e.g., "haw", "yue") - A language tag with region (e.g., "en-US", "pt-BR") _Note: The specified locale setting applies only to the current application session. To preserve the preference after an app restart, make sure to call `setLocale(...)` again, anytime after `Survicate.init(...)`._ ## Theme mode When your survey has a theme with both light and dark modes, the SDK will select the proper variant following the system setting by default. Optionally, you can enforce a specific theme mode with the `setThemeMode` method: ```swift title="Swift" // light, dark, auto SurvicateSdk.shared.setThemeMode(ThemeMode.auto) ``` ```objective-c title="Objective-C" // ThemeModeLight, ThemeModeDark, or ThemeModeAuto [[SurvicateSdk shared] setThemeMode:ThemeModeAuto]; ``` ## Custom fonts Using the `SurvicateSdk.shared.setFonts` method you can specify custom fonts for survey presentation. You need to provide a PostScript font name for each font style required by the SDK. ```swift title="Swift" let fontSystem = SurvicateFontSystem( regular: "MyFont-Regular", regularItalic: "MyFont-Italic", bold: "MyFont-SemiBold", boldItalic: "MyFont-SemiBoldItalic" ) SurvicateSdk.shared.setFonts(fontSystem) ``` ```objective-c title="Objective-C" SurvicateFontSystem *fontSystem = [[SurvicateFontSystem alloc] initWithRegular:@"MyFont-Regular" regularItalic:@"MyFont-Italic" bold:@"MyFont-SemiBold" boldItalic:@"MyFont-SemiBoldItalic" ]; [SurvicateSdk.shared setFonts:fontSystem]; ``` Font names must be **PostScript font names** — not the file name or display name. > **Note:** > Custom fonts must be registered in your app's `Info.plist` file and included in your bundle before they can be used with `setFonts()`. Unregistered fonts will cause the SDK to fall back to the default Survicate fonts. ## Listeners SDK allows you to utilize event listeners. You may find them useful to trigger actions in your application based on actions performed by respondents. Here's a list of events you can subscribe to: - survey_displayed - occurs when survey is loaded and appears in the User Interface - question_answered - occurs after a question is answered ( Survicate stores incomplete survey submissions ) - survey_closed - occurs when a user closes the survey using the close button - survey_completed - occurs when a user finishes the survey. ```swift title="Swift" class YourClassName{ // ... SurvicateSdk.shared.initialize() SurvicateSdk.shared.addListener(delegate) // ... } extension YourClassName: SurvicateDelegate { func surveyDisplayed(event: SurveyDisplayedEvent) { print("DELEGATE survey_displayed \(event.surveyId)") } func questionAnswered(_ event: QuestionAnsweredEvent) { print("DELEGATE question_answered \(event.surveyId) \(event.questionId) \(event.answer.value)") } func surveyCompleted(event: SurveyCompletedEvent) { print("DELEGATE survey_completed \(event.surveyId)") } func surveyClosed(event: SurveyClosedEvent) { print("DELEGATE survey_closed \(event.surveyId)") } } ``` ```objective-c title="Objective-C" @import Survicate; @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // ... [[SurvicateSdk shared] initialize]; [[SurvicateSdk shared] addListener:self]; // ... } - (void)surveyDisplayedWithEvent:(SurveyDisplayedEvent *)event { NSLog(@"Survey displayed"); } - (void)surveyCompletedWithEvent:(SurveyCompletedEvent *)event { NSLog(@"Survey completed"); } - (void)surveyClosedWithEvent:(SurveyClosedEvent *)event { NSLog(@"Survey closed"); } - (void)questionAnswered:(QuestionAnsweredEvent *)event { NSLog(@"Question answered"); } ``` ### _SurvicateAnswer_ object properties (_QuestionAnsweredEvent.answer_) | Property | Type | Description | |:---------|:-----------|:-----------------------------------------------------------------------------------------------| | type | String | Answer type. One of: ['text', 'single', 'multiple', 'smiley_scale', 'rating', 'csat', 'numerical_scale', 'nps', 'date', 'form', 'matrix', 'button_close', 'button_next', 'button_link']. | | id | Integer | Answer ID. **Applicable only for types: ['single', 'smiley_scale', 'csat', 'rating', 'numerical_scale'].** | | ids | Integer[] | Selected answer IDs. **Applicable only for type = ['multiple'].** | | value | String? | Text representation of an answer, e.g. "Happy" for smiley scale. A `nil` value in case of a skipped question. **Not applicable for call-to-action answers: ['button_close', 'button_next', 'button_link'].** | _Note: We currently support passing the `id`, `ids` and `value` properties only for the cases enlisted in the table above. You can expect to stumble upon answer objects that consist only of the `type` property._ ## Reseting user data for testing purposes If you need to test surveys on your device, the `reset()` method can be useful. It clears all user data stored on the device — including survey views, attributes, and information about answered surveys — as well as the current in-memory state of the SDK. ```swift title="Swift" SurvicateSdk.shared.reset() ``` ```objective-c title="Objective-C" [SurvicateSdk.shared reset]; ``` --- # iOS SDK changelog Source: https://developers.survicate.com/mobile-sdk/ios/changelog/ Releases of the Survicate iOS SDK, newest first. ## 8.3.2 (2026-08-12) #### Fixed - An issue where in some cases locally stored survey data could be cleared on app launch after the SDK was updated. ## 8.3.1 (2026-07-21) #### Fixed - An issue where the randomized order of answer choices could change after a respondent switched the survey language. - An issue where time-based targeting could be evaluated incorrectly. ## 8.3.0 (2026-06-30) #### New - Multiple choice question type has a new answer choice - None of the above. If enabled, it's always displayed at the end of the answer list and deselects other answers. - Contact form question and integrations connection: You can decide whether to use data from the contact form question to identify respondents in integrations. #### Updated - Pin answer: you can now pin any answer to its position during randomization (previously only the last answer could be pinned). ## 8.2.0 (2026-06-12) #### Improved - Backend targeting performance. #### Fixed - Thread safety issues in survey targeting. - An issue where the SDK could show as not installed in the Survicate panel. ## 8.1.2 (2026-05-28) #### Updated - Domain used for backend targeting. #### Fixed - Fixed an issue with the hint message not displaying correctly in the Text question. ## 8.1.1 (2026-05-27) #### Fixed - Fixed an issue with the Text question not displaying correctly. ## 8.1.0 (2026-05-26) #### New - New scale styles are added in the smiley scale question type - filled and outlined - with an option to select a custom color for them. The default scale style is emojis as before. #### Improved - Accessibility in the survey progress bar. ## 8.0.2 (2026-05-11) #### Fixed - An issue where surveys triggered by delayed events could fail to display. ## 8.0.1 (2026-04-29) #### Fixed - A rare crash that could occur when the SDK evaluated survey display conditions while user traits were being updated at the same time. ## 8.0.0 (2026-04-14) #### New - Backend targeting is now available for beta testing. When enabled for your workspace, survey targeting is evaluated server-side so the same respondent won't be targeted twice across different channels (e.g. Web, Mobile) or devices. #### Improved - Surveys are now displayed above app navigation and system alerts. #### Fixed - An issue where Bokmål (nb) and Nynorsk (nn) locale variants were not matched to the Norwegian translation. ## 7.3.0 (2026-03-25) #### New - You can allow respondents to select their preferred survey language. Make sure this option is enabled in the panel and that all required translations are added. #### Fixed - Refined internal persistence architecture to improve thread safety. ## 7.2.0 (2026-03-2) #### New - Response attributes can now be attached to survey responses via `Survicate.setResponseAttributes` method. Use `ResponseAttribute` to pass key-value pairs of type String, Number, Boolean, or Date alongside response data. - SDK fonts are customizable using `SurvicateSdk.shared.setFonts`, allowing surveys to match your app's typography. ## 7.1.1 (2026-02-16) #### Fixed - Restored missing `throws` declaration in `setWorkspaceKey` method to maintain backward compatibility. ## 7.1.0 (2026-02-11) #### New - You can now adjust the survey theme based on your app mode. The supported theme modes are: - auto (default) - light - dark The additional theme version should be added in the panel first. #### Fixed - An issue with scrollview height calculations in Matrix question type. - Refined internal concurrent operations architecture to improve thread safety. ## 7.0.0 (2026-01-20) #### New - New operators available in Audience targeting for all attribute types: - value exists - value doesn't exist - Added workspace key validation during SDK initialization #### Fixed - An issue with setLocale method requiring strict case formatting. Now it accepts locale codes in any case (e.g., zh-tw, zh-TW). - An issue with UI glitch in survey question transition. - An issue with surveys not being shown again after being dismissed by native components. ## 6.4.6 (2026-01-05) #### Fixed - An issue with thread safety causing crashes when accessing deallocated objects. ## 6.4.5 (2025-12-9) #### Fixed - An issue with thread safety causing crashes during concurrent SDK operations. ## 6.4.4 (2025-11-25) #### Improved - Enhanced performance of checkbox selection in multiple answer question type. - Updated data storage handling for better iOS compatibility ## 6.4.3 (2025-10-28) #### Updated - Added mentions for transitive dependencies in LICENSE. - XCFramework is now signed with a distribution certificate. #### Fixed - An issue that prevented the screen delay trigger from firing when enterScreen() was called too soon after SDK initialization. - An issue with screen delay trigger not being scheduled upon enterScreen() call. ## 6.4.2 (2025-09-30) #### Improved - Optimized memory performance. #### Fixed - An issue with surveys new event property operators behavior. ## 6.4.1 (2025-09-15) #### Fixed - An issue preventing listeners from being added at SDK initialization. ## 6.4.0 (2025-09-01) > **Note:** This version contains an issue with backward compatibility of new event property operators. To use the new operators please use version 6.4.2 or later. #### New - More operators are now available for targeting by event properties. Previously, the only option available and applied by default was "equals". Now you can select among these operators: - equals - doesn't equal - contains - doesn't contain - value exists - value doesn't exist #### Improved - Performance optimization by moving some SDK initialization tasks to a background thread. ## 6.3.7 (2025-08-19) #### Fixed - An issue with delayed event triggers conflicting with workspace refresh attempts. ## 6.3.6 (2025-08-13) #### Fixed - An issue with thread-safety causing crashes during concurrent SDK initialization. ## 6.3.5 (2025-07-29) #### Fixed - Resolved a thread safety issue that occurred when loading plist properties from background threads, ensuring proper synchronization and preventing potential crashes during configuration loading. ## 6.3.4 (2025-07-22) #### Fixed - An issue with scroll in `single answer selection` and `multiple answer selection` question types after selecting an answer. ## 6.3.3 (2025-07-18) #### Fixed - An issue with non wrapping description text in `nps`, `rating numerical` and `rating shape` question types. - An issue with submitting answers in `single answer selection`, `nps`, `smiley scale` and `rating` question types when the question is set as mandatory and disclaimer is not present. ## 6.3.2 (2025-07-17) #### Fixed - An issue with resolving survey language based on device language instead of the app language - An issue with submit section visibility in `single answer selection`, `nps`, `smiley scale` and `rating` question types when the question is set as mandatory and disclaimer is present. ## 6.3.1 (2025-05-23) #### Fixed - An issue with invalid response language attribute in analysis tab after using `setLocale()` method. ## 6.3.0 (2025-04-19) #### New - In text question type, it’s now possible to have 1 or 2 follow-up questions generated by AI to clarify the initial answer and collect more details. - Survey language can be changed independently of the app's language by using a new locale-forcing method. - Survey translations and audience language filter now support regional localizations. #### Improved - Accessibility in all question types following the WCAG standard. ## 6.2.0 (2025-03-17) #### New - You can add images to every question type. Available image placement options are above and under the questions. ## 6.1.0 (2025-03-11) #### New - You can add a disclaimer with or without a consent checkbox to all question types. #### Improved - Enhanced support for landscape orientation. #### Fixed - The "has any value" logic condition in Matrix question now applies also to partial and empty answers. ## 6.0.0 (2025-02-18) #### Breaking - SDK requires minimum deployment target of iOS 14. #### New - Survey logic has been split into 2 types - Branch and Display logic. Branch logic includes all the previously available logic settings that allow you to select which question your respondents should see next based on their response to the current question. A new type of logic - Display logic - allows you to decide whether the current question should be shown or not based on the respondents’ answers to the questions earlier in the survey. #### Improved - Surveys are now displayed consecutively, if more than one survey meets the targeting criteria (instantly recurring surveys without event trigger will result in showing the survey in a loop). #### Updated - Removed deprecated event listeners callbacks. - Removed deprecated predefined UserTraits. - Removed deprecated `SurvicateSdk.shared.delegate` property. - Removed deprecated `SurvicateSdk.shared.setApiKey` methods. #### Fixed - An issue with answer selection in `shape` question. ## 5.5.2 (2024-12-20) #### Fixed - Resolved a crash caused by non-thread-safe access to `localizedDescription` during error logging. ## 5.5.1 (2024-12-9) #### Fixed - Resolved an issue where comments were missing in event listeners, ensuring proper event tracking. - Fixed a bug where the submit button was disabled in Smiley Scale questions in some cases. - Addressed an issue with the missing submit button in Multiple answer question type. - Fixed an issue with missing comment field in CSAT question when answer is mandatory. ## 5.5.0 (2024-12-4) #### New - You can now add a comment field to NPS, Smiley scale, Rating scale, Matrix, and Date question types. There is also a comment title available for all comment fields. You can use it to ask a question and give your respondents some context of what you would like to see in the comment. ## 5.4.0 (2024-10-22) #### New - Each question type except Welcome message, Date, and Thank you screen can be set as mandatory or optional. #### Improved - Accessibility features for Matrix question, survey progress indicator, and navigation buttons. ## 5.3.0 (2024-09-12) #### New - Once an event is invoked in the app, its name and property names are also sent to Survicate’s panel now. They will be shown as suggestions when a user configures event targeting of a survey. ## 5.2.0 (2024-09-04) #### New - New conditions are available in event targeting: - Time delay after event occurrence. - Number of event occurrences. - Time of the first occurrence. - Time of the last occurrence. If multiple conditions are applied, all of them should be met for a survey to appear. #### Fixed - Fixed an issue with submit button visibility in single choice question. ## 5.1.2 (2024-07-25) #### Improved - More distinguishable emojis in the 3-choice Smiley scale. #### Fixed - Excessive spacing between Smiley scale emojis in the 3-choice layout. - Issue with non visible Submit button in multiple choice questions. ## 5.1.1 (2024-07-18) #### Fixed - Issue with non-validating fields in form questions. ## 5.1.0 (2024-07-17) #### New - Navigation buttons are available now. When enabled, your survey respondents can go back to the previous questions, see their selected answers, and change them if necessary. #### Fixed - Propagating Matrix answer in `SurvicateAnswer.value` of event listener. - Configuration json will be printed in console only in verbose log level. ## 5.0.0 (2024-06-10) #### New - Matrix question type added. #### Fixed - An issue where `setUserTrait` cleared previously set user traits. ## 4.4.0 (2024-04-30) #### New - New targeting option available - event properties. You can add multiple properties to one event and join them with either “or” or “and” operator. ## 4.3.1 (2024-03-26) #### Fixed - Issue with non triggering questionAnswered delegate method. ## 4.3.0 (2024-03-26) #### New - More flexible survey recurring options are available now. Now you can specify how many days / weeks / months / years should pass before the survey can appear again. It’s also possible to set after how many days / weeks / months / years the survey should stop recurring. - If you run several mobile surveys, now you can use survey throttling settings to specify a time frame that should pass between showing them. Use global throttling to set the same time frame for all your mobile surveys. Or use the survey level throttling to override the global settings and specify a different period before showing a particular survey. ## 4.2.1 (2024-03-25) #### Fixed - Issue with recursive display of non-recurring survey. ## 4.2.0 (2024-03-15) #### New - New targeting filter is available - screen orientation (portrait mode or landscape mode targeting). You can either include or exclude one of the orientation modes. - SDK now supports ISO 8601 date format with milliseconds. ## 4.1.1 (2024-02-15) #### Fixed - Properties of the models in the listener are available within Objective-C. ## 4.1.0 (2024-02-08) #### New - Events like `onSurveyDisplayed`, `onQuestionAnswered`, `onSurveyClosed`, and `onSurveyCompleted` now utilize specific event objects: `SurveyDisplayedEvent`, `QuestionAnsweredEvent`, `SurveyClosedEvent`, `SurveyCompletedEvent`. - The SDK now supports the registration of multiple event listeners. ## 4.0.2 (2024-01-22) #### Fixed - An issue where Thank you screen don't close survey in classic theme. ## 4.0.1 (2024-01-09) #### Improved - Date format in user traits recalling. #### Fixed - A bug where users could see survey more times than specified in recurrence settings if SDK was updated in meantime. ## 4.0.0 (2023-11-30) #### New - User conditions targeting is changed to the audience targeting: create an audience that will be available for usage among all your mobile surveys. - Enable multiple audiences at the same time in one survey if necessary. - User attributes now support not only string values but also numbers, boolean, and datetime values. - New attribute operators are available to support new data types. - Survey audience can be set not only by including a set of respondents who met the required criteria but also by excluding those who should not see the survey. - And / or operators in audience targeting are switchable now: within one attribute filter that has several attributes in it and between different filters. ## 3.0.4 (2023-09-28) #### Fixed - Issue where surveys were not translated when app language was set to dialect. ## 3.0.3 (2023-09-27) #### Fixed - Issue where rating scale question answer ID was missing in listener. ## 3.0.2 (2023-08-21) #### Improved - Not displaying surveys when alerts are visible. ## 3.0.1 (2023-07-31) #### Fixed - Issue with displaying a survey in workspaces with multiple recurring surveys despite meeting all the conditions. ## 3.0.0 (2023-07-25) #### New - New logic settings have been added to all question types (except Welcome message, Date and Thank you screen). #### Fixed - Issue with keyboard animations. ## 2.4.0 (2023-07-11) #### New - Now it's possible to select how to position answer choices in the NPS question: vertically (default option) or horizontally. #### Fixed - An issue with the first question being displayed incorrectly. ## 2.3.1 (2023-06-06) #### Fixed - An issue when it was not possible to filter survey responses by language in the panel. - An issue where after synchronization failure the SDK was not respecting refresh interval. - An issue where submit button on iPad was not displayed correctly. ## 2.3.0 (2023-05-25) #### New - Now while adding introduction or question texts you can recall information from attributes passed to Survicate or from answers to other questions in the survey. ## 2.2.1 (2023-05-9) #### Fixed - Assigning answers to the wrong survey within the same workspace. ## 2.2.0 (2023-05-4) #### New - Surveys can be translated into an app language if a corresponding translation is added in the panel. ## 2.1.2 (2023-04-24) #### Fixed - Bug that caused a crash when calling SDK on multiple threads. ## 2.1.1 (2023-04-12) #### Fixed - Visible hyphen even in the absence of a label in NPS and rating scale. ## 2.1.0 (2023-04-06) #### New - Rating question type added. - Question and introduction texts can be made bold, italics, or hyperlinked. ## 2.0.2 (2023-03-20) #### Fixed - Special characters encoding issue. ## 2.0.1 (2023-03-14) #### Fixed - Disabled dismiss on overlay tap. ## 2.0.0 (2023-03-09) #### New - 21 new design themes. - 2 new survey settings - "Progress bar" and "Remove Survicate branding". - New customization options: add a company's logo or a survey sender's avatar and a greeting message from them. ## 1.8.10 (2023-02-9) #### Improved - Accuracy of survey sampling. #### Fixed - Code causing priority inversion warning to be displayed. ## 1.8.9 (2023-01-24) #### Fixed - Language detection issues. ## 1.8.8 (2023-01-1) #### Updated - Remove character limit from text fields. ## 1.8.7 (2022-12-6) #### Fixed - An issue of not showing the survey on dismissing the view controller. ## 1.8.6 (2022-12-5) #### Fixed - Problem with truncating endings in long answer texts. ## 1.8.5 (2022-11-22) #### Fixed - An issues causing a survey to be displayed repeatedly, when using a delayed display feature. ## 1.8.4 (2022-11-16) #### Fixed - A possible race condition when multiple SDK methods are called at the same time. ## 1.8.3 (2022-09-03) #### Fixed - An issue causing NPS button labels to be displayed in incorrect colors. #### Updated - The minimum iOS version requirement for the respondent's device is now iOS 12. ## 1.8.2 (2022-08-05) #### Fixed - Layout fixes for large displays. - Answers for smiley scale questions could be not stored. ## 1.8.1 (2022-06-14) #### Fixed - Tracking the SDK version for internal purposes. ## 1.8.0 (2022-05-19) #### New - Detailed answer value for the Smile scale question is provided in the Question answered event listener. ## 1.7.3 (2022-05-10) #### Fixed - Survey layout issues. ## 1.7.1 (2022-04-05) #### Fixed - Memory leaks. ## 1.7.0 (2022-03-22) #### New - Survicate Mobile SDK can now be integrated using Swift Package Manager. Please refer to the [installation](/mobile-sdk/installation/) documentation to see, how to integrate Survicate Mobile SDK using Swift Package Manager. ## 1.6.7 (2022-03-15) #### Updated - Improved UI rendering speed, we fixed minor layout glitches and some memory leaks. ## 1.6.6 (2022-03-08) #### Fixed - UI rendering speed and layout glitches. ## 1.6.5 (2022-02-23) #### Fixed - Memory leaks and UI rendering speed. ## 1.6.4 (2022-02-16) #### Fixed - When setting the survey to appear to less than 1% of targeted users, the survey was not displayed. In general, the audience sampling feature in the targeting engine had issues with interpreting numbers with decimal points. ## 1.6.3 (2022-02-04) #### Fixed - In some cases survey settings (TTL) mechanism was not refreshed correctly. #### Updated - Survey settings Time to Live(TTL) reduced to 10 minutes. ## 1.6.2 (2022-01-26) #### Fixed - The `setWorkspaceKey()` method is now working properly, as described in the documentation. ## 1.6.1 (2021-12-08) #### Updated - The minimum Xcode version required to run Survicate Mobile SDK is now: 12.5.1. ## 1.6.0 (2021-11-18) #### New - Surveys can now be set to appear on a recurring basis. This means respondents can answer the same mobile survey again, and again – on a daily, weekly, monthly, or quarterly basis. ## 1.5.8 (2021-10-26) #### New - Scale labels can now be displayed below the smiley scale question. ## 1.5.7 (2021-10-21) #### New - Survey settings Time to Live(TTL) mechanism on respondent's device. The mechanism ensures that the survey settings are up to date on the respondent's side. If the current version of survey settings is older than 60 minutes, the survey configuration is checked for updates. ## 1.5.6 (2021-09-29) #### New - The method `setWorkspaceKey()` allows to specify Survicate workspace key from code. ## 1.5.5 (2021-08-26) #### Fixed - Locales used by SDK were improved to resolve issue related to warning WARNING ITMS-90176 appearing during upload the app using SDK to the AppStore. ## 1.5.4 (2021-08-26) #### Fixed - We restored the minimum iOS version required for the SDK to work to 10.0. ## 1.5.3 (2021-08-23) #### Updated - Survicate iOS SDK is now distributed as an XCFramework binary, making the SDK compatible with Swift 5.x. As a result, the main class of Survicate Mobile SDK had to be renamed. The version **1.5.3** of the Survicate iOS SDK introduces support for binary framework, which causes a minor **backward compatibility break**. Until the version 1.5.3 the main SDK class was called `Survicate`, in the version 1.5.3 that class was renamed to `SurvicateSdk`. The change was introduced to make it possible to distribute Survicate Mobile SDK as the XCFramework binary. ## 1.5.2 (2021-07-23) #### Fixed - Support for using the Survicate Mobile SDK with Swift 5.x. ## 1.5.1 (2021-06-24) #### Updated - Provides support for using the Survicate Mobile SDK with Swift 5.4.1. ## 1.5.0 (2021-06-15) #### New - Multiple choice question are shown as checkboxes instead of radio buttons. - SDK uses currently respondent API v3 endpoints. #### Fixed - The `cornerRadius` extension was renamed in order to avoid conflict in apps that would use SDK. ## 1.4.5 (2021-04-28) #### Updated - Supported Swift version 5.4. ## 1.4.4 (2021-04-19) #### Fixed - An issue that caused targeting by attributes to malfunction in some cases. ## 1.4.3 (2020-12-02) #### Updated - Supported Swift version 5.3.1. ## 1.4.2 (2020-09-23) #### Updated - Supported Swift version 5.3. ## 1.4.1 (2020-09-22) #### New - It's now possible to suppress a survey if other was answered during the current visit to your app. ## 1.4.0 (2020-04-22) #### Updated - Unnecessary spacing on the left side of the question has been removed. #### Fixed - Proper handling of 4xx error codes. - A bug causing surveys not to appear when targeted only at logged in users. - A minor issue causing the survey not to appear when targeted at multiple values of the same attribute. ## 1.3.2 (2020-04-01) #### Updated - Supported Swift version 5.2. ## 1.3.1 (2020-02-11) #### Fixed - SDK listeners – answer object minor fixes. ## 1.3.0 (2020-01-23) #### New - SDK now supports listeners. ## 1.2.0 (2019-12-19) #### New - SDK now supports survey completion rate. #### Fixed - Survey ends after Thank you message and CTA. ## 1.1.5 (2019-10-11) #### Fixed - Surveys layout leaned on right column. ## 1.1.4 (2019-09-25) #### Updated - Supported Swift version 5.1. ## 1.1.3 (2019-09-10) #### Updated - SDK now supports new installation flow. ## 1.1.2 (2019-08-08) #### Fixed - Skip-logic wasn't functioning properly in some cases. - `reset()` method didn't clear user attributes. ## 1.1.0 (2019-04-05) #### Updated - Supported Swift version 5.0. ## 1.0.8 (2019-03-19) #### Fixed - Surveys were sometimes shown on a wrong 'ViewController'. ## 1.0.7 (2019-01-30) #### Fixed - `UserTrait` default constructor was missing. --- # Android SDK Source: https://developers.survicate.com/mobile-sdk/android/ The Survicate Android SDK will increase your APK size by approximately 2MB when obfuscated. Note that the SDK features a Time To Live (TTL) mechanism of 60 seconds. This means any modifications made to your survey will be reflected on your respondents' devices after a delay of up to 60 seconds. ## Requirements - Using Survicate Mobile SDK requires an account at [survicate.com](https://survicate.com). You can create your account [here](https://panel.survicate.com/signup) for free, or become invited to your company account by one of your colleagues. - Survicate SDK version 6.0.0 or higher. - CompileSdk version 35 or higher. - Android Gradle Plugin version 8.6.0 or higher with compatible Gradle version. - Kotlin version 2.0 or higher (if your app uses Kotlin). - Compatibility with [Java 8 language features](https://developer.android.com/studio/write/java8-support). - Respondent's device running Android version 5 or above. - [Installation](/mobile-sdk/android/installation) - [Configuration](/mobile-sdk/android/configuration) - [Using SDK](/mobile-sdk/android/using-sdk) - [Changelog](/mobile-sdk/android/changelog) --- # Android SDK installation Source: https://developers.survicate.com/mobile-sdk/android/installation/ 1. Define `https://repo.survicate.com` Maven repository in one of the following ways: ```groovy title="Groovy" dependencyResolutionManagement { // ... repositories { // ... maven { url 'https://repo.survicate.com' } } } ``` ```kotlin title="Kotlin" dependencyResolutionManagement { // ... repositories { // ... maven { url = uri("https://repo.survicate.com") } } } ``` ```groovy title="Groovy" allprojects { repositories { // ... maven { url 'https://repo.survicate.com' } } } ``` ```kotlin title="Kotlin" allprojects { repositories { // ... maven { url = uri("https://repo.survicate.com") } } } ``` 2. Add Survicate SDK dependency to your app's `build.gradle` file. ```groovy title="Groovy" dependencies { // ... implementation 'com.survicate:survicate-sdk:8.3.1' } ``` ```kotlin title="Kotlin" dependencies { // ... implementation("com.survicate:survicate-sdk:8.3.1") } ``` --- # Android SDK configuration Source: https://developers.survicate.com/mobile-sdk/android/configuration/ The following configuration will require workspace key. You can get your workspace key in the [Access Keys section](https://panel.survicate.com/o/0/w/0/settings/access-keys) of the Survicate panel. 1. Configure your *workspace key* in `AndroidManifest.xml` file. Create meta-data: `com.survicate.surveys.workspaceKey`. ```xml title="AndroidManifest.xml" ``` As an alternative to the main way of specifying the Workspace Key, you can also use the `setWorkspaceKey()` method. Important: * Using `setWorkspaceKey()` method overrides the Workspace Key defined in the configuration. * `setWorkspaceKey()` method must be used before `init()` method is called. ```kotlin title="Kotlin" Survicate.setWorkspaceKey("your_workspace_key") ``` ```java title="Java" Survicate.setWorkspaceKey("your_workspace_key"); ``` 2. Initialize the SDK in your application class using `init()` method. If your project doesn't have a custom application class yet, you'll need to create one. Make sure that your custom application class is defined in `AndroidManifest.xml`. ```kotlin title="Kotlin" import android.app.Application import com.survicate.surveys.Survicate class MyApp : Application() { override fun onCreate() { super.onCreate() Survicate.init(this) } } ``` ```java title="Java" import android.app.Application; import com.survicate.surveys.Survicate; public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); Survicate.init(this); } } ``` **Enable debug messaging** To enable debug logcat messages from the SDK, pass `true` as the second parameter to the `init()` method: ```kotlin title="Kotlin" Survicate.init(this, true) ``` ```java title="Java" Survicate.init(this, true); ``` This is useful for development and debugging purposes. Make sure to disable it in production builds. ## ProGuard / R8 The SDK provides built-in proguard rules, so you don't have to specify them manually. **Included rules** ```text -keep @com.squareup.moshi.JsonQualifier class * -keepattributes InnerClasses,Signature,RuntimeVisible*Annotations,EnclosingMethod -keep public class com.survicate.surveys.entities.** { *; } -keep public class com.survicate.surveys.infrastructure.network.** { *; } -keep public class com.survicate.surveys.infrastructure.serialization.** { *; } -keepclassmembers public class com.survicate.surveys.traits.UserTrait { (...); ; } -keepclassmembers public class com.survicate.surveys.IntegrationPayload{ (...); ; } ``` _The proguard rules listed above were applicable only up to SDK version 6.4.3. Starting from version 7.0.0, the Survicate Android SDK no longer uses any custom proguard rules. However, the SDK depends on [Coil](https://coil-kt.github.io/coil/) and [Kotlinx Serialization](https://github.com/Kotlin/kotlinx.serialization) libraries, which apply some rules by default._ --- # Using the Android SDK Source: https://developers.survicate.com/mobile-sdk/android/using-sdk/ Survicate allows you to launch precisely targeted surveys inside your app. In the Survicate Panel, you can set conditions that need to be met for the surveys to appear. Users matching conditions defined in the Survicate panel will see the survey automatically. Here's a list of conditions you can use to target your surveys: - Name of the screen that a user currently sees - Any application event - User attributes and identities - Device language - Operating system Make sure to list all the screens and events described in your application. Once you got this covered, you or any person responsible for creating and managing surveys will be able to trigger surveys from the Survicate panel with no need for you to update the application. **Warning** Warning The SDK utilizes [SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences) to store information used by the targeting engine described in this section. Clearing SharedPreferences will cause the targeting system to malfunction; f.e. by showing the same survey twice to a single user. ## Targeting a survey by screen name A survey can appear when a user is viewing a specific screen. For example, a survey can be triggered to show up on the application's home screen after a user spends more than ten seconds there. To set it up, you need to send information to Survicate about the user entering and leaving a screen. _Note: Multiple active screens are allowed. In specific, calling enterScreen() does not make the previous screen to be discarded. Be sure to call leaveScreen() when you no longer want the screen to be treated as active._ ```kotlin title="Kotlin" // XML class PurchaseSuccessActivity : Activity() { val SCREEN_NAME = "purchaseSuccess" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... Survicate.enterScreen(SCREEN_NAME) } override fun onDestroy() { super.onDestroy() Survicate.leaveScreen(SCREEN_NAME) } } ``` ```java title="Java" public class PurchaseSuccessActivity extends Activity { public static final String SCREEN_KEY = "purchaseSuccess"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... Survicate.enterScreen(SCREEN_KEY); } @Override protected void onDestroy(){ super.onDestroy(); Survicate.leaveScreen(SCREEN_KEY); } } ``` ```kotlin title="Kotlin" class PurchaseSuccessFragment : Fragment() { val SCREEN_NAME = "purchaseSuccess" override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // ... Survicate.enterScreen(SCREEN_NAME) } override fun onDestroyView() { super.onDestroyView() Survicate.leaveScreen(SCREEN_NAME) } } ``` ```java title="Java" public class PurchaseSuccessFragment extends Fragment { public static final String SCREEN_KEY = "purchaseSuccess"; @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // ... Survicate.enterScreen(SCREEN_KEY); } @Override public void onDestroyView() { super.onDestroyView(); Survicate.leaveScreen(SCREEN_KEY); } } ``` ```kotlin title="Kotlin" const val SCREEN_NAME = "purchaseSuccess" @Composable fun PurchaseSuccessScreen() { DisposableEffect(Unit) { Survicate.enterScreen(SCREEN_NAME) onDispose { Survicate.leaveScreen(SCREEN_NAME) } } } ``` _Screen name is case sensitive. If there's any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Events-based survey targeting Survicate Android SDK allows you to launch surveys based on events your users trigger in your app. Your survey will show instantly after an event occurs in your app. ```kotlin title="Kotlin" // XML button.setOnClickListener { // event without properties Survicate.invokeEvent("eventName") // event with properties val eventProperties = mapOf( "property1" to "value1", "property2" to "value2" ) Survicate.invokeEvent("eventName", eventProperties) } // Jetpack Compose Button( onClick = { // Event without properties Survicate.invokeEvent("eventName") // Event with properties val eventProperties = mapOf( "property1" to "value1", "property2" to "value2" ) Survicate.invokeEvent("eventName", eventProperties) } ) { Text("Click Me") } ``` ```java title="Java" button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // event without properties Survicate.invokeEvent("eventName"); // event with properties Map eventProperties = new HashMap<>(); eventProperties.put("property1", "value1"); eventProperties.put("property2", "value2"); Survicate.invokeEvent("eventName", eventProperties); } }); ``` _Event name and property keys are case sensitive. If there is any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## User identification & attributes You can pass user attributes to Survicate as an additional layer of information about your users. Attributes can be used to: * Identify respondents (by default survey responses are anonymous). * Target surveys to specific users with Audience filters. * Recall information in survey questions (e.g. include user name). * Filter survey results. ```kotlin title="Kotlin" // set a single trait val trait = UserTrait("user_id", "YourUserID") Survicate.setUserTrait(trait) // or multiple traits at once val textTrait = UserTrait("my_custom_attribute", "some value") val numberTrait = UserTrait("age", 18) val booleanTrait = UserTrait("subscription_active", true) val dateTrait = UserTrait("purchase_date", Date()) val traits = listOf( textTrait, numberTrait, booleanTrait, dateTrait ) Survicate.setUserTraits(traits) ``` ```java title="Java" // set a single trait UserTrait trait = new UserTrait("user_id", "YourUserID"); Survicate.setUserTrait(trait); // or multiple traits at once UserTrait textTrait = new UserTrait("my_custom_attribute", "some value"); UserTrait numberTrait = new UserTrait("age", 18); UserTrait booleanTrait = new UserTrait("subscription_active", true); UserTrait dateTrait = new UserTrait("purchase_date", new Date()); List traits = Arrays.asList( textTrait, numberTrait, booleanTrait, dateTrait ); Survicate.setUserTraits(traits); ``` _Bear in mind that user attributes are cached. You only need to provide them once, e.g. when user logs in, not after each `init()`. You can also change their values at any time to trigger a survey._ **Attribute types** - **String**: any text, e.g. user name or e-mail. - **Number**: an integer or decimal. - **Boolean**: a logic value. - **Date**: a `java.util.Date` that can be used in date or time interval filters (the latter measure elapsed time from a given timestamp). **Special attributes** - **user_id**: This corresponds to the "Logged-in status" in the panel's Audience filter. A user is considered logged-in when a trait with the "user_id" key has been set on the device, regardless of the value. - **first_name**, **last_name**, **email**: If none of these is specified, a response will be marked as Anonymous in the panel. **Additional notes** - You can freely use custom attribute keys without the need to register them anywhere. - In some panel functionalities (e.g. autocompletion), the attribute key will be available only after a survey response with the given attribute is uploaded (unless the key was added in the panel manually). By that time, the trait is saved only locally on the user's device. - Note that the predefined attribute classes (`UserTrait.UserId`, `UserTrait.FirstName`, etc.) have been deprecated in version 4.0. Instead, you should use the `UserTrait(key, value)` constructor. You will find migration details in the deprecation messages. ## Response attributes Response attributes are session-scoped attributes attached to survey responses. Unlike user attributes, they are cleared at the start of each new app session and are sent to Survicate along with the user's survey answers. To update a response attribute, call the method again with the same name and a new value. To clear an attribute, pass an empty string as the value. ```kotlin title="Kotlin" // set a single attribute Survicate.setResponseAttribute(ResponseAttribute(name = "promo_code", value = "SAVE20")) // or multiple attributes at once val attributes = listOf( ResponseAttribute(name = "campaign_id", value = "summer-2024"), ResponseAttribute(name = "age", value = 18), ResponseAttribute(name = "subscription_active", value = true), ResponseAttribute(name = "trial_started_at", value = Date()) ) Survicate.setResponseAttributes(attributes) ``` ```java title="Java" // set a single attribute Survicate.setResponseAttribute(new ResponseAttribute("promo_code", "SAVE20")); // or multiple attributes at once List attributes = Arrays.asList( new ResponseAttribute("campaign_id", "summer-2024"), new ResponseAttribute("age", 18), new ResponseAttribute("subscription_active", true), new ResponseAttribute("trial_started_at", new Date()) ); Survicate.setResponseAttributes(attributes); ``` `ResponseAttribute` accepts the following parameters: - **name** (required): The key that identifies the attribute. - **value** (required): The attribute value. Pass an empty string to clear an existing attribute. - **provider** (optional): The name of the external service where this data comes from (e.g., "hubspot", "intercom"). This helps integrations identify and match your survey respondents with their profiles in that service. **Attribute types** - **String**: any text value. - **Number**: an integer or decimal. - **Boolean**: a logic value. - **Date**: a `java.util.Date`. ## Setting the locale Survicate SDK automatically detects the device locale using `Locale.getDefault()` and uses it both to choose the translation of a survey and to evaluate any Device language targeting filters. If your app allows users to change the locale independently of the system settings, you can override the default by calling: ```kotlin title="Kotlin" Survicate.setLocale(languageTag) ``` ```java title="Java" Survicate.setLocale(languageTag); ``` The argument must be a valid IETF language tag such as: - A two‑letter ISO 639 code (e.g., "en", "fr") - A three-letter code for languages without the two-letter equivalent (e.g., "haw", "yue") - A language tag with region (e.g., "en-US", "pt-BR") _Note: The specified locale setting applies only to the current application session. To preserve the preference after an app restart, make sure to call `setLocale(...)` again, anytime after `Survicate.init(...)`._ ## Theme mode When your survey has a theme with both light and dark modes, the SDK will select the proper variant following the system setting by default. Optionally, you can enforce a specific theme mode with the `setThemeMode` method: ```kotlin title="Kotlin" // LIGHT, DARK, or AUTO Survicate.setThemeMode(ThemeMode.DARK) ``` ```java title="Java" // LIGHT, DARK, or AUTO Survicate.setThemeMode(ThemeMode.DARK); ``` ## Custom fonts Using the `Survicate.setFonts` method you can specify custom fonts for survey presentation. You need to provide a font source for each font style required by the SDK. ```kotlin title="Kotlin" val fontSystem = SurvicateFontSystem( regular = FontSource.ResId(R.font.my_font_regular), regularItalic = FontSource.ResId(R.font.my_font_regular_italic), bold = FontSource.ResId(R.font.my_font_bold), boldItalic = FontSource.ResId(R.font.my_font_bold_italic) ) Survicate.setFonts(fontSystem) ``` ```java title="Java" SurvicateFontSystem fontSystem = new SurvicateFontSystem( /* regular */ new FontSource.ResId(R.font.my_font_regular), /* regularItalic */ new FontSource.ResId(R.font.my_font_regular_italic), /* bold */ new FontSource.ResId(R.font.my_font_bold), /* boldItalic */ new FontSource.ResId(R.font.my_font_bold_italic) ); Survicate.setFonts(fontSystem); ``` The font can be provided by a resource ID or an asset path: * `FontSource.ResId` - the Android resource ID of the font located in the `res/font` directory * `FontSource.AssetPath` - the path to the font file relative to the `assets` directory (e.g. "fonts/MyFont.ttf") ## Event listeners SDK allows you to utilize event listeners. You may find them useful to trigger actions in your application based on actions performed by respondents. Here's a list of events you can subscribe to: * survey_displayed - occurs when survey is loaded and appears in the User Interface * question_answered - occurs after a question is answered ( Survicate stores incomplete survey submissions ) * survey_closed - occurs when a user closes the survey using the close button * survey_completed - occurs when a user finishes the survey ```kotlin title="Kotlin" val listener = object : SurvicateEventListener() { override fun onSurveyDisplayed(event: SurveyDisplayedEvent) { Toast.makeText(this@MainActivity, "on survey displayed", Toast.LENGTH_SHORT).show() } override fun onQuestionAnswered(event: QuestionAnsweredEvent) { Toast.makeText(this@MainActivity, "on question answered", Toast.LENGTH_SHORT).show() } override fun onSurveyClosed(event: SurveyClosedEvent) { Toast.makeText(this@MainActivity, "on survey closed", Toast.LENGTH_SHORT).show() } override fun onSurveyCompleted(event: SurveyCompletedEvent) { Toast.makeText(this@MainActivity, "on survey completed", Toast.LENGTH_SHORT).show() } } Survicate.addEventListener(listener) Survicate.removeEventListener(listener) // remember to remove the listener (e.g. in onDestroy) ``` ```java title="Java" SurvicateEventListener listener = new SurvicateEventListener() { @Override public void onSurveyDisplayed(@NonNull SurveyDisplayedEvent event) { Toast.makeText(MainActivity.this, "on survey displayed", Toast.LENGTH_SHORT).show(); } @Override public void onQuestionAnswered(@NonNull QuestionAnsweredEvent event) { Toast.makeText(MainActivity.this, "on question answered", Toast.LENGTH_SHORT).show(); } @Override public void onSurveyClosed(@NonNull SurveyClosedEvent event) { Toast.makeText(MainActivity.this, "on survey closed", Toast.LENGTH_SHORT).show(); } @Override public void onSurveyCompleted(@NonNull SurveyCompletedEvent event) { Toast.makeText(MainActivity.this, "on survey completed", Toast.LENGTH_SHORT).show(); } }; Survicate.addEventListener(listener); Survicate.removeEventListener(listener); // remember to remove the listener (e.g. in onDestroy) ``` _Deprecation note: The `Survicate.setEventListener` method has been deprecated since version 4.1.0. You should use the `addEventListener` and `removeEventListener` methods instead._ **SurvicateAnswer properties (`QuestionAnsweredEvent.answer`)** | Property | Type | Description | |:---------|:----------|:-----------------------------------------------------------------------------------------------| | type | String | Answer type. One of: ['text', 'single', 'multiple', 'smiley_scale', 'rating', 'csat', 'numerical_scale', 'nps', 'date', 'form', 'matrix', 'button_close', 'button_next', 'button_link']. | | id | Long? | Answer ID. **Applicable only for types: ['single', 'smiley_scale', 'csat', 'rating', 'numerical_scale'].** | | ids | Set<Long>? | Selected answer IDs. **Applicable only for type = ['multiple'].** | | value | String? | Text representation of an answer, e.g. "Happy" for smiley scale. A `null` value in case of a skipped question. **Not applicable for call-to-action answers: ['button_close', 'button_next', 'button_link'].** | _The `id`, `ids` and `value` properties are provided only for the cases enlisted in the table above. Therefore, expect that there might be answer objects that consist only of the `type` property._ ## Reseting user data for testing purposes If you need to test surveys on your device, the `reset()` method can be useful. It clears all user data stored on the device — including survey views, attributes, and information about answered surveys — as well as the current in-memory state of the SDK. ```kotlin title="Kotlin" Survicate.reset() ``` ```java title="Java" Survicate.reset(); ``` --- # Android SDK changelog Source: https://developers.survicate.com/mobile-sdk/android/changelog/ Releases of the Survicate Android SDK, newest first. ## 8.3.1 (2026-07-21) #### Fixed - An issue where screen readers announced an optional comment field as "required". - Screen reader focus landing on the whole question instead of the comment field. - An issue where the text cursor could move to the first input on the page after the survey language was changed. ## 8.3.0 (2026-06-30) #### New - Multiple choice question type has a new answer choice - None of the above. If enabled, it's always displayed at the end of the answer list and deselects other answers. - Contact form question and integrations connection: You can decide whether to use data from the contact form question to identify respondents in integrations. #### Updated - Pin answer: you can now pin any answer to its position during randomization (previously only the last answer could be pinned). ## 8.2.0 (2026-06-12) #### Improved - Backend targeting performance. #### Fixed - A bug where the layout direction was not applied after screen rotation when the device's default locale was overridden. ## 8.1.1 (2026-05-28) #### Updated - Domain used for backend targeting. ## 8.1.0 (2026-05-26) #### New - New scale styles are added in the smiley scale question type - filled and outlined - with an option to select a custom color for them. The default scale style is emojis as before. #### Improved - Accessibility in the survey progress bar. ## 8.0.1 (2026-05-11) #### Fixed - Answer order is now preserved across device configuration changes when "Randomize answers" is enabled. - Accessibility focus of Smiley scale icons on Android versions prior to 8.0 (API < 26). ## 8.0.0 (2026-04-14) #### New - Backend targeting is now available for beta testing. When enabled for your workspace, survey targeting is evaluated server-side so the same respondent won't be targeted twice across different channels (e.g. Web, Mobile) or devices. #### Fixed - An issue where Bokmål (`nb`) and Nynorsk (`nn`) locale variants were not matched to the Norwegian translation. ## 7.3.0 (2026-03-25) #### New - You can allow respondents to select their preferred survey language. Make sure this option is enabled in the panel and that all required translations are added. #### Updated - The SDK now requires Kotlin 2.0+ and compileSdk 35 or higher. - Kotlin to 2.1.21 - Kotlinx Coroutines Android to 1.10.2 - Kotlinx Serialization JSON to 1.8.1 - AndroidX Lifecycle Process to 2.9.4 - AndroidX RecyclerView to 1.4.0 ## 7.2.0 (2026-03-02) #### New - Response attributes can now be attached to survey responses via `Survicate.setResponseAttributes` method. Use `ResponseAttribute` to pass key-value pairs of type String, Number, Boolean, or Date alongside response data. - SDK fonts are customizable using `Survicate.setFonts`, allowing surveys to match your app's typography. ## 7.1.1 (2026-02-16) #### New - You can now adjust the survey theme based on your app mode. The supported theme modes are: - auto (default) - light - dark The additional theme version should be added in the panel first. #### Fixed - An issue with `Powered by Survicate` logo scaling. ## 7.0.0 (2026-01-20) #### New - New operators available in Audience targeting for all attribute types: - value exists - value doesn't exist - Added workspace key validation during SDK initialization. #### Updated - Removed Moshi dependency. ## 6.4.3 (2025-12-09) #### Improved - The Shape Rating horizontal layout on very narrow devices, ensuring all five items fit on the screen. ## 6.4.2 (2025-10-28) #### Fixed - An issue that prevented the screen delay trigger from firing when `enterScreen()` was called too soon after SDK initialization. ## 6.4.1 (2025-09-30) #### Fixed - An issue with surveys new event property operators behavior. ## 6.4.0 (2025-09-01) > **Note:** This version contains an issue with backward compatibility of new event property operators. To use the new operators please use version 6.4.1 or later. #### New - More operators are now available for targeting by event properties. Previously, the only option available and applied by default was "equals". Now you can select among these operators: - equals - doesn't equal - contains - doesn't contain - value exists - value doesn't exist ## 6.3.3 (2025-08-21) #### Improved - Performance optimization by moving some SDK initialization tasks to a background thread. ## 6.3.2 (2025-08-19) #### Fixed - An issue where an instantly recurring survey with a delayed event trigger could reappear after being closed in long app sessions. #### Updated - AndroidX AppCompat to 1.7.1 - AndroidX Autofill to 1.3.0 - Added OkHttp 4.12.0 dependency - Added AndroidX Lifecycle Process 2.8.7 dependency ## 6.3.1 (2025-06-11) #### Improved - Horizontal layout for Shape and Numerical Rating questions to fit the screen width even on smaller devices. ## 6.3.0 (2025-05-19) #### New - In text question type, it’s now possible to have 1 or 2 follow-up questions generated by AI to clarify the initial answer and collect more details. - Survey language can be changed independently of the app's language by using a new locale-forcing method. - Survey translations and audience language filter now support regional localizations. #### Improved - Accessibility in all question types following the WCAG standard. - Nested scrolling in input fields for Text questions and comments. #### Fixed - Legend text alignment and item spacing in Rating and NPS questions for right-to-left languages. - The footer's logo placement in RTL layout. #### Updated - AndroidX ConstraintLayout to 2.2.1 - Added AndroidX Autofill 1.1.0 dependency to support autofill in Form fields ## 6.2.0 (2025-03-17) #### New - You can add images to every question type. Available image placement options are above and under the questions. ## 6.1.0 (2025-03-11) #### New - You can add a disclaimer with or without a consent checkbox to all question types. #### Improved - Enhanced support for landscape orientation. #### Fixed - The "has any value" logic condition in Matrix question now applies also to partial and empty answers. ## 6.0.0 (2025-02-18) #### Breaking - SDK requires CompileSDK 34 or higher #### New - Survey logic has been split into 2 types - Branch and Display logic. Branch logic includes all the previously available logic settings that allow you to select which question your respondents should see next based on their response to the current question. A new type of logic - Display logic - allows you to decide whether the current question should be shown or not based on the respondents’ answers to the questions earlier in the survey. #### Improved - Surveys are now displayed consecutively, if more than one survey meets the targeting criteria (instantly recurring surveys without event trigger will result in showing the survey in a loop). - Improved animation on survey close and completion. #### Updated - Removed deprecated event listeners callbacks - Removed deprecated predefined UserTraits - Removed deprecated `SurvicateSdk.setEventListener` and `SurvicateSdk.changeWorkspaceKey` methods - AndroidX AppCompat to 1.7.0 - AndroidX ConstraintLayout to 2.2.0 - AndroidX Transition to 1.5.1 - Moshi to 1.15.2 - Coil to 2.7.0 ## 5.5.1 (2024-12-19) #### Fixed - An issue with the Android `getNetworkCapabilities` method that could occasionally cause exceptions during SDK initialization. ## 5.5.0 (2024-12-04) #### New - You can now add a comment field to NPS, Smiley scale, Rating scale, Matrix, and Date question types. There is also a comment title available for all comment fields. You can use it to ask a question and give your respondents some context of what you would like to see in the comment. #### Updated - AndroidX Annotation to 1.9.1 - Coroutines Android to 1.9.0 ## 5.4.0 (2024-10-22) #### New - Each question type except Welcome message, Date, and Thank you screen can be set as mandatory or optional. #### Improved - Accessibility features for Matrix question, survey progress indicator, and navigation buttons. ## 5.3.0 (2024-09-12) #### New - Once an event is invoked in the app, its name and property names are also sent to Survicate’s panel now. They will be shown as suggestions when a user configures event targeting of a survey. ## 5.2.0 (2024-09-04) #### New - New conditions are available in event targeting: - Time delay after event occurrence. - Number of event occurrences. - Time of the first occurrence. - Time of the last occurrence. If multiple conditions are applied, all of them should be met for a survey to appear. ## 5.1.1 (2024-07-25) #### Improved - More distinguishable emojis in the 3-choice Smiley scale. #### Fixed - Excessive spacing between Smiley scale emojis in the 3-choice layout. - Back button icon color on dark backgrounds. - An issue where "Submit" was displayed instead of "Start Survey" on the welcome CTA point after navigating back to it. ## 5.1.0 (2024-07-17) #### New - Navigation buttons are available now. When enabled, your survey respondents can go back to the previous questions, see their selected answers, and change them if necessary. #### Improved - Higher resolution of Smiley scale icons. #### Fixed - Propagating Matrix answer in `SurvicateAnswer.value` of event listener. - An issue that resulted in unexpected vertical padding for Matrix question in full screen mode. ## 5.0.0 (2024-06-10) #### New - Matrix question type added. #### Updated - AndroidX Annotation to 1.8.0 - Coroutines Android to 1.8.1 #### Fixed - UI state bugs related to Activity's configuration changes. - Animation resource names that could conflict with resources of the app or other libraries. ## 4.4.0 (2024-04-30) #### New - New targeting option available – event properties. You can add multiple properties to one event and join them with either “or” or “and” operator. Property names and values are case-sensitive. Only string values are supported. #### Updated - AndroidX Annotation to 1.7.1 - Coroutines Android to 1.8.0 - Moshi to 1.15.1 #### Fixed - A bug that could prevent a survey from being displayed if a delay was set for multiple screens in the panel. - Horizontal mode support for Numerical Rating question for up to 5 items. ## 4.3.0 (2024-03-26) #### New - More flexible survey recurring options are available now. You can specify how many days / weeks / months / years should pass before the survey can appear again. It’s also possible to set after how many days / weeks / months / years the survey should stop recurring. - If you run several mobile surveys, you can use survey throttling settings to specify a time frame that should pass between showing them. Use global throttling to set the same time frame for all your mobile surveys, or use survey level throttling to override the global settings and specify a different period before showing a particular survey. ## 4.2.0 (2024-03-15) #### New - New targeting filter available – screen orientation (portrait mode or landscape mode targeting). You can either include or exclude one of the orientation modes. ## 4.1.1 (2024-02-26) #### Improved - Performance enhancements in answers synchronization. - Support for the milliseconds part when parsing ISO date-time strings within a UserTrait. ## 4.1.0 (2024-02-08) #### New - Events like `onSurveyDisplayed`, `onQuestionAnswered`, `onSurveyClosed`, and `onSurveyCompleted` now utilize specific event objects: `SurveyDisplayedEvent`, `QuestionAnsweredEvent`, `SurveyClosedEvent`, `SurveyCompletedEvent`. - The SDK now supports the registration of multiple event listeners. #### Updated - Reverted Coil to version 2.4.0 for better compatibility with cross-platforms (compileSdk 34 is no longer required). #### Fixed - An issue where `SurveyActivity` could crash when it was restored after process termination. - A race condition in the recalling feature. ## 4.0.2 (2024-01-09) This version requires `compileSdkVersion` to be at least 34. If you are not ready to use API level 34, please stay on Survicate version 3.0.4. #### Improved - Date format in user traits recalling. #### Fixed - A bug where users could see the survey more times than specified in recurrence settings if the SDK was updated in the meantime. - Sending user attributes to the backend only when necessary. ## 4.0.1 (2023-12-11) This version requires `compileSdkVersion` to be at least 34. If you are not ready to use API level 34, please stay on Survicate version 3.0.4. #### Updated - Use `NetworkCapabilities` to check internet connection (API 24+). - Migrate to `WindowCompat` APIs for setting full-screen background. #### Fixed - Issue with recurring period calculation. ## 4.0.0 (2023-11-30) This version requires `compileSdkVersion` to be at least 34. If you are not ready to use API level 34, please stay on Survicate version 3.0.4. #### New - User conditions targeting is changed to audience targeting: create an audience that will be available for usage among all your mobile surveys. Enable multiple audiences at the same time in one survey if necessary. - User attributes now support not only string values but also numbers, boolean, and datetime values. - New attribute operators are available to support new data types. - Survey audience can be set not only by including a set of respondents who met the required criteria but also by excluding those who should not see the survey. - AND/OR operators in audience targeting are switchable now: within one attribute filter that has several attributes in it and between different filters. #### Fixed - Fixed invalid survey closing when the app has specified `android:enableOnBackInvokedCallback="true"` in the `AndroidManifest.xml`. ## 3.0.6 (2023-11-28) #### Updated - This version requires `compileSdkVersion` to be at least 34. If you are not ready to use API level 34, please stay on Survicate version 3.0.4. - Creating User Trait requires a non-null key. - Added a Proguard rule for User Traits. #### Fixed - An issue with saving User Traits that could cause a crash whenever the saved User Trait key was null. ## 3.0.5 (2023-11-20) #### Updated - This version requires `compileSdkVersion` to be at least 34. If you are not ready to use API level 34, please stay on Survicate version 3.0.4. - AGP to 8.1.2 - Kotlin to 1.9.10 - AndroidX RecyclerView to 1.3.2 - Coil to 2.5.0 #### Fixed - An issue where answers saved without internet were not synchronized in the next app sessions. - An issue with javadoc generation. ## 3.0.4 (2023-10-25) #### Updated - Android TargetSdk to 33 - AndroidX AppCompat to 1.6.1 - AndroidX RecyclerView to 1.3.1 - AndroidX Annotation to 1.7.3 - Moshi to 1.15.0 - Coil to 2.4.0 #### Fixed - An issue where `workspaceKey` metadata was not provided in `AndroidManifest.xml` would cause a crash. ## 3.0.3 (2023-09-27) #### Fixed - Added image scaling to shapes rating questions to fit all answers on the screen in horizontal layout. - Fixed issue on Thank You question with the button's title not using text from survey settings. ## 3.0.2 (2023-08-11) #### Fixed - Issue where in some cases the survey was not dismissible. ## 3.0.1 (2023-08-08) #### Updated - AGP version to 8.1.0 - Gradle version to 8.1.1 - Kotlin version to 1.8.22 - Removed Material Design dependency ## 3.0.0 (2023-07-25) #### New - New logic settings have been added to all question types (except Welcome message, Date, and Thank you screen). ## 2.4.0 (2023-07-11) #### New - Now it's possible to select how to position answer choices in the NPS question: vertically (default option) or horizontally. #### Fixed - An issue in recurring surveys where in some cases survey progress was calculated incorrectly. - Adjusted text color for NPS descriptions in the classic theme. - Adjusted text color for forms disclaimer in the classic theme. ## 2.3.2 (2023-06-06) #### Fixed - An issue when it was not possible to filter survey responses by language in the panel. - An issue where after synchronization failure the SDK was not respecting the refresh interval. - An issue in rating scale questions where in some cases the UI was not displayed correctly. ## 2.3.1 (2023-05-25) #### Fixed - An issue where recalling fallback value was not respected when the related text answer is blank. ## 2.3.0 (2023-05-25) #### New - Now while adding introduction or question texts, you can recall information from attributes passed to Survicate or from answers to other questions in the survey. #### Updated - Updated Moshi to 1.13.0. #### Fixed - An issue that could cause an ANR during SDK initialization. ## 2.2.0 (2023-05-04) #### New - Surveys can be translated into an app language if a corresponding translation is added in the panel. #### Fixed - On SDK initialization, the survey cache is cleared now, and only surveys fetched from the server are shown. ## 2.1.1 (2023-04-18) #### Updated - Close animation for standard theme surveys. #### Fixed - An issue where one survey in a session flag was not respected. - An issue where the survey delay trigger timer was restarted after any other screen or event was triggered. ## 2.1.0 (2023-04-06) #### New - Rating question type added. - Question and introduction texts can be made bold, italic, or hyperlinked. - New look of a date picker in the date question type. ## 2.0.1 (2023-03-14) #### Updated - Updated Proguard rules. #### Improved - When using R8, Proguard rules are included automatically. ## 2.0.0 (2023-03-09) #### New - 21 new design themes. - 2 new survey settings – “Progress bar” and “Remove Survicate branding”. - New customization options: add a company's logo or a survey sender's avatar and a greeting message from them. ## 1.7.7 (2023-02-14) #### Improved - Accuracy of survey sampling. ## 1.7.6 (2023-01-17) #### Updated - Removed character limit from text fields. ## 1.7.5 (2023-01-09) #### Updated - Removed explicit setting of `usesCleartextTraffic` flag in Survicate SDK manifest file. ## 1.7.4 (2022-10-25) #### Fixed - An issue causing concurrency-related exceptions when initializing Survicate. ## 1.7.3 (2022-10-12) #### Fixed - An issue in Single Answer Question where in some cases switching from an answer with a comment with focus on input to an answer without a comment would cause a crash. - An issue where surveys with triggering by screen and events would not show. ## 1.7.2 (2022-09-20) #### Fixed - An issue causing NPS button labels to be displayed in incorrect colors. ## 1.7.1 (2022-09-14) #### Fixed - An issue causing concurrency-related exceptions when processing survey data. - Memory leak when closing a survey. ## 1.7.0 (2022-09-07) #### Fixed - An issue causing exceptions on Android 6 and lower. #### Updated - The minimum supported version of Android changed to 5 (API 21). ## 1.6.5 (2022-08-04) #### Fixed - An issue causing concurrency-related exceptions when responses were processed to the server. - Answers for smiley scale questions could not be stored. #### Updated - Removed TLSv1.1 and added TLSv1.3 support. ## 1.6.3 (2022-06-15) #### Fixed - Tracking the SDK version for internal purposes. - A bug causing the SDK to send a single answer multiple times in some edge case scenarios. ## 1.6.1 (2022-05-27) #### Fixed - A bug causing the SDK to crash when using custom audience targeting. ## 1.6.0 (2022-05-20) #### New - Detailed answer value for the Smile scale question is provided in the Question answered event listener. ## 1.5.15 (2022-05-17) #### Fixed - A bug causing the SDK to crash when using event-based targeting in some particular cases. ## 1.5.14 (2022-04-25) #### Fixed - Memory leaks on the Survicate SDK backend communication. ## 1.5.13 (2022-04-13) #### Fixed - Crash in landscape mode on the NPS screen. ## 1.5.12 (2022-03-21) #### Fixed - ProGuard configuration has been improved to avoid exceptions. ## 1.5.11 (2022-03-18) #### Fixed - A bug causing the SDK to crash when using event-based targeting in some particular cases. ## 1.5.10 (2022-03-15) #### Fixed - In some cases, it was possible that the survey would reappear to some respondents when it shouldn’t. ## 1.5.9 (2022-03-03) #### Updated - Version of Gradle used to build the SDK is now bumped to 7.2. ## 1.5.8 (2022-02-18) #### Fixed - When setting the survey to appear to less than 1% of targeted users, the survey was not displayed. - The audience sampling feature in the targeting engine had issues with interpreting numbers with decimal points. ## 1.5.7 (2022-02-04) #### Fixed - ProGuard configuration has been improved to avoid exceptions. #### Updated - Survey settings Time to Live (TTL) reduced to 10 minutes. ## 1.5.6 (2022-01-20) #### Fixed - In some cases, loading survey data from device storage caused the application to crash. ## 1.5.5 (2022-01-13) #### Fixed - In some cases, using survey background overlay caused the application to crash. ## 1.5.3 (2021-12-10) #### Updated - Improved initialization time on the Survicate SDK startup. ## 1.5.2 (2021-12-03) #### Fixed - Memory leaks and initialization time on the Survicate SDK startup. ## 1.5.1 (2021-12-02) #### Fixed - In some scenarios, respondents were asked to answer only the last survey question. ## 1.5.0 (2021-11-18) #### New - Surveys can now be set to appear on a recurring basis. Respondents can answer the same mobile survey again and again on a daily, weekly, monthly, or quarterly basis. #### Fixed - Crashing caused by missing overlay theme. ## 1.4.5 (2021-10-26) #### New - Scale labels can now be displayed below the smiley scale question. ## 1.4.4 (2021-10-21) #### New - Survey settings Time to Live (TTL) mechanism on the respondent's device. The mechanism ensures that the survey settings are up to date on the respondent's side. If the current version of survey settings is older than 60 minutes, the survey configuration is checked for updates. #### Fixed - Memory leaks on the list-based questions views. ## 1.4.3 (2021-09-30) #### Fixed - A bug causing the SDK to crash when the survey was about to appear in some cases. ## 1.4.2 (2021-09-29) #### New - The method `setWorkspaceKey()` allows specifying the Survicate workspace key from code. ## 1.4.1 (2021-09-23) #### New - Native support for Android X. #### Fixed - ProGuard configuration has been improved to avoid exceptions. Please refer to the [documentation](/mobile-sdk/pro_guard/) to see how to configure the Survicate SDK with ProGuard. ## 1.3.0 (2021-06-15) #### New - SDK uses the current respondent API v3 endpoints. ## 1.2.5 (2021-03-24) #### Fixed - Visual bugs with padding and font size on CTA questions. ## 1.2.4 (2021-01-29) #### Fixed - A bug causing the SDK to malfunction when it was initialized multiple times. ## 1.2.3 (2020-12-23) #### Fixed - When tapping two answers simultaneously, the SDK crashed on some devices. ## 1.2.2 (2020-09-22) #### New - It’s now possible to suppress a survey if another was answered during the current visit to your app. ## 1.2.1 (2020-06-17) #### Fixed - A bug causing the SDK to crash when the “Survey invitation” question had “next step” logic branching configured. ## 1.2.0 (2020-04-22) #### Fixed - A bug causing surveys not to appear when targeted only at logged-in users. - A minor issue causing the survey not to appear when targeted at multiple values of the same attribute. ## 1.1.2 (2020-03-05) #### Fixed - Minor bug causing issues when targeting with user traits. - Proper handling of 4xx error codes. #### Updated - Unnecessary spacing on the left side of the question has been removed. #### New - It's now possible to clear user traits by setting them to a `null` value. ## 1.1.1 (2020-02-11) #### Fixed - SDK listeners – answer object fixes. ## 1.1.0 (2020-01-24) #### New - SDK now supports listeners. ## 1.0.19 (2019-12-23) #### New - SDK now supports survey completion rate. ## 1.0.18 (2019-12-19) #### Fixed - Survey ends after the Thank You message and CTA. ## 1.0.17 (2019-09-04) #### Updated - SDK now supports a new installation flow. ## 1.0.16 (2019-08-12) #### Fixed - Survey close counters weren't functioning properly in some cases. ## 1.0.15 (2019-08-08) #### Fixed - The `reset()` method didn't clear user attributes. ## 1.0.14 (2019-08-07) #### Fixed - Targeting surveys using multiple user attributes wasn't working. ## 1.0.13 (2019-06-05) #### Fixed - Building a React Native project couldn't be completed in some cases. ## 1.0.12 (2019-04-01) #### Fixed - Survey logic was broken when the next step was set up to "Finish". ## 1.0.11 (2019-03-20) #### Fixed - Targeting over screen name didn't work when screen delay was set up. ## 1.0.10 (2019-03-08) #### Fixed - View & response counters weren't functioning properly in some cases. --- # React Native SDK Source: https://developers.survicate.com/mobile-sdk/react-native/ The Survicate React Native SDK will increase your APK size by approximately 2.5MB when obfuscated and your IPA size by approximately 2.1 MB. Note that the SDK features a Time To Live (TTL) mechanism of 60 seconds. This means any modifications made to your survey will be reflected on your respondents' devices after a delay of up to 60 seconds. ## Requirements - Using Survicate Mobile SDK requires an account at [survicate.com](https://survicate.com). You can create your account [here](https://panel.survicate.com/signup) for free, or become invited to your company account by one of your colleagues. - Your React Native application can be used in Expo and React Native CLI. Please note that due to custom native code in this package "Expo Go" is not available. - Survicate SDK version 4.0.0 or higher. - Additionally, please check [iOS](/mobile-sdk/ios/) and [Android](/mobile-sdk/android/) library requirements, as they're applicable too. ## Recommendations - We recommend using React Native version 0.70.0 or higher. > **Note:** > #### Apps using Survicate SDK after 1st March 2026: > > React Native: > > - Survicate SDK version 6.0.0 or higher (required). > - React Native version 0.75.0 or higher (recommended). > > Android: > > - CompileSdk version 35 or higher (required). > - Android Gradle Plugin version 8.6.x or higher with compatible Gradle version (required). > - Kotlin version 2.0 or higher (required). > > iOS: > > - Respondent's device running iOS 15.0 or higher (required). - [Installation](/mobile-sdk/react-native/installation) - [Configuration](/mobile-sdk/react-native/configuration) - [Using SDK](/mobile-sdk/react-native/using-sdk) - [Changelog](/mobile-sdk/react-native/changelog) --- # React Native SDK installation Source: https://developers.survicate.com/mobile-sdk/react-native/installation/ ## React Native CLI Mobile SDK is compatible with React Native apps. Use [these](https://github.com/survicate/survicate-react-native-sdk) React Native bindings to install Mobile SDK in your app. To install run: `npm install @survicate/react-native-survicate --save` To create linking for iOS and Android in your react native app run `react-native link @survicate/react-native-survicate` _Note: Our bindings are compatible with the Autolinking feature introduced in React Native 0.60, so there is no need to run this command on 0.60 and newer versions._ **Android** You need to add the Survicate Maven repository to your project `build.gradle` located under `android` directory. ```groovy title="Project's build.gradle" allprojects { repositories { // ... maven { url 'https://repo.survicate.com' } } } ``` **iOS** Run `pod update` in your `ios` directory after adding the dependency. ## Expo To use @survicate/react-native-survicate in an Expo managed project, use npm, yarn or expo-cli. ```sh expo install @survicate/react-native-survicate ``` --- # React Native SDK configuration Source: https://developers.survicate.com/mobile-sdk/react-native/configuration/ ## Configuration for Android Configure your *workspace key* in `AndroidManifest.xml` file. ```xml title="AndroidManifest.xml" ``` ## Configuration for iOS Add workspace key to your `Info.plist` file. - Create `Survicate` *Dictionary*. - Define `WorkspaceKey` *String* in `Survicate` *Dictionary*. Your `Info.plist` file should look like this: ![Info.plist example](/ios-infoplist.png) ## Configuring Survicate Bindings for Expo Add [config plugin](https://docs.expo.dev/config-plugins/introduction/) to `plugins` array of your `app.json` or `app.config.js` ```json { "expo": { "plugins": [ [ "@survicate/react-native-survicate", { "workspaceKey": "YOUR_WORKSPACE_KEY" } ] ] } } ``` _Note: Please note that every time you change the props or plugins, you'll need to [rebuild](https://docs.expo.dev/workflow/customizing/) the native app. As an alternative to the main way of specifying the Workspace Key, you can also use the `setWorkspaceKey()` method. Important: * Regardless of the method used to set the Workspace Key, the config plugin entry with the `workspaceKey` property must be added to the `plugins` array in your `app.json` or `app.config.js`. If you use `setWorkspaceKey()` to provide the key at runtime, you still need to include the plugin entry with an empty `workspaceKey` value. * Using `setWorkspaceKey()` method overrides the Workspace Key defined in the configuration. * `setWorkspaceKey()` method must be used before `initializeSdk()` method is called. ```javascript Survicate.setWorkspaceKey('your_workspace_key'); ``` ## Initialization Initialize the SDK in your application using `initializeSdk()` method. Call this method only once, in the main component (e.g `src/App.js` file). ```javascript import Survicate from '@survicate/react-native-survicate'; // ... // useEffect(() => { Survicate.initializeSdk(); // }, []); // ... ``` --- # Using the React Native SDK Source: https://developers.survicate.com/mobile-sdk/react-native/using-sdk/ Survicate allows you to launch precisely targeted surveys inside your app. In the Survicate Panel, you can set conditions that need to be met for the surveys to appear. Users matching conditions defined in the Survicate panel will see the survey automatically. Here's a list of conditions you can use to target your surveys: - Name of the screen that a user currently sees - Any application event - User attributes and identities - Language of the device - Operating system Make sure to list all the screens and events described in your application. Once you got this covered, you or any person responsible for creating and managing surveys will be able to trigger surveys from the Survicate panel with no need for you to update the application. ## Targeting a survey by screen name A survey can appear when a user is viewing a specific screen. For example, a survey can be triggered to show up on the application's home screen after a user spends more than ten seconds there. To set it up, you need to send information to Survicate about the user entering and leaving a screen. _Note: Multiple active screens are allowed. In specific, calling enterScreen() does not make the previous screen to be discarded. Be sure to call leaveScreen() when you no longer want the screen to be treated as active._ ```javascript const Screen = () => { useEffect(() => { Survicate.enterScreen("screenName"); return () => { Survicate.leaveScreen("screenName"); }; }, []); return (
{/* UI */}
); }; ``` _Screen name is case sensitive. If there's any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Events-based survey targeting The SDK allows you to launch surveys based on events your users trigger in your app. Your survey will show instantly after an event occurs in your app. ```javascript Survicate.invokeEvent("eventName"); const properties = { "property1": "value1", "property2": "value2" }; Survicate.invokeEvent("eventName", properties); ``` _Event name and property keys are case sensitive. If there is any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Passing user attributes You can provide user attributes to Survicate as an extra layer of information about your users. The attributes have various use cases: * Identification of survey participants (answers are anonymous by default). * Directing surveys to particular users (Audience filters). * Filtering responses. * Recalling data in questions. ```javascript const userTrait = new UserTrait('traitName', 'traitValue'); Survicate.setUserTrait(userTrait); const textTrait = new UserTrait('name', 'John'); const numberTrait = new UserTrait('age', 25); const booleanTrait = new UserTrait('isPremium', true); const dateTrait = new UserTrait('lastLogin', new Date()); const timeIntervalTrait = new UserTrait('timeOfPurchase', new Date()); Survicate.setUserId("screenName"); ``` _Bear in mind that user attributes are cached. You only need to provide them once, e.g. when user logs in, not after each initilization. You can also change their values at any time to trigger a survey._ **Attribute types** - **string**: any text. - **number**: an integer or decimal. - **boolean**: a logic value. - **Date**: a `Date` object suitable for use with date or time interval Audience filters (the time interval filter measures elapsed time from a given timestamp). **Special attributes** - **user_id**: This corresponds to the "Logged-in status" in the panel's Audience filter. A user is considered logged-in when a trait with the "user_id" key has been set on the device, regardless of the value. - **first_name**, **last_name**, **email**: If none of these is specified, a response will be marked as Anonymous in the panel. **Additional notes** You can set your own attribute keys without any prior registration. They will show up in the panel once any response with the attribute is uploaded. ## Response attributes Response attributes are session-scoped attributes attached to survey responses. Unlike user attributes, they are cleared at the start of each new app session and are sent to Survicate along with the user's survey answers. To update a response attribute, call the method again with the same name and a new value. To clear an attribute, pass an empty string as the value. ```javascript // set a single attribute Survicate.setResponseAttribute(new ResponseAttribute('plan', 'premium')); // or multiple attributes at once Survicate.setResponseAttributes([ new ResponseAttribute('plan', 'premium'), new ResponseAttribute('seats', 10), new ResponseAttribute('isEnterprise', true), new ResponseAttribute('renewalDate', new Date()), ]); ``` `ResponseAttribute` accepts the following parameters: - **name** (required): The key that identifies the attribute. - **value** (required): The attribute value. Pass an empty string to clear an existing attribute. - **provider** (optional): The name of the external service where this data comes from (e.g., "hubspot", "intercom"). This helps integrations identify and match your survey respondents with their profiles in that service. **Attribute types** - **string**: any text. - **number**: an integer or decimal. - **boolean**: a logic value. - **Date**: a `Date` object ## Setting the locale Survicate SDK automatically detects the device locale and uses it both to choose the translation of a survey and to evaluate any Device language targeting filters. If your app allows users to change the locale independently of the system settings, you can override the default by calling: ```javascript Survicate.setLocale("en-US"); ``` The argument must be a valid IETF language tag such as: - A two‑letter ISO 639 code (e.g., "en", "fr") - A three-letter code for languages without the two-letter equivalent (e.g., "haw", "yue") - A language tag with region (e.g., "en-US", "pt-BR") _Note: The specified locale setting applies only to the current application session. To preserve the preference after an app restart, make sure to call `setLocale(...)` again, anytime after `Survicate.initializeSdk(...)`._ ## Theme mode When your survey has a theme with both light and dark modes, the SDK will select the proper variant following the system setting by default. Optionally, you can enforce a specific theme mode with the `setThemeMode` method: ```javascript // light, dark, or auto Survicate.setThemeMode(ThemeMode.auto); ``` ## Custom fonts Using `Survicate.setFonts` you can specify custom fonts for survey presentation. You need to provide a font path for each font style required by the SDK. Place your font files in the `assets/` directory of your project: ``` assets/ fonts/ MyFont-Regular.ttf MyFont-Italic.ttf MyFont-Bold.ttf MyFont-BoldItalic.ttf ``` Declare your font files: ```js title="React Native CLI" // react-native.config.js module.exports = { assets: ['./assets/fonts'], }; ``` ```json title="Expo" // app.json { "expo": { "plugins": [ [ "expo-font", { "fonts": [ "./assets/fonts/MyFont-Regular.ttf", "./assets/fonts/MyFont-Italic.ttf", "./assets/fonts/MyFont-Bold.ttf", "./assets/fonts/MyFont-BoldItalic.ttf" ] } ] ] } } ``` Link the fonts to your native projects: ```bash title="React Native CLI" npx react-native-asset ``` ```bash title="Expo" npx expo prebuild ``` Call `Survicate.setFonts()` with a `SurvicateFontSystem`. The paths must match **exactly** the filenames declared in your assets folder: ```typescript import Survicate, { SurvicateFontSystem } from '@survicate/react-native-survicate'; Survicate.setFonts({ regular: 'fonts/MyFont-Regular.ttf', regularItalic: 'fonts/MyFont-Italic.ttf', bold: 'fonts/MyFont-Bold.ttf', boldItalic: 'fonts/MyFont-BoldItalic.ttf', }); ``` ## Reseting user data for testing purposes If you need to test surveys on your device, the `reset()` method can be useful. It clears all user data stored on the device — including survey views, attributes, and information about answered surveys — as well as the current in-memory state of the SDK. ```javascript Survicate.reset(); ``` ## Event listeners SDK allows you to utilize event listeners. You may find them useful to trigger actions in your application based on actions performed by respondents. Here's a list of events you can subscribe to: * survey_displayed - occurs when survey is loaded and appears in the User Interface * question_answered - occurs after a question is answered ( Survicate stores incomplete survey submissions ) * survey_closed - occurs when a user closes the survey using the close button * survey_completed - occurs when a user finishes the survey ```javascript useEffect(() => { const listener: SurvicateEventListener = { onSurveyDisplayed: (event: SurveyDisplayedEvent) => { console.log("on survey displayed"); }, onQuestionAnswered: (event: QuestionAnsweredEvent) => { console.log("on question answered"); }, onSurveyClosed: (event : SurveyClosedEvent) => { console.log("on survey closed"); }, onSurveyCompleted: (event: SurveyCompletedEvent) => { console.log("on survey completed"); } } const subscription = Survicate.addSurvicateEventListener(listener); return subscription; }, []); ``` ### _SurvicateAnswer_ properties (_QuestionAnsweredEvent.answer_) | Property | Type | Description | |:---------|:----------|:-----------------------------------------------------------------------------------------------| | type | string \| null | Answer type. One of: ['text', 'single', 'multiple', 'smiley_scale', 'rating', 'csat', 'numerical_scale', 'nps', 'date', 'form', 'matrix', 'button_close', 'button_next', 'button_link']. | | id | number \| null | Answer ID. **Applicable only for types: ['single', 'smiley_scale', 'csat', 'rating', 'numerical_scale'].** | | ids | number[] | Selected answer IDs. **Applicable only for type = ['multiple'].** | | value | string \| null | Text representation of an answer, e.g. "Happy" for smiley scale. A `null` value in case of a skipped question. **Not applicable for call-to-action answers: ['button_close', 'button_next', 'button_link'].** | _The `id`, `ids` and `value` properties are provided only for the cases enlisted in the table above. Therefore, expect that there might be answer objects that consist only of the `type` property._ --- # React Native SDK changelog Source: https://developers.survicate.com/mobile-sdk/react-native/changelog/ Releases of the Survicate React Native SDK, newest first. ## 8.3.2 (2026-08-13) #### Updated - Bumping up reference of iOS to 8.3.2 #### Fixed - An issue on iOS where in some cases locally stored survey data could be cleared on app launch after the SDK was updated. ## 8.3.1 (2026-07-22) #### Updated - Bumping up reference of Android to 8.3.1 - Bumping up reference of iOS to 8.3.1 #### Fixed - An issue on iOS where the randomized order of answer choices could change after a respondent switched the survey language. - An issue on iOS where time-based targeting could be evaluated incorrectly. - An issue on Android where screen readers announced an optional comment field as "required". - Screen reader focus on Android landing on the whole question instead of the comment field. - An issue on Android where the text cursor could move to the first input on the page after the survey language was changed. ## 8.3.0 (2026-07-01) #### New - Multiple choice question type has a new answer choice - None of the above. If enabled, it's always displayed at the end of the answer list and deselects other answers. - Contact form question and integrations connection: You can decide whether to use data from the contact form question to identify respondents in integrations. #### Updated - Bumping up reference of Android to 8.3.0 - Bumping up reference of iOS to 8.3.0 - Pin answer: you can now pin any answer to its position during randomization (previously only the last answer could be pinned). ## 8.2.0 (2026-06-12) #### Improved - Backend targeting performance. #### Updated - Bumping up reference of Android to 8.2.0 - Bumping up reference of iOS to 8.2.0 #### Fixed - Thread safety issues on iOS in survey targeting. - An issue on iOS where the SDK could show as not installed in the Survicate panel. - A bug on Android where the layout direction was not applied after screen rotation when the device's default locale was overridden. ## 8.1.1 (2026-05-29) #### Updated - Bumping up reference of Android to 8.1.1 - Bumping up reference of iOS to 8.1.2 - Domain used for backend targeting. #### Fixed - Fixed an issue on iOS with the hint message not displaying correctly in the Text question. ## 8.1.0 (2026-05-27) #### New - New scale styles are added in the smiley scale question type - filled and outlined - with an option to select a custom color for them. The default scale style is emojis as before. #### Improved - Accessibility in the survey progress bar. #### Updated - Bumping up reference of Android to 8.1.0 - Bumping up reference of iOS to 8.1.1 ## 8.0.2 (2026-05-13) #### Updated - Bumping up reference of Android to 8.0.1 - Bumping up reference of iOS to 8.0.2 #### Fixed - An issue on iOS where surveys triggered by delayed events could fail to display. - Answer order is now preserved on Android across device configuration changes when "Randomize answers" is enabled. - Accessibility focus of Smiley scale icons on Android versions prior to 8.0 (API < 26). ## 8.0.1 (2026-05-05) #### Updated - Bumping up reference of iOS to 8.0.1 #### Fixed - A rare crash on iOS that could occur when the SDK evaluated survey display conditions while user traits were being updated at the same time. ## 8.0.0 (2026-04-15) #### New - Backend targeting is now available for beta testing. When enabled for your workspace, survey targeting is evaluated server-side so the same respondent won't be targeted twice across different channels (e.g. Web, Mobile) or devices. #### Improved - Surveys are now displayed above app navigation and system alerts on iOS. #### Updated - Bumping up reference of Android to 8.0.0 - Bumping up reference of iOS to 8.0.0 #### Fixed - An issue where Bokmål (nb) and Nynorsk (nn) locale variants were not matched to the Norwegian translation. ## 7.3.0 (2026-03-27) #### New - You can allow respondents to select their preferred survey language. Make sure this option is enabled in the panel and that all required translations are added. #### Updated - Bumping up reference of Android to 7.3.0 - Bumping up reference of iOS to 7.3.0 - The SDK now requires Kotlin 2.0+ and compileSdk 35 or higher on Android. - Kotlin to 2.1.21 - Kotlinx Coroutines Android to 1.10.2 - Kotlinx Serialization JSON to 1.8.1 - AndroidX Lifecycle Process to 2.9.4 - AndroidX RecyclerView to 1.4.0 #### Fixed - Refined internal persistence architecture to improve thread safety on iOS. ## 7.2.0 (2026-03-03) #### New - Response attributes can now be attached to survey responses via `Survicate.setResponseAttributes` method. Use `ResponseAttribute` to pass key-value pairs of type String, Number, Boolean, or DateTime alongside response data. - SDK fonts are customizable using `Survicate.setFonts`, allowing surveys to match your app's typography. #### Updated - Bumping up reference of Android to 7.2.0 - Bumping up reference of iOS to 7.2.0 ## 7.1.0 (2026-02-18) #### New - You can now adjust the survey theme based on your app mode. The supported theme modes are: - auto (default) - light - dark The additional theme version should be added in the panel first. #### Updated - Bumping up reference of Android to 7.1.1 - Bumping up reference of iOS to 7.1.1 #### Fixed - Removed `jcenter()` repository from Android build configuration. - An issue with missing NativeSurvicateModule class. - An issue on Android with `Powered by Survicate` logo scaling. - An issue on iOS with scrollview height calculations in Matrix question type. - Refined internal concurrent operations architecture to improve thread safety on iOS. ## 7.0.0 (2026-01-21) #### New - New operators available in Audience targeting for all attribute types: - "value exists" - "value doesn't exist" - Added workspace key validation during SDK initialization #### Updated - Bumping up reference of Android to 7.0.0 - Bumping up reference of iOS to 7.0.0 - Removed Moshi dependency on Android #### Fixed - An issue on iOS with setLocale method requiring strict case formatting. Now it accepts locale codes in any case (e.g., zh-tw, zh-TW) - An issue on iOS with UI glitch in survey question transition - An issue on iOS with surveys not being shown again after being dismissed by native components ## 6.4.6 (2026-01-07) #### Fixed - An issue on iOS with thread safety causing crashes when accessing deallocated objects. ## 6.4.5 (2025-12-11) #### Improved - The Shape Rating horizontal layout on very narrow Android devices, ensuring all five items fit on the screen. #### Fixed - An issue on iOS with thread safety causing crashes during concurrent SDK operations. ## 6.4.4 (2025-11-26) #### Improved - Enhanced performance of checkbox selection in multiple answer question type on iOS. - Updated data storage handling for better iOS compatibility ## 6.4.3 (2025-10-28) #### Updated - XCFramework is now signed with a distribution certificate. #### Improved - Optimized text component behavior when focused on iOS. #### Fixed - An issue that prevented the screen delay trigger from firing when enterScreen() was called too soon after SDK initialization. - An issue on iOS with screen delay trigger not being scheduled upon enterScreen() call. ## 6.4.2 (2025-09-30) #### Improved - Optimized memory performance on iOS. #### Fixed - An issue with surveys new event property operators behavior. ## 6.4.1 (2025-09-15) #### Fixed - An issue on iOS preventing listeners from being added at SDK initialization. ## 6.4.0 (2025-09-01) > **Note:** This version contains an issue with backward compatibility of new event property operators. To use the new operators please use version 6.4.2 or later. #### New - More operators are now available for targeting by event properties. Previously, the only option available and applied by default was "equals". Now you can select among these operators: - equals - doesn't equal - contains - doesn't contain - value exists - value doesn't exist #### Improved - Performance optimization on iOS by moving some SDK initialization tasks to a background thread. ## 6.3.5 (2025-08-25) #### Improved - Performance optimization on Android by moving some SDK initialization tasks to a background thread. #### Fixed - An issue on iOS with delayed event triggers conflicting with workspace refresh attempts. - An issue on iOS with thread-safety causing crashes during concurrent SDK initialization. - An issue on iOS with thread safety that occurred when loading plist properties from background threads, ensuring proper synchronization and preventing potential crashes during configuration loading. - An issue on Android where an instantly recurring survey with a delayed event trigger could reappear after being closed in long app sessions. #### Updated - AndroidX AppCompat to 1.7.1 - AndroidX Autofill to 1.3.0 - Added OkHttp 4.12.0 dependency - Added AndroidX Lifecycle Process 2.8.7 dependency ## 6.3.4 (2025-07-22) #### Fixed - An issue on iOS with scroll in `single answer selection` and `multiple answer selection` question types after selecting an answer. ## 6.3.3 (2025-07-18) #### Fixed - An issue on iOS with non wrapping description text in `nps`, `rating numerical` and `rating shape` question types. - An issue on iOS with resolving survey language based on device language instead of the app language - An issue on iOS with submit section visibility in `single answer selection`, `nps`, `smiley scale` and `rating` question types when the question is set as mandatory and disclaimer is present . ## 6.3.2 (2025-06-12) #### Improved - Horizontal layout for Shape and Numerical Rating questions to fit the screen width even on smaller devices on Android. ## 6.3.1 (2025-05-26) #### Fixed - An issue with invalid response language attribute in analysis tab after using `setLocale()` method on iOS. ## 6.3.0 (2025-05-22) #### New - In text question type, it’s now possible to have 1 or 2 follow-up questions generated by AI to clarify the initial answer and collect more details. - Survey language can be changed independently of the app's language by using a new locale-forcing method. - Survey translations and audience language filter now support regional localizations. #### Improved - Accessibility in all question types following the WCAG standard. - Nested scrolling in input fields for Text questions and comments on Android. #### Updated - Bumping up reference of Android to 6.3.0. - Bumping up reference of iOS to 6.3.0. #### Fixed - Legend text alignment and item spacing in Rating and NPS questions for right-to-left languages on Android. - Footer's logo placement in RTL layout on Android. ## 6.2.0 (2025-03-18) #### New - You can add images to every question type. Available image placement options are above and under the questions. #### Updated - Bumping up reference of Android to 6.2.0. - Bumping up reference of iOS to 6.2.0. ## 6.1.0 (2025-03-12) #### New - You can add a disclaimer with or without a consent checkbox to all question types. #### Improved - Enhanced support for landscape orientation. #### Updated - Bumping up reference of Android to 6.1.0. - Bumping up reference of iOS to 6.1.0. #### Fixed - The "has any value" logic condition in Matrix question now applies also to partial and empty answers. ## 6.0.0 (2025-02-19) #### Breaking - SDK requires CompileSDK 34 or higher. - SDK requires minimum deployment target of iOS 14. #### New - Survey logic has been split into 2 types - Branch and Display logic. Branch logic includes all the previously available logic settings that allow you to select which question your respondents should see next based on their response to the current question. A new type of logic - Display logic - allows you to decide whether the current question should be shown or not based on the respondents' answers to the questions earlier in the survey. #### Improved - Surveys are now displayed consecutively, if more than one survey meets the targeting criteria (instantly recurring surveys without event trigger will result in showing the survey in a loop). - Improved animation on survey close and completion. #### Updated - Bumping up reference of Android to 6.0.0. - Bumping up reference of iOS to 6.0.0. - Deprecated `setUserId` method. #### Fixed - An issue on iOS with answer selection in `shape` question. ## 5.5.2 (2024-12-20) #### Fixed - Fixed an issue with Android's `getNetworkCapabilities` method that could occasionally cause exceptions during SDK initialization. - Fixed a crash on iOS caused by non-thread-safe access to `localizedDescription` during error logging. ## 5.5.1 (2024-12-10) #### Fixed - Fixed an issue on iOS where comments were missing in event listeners. - Fixed an issue on iOS where in Smiley Scale question in some cases the submit button was disabled. - Fixed an issue on iOS with missing submit button in Multiple Answer question. - Fixed an issue on iOS with missing comment field in CSAT question when answer is mandatory. ## 5.5.0 (2024-12-06) #### New - You can now add a comment field to NPS, Smiley scale, Rating scale, Matrix, and Date question types. There is also a comment title available for all comment fields. You can use it to ask a question and give your respondents some context of what you would like to see in the comment. #### Updated - AndroidX Annotation to 1.9.1. - Coroutines Android to 1.9.0. ## 5.4.0 (2024-10-23) #### New - Each question type except Welcome message, Date, and Thank you screen can be set as mandatory or optional. #### Improved - Accessibility features for Matrix question, survey progress indicator, and navigation buttons. ## 5.3.0 (2024-09-13) #### New - Once an event is invoked in the app, its name and property names are also sent to Survicate’s panel now. They will be shown as suggestions when a user configures event targeting of a survey. ## 5.2.0 (2024-09-05) #### New - New conditions are available in event targeting: - Time delay after event occurrence. - Number of event occurrences. - Time of the first occurrence. - Time of the last occurrence. If multiple conditions are applied, all of them should be met for a survey to appear. #### Updated - Bumping up reference of Android to 5.2.0. - Bumping up reference of iOS to 5.2.0. #### Fixed - Fixed an issue with submit button visibility in single choice question on iOS. ## 5.1.1 (2024-08-01) #### Updated - Bumping up reference of Android to 5.1.1. - Bumping up reference of iOS to 5.1.2. #### Improved - More distinguishable emojis in the 3-choice Smiley scale. #### Fixed - Excessive spacing between Smiley scale emojis in the 3-choice layout. - Back button icon color on dark backgrounds on Android. - An issue on Android where "Submit" was displayed instead of "Start Survey" on the welcome CTA point after navigating back to it. - Issue on iOS with non visible Submit button in multiple choice questions. ## 5.1.0 (2024-07-19) #### New - Navigation buttons are available now. When enabled, your survey respondents can go back to the previous questions, see their selected answers, and change them if necessary. #### Improved - Higher resolution of Smiley scale icons on Android. #### Updated - Bumping up reference of Android to 5.1.0. - Bumping up reference of iOS to 5.1.1. #### Fixed - Propagating Matrix answer in `SurvicateAnswer.value` of event listener. - An issue on Android that resulted in unexpected vertical padding for Matrix question in full screen mode. - Configuration json will be printed in console only in verbose log level on iOS. ## 5.0.0 (2024-06-14) #### New - Matrix question type added. - Added setWorkspaceKey method. It is now possible to set workspace key in code. #### Breaking - Removed `initialize` method from native modules. In consequence Survicate SDK no longer initializes by itself so please use `initializeSdk`. #### Updated - Bumping up reference of Android to 5.0.0. - Bumping up reference of iOS to 5.0.0. #### Fixed - UI state bugs related to Activity's configuration changes. - Animation resource names that could conflict with resources of the app or other libraries on Android. ## 4.4.0 (2024-05-14) #### New - New targeting option available – event properties. You can add multiple properties to one event and join them with either "or" or "and" operator. Property names and values are case-sensitive. Only string values are supported. #### Updated - Bumping up reference of Android to 4.4.0. - Bumping up reference of iOS to 4.4.0. #### Fixed - Issue with non triggering questionAnswered delegate method in iOS. - A bug in Android that could prevent a survey from being displayed if a delay was set for multiple screens in the panel. - Horizontal mode support for Numerical Rating question for up to 5 items in Android. ## 4.3.0 (2024-03-26) #### New - More flexible survey recurring options are available now. Now you can specify how many days / weeks / months / years should pass before the survey can appear again. It’s also possible to set after how many days / weeks / months / years the survey should stop recurring. - If you run several mobile surveys, now you can use survey throttling settings to specify a time frame that should pass between showing them. Use global throttling to set the same time frame for all your mobile surveys. Or use the survey level throttling to override the global settings and specify a different period before showing a particular survey. #### Updated - Bumping up reference of Android to 4.3.0. - Bumping up reference of iOS to 4.3.0. #### Fixed - Issue with recursive display of non-recurring survey on iOS. ## 4.2.0 (2024-03-19) #### New - SDK now supports Expo managed apps. - New targeting filter is available - screen orientation (portrait mode or landscape mode targeting). You can either include or exclude one of the orientation modes. #### Updated - Bumping up reference of Android to 4.2.0. - Bumping up reference of iOS to 4.2.0. ## 4.1.1 (2024-02-29) #### Updated - Bumping up reference of Android to 4.1.1. - Added backward compatibility for AGP below 7.3. - New API for event listeners in native modules. #### Improved - Performance enhancements in answers synchronization on Android. #### Fixed - Readme update for initialization and listener. ## 4.1.0 (2024-02-16) #### New - SDK now supports listeners. #### Updated - Bumping up reference of iOS to 4.1.1. ## 4.0.2 (2024-02-14) #### Updated - Bumping up reference of Android to 4.1.0. - Bumping up reference of iOS to 4.1.0. #### Fixed - An issue on Android where `SurveyActivity` could crash when it was restored after process termination. - A race condition on Android in the recalling feature. ## 4.0.1 (2024-01-23) #### Updated - Bumping up reference of Android to 4.0.2. - Bumping up reference of iOS to 4.0.2. #### Improved - Date format in user traits recalling. #### Fixed - A bug where users could see survey more times than specified in recurrence settings if SDK was updated in meantime. - Sending user attributes to backend only when necessary in Android. - An issue where Thank you screen don't close survey in classic theme in iOS. ## 4.0.0 (2024-01-08) #### New - User conditions targeting is changed to the audience targeting: create an audience that will be available for usage among all your mobile surveys. Enable multiple audiences at the same time in one survey if necessary. - User attributes now support not only string values but also numbers, boolean, and datetime values. - New attribute operators are available to support new data types. - Survey audience can be set not only by including a set of respondents who met the required criteria but also by excluding those who should not see the survey. - And / or operators in audience targeting are switchable now: within one attribute filter that has several attributes in it and between different filters. - Migrated from DefinitelyTyped types to library types using builder-bob. #### Breaking - Library types no longer contain `initialize` method, use `initializeSdk` instead. #### Updated - Bumping up reference of Android to 4.0.1. - Bumping up reference of iOS to 4.0.0. - Use `NetworkCapabilities` to check internet connection (API 24+). - Migrate to `WindowCompat` APIs for setting full screen background. #### Fixed - Fixed invalid survey closing when app has specified `android:enableOnBackInvokedCallback="true"` in the AndroidManifest.xml. ## 3.1.2 (2023-12-06) #### Updated - Bumping up reference of Android to 3.0.6. - Android TargetSdk to 33. - AGP to 8.1.2. - Kotlin to 1.9.10. - AndroidX Appcompat to 1.6.1. - AndroidX RecyclerView to 1.3.2. - AndroidX Annotation to 1.7.3. - Moshi to 1.15.0. - Coil to 2.4.0. - Creating User Trait requires non null key. - Added a Proguard rule for User Traits. #### Fixed - An issue where workspaceKey metadata was not provided in AndroidManifest.xml would cause a crash. - An issue where answers saved without internet were not synchronized in next app sessions. - An issue with javadoc generation. - An issue with saving User Traits that could cause crash whenever saved User Trait key was null. ## 3.1.0 (2023-09-28) #### New - Support for React Native New Architecture. #### Updated - Bumping up reference of Android to 3.0.3. - Bumping up reference of iOS to 3.0.4. #### Fixed - On Android added image scaling to shapes rating questions to fit all answers on the screen in horizontal layout. - On Android fixed issue on Thank You question with button's title not using text from survey settings. - On iOS fixed issue where rating scale question answer ID was missing in listener. - On iOS fixed issue where surveys were not translated when app language was set to dialect. ## 3.0.3 (2023-09-12) #### Updated - React peer dependency to 16.8.6. - React-Native peer dependency to 0.60.0. - Added initializeSdk method to initialize Survicate (replacing initialize). #### Deprecated - Initialize method is now deprecated and will be removed in version 4.0. ## 3.0.2 (2023-08-23) #### Updated - Repository name has been changed to survicate-react-native-sdk. - Bumping up references of Android to 3.0.2. - Bumping up references of iOS to 3.0.2. - Not displaying surveys on iOS when alerts are visible. #### Fixed - Issue in Android where in some cases survey was not dismissible. ## 3.0.1 (2023-08-09) #### Updated - Bumping up references: Android to 3.0.1 and iOS to 3.0.1. ## 3.0.0 (2023-07-27) #### Updated - Bumping up references: Android to 3.0.0 and iOS to 3.0.0. ## 2.4.0 (2023-07-17) #### Updated - Bumping up references: Android to 2.4.0 and iOS to 2.4.0. ## 2.3.0 (2023-05-30) #### Updated - Bumping up references: Android to 2.3.1 and iOS to 2.3.0. ## 2.1.0 (2023-04-07) #### Updated - Bumping up references: Android to 2.1.0 and iOS to 2.1.0. ## 2.0.0 (2023-03-10) #### Updated - Bumping up references: Android to 2.0.0 and iOS to 2.0.0. ## 1.1.19 (2023-01-09) #### Updated - Bumping up references: Android to 1.7.5 and iOS to 1.8.7. ## 1.1.18 (2022-11-23) #### Updated - Bumping up references: iOS to 1.8.5. ## 1.1.17 (2022-11-17) #### Updated - Bumping up references: Android to 1.7.4 and iOS to 1.8.4. ## 1.1.16 (2022-09-12) #### Fixed - build.gradle file cleanup to fix gradle sync. ## 1.1.15 (2022-09-07) #### Updated - Bumping up references: Android to 1.7.0. - The minimum supported version of Android changed to 5 (API 21). ## 1.1.13 (2022-08-05) #### Updated - Bumping up references: iOS to 1.8.2. ## 1.1.12 (2022-08-04) #### Updated - Bumping up references: Android to 1.6.5. ## 1.1.11 (2022-07-01) #### Updated - Bumping up references: Android to 1.6.1 and iOS to 1.8.0. #### Fixed - Gradle sync failure if referring to React Native 0.68.* and using gradle version lower than 7.2.*. ## 1.1.10 (2022-06-03) #### Updated - Bumping up references: Android to 1.6.1 and iOS to 1.8.0. ## 1.1.9 (2022-04-29) #### Updated - Bumping up references: Android to 1.5.14 and iOS to 1.7.2. ## 1.1.8 (2022-04-11) #### Updated - Bumping up references: iOS to 1.7.1. ## 1.1.7 (2022-03-28) #### Updated - React version dependency rule, to allow higher version than 16.8.1. ## 1.1.6 (2022-03-23) #### Updated - Bumping up references: Android to 1.5.12 and iOS to 1.6.7. #### Fixed - Clean up `build.gradle` file for fixing Android build issues. ## 1.1.5 (2022-03-03) #### New - Use `maven-publish` to support React Native 0.67.1. #### Updated - Bumping up references: Android to 1.5.9 and iOS to 1.6.5. ## 1.1.4 (2022-01-20) #### Updated - Bumping up references: Android to 1.5.6. ## 1.1.3 (2022-01-17) #### Updated - Bumping up references: Android to 1.5.5. ## 1.1.2 (2021-12-9) #### Updated - Bumping up references: Android to 1.5.2 and iOS to 1.6.1. ## 1.1.1 (2021-11-10) #### Updated - Bumping up references: Android to 1.4.5 and iOS to 1.5.8. ## 1.1.0 (2021-10-29) #### Updated - Bumping up references: Android to 1.3.0 and iOS to 1.5.5. - Survicate iOS SDK is now distributed as an XCFramework binary. ## 1.0.5 (2021-05-04) #### Updated - Bumping up references: Android to 1.2.6. ## 1.0.3 (2021-02-04) #### Updated - Bumping up references: Android to 1.2.4 and iOS to 1.4.3. ## 1.0.2 (2020-04-23) #### Updated - Bumping up references: Android to 1.2.0 and iOS to 1.4.0. ## 1.0.1 (2020-03-06) #### Updated - Bumping up references: Android to 1.1.2. ## 1.0.0 (2020-01-24) #### New - Initial version of the SDK, with references to the native Survicate SDKs as follows: Android - 1.0.19 and iOS to 1.3.0. --- # Flutter SDK Source: https://developers.survicate.com/mobile-sdk/flutter/ The Survicate Flutter SDK will increase your APK size by approximately 3 MB when obfuscated and your IPA size by approximately 2.2 MB. Note that the SDK features a Time To Live (TTL) mechanism of 60 seconds. This means any modifications made to your survey will be reflected on your respondents' devices after a delay of up to 60 seconds. ## Requirements * Using Survicate Mobile SDK requires an account at [survicate.com](https://survicate.com). You can create your account [here](https://panel.survicate.com/signup) for free, or become invited to your company account by one of your colleagues. * Survicate SDK version 4.0.0 or higher. * Additionally, please check [iOS](/mobile-sdk/ios/) and [Android](/mobile-sdk/android/) library requirements, as they're applicable too. ## Recommendations * We recommend using Flutter 3.0.0 or higher. > **Note:** > #### Apps using Survicate SDK after 1st March 2026: > > Flutter: > > - Survicate SDK version 6.0.0 or higher (required). > - Flutter version 3.24.0 or higher (recommended). > > Android: > > - CompileSdk version 35 or higher (required). > - Android Gradle Plugin version 8.6.x or higher with compatible Gradle version (required). > - Kotlin version 2.0 or higher (required). > > iOS: > > - Respondent's device running iOS 15.0 or higher (required). - [Installation](/mobile-sdk/flutter/installation) - [Configuration](/mobile-sdk/flutter/configuration) - [Using SDK](/mobile-sdk/flutter/using-sdk) - [Changelog](/mobile-sdk/flutter/changelog) --- # Flutter SDK installation Source: https://developers.survicate.com/mobile-sdk/flutter/installation/ To use this plugin, add `survicate_sdk` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). ## Android You need to add the Survicate Maven repository to your project `build.gradle` located under `android` directory. ```groovy title="Project's build.gradle" allprojects { repositories { // ... maven { url 'https://repo.survicate.com' } } } ``` ## iOS Survicate SDK supports both **CocoaPods** and **Swift Package Manager (SPM)** for iOS integration. **Using CocoaPods** If you're using CocoaPods, run `pod update` in your `ios` directory after adding the dependency. **Using Swift Package Manager (SPM)** If you're using SPM, the dependency will be automatically resolved. --- # Flutter SDK configuration Source: https://developers.survicate.com/mobile-sdk/flutter/configuration/ ## Configuration for Android Configure your *workspace key* in `AndroidManifest.xml` file. ```xml title="AndroidManifest.xml" ``` ## Configuration for iOS Add workspace key to your `Info.plist` file. - Create `Survicate` *Dictionary*. - Define `WorkspaceKey` *String* in `Survicate` *Dictionary*. Your `Info.plist` file should look like this: ![Info.plist example](/ios-infoplist.png) As an alternative to the main way of specifying the Workspace Key, you can also use the `setWorkspaceKey()` method. Important: * Using `setWorkspaceKey()` method overrides the Workspace Key defined in the configuration. * `setWorkspaceKey()` method must be used before `initializeSdk()` method is called. ```dart SurvicateSdk.setWorkspaceKey('your_workspace_key'); ``` ## Initialization Initialize the SDK in your application using `initializeSdk()` method. Call this method only once, in the main component (e.g `lib/main.dart` file). ```dart import 'package:survicate_sdk/survicate_sdk.dart'; class _MyAppState extends State { @override void initState() { super.initState(); SurvicateSdk.initializeSdk(); } } ``` --- # Using the Flutter SDK Source: https://developers.survicate.com/mobile-sdk/flutter/using-sdk/ Survicate allows you to launch precisely targeted surveys inside your app. In the Survicate Panel, you can set conditions that need to be met for the surveys to appear. Users matching conditions defined in the Survicate panel will see the survey automatically. Here's a list of conditions you can use to target your surveys: - Name of the screen that a user currently sees - Any application event - User attributes and identities - Language of the device - Operating system Make sure to list all the screens and events described in your application. Once you got this covered, you or any person responsible for creating and managing surveys will be able to trigger surveys from the Survicate panel with no need for you to update the application. ## Targeting a survey by screen name A survey can appear when a user is viewing a specific screen. For example, a survey can be triggered to show up on the application's home screen after a user spends more than ten seconds there. To set it up, you need to send information to Survicate about the user entering and leaving a screen. _Note: Multiple active screens are allowed. In specific, calling enterScreen() does not make the previous screen to be discarded. Be sure to call leaveScreen() when you no longer want the screen to be treated as active._ ```dart // Example of tracking screen changes using the RouteObserver and Flutter Navigator // Define the RouteObserver as a global variable: final RouteObserver routeObserver = RouteObserver(); // Set up your main app and attach the RouteObserver: class MainApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Route Observer Example', navigatorObservers: [routeObserver], home: Screen(), ); } } // Implement the RouteAware interface on your screen widget // Subscribe to the route observer in the didChangeDependencies() method and unsubscribe in the dispose() method. // Call SurvicateSdk.enterScreen() in the didPush() and didPopNext() methods. // Call SurvicateSdk.leaveScreen() in the didPop() and didPushNext() methods. class _ScreenState extends State with RouteAware { @override void didChangeDependencies() { super.didChangeDependencies(); routeObserver.subscribe(this, ModalRoute.of(context)); } @override void dispose() { routeObserver.unsubscribe(this); super.dispose(); } @override void didPush() { // Route was pushed onto navigator, this widget is now visible SurvicateSdk.enterScreen("screenName"); } @override void didPopNext() { // Covering route was popped off the navigator, this widget is now visible again SurvicateSdk.enterScreen("screenName"); } @override void didPop() { // This route was popped off the navigator SurvicateSdk.leaveScreen("screenName"); } @override void didPushNext() { // A new route was pushed onto navigator, this widget is no longer visible SurvicateSdk.leaveScreen("screenName"); } } ``` _Screen name is case sensitive. If there's any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Events-based survey targeting The SDK allows you to launch surveys based on events your users trigger in your app. Your survey will show instantly after an event occurs in your app. ```dart SurvicateSdk.invokeEvent("eventName"); Map properties = { 'property1': 'value1', 'property2': 'value2', }; SurvicateSdk.invokeEvent('Event', eventProperties: properties); ``` _Event name and property keys are case sensitive. If there is any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Passing user attributes You can provide user attributes to Survicate as an extra layer of information about your users. The attributes have various use cases: * Identification of survey participants (answers are anonymous by default). * Directing surveys to particular users (Audience filters). * Filtering responses. * Recalling data in questions. ```dart UserTrait trait = UserTrait.string("traitName", "traitValue"); SurvicateSdk.setUserTrait(trait); UserTrait textTrait = UserTrait.string("name", "traitValue"); UserTrait numberTrait = UserTrait.num("age", 123); UserTrait booleanTrait = UserTrait.bool("isPremium", true); UserTrait datetimeTrait = UserTrait.dateTime("lastLogin", DateTime.now()); UserTrait timeIntervalTrait = UserTrait.dateTime("timeOfPurchase", DateTime.now()); List traits = [ textTrait, numberTrait ]; SurvicateSdk.setUserTraits(traits); ``` _Bear in mind that user attributes are cached. You only need to provide them once, e.g. when user logs in, not after each initilization. You can also change their values at any time to trigger a survey._ **Attribute types** - **string**: any text. - **num**: an integer or decimal. - **bool**: a logic value. - **dateTime**: a dart:core `DateTime` object which can be used with date or time interval filters in the panel (the latter measure elapsed time from a given timestamp). **Special attributes** - **user_id**: This corresponds to the "Logged-in status" in the panel's Audience filter. A user is considered logged-in when a trait with the "user_id" key has been set on the device, regardless of the value. - **first_name**, **last_name**, **email**: If none of these is specified, a response will be marked as Anonymous in the panel. **Additional notes** You can set your own attribute keys without any prior registration. They will show up in the panel once any response with the attribute is uploaded. ## Response attributes Response attributes are session-scoped attributes attached to survey responses. Unlike user attributes, they are cleared at the start of each new app session and are sent to Survicate along with the user's survey answers. To update a response attribute, call the method again with the same name and a new value. To clear an attribute, pass an empty string as the value. ```dart // set a single attribute SurvicateSdk.setResponseAttribute(ResponseAttribute.string('plan', 'premium')); // or multiple attributes at once SurvicateSdk.setResponseAttributes([ ResponseAttribute.string('plan', 'premium'), ResponseAttribute.bool('isTrialExpired', false), ResponseAttribute.num('seats', 5), ResponseAttribute.dateTime('renewalDate', DateTime.now()), ]); ``` `ResponseAttribute` accepts the following parameters: - **name** (required): The key that identifies the attribute. - **value** (required): The attribute value. Pass an empty string to clear an existing attribute. - **provider** (optional): The name of the external service where this data comes from (e.g., "hubspot", "intercom"). This helps integrations identify and match your survey respondents with their profiles in that service. **Attribute types** - **string**: any text. - **num**: an integer or decimal. - **bool**: a logic value. - **dateTime**: a dart:core `DateTime` object. ## Setting the locale Survicate SDK automatically detects the device locale and uses it both to choose the translation of a survey and to evaluate any Device language targeting filters. If your app allows users to change the locale independently of the system settings, you can override the default by calling: ```dart SurvicateSdk.setLocale("en-US"); ``` The argument must be a valid IETF language tag such as: - A two‑letter ISO 639 code (e.g., "en", "fr") - A three-letter code for languages without the two-letter equivalent (e.g., "haw", "yue") - A language tag with region (e.g., "en-US", "pt-BR") _Note: The specified locale setting applies only to the current application session. To preserve the preference after an app restart, make sure to call `setLocale(...)` again, anytime after `Survicate.initializeSdk(...)`._ ## Theme mode When your survey has a theme with both light and dark modes, the SDK will select the proper variant following the system setting by default. Optionally, you can enforce a specific theme mode with the `setThemeMode` method: ```dart // light, dark, or auto SurvicateSdk.setThemeMode(ThemeMode.auto); ``` ## Custom Fonts Using the `SurvicateSdk.setFonts` method you can specify custom fonts for survey presentation. You need to provide a font path for each font style required by the SDK. Place your font files in the `assets/` directory of your project: ``` assets/ fonts/ MyFont-Regular.ttf MyFont-Italic.ttf MyFont-Bold.ttf MyFont-BoldItalic.ttf ``` Declare your font files under the `assets:` section in `pubspec.yaml`: ```yaml flutter: assets: - assets/fonts/MyFont-Regular.ttf - assets/fonts/MyFont-Italic.ttf - assets/fonts/MyFont-Bold.ttf - assets/fonts/MyFont-BoldItalic.ttf ``` Call `SurvicateSdk.setFonts()` with a `SurvicateFontSystem`. The paths must match **exactly** what you declared in `pubspec.yaml`: ```dart import 'package:survicate_sdk/survicate_sdk.dart'; SurvicateSdk.setFonts(SurvicateFontSystem( regular: 'assets/fonts/MyFont-Regular.ttf', regularItalic: 'assets/fonts/MyFont-Italic.ttf', bold: 'assets/fonts/MyFont-Bold.ttf', boldItalic: 'assets/fonts/MyFont-BoldItalic.ttf', )); ``` ## Event listeners SDK allows you to utilize event listeners. You may find them useful to trigger actions in your application based on actions performed by respondents. Here's a list of events you can subscribe to: * onSurveyDisplayed - occurs when survey is loaded and appears in the User Interface * onQuestionAnswered - occurs after a question is answered ( Survicate stores incomplete survey submissions ) * onSurveyClosed - occurs when a user closes the survey using the close button * onSurveyCompleted - occurs when a user finishes the survey ```dart import 'package:survicate_sdk/survicate_sdk.dart'; SurvicateEventListener listener = SurvicateEventListener( onSurveyDisplayed: (SurveyDisplayedEvent event) { }, // onSurveyDisplayed onQuestionAnswered: (QuestionAnsweredEvent event) { }, // onQuestionAnswered onSurveyClosed: (SurveyClosedEvent event) { }, // onSurveyClosed onSurveyCompleted: (SurveyCompletedEvent event) { }, // onSurveyCompleted ); SurvicateSdk.addSurvicateEventListener(listener); SurvicateSdk.removeSurvicateEventListener(listener); ``` ### _SurvicateAnswer_ properties (_QuestionAnsweredEvent.answer_) | Property | Type | Description | |:---------|:------------|:-----------------------------------------------------------------------------------------------| | type | String? | Answer type. One of: ['text', 'single', 'multiple', 'smiley_scale', 'rating', 'csat', 'numerical_scale', 'nps', 'date', 'form', 'matrix', 'button_close', 'button_next', 'button_link']. | | id | int? | Answer ID. **Applicable only for types: ['single', 'smiley_scale', 'csat', 'rating', 'numerical_scale'].** | | ids | List<int> | Selected answer IDs. **Applicable only for type = ['multiple'].** | | value | String? | Text representation of an answer, e.g. "Happy" for smiley scale. A `null` value in case of a skipped question. **Not applicable for call-to-action answers: ['button_close', 'button_next', 'button_link'].** | _The `id`, `ids` and `value` properties are provided only for the cases enlisted in the table above. Therefore, expect that there might be answer objects that consist only of the `type` property._ ## Reseting user data for testing purposes If you need to test surveys on your device, the `reset()` method can be useful. It clears all user data stored on the device — including survey views, attributes, and information about answered surveys — as well as the current in-memory state of the SDK. ```dart SurvicateSdk.reset(); ``` --- # Flutter SDK changelog Source: https://developers.survicate.com/mobile-sdk/flutter/changelog/ Releases of the Survicate Flutter SDK, newest first. ## 8.3.2 (2026-08-13) #### Updated - Bumping up reference of iOS to 8.3.2 #### Fixed - An issue on iOS where in some cases locally stored survey data could be cleared on app launch after the SDK was updated. ## 8.3.1 (2026-07-22) #### Updated - Bumping up reference of Android to 8.3.1 - Bumping up reference of iOS to 8.3.1 #### Fixed - An issue on iOS where the randomized order of answer choices could change after a respondent switched the survey language. - An issue on iOS where time-based targeting could be evaluated incorrectly. - An issue on Android where screen readers announced an optional comment field as "required". - Screen reader focus on Android landing on the whole question instead of the comment field. - An issue on Android where the text cursor could move to the first input on the page after the survey language was changed. ## 8.3.0 (2026-07-01) #### New - Multiple choice question type has a new answer choice - None of the above. If enabled, it's always displayed at the end of the answer list and deselects other answers. - Contact form question and integrations connection: You can decide whether to use data from the contact form question to identify respondents in integrations. #### Updated - Bumping up reference of Android to 8.3.0 - Bumping up reference of iOS to 8.3.0 - Pin answer: you can now pin any answer to its position during randomization (previously only the last answer could be pinned). ## 8.2.0 (2026-06-12) #### Improved - Backend targeting performance. #### Updated - Bumping up reference of Android to 8.2.0 - Bumping up reference of iOS to 8.2.0 #### Fixed - Thread safety issues on iOS in survey targeting. - An issue on iOS where the SDK could show as not installed in the Survicate panel. - A bug on Android where the layout direction was not applied after screen rotation when the device's default locale was overridden. ## 8.1.1 (2026-05-29) #### Updated - Bumping up reference of Android to 8.1.1 - Bumping up reference of iOS to 8.1.2 - Domain used for backend targeting. #### Fixed - Fixed an issue on iOS with the hint message not displaying correctly in the Text question. ## 8.1.0 (2026-05-27) #### New - New scale styles are added in the smiley scale question type - filled and outlined - with an option to select a custom color for them. The default scale style is emojis as before. #### Improved - Accessibility in the survey progress bar. #### Updated - Bumping up reference of Android to 8.1.0 - Bumping up reference of iOS to 8.1.1 ## 8.0.2 (2026-05-13) #### Updated - Bumping up reference of Android to 8.0.1 - Bumping up reference of iOS to 8.0.2 #### Fixed - An issue on iOS where surveys triggered by delayed events could fail to display. - Answer order is now preserved on Android across device configuration changes when "Randomize answers" is enabled. - Accessibility focus of Smiley scale icons on Android versions prior to 8.0 (API < 26). ## 8.0.1 (2026-05-05) #### Updated - Bumping up reference of iOS to 8.0.1 #### Fixed - A rare crash on iOS that could occur when the SDK evaluated survey display conditions while user traits were being updated at the same time. ## 8.0.0 (2026-04-15) #### New - Backend targeting is now available for beta testing. When enabled for your workspace, survey targeting is evaluated server-side so the same respondent won't be targeted twice across different channels (e.g. Web, Mobile) or devices. #### Improved - Surveys are now displayed above app navigation and system alerts on iOS. #### Updated - Bumping up reference of Android to 8.0.0 - Bumping up reference of iOS to 8.0.0 #### Fixed - An issue where Bokmål (nb) and Nynorsk (nn) locale variants were not matched to the Norwegian translation. ## 7.3.0 (2026-03-27) #### New - You can allow respondents to select their preferred survey language. Make sure this option is enabled in the panel and that all required translations are added. #### Updated - Bumping up reference of Android to 7.3.0 - Bumping up reference of iOS to 7.3.0 - The SDK now requires Kotlin 2.0+ and compileSdk 35 or higher on Android. - Kotlin to 2.1.21 - Kotlinx Coroutines Android to 1.10.2 - Kotlinx Serialization JSON to 1.8.1 - AndroidX Lifecycle Process to 2.9.4 - AndroidX RecyclerView to 1.4.0 #### Fixed - Refined internal persistence architecture to improve thread safety on iOS. ## 7.2.0 (2026-03-03) #### New - Response attributes can now be attached to survey responses via `SurvicateSdk.setResponseAttributes` method. Use `ResponseAttribute` to pass key-value pairs of type String, Number, Boolean, or DateTime alongside response data. - SDK fonts are customizable using `SurvicateSdk.setFonts`, allowing surveys to match your app's typography. #### Updated - Bumping up reference of Android to 7.2.0 - Bumping up reference of iOS to 7.2.0 ## 7.1.0 (2026-02-18) #### New - You can now adjust the survey theme based on your app mode. The supported theme modes are: - auto (default) - light - dark The additional theme version should be added in the panel first. #### Updated - Bumping up reference of Android to 7.1.1 - Bumping up reference of iOS to 7.1.1 #### Fixed - An issue on Android with `Powered by Survicate` logo scaling. - An issue on iOS with scrollview height calculations in Matrix question type. - Refined internal concurrent operations architecture to improve thread safety on iOS. ## 7.0.0 (2026-01-21) #### New - New operators available in Audience targeting for all attribute types: - "value exists" - "value doesn't exist" - Added workspace key validation during SDK initialization #### Updated - Bumping up reference of Android to 7.0.0 - Bumping up reference of iOS to 7.0.0 - Removed Moshi dependency on Android #### Fixed - An issue on iOS with setLocale method requiring strict case formatting. Now it accepts locale codes in any case (e.g., zh-tw, zh-TW) - An issue on iOS with UI glitch in survey question transition - An issue on iOS with surveys not being shown again after being dismissed by native components ## 6.4.6 (2026-01-07) #### Fixed - An issue on iOS with thread safety causing crashes when accessing deallocated objects. ## 6.4.5 (2025-12-11) #### Improved - The Shape Rating horizontal layout on very narrow Android devices, ensuring all five items fit on the screen. #### Fixed - An issue on iOS with thread safety causing crashes during concurrent SDK operations. ## 6.4.4 (2025-11-26) #### Updated - Added Swift Package Manager support on iOS #### Improved - Enhanced performance of checkbox selection in multiple answer question type on iOS. - Updated data storage handling for better iOS compatibility ## 6.4.3 (2025-10-28) #### Updated - XCFramework is now signed with a distribution certificate. #### Improved - Optimized text component behavior when focused on iOS. #### Fixed - An issue that prevented the screen delay trigger from firing when enterScreen() was called too soon after SDK initialization. - An issue on iOS with screen delay trigger not being scheduled upon enterScreen() call. ## 6.4.2 (2025-09-30) #### Improved - Optimized memory performance on iOS. #### Fixed - An issue with surveys new event property operators behavior. ## 6.4.1 (2025-09-15) #### Fixed - An issue on iOS preventing listeners from being added at SDK initialization. ## 6.4.0 (2025-09-01) > **Note:** This version contains an issue with backward compatibility of new event property operators. To use the new operators please use version 6.4.2 or later. #### New - More operators are now available for targeting by event properties. Previously, the only option available and applied by default was "equals". Now you can select among these operators: - equals - doesn't equal - contains - doesn't contain - value exists - value doesn't exist #### Improved - Performance optimization on iOS by moving some SDK initialization tasks to a background thread. ## 6.3.5 (2025-08-25) #### Improved - Performance optimization on Android by moving some SDK initialization tasks to a background thread. #### Fixed - An issue on iOS with delayed event triggers conflicting with workspace refresh attempts. - An issue on iOS with thread-safety causing crashes during concurrent SDK initialization. - An issue on iOS with thread safety that occurred when loading plist properties from background threads, ensuring proper synchronization and preventing potential crashes during configuration loading. - An issue on Android where an instantly recurring survey with a delayed event trigger could reappear after being closed in long app sessions. #### Updated - AndroidX AppCompat to 1.7.1 - AndroidX Autofill to 1.3.0 - Added OkHttp 4.12.0 dependency - Added AndroidX Lifecycle Process 2.8.7 dependency ## 6.3.4 (2025-07-22) #### Fixed - An issue on iOS with scroll in `single answer selection` and `multiple answer selection` question types after selecting an answer. ## 6.3.3 (2025-07-18) #### Fixed - An issue on iOS with non wrapping description text in `nps`, `rating numerical` and `rating shape` question types. - An issue on iOS with resolving survey language based on device language instead of the app language - An issue on iOS with submit section visibility in `single answer selection`, `nps`, `smiley scale` and `rating` question types when the question is set as mandatory and disclaimer is present . ## 6.3.2 (2025-06-12) #### Improved - Horizontal layout for Shape and Numerical Rating questions to fit the screen width even on smaller devices on Android. ## 6.3.1 (2025-05-26) #### Fixed - An issue with invalid response language attribute in analysis tab after using `setLocale()` method on iOS. ## 6.3.0 (2025-05-22) #### New - In text question type, it's now possible to have 1 or 2 follow-up questions generated by AI to clarify the initial answer and collect more details. - Survey language can be changed independently of the app's language by using a new locale-forcing method. - Survey translations and audience language filter now support regional localizations. #### Improved - Accessibility in all question types following the WCAG standard. - Nested scrolling in input fields for Text questions and comments on Android. #### Updated - Bumping up reference of Android to 6.3.0. - Bumping up reference of iOS to 6.3.0. #### Fixed - Legend text alignment and item spacing in Rating and NPS questions for right-to-left languages on Android. - Footer's logo placement in RTL layout on Android. ## 6.2.0 (2025-03-18) #### New - You can add images to every question type. Available image placement options are above and under the questions. #### Updated - Bumping up reference of Android to 6.2.0. - Bumping up reference of iOS to 6.2.0. ## 6.1.0 (2025-03-12) #### New - You can add a disclaimer with or without a consent checkbox to all question types. #### Improved - Enhanced support for landscape orientation. #### Updated - Bumping up reference of Android to 6.1.0. - Bumping up reference of iOS to 6.1.0. #### Fixed - The "has any value" logic condition in Matrix question now applies also to partial and empty answers. ## 6.0.0 (2025-02-19) #### Breaking - SDK requires CompileSDK 34 or higher. - SDK requires minimum deployment target of iOS 14. #### New - Survey logic has been split into 2 types - Branch and Display logic. - Branch logic includes all the previously available logic settings that allow you to select which question your respondents should see next based on their response to the current question. - A new type of logic - Display logic - allows you to decide whether the current question should be shown or not based on the respondents’ answers to the questions earlier in the survey. #### Improved - Surveys are now displayed consecutively, if more than one survey meets the targeting criteria (instantly recurring surveys without event trigger will result in showing the survey in a loop). - Improved animation on survey close and completion. #### Updated - Bumping up reference of Android to 6.0.0. - Bumping up reference of iOS to 6.0.0. #### Fixed - An issue on iOS with answer selection in `shape` question. ## 5.5.2 (2024-12-20) #### Fixed - Fixed an issue with Android's `getNetworkCapabilities` method that could occasionally cause exceptions during SDK initialization. - Fixed a crash on iOS caused by non-thread-safe access to `localizedDescription` during error logging. ## 5.5.1 (2024-12-10) #### Fixed - Fixed an issue on iOS where comments were missing in event listeners. - Fixed an issue on iOS where in Smiley Scale question in some cases the submit button was disabled. - Fixed an issue on iOS with missing submit button in Multiple Answer question. - Fixed an issue on iOS with missing comment field in CSAT question when answer is mandatory. ## 5.5.0 (2024-12-06) #### New - You can now add a comment field to NPS, Smiley scale, Rating scale, Matrix, and Date question types. There is also a comment title available for all comment fields. You can use it to ask a question and give your respondents some context of what you would like to see in the comment. #### Updated - AndroidX Annotation to 1.9.1. - Coroutines Android to 1.9.0. ## 5.4.0 (2024-10-23) #### New - Each question type except Welcome message, Date, and Thank you screen can be set as mandatory or optional. #### Improved - Accessibility features for Matrix question, survey progress indicator, and navigation buttons. ## 5.3.0 (2024-09-13) #### New - Once an event is invoked in the app, its name and property names are also sent to Survicate’s panel now. They will be shown as suggestions when a user configures event targeting of a survey. ## 5.2.0 (2024-09-05) #### New - New conditions are available in event targeting: - Time delay after event occurrence. - Number of event occurrences. - Time of the first occurrence. - Time of the last occurrence. If multiple conditions are applied, all of them should be met for a survey to appear. #### Updated - Bumping up reference of Android to 5.2.0. - Bumping up reference of iOS to 5.2.0. #### Fixed - Fixed an issue with submit button visibility in single choice question on iOS. ## 5.1.1 (2024-08-01) #### Updated - Bumping up reference of Android to 5.1.1. - Bumping up reference of iOS to 5.1.2. #### Improved - More distinguishable emojis in the 3-choice Smiley scale. #### Fixed - Excessive spacing between Smiley scale emojis in the 3-choice layout. - Back button icon color on dark backgrounds on Android. - An issue on Android where "Submit" was displayed instead of "Start Survey" on the welcome CTA point after navigating back to it. - Issue on iOS with non visible Submit button in multiple choice questions. ## 5.1.0 (2024-07-19) #### New - Navigation buttons are available now. When enabled, your survey respondents can go back to the previous questions, see their selected answers, and change them if necessary. #### Improved - Higher resolution of Smiley scale icons on Android. #### Updated - Bumping up reference of Android to 5.1.0. - Bumping up reference of iOS to 5.1.1. #### Fixed - Propagating Matrix answer in `SurvicateAnswer.value` of event listener. - An issue on Android that resulted in unexpected vertical padding for Matrix question in full screen mode. - Configuration json will be printed in console only in verbose log level on iOS. ## 5.0.0 (2024-06-19) #### New - Matrix question type added. #### Updated - Bumping up reference of Android to 5.0.0. - Bumping up reference of iOS to 5.0.0. #### Fixed - UI state bugs related to Activity's configuration changes. - Animation resource names that could conflict with resources of the app or other libraries on Android. - An issue on iOS where `setUserTraits` cleared previously set user traits. ## 4.4.0 (2024-05-09) #### New - New targeting option available – event properties. You can add multiple properties to one event and join them with either "or" or "and" operator. Property names and values are case-sensitive. Only string values are supported. - SDK now supports listeners. #### Updated - Bumping up reference of Android to 4.4.0. - Bumping up reference of iOS to 4.4.0. #### Fixed - A bug in Android that could prevent a survey from being displayed if a delay was set for multiple screens in the panel. - Horizontal mode support for Numerical Rating question for up to 5 items in Android. ## 4.3.0 (2024-03-26) #### New - More flexible survey recurring options are available now. Now you can specify how many days / weeks / months / years should pass before the survey can appear again. It’s also possible to set after how many days / weeks / months / years the survey should stop recurring. - If you run several mobile surveys, now you can use survey throttling settings to specify a time frame that should pass between showing them. Use global throttling to set the same time frame for all your mobile surveys. Or use the survey level throttling to override the global settings and specify a different period before showing a particular survey. #### Updated - Bumping up reference of Android to 4.3.0. - Bumping up reference of iOS to 4.3.0. #### Fixed - Issue with recursive display of non-recurring survey on iOS. ## 4.2.0 (2024-03-20) #### New - New targeting filter is available - screen orientation (portrait mode or landscape mode targeting). You can either include or exclude one of the orientation modes. #### Updated - Bumping up reference of Android to 4.2.0. - Bumping up reference of iOS to 4.2.0. #### Improved - Performance enhancements in answers synchronization on Android. #### Fixed - An issue where SurveyActivity could crash when it was restored after process termination on Android. - A race condition in the recalling feature on Android. ## 4.0.1 (2024-01-23) #### Updated - Bumping up reference of Android to 4.0.2. - Bumping up reference of iOS to 4.0.2. #### Improved - Date format in user traits recalling. #### Fixed - A bug where users could see survey more times than specified in recurrence settings if SDK was updated in meantime. - Sending user attributes to backend only when necessary in Android. - An issue where Thank you screen don't close survey in classic theme in iOS. ## 4.0.0 (2024-01-09) #### New - User conditions targeting is changed to the audience targeting: create an audience that will be available for usage among all your mobile surveys. Enable multiple audiences at the same time in one survey if necessary. - User attributes now support not only string values but also numbers, boolean, and datetime values. - New attribute operators are available to support new data types. - Survey audience can be set not only by including a set of respondents who met the required criteria but also by excluding those who should not see the survey. - And / or operators in audience targeting are switchable now: within one attribute filter that has several attributes in it and between different filters. #### Breaking - Method `setUserTrait` now takes single `UserTrait` argument instead of two String arguments. - Method `setUserTraits` now takes `List` argument instead of `Map` argument. #### Updated - Bumping up reference of Android to 4.0.1. - Bumping up reference of iOS to 4.0.0. - Use `NetworkCapabilities` to check internet connection (API 24+). - Migrate to `WindowCompat` APIs for setting full screen background. #### Fixed - Fixed invalid survey closing when app has specified `android:enableOnBackInvokedCallback="true"` in the AndroidManifest.xml. ## 3.0.5 (2023-12-14) #### Updated - Bumping up references: Android to 3.0.6. - AGP to 8.1.2. - Kotlin to 1.9.10. - AndroidX RecyclerView to 1.3.2. - Creating User Trait requires non null key. - Added a Proguard rule for User Traits. #### Fixed - Issue on Android with saving User Traits that could cause crash whenever saved User Trait key was null. - Issue on Android where answers saved without internet were not synchronized in next app sessions. - Issue on Android with javadoc generation. ## 3.0.4 (2023-10-02) #### Fixed - Bumping up references: Android to 3.0.4 and iOS to 3.0.4. - Issue on iOS where surveys were not translated when app language was set to dialect. - Issue on iOS where rating scale question answer ID was missing in listener. - On Android, added image scaling to shapes rating questions to fit all answers on the screen in horizontal layout. - Issue on Android on Thank You question with button's title not using text from survey settings. - Issue on Android where in some cases survey was not dismissible. ## 3.0.2 (2023-09-19) #### New - First version of the SDK, with references to the native Survicate SDKs version 3.0.2. --- # Unity SDK Source: https://developers.survicate.com/mobile-sdk/unity/ The Survicate Unity SDK will increase your APK size by approximately 2.5MB when obfuscated and your IPA size by approximately 2.2 MB. Note that the SDK features a Time To Live (TTL) mechanism of 60 seconds. This means any modifications made to your survey will be reflected on your respondents' devices after a delay of up to 60 seconds. ## Requirements - Using Survicate Mobile SDK requires an account at survicate.com. You can create your account [here](https://www.survicate.com) for free, or become invited to your company account by one of your colleagues. - Additionally, please check [iOS](/mobile-sdk/ios/) and [Android](/mobile-sdk/android/) library requirements, as they're applicable too. ## Recommendations - We recommend using Unity version 2021 LTS or higher. > **Note:** > #### Apps using Survicate SDK after 1st March 2026: > > Unity: > > - Survicate SDK version 6.0.0 or higher (required). > - Unity version 2022 LTS or higher (recommended). > > Android: > > - CompileSdk version 35 or higher (required). > - Android Gradle Plugin version 8.6.x or higher with compatible Gradle version (required). > - Kotlin version 2.0 or higher (required). > > iOS: > > - Respondent's device running iOS 15.0 or higher (required). - [Installation](/mobile-sdk/unity/installation) - [Configuration](/mobile-sdk/unity/configuration) - [Using SDK](/mobile-sdk/unity/using-sdk) - [Changelog](/mobile-sdk/unity/changelog) --- # Unity SDK installation Source: https://developers.survicate.com/mobile-sdk/unity/installation/ The Survicate Unity SDK is distributed as source files in the [survicate-unity-sdk](https://github.com/Survicate/survicate-unity-sdk) GitHub repository. Clone or download the repository, then copy all `.cs` files from its [`Plugins`](https://github.com/Survicate/survicate-unity-sdk/tree/master/Plugins) directory to `Assets/Plugins` in your Unity project. `SurvicatePluginIOS.cs` and `SurvicatePluginAndroid.cs` are wrapped in `#if UNITY_IOS` / `#if UNITY_ANDROID`, so copying the whole set is safe even if you build for one platform only. The platform-specific native files come next. ## iOS 1. Copy the files from the repository's [`Plugins/iOS`](https://github.com/Survicate/survicate-unity-sdk/tree/master/Plugins/iOS) directory (`SurvicateNativeBridgeIOS.mm`, `SurvicateNativeListener.h`, `SurvicateNativeListener.m`) to `Assets/Plugins/iOS` in your Unity project. 2. Download the latest iOS SDK from [here](https://repo.survicate.com/latest/ios/Survicate.zip), unzip it and copy `Survicate.xcframework` to your exported Xcode project folder. Inside your exported Xcode project, on **Build Phases -> Link Binary With Libraries**, add `Survicate.xcframework` ## Android 1. Copy the files from the repository's [`Plugins/Android`](https://github.com/Survicate/survicate-unity-sdk/tree/master/Plugins/Android) directory (`SurvicateNativeBridgeAndroid.java`, `SurvicateNativeEventListener.java`) to `Assets/Plugins/Android` in your Unity project. 2. Define `https://repo.survicate.com` Maven repository in one of the following ways: ```groovy title="settingsTemplate.gradle" dependencyResolutionManagement { // ... repositories { // ... maven { url 'https://repo.survicate.com' } } } ``` ```groovy title="mainTemplate.gradle" allprojects { repositories { // ... maven { url 'https://repo.survicate.com' } } } ``` 3. Add Survicate SDK dependency to your app's `build.gradle` file. ```groovy title="Groovy" dependencies { // ... implementation 'com.survicate:survicate-sdk:8.3.1' } ``` --- # Unity SDK configuration Source: https://developers.survicate.com/mobile-sdk/unity/configuration/ ## Configuration for Android 1. Configure your *workspace key* in `AndroidManifest.xml` file. ```xml title="AndroidManifest.xml" ``` When using Proguard or R8, add the following rules to your custom Proguard file. ```text -keep class SurvicateNativeBridgeAndroid { *; } -keep interface SurvicateNativeEventListener { *; } ``` ## Configuration for iOS Add workspace key to your `Info.plist` file: - Create `Survicate` *Dictionary*. - Define `WorkspaceKey` *String* in `Survicate` *Dictionary*. Your `Info.plist` file should look like this: ![Info.plist example](/ios-infoplist.png) As an alternative to the main way of specifying the Workspace Key, you can also use the `SetWorkspaceKey()` method. Important: * Using `SetWorkspaceKey()` method overrides the Workspace Key defined in the configuration. * `SetWorkspaceKey()` method must be used before `Initialize()` method is called. ```csharp using Plugins.Survicate; Survicate.SetWorkspaceKey('your_workspace_key'); ``` ## Initialization Initialize the SDK in your application using `Initialize()` method. Call this method only once, in the main script of your project. ```csharp using Plugins.Survicate; Survicate.Initialize(); ``` --- # Using the Unity SDK Source: https://developers.survicate.com/mobile-sdk/unity/using-sdk/ Survicate allows you to launch precisely targeted surveys inside your app. In the Survicate Panel, you can set conditions that need to be met for the surveys to appear. Users matching conditions defined in the Survicate panel will see the survey automatically. Here's a list of conditions you can use to target your surveys: - Name of the screen that a user currently sees - Any application event - User attributes and identities - Language of the device - Operating system Make sure to list all the screens and events described in your application. Once you got this covered, you or any person responsible for creating and managing surveys will be able to trigger surveys from the Survicate panel with no need for you to update the application. ## Targeting a survey by screen name A survey can appear when a user is viewing a specific screen. For example, a survey can be triggered to show up on the application's home screen after a user spends more than ten seconds there. To set it up, you need to send information to Survicate about the user entering and leaving a screen. _Note: Multiple active screens are allowed. In specific, calling EnterScreen() does not make the previous screen to be discarded. Be sure to call LeaveScreen() when you no longer want the screen to be treated as active._ ```csharp using Plugins.Survicate; Survicate.EnterScreen("your_screen_key"); Survicate.LeaveScreen("your_screen_key"); ``` _Screen name is case sensitive. If there's any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Events-based survey targeting The SDK allows you to launch surveys based on events your users trigger in your app. Your survey will show instantly after an event occurs in your app. ```csharp using Plugins.Survicate; // event without properties Survicate.InvokeEvent("your_event_name"); // event with properties Dictionary eventProperties = new Dictionary(); eventProperties.Add("property1", "value1"); eventProperties.Add("property2", "value2"); Survicate.InvokeEvent("your_event_name", eventProperties); ``` _Event name and property keys are case sensitive. If there is any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the application code, the survey will not appear._ ## Passing user attributes You can provide user attributes to Survicate as an extra layer of information about your users. The attributes have various use cases: * Identification of survey participants (answers are anonymous by default). * Directing surveys to particular users (Audience filters). * Filtering responses. * Recalling data in questions. ```csharp using Plugins.Survicate; Survicate.SetUserTrait(new UserTrait("name", "John")); Survicate.SetUserTrait(new UserTrait("age", 25)); Survicate.SetUserTrait(new UserTrait("count", 0.1)); Survicate.SetUserTrait(new UserTrait("isActive", true)); Survicate.SetUserTrait(new UserTrait("birthDate", DateTime.Now)); ``` _Bear in mind that user attributes are cached. You only need to provide them once, e.g. when user logs in, not after each initilization. You can also change their values at any time to trigger a survey._ **Attribute types** - **string**: any text. - **int**: an integer. - **double**: a decimal. - **bool**: a logic value. - **DateTime**: a `Date` object suitable for use with date or time interval Audience filters (the time interval filter measures elapsed time from a given timestamp). **Special attributes** - **user_id**: This corresponds to the "Logged-in status" in the panel's Audience filter. A user is considered logged-in when a trait with the "user_id" key has been set on the device, regardless of the value. - **first_name**, **last_name**, **email**: If none of these is specified, a response will be marked as Anonymous in the panel. **Additional notes** You can set your own attribute keys without any prior registration. They will show up in the panel once any response with the attribute is uploaded. ## Response attributes Response attributes are session-scoped attributes attached to survey responses. Unlike user attributes, they are cleared at the start of each new app session and are sent to Survicate along with the user's survey answers. To update a response attribute, call the method again with the same name and a new value. To clear an attribute, pass an empty string as the value. ```csharp // set a single attribute Survicate.SetResponseAttribute(new ResponseAttribute("promo_code", "SAVE20")); // or multiple attributes at once Survicate.SetResponseAttributes(new List { new ResponseAttribute("campaign_id", "summer-2024"), new ResponseAttribute("age", 18), new ResponseAttribute("subscription_active", true), new ResponseAttribute("trial_started_at", DateTime.Now) }); ``` `ResponseAttribute` accepts the following parameters: - **name** (required): The key that identifies the attribute. - **value** (required): The attribute value. Pass an empty string to clear an existing attribute. - **provider** (optional): The name of the external service where this data comes from (e.g., "hubspot", "intercom"). This helps integrations identify and match your survey respondents with their profiles in that service. **Attribute types** - **string**: any text. - **int**: an integer. - **double**: a decimal. - **bool**: a logic value. - **DateTime**: a `Date` object. ## Setting the locale Survicate SDK automatically detects the device locale and uses it both to choose the translation of a survey and to evaluate any Device language targeting filters. If your app allows users to change the locale independently of the system settings, you can override the default by calling: ```csharp using Plugins.Survicate; Survicate.SetLocale("en-US"); ``` The argument must be a valid IETF language tag such as: - A two‑letter ISO 639 code (e.g., "en", "fr") - A three-letter code for languages without the two-letter equivalent (e.g., "haw", "yue") - A language tag with region (e.g., "en-US", "pt-BR") _Note: The specified locale setting applies only to the current application session. To preserve the preference after an app restart, make sure to call `SetLocale(...)` again, anytime after `Survicate.Initialize(...)`._ ## Theme mode When your survey has a theme with both light and dark modes, the SDK will select the proper variant following the system setting by default. Optionally, you can enforce a specific theme mode with the `SetThemeMode` method: ```csharp using Plugins.Survicate; // Light, Dark, or Auto Survicate.SetThemeMode(ThemeMode.Auto); ``` ## Event listeners SDK allows you to utilize event listeners. You may find them useful to trigger actions in your application based on actions performed by respondents. Here's a list of events you can subscribe to: * onSurveyDisplayed - occurs when survey is loaded and appears in the User Interface * onQuestionAnswered - occurs after a question is answered ( Survicate stores incomplete survey submissions ) * onSurveyClosed - occurs when a user closes the survey using the close button * onSurveyCompleted - occurs when a user finishes the survey ```csharp using Plugins.Survicate; SurvicateEventListener survicateEventListener = new SurvicateEventListener( onSurveyDisplayed: (SurveyDisplayedEvent event) => /* Implement action */, onQuestionAnswered: (QuestionAnsweredEvent event) => /* Implement action */, onSurveyClosed: (SurveyClosedEvent event) => /* Implement action */, onSurveyCompleted: (SurveyCompletedEvent event) => /* Implement action */ ); Survicate.AddSurvicateEventListener(survicateEventListener); Survicate.RemoveSurvicateEventListener(survicateEventListener); ``` ### _SurvicateAnswer_ properties (_QuestionAnsweredEvent.answer_) | Property | Type | Description | |:---------|:------------|:-----------------------------------------------------------------------------------------------| | type | string | Answer type. One of: ['text', 'single', 'multiple', 'smiley_scale', 'rating', 'csat', 'numerical_scale', 'nps', 'date', 'form', 'matrix', 'button_close', 'button_next', 'button_link']. | | id | long? | Answer ID. **Applicable only for types: ['single', 'smiley_scale', 'csat', 'rating', 'numerical_scale'].** | | ids | List<long> | Selected answer IDs. **Applicable only for type = ['multiple'].** | | value | string | Text representation of an answer, e.g. "Happy" for smiley scale. A `null` value in case of a skipped question. **Not applicable for call-to-action answers: ['button_close', 'button_next', 'button_link'].** | _The `id`, `ids` and `value` properties are provided only for the cases enlisted in the table above. Therefore, expect that there might be answer objects that consist only of the `type` property._ ## Reseting user data for testing purposes If you need to test surveys on your device, the `reset()` method can be useful. It clears all user data stored on the device — including survey views, attributes, and information about answered surveys — as well as the current in-memory state of the SDK. ```csharp using Plugins.Survicate; Survicate.Reset(); ``` --- # Unity SDK changelog Source: https://developers.survicate.com/mobile-sdk/unity/changelog/ Releases of the Survicate Unity SDK, newest first. ## 8.3.2 (2026-08-13) #### Updated - Version Alignment: Updated the Unity SDK version to 8.3.2 to match the latest release of the native iOS SDK (Version 8.3.2). ## 8.3.1 (2026-07-22) #### Updated - Version Alignment: Updated the Unity SDK version to 8.3.1 to match the latest release of the native Android SDK (Version 8.3.1) and iOS SDK (Version 8.3.1). ## 8.3.0 (2026-07-01) #### Updated - Version Alignment: Updated the Unity SDK version to 8.3.0 to match the latest release of the native Android SDK (Version 8.3.0) and iOS SDK (Version 8.3.0). ## 8.2.0 (2026-06-12) #### Updated - Version Alignment: Updated the Unity SDK version to 8.2.0 to match the latest release of the native Android SDK (Version 8.2.0) and iOS SDK (Version 8.2.0). ## 8.1.1 (2026-05-29) #### Updated - Version Alignment: Updated the Unity SDK version to 8.1.1 to match the latest release of the native Android SDK (Version 8.1.1) and iOS SDK (Version 8.1.2). ## 8.1.0 (2026-05-27) #### Updated - Version Alignment: Updated the Unity SDK version to 8.1.0 to match the latest release of the native Android SDK (Version 8.1.0) and iOS SDK (Version 8.1.1). ## 8.0.2 (2026-05-13) #### Updated - Version Alignment: Updated the Unity SDK version to 8.0.2 to match the latest release of the native Android SDK (Version 8.0.1) and iOS SDK (Version 8.0.2). ## 8.0.1 (2026-05-05) #### Updated - Version Alignment: Updated the Unity SDK version to 8.0.1 to match the latest release of the native iOS SDK (Version 8.0.1). ## 8.0.0 (2026-04-15) #### Updated - Version Alignment: Updated the Unity SDK version to 8.0.0 to match the latest release of the native Android SDK (Version 8.0.0) and iOS SDK (Version 8.0.0). ## 7.3.0 (2026-03-27) #### Updated - Version Alignment: Updated the Unity SDK version to 7.3.0 to match the latest release of the native Android SDK (Version 7.3.0) and iOS SDK (Version 7.3.0). ## 7.2.0 (2026-03-03) #### New - Response attributes can now be attached to survey responses via `Survicate.SetResponseAttributes` method. Use `ResponseAttribute` to pass key-value pairs of type String, Number, Boolean, or DateTime alongside response data. - SDK fonts are customizable using `Survicate.SetFonts`, allowing surveys to match your app's typography. #### Updated - Version Alignment: Updated the Unity SDK version to 7.2.0 to match the latest release of the native Android SDK (Version 7.2.0) and iOS SDK (Version 7.2.0). ## 7.1.0 (2026-02-18) #### New - You can now adjust the survey theme based on your app mode. The supported theme modes are: - auto (default) - light - dark The additional theme version should be added in the panel first. #### Updated - Version Alignment: Updated the Unity SDK version to 7.1.0 to match the latest release of the native Android SDK (Version 7.1.1) and iOS SDK (Version 7.1.1). ## 7.0.0 (2026-01-21) #### Updated - Version Alignment: Updated the Unity SDK version to 7.0.0 to match the latest release of the native Android SDK (Version 7.0.0) and iOS SDK (Version 7.0.0). ## 6.4.6 (2026-01-07) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.6 to match the latest release of iOS SDK (Version 6.4.6). ## 6.4.5 (2025-12-11) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.5 to match the latest release of the native Android SDK (Version 6.4.3) and iOS SDK (Version 6.4.5). ## 6.4.4 (2025-11-26) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.4 to match the latest release of iOS SDK (Version 6.4.4). ## 6.4.3 (2025-10-28) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.3 to match the latest release of the native Android SDK (Version 6.4.2) and iOS SDK (Version 6.4.3). ## 6.4.2 (2025-09-30) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.2 to match the latest release of the native Android SDK (Version 6.4.1) and iOS SDK (Version 6.4.2). ## 6.4.1 (2025-09-15) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.1 to match the latest release of the native iOS SDK (Version 6.4.1). ## 6.4.0 (2025-09-01) #### Updated - Version Alignment: Updated the Unity SDK version to 6.4.0 to match the latest release of the native Android SDK (Version 6.4.0) and iOS SDK (Version 6.4.0). ## 6.3.5 (2025-08-25) #### Updated - Version Alignment: Updated the Unity SDK version to 6.3.5 to match the latest release of the native Android SDK (Version 6.3.3) and iOS SDK (Version 6.3.7). ## 6.3.4 (2025-07-22) #### Updated - Version Alignment: Updated the Unity SDK version to 6.3.4 to match the latest release of native iOS SDK (Version 6.3.4). ## 6.3.3 (2025-07-18) #### Updated - Version Alignment: Updated the Unity SDK version to 6.3.3 to match the latest release of native iOS SDK (Version 6.3.3). ## 6.3.2 (2025-06-12) #### Updated - Version Alignment: Updated the Unity SDK version to 6.3.2 to match the latest release of native Android SDK (Version 6.3.1). ## 6.3.1 (2025-05-26) #### Updated - Version Alignment: Updated the Unity SDK version to 6.3.1 to match the latest release of native iOS SDK (Version 6.3.1). ## 6.3.0 (2025-05-22) #### New - Survey language can be changed independently of the app's language by using a new locale-forcing method. #### Updated - Version Alignment: Updated the Unity SDK version to 6.3.0 to match the latest release of the native Android SDK (Version 6.3.0) and iOS SDK (Version 6.3.0). ## 6.2.1 (2025-04-23) #### Fixed - An issue with double value conversion in UserTrait. ## 6.2.0 (2025-03-18) #### Updated - Version Alignment: Updated the Unity SDK version to 6.2.0 to match the latest release of the native Android SDK (Version 6.2.0) and iOS SDK (Version 6.2.0). ## 6.1.0 (2025-03-12) #### Updated - Version Alignment: Updated the Unity SDK version to 6.1.0 to match the latest release of the native Android SDK (Version 6.1.0) and iOS SDK (Version 6.1.0). ## 6.0.0 (2025-02-19) #### Breaking - SDK requires CompileSDK 34 or higher. - SDK requires minimum deployment target of iOS 14. #### Updated - Version Alignment: Updated the Unity SDK version to 6.0.0 to match the latest release of the native Android SDK (Version 6.0.0) and iOS SDK (Version 6.0.0). ## 5.5.3 (2025-01-03) #### Updated - Updated the documentation to reflect simplified integration steps (replaced manual .aar import with Gradle dependency). - Removed androidx.annotation import from Android Bridge. ## 5.5.2 (2024-12-20) #### Updated - Version Alignment: Updated the Unity SDK version to 5.5.2 to match the latest minor release of the native Android SDK (Version 5.5.1) and iOS SDK (Version 5.5.2). ## 5.5.1 (2024-12-10) #### Updated - Version Alignment: Updated the Unity SDK version to 5.5.1 to match the latest minor release of the native Android SDK (Version 5.5.0) and iOS SDK (Version 5.5.1). ## 5.5.0 (2024-12-06) #### Updated - Version Alignment: Updated the Unity SDK version to 5.5.0 to match the latest minor release of the native Android SDK (Version 5.5.0) and iOS SDK (Version 5.5.0). ## 5.4.0 (2024-10-23) #### Updated - Version Alignment: Updated the Unity SDK version to 5.4.0 to match the latest minor release of the native Android SDK (Version 5.4.0) and iOS SDK (Version 5.4.0). ## 5.3.0 (2024-09-13) #### Updated - Version Alignment: Updated the Unity SDK version to 5.3.0 to match the latest minor release of the native Android SDK (Version 5.3.0) and iOS SDK (Version 5.3.0). ## 5.2.0 (2024-09-05) #### Updated - Version Alignment: Updated the Unity SDK version to 5.2.0 to match the latest minor release of the native Android SDK (Version 5.2.0) and iOS SDK (Version 5.2.0). ## 5.1.1 (2024-08-01) #### Updated - Version Alignment: Updated the Unity SDK version to 5.1.1 to match the latest patch release of the native Android SDK (Version 5.1.1) and iOS SDK (Version 5.1.2). ## 5.1.0 (2024-07-19) #### Updated - Version Alignment: Updated the Unity SDK version to 5.1.0 to match the latest minor release of the native Android SDK (Version 5.1.0) and iOS SDK (Version 5.1.1). ## 5.0.0 (2024-06-18) #### Updated - Version Alignment: Updated the Unity SDK version to 5.0.0 to match the latest major release of the native Android and iOS SDKs (Version 5.0.0). ## 4.4.0 (2024-05-07) #### New - New targeting option available – event properties. You can add multiple properties to one event and join them with either "or" or "and" operator. Property names and values are case-sensitive. Only string values are supported. - SDK now supports listeners. ## 4.0.0 (2024-01-19) #### New - User conditions targeting is changed to the audience targeting: create an audience that will be available for usage among all your mobile surveys. Enable multiple audiences at the same time in one survey if necessary. - User attributes now support not only string values but also numbers, boolean, and datetime values. - New attribute operators are available to support new data types. - Survey audience can be set not only by including a set of respondents who met the required criteria but also by excluding those who should not see the survey. - And / or operators in audience targeting are switchable now: within one attribute filter that has several attributes in it and between different filters - Please note aforementioned changes are only available when using native SDK version 4.0.0 and above. #### Updated - SetUserTrait(string, string) is deprecated, please use SetUserTrait(UserTrait) instead. #### Fixed - Fixed issue with argument name and use mismatch in Android. - Fixed issue with setting UserTraits in Android. --- # Survicate Segment Integration Source: https://developers.survicate.com/mobile-sdk/segment-integration/ Survicate Mobile SDK can be integrated with Segment. Segment is a customer data platform (CDP) that helps you collect, clean, and control your customer data. When integrated with Segment, you can pass your customer data seamlessly to Survicate. There are two use cases for using the customer data in Survicate: - Events, attributes, and screen names can be used to trigger surveys - Attributes can be used to filter your survey results # Installation For the integration to work, you need to install one of our plugins listed below: - [React Native Segment Plugin](https://github.com/Survicate/analytics-react-native-survicate) - [Swift Segment Plugin](https://github.com/Survicate/analytics-swift-survicate) - [Kotlin Segment Plugin](https://github.com/Survicate/analytics-kotlin-survicate) --- # UXCam Integration Source: https://developers.survicate.com/mobile-sdk/uxcam-integration/ Survicate and UXCam integration improves mobile user experience analysis. UXCam is a user experience analytics tool that helps businesses understand how users interact with their mobile apps. The integration allows you to send survey responses as custom events to UXCam and seamlessly access UXCam user sessions within Survicate. Popular use cases include: - Discover which elements of your mobile app can be improved. - Find out what’s causing people to feel the way they do about your brand or app. - Reorganize your audience knowledge to improve targeting # Installation For the integration to work, you need to use one of our plugins listed below: - [Survicate-UXCam iOS plugin](https://github.com/Survicate/survicate-uxcam-integration-ios) - [Survicate-UXCam Android plugin](https://github.com/Survicate/survicate-uxcam-integration-android) - [Survicate-UXCam React Native plugin](https://github.com/Survicate/survicate-uxcam-integration-react-native) --- # FullStory Integration Source: https://developers.survicate.com/mobile-sdk/full-story-integration/ Survicate and FullStory integration helps you understand and improve mobile user experiences. FullStory is a digital experience analytics platform that reveals how people interact with your mobile apps. The integration lets you send survey responses as custom events to FullStory and instantly access FullStory session replays directly from Survicate. Popular use cases include: - Identify which parts of your mobile app need improvement. - Uncover what drives user sentiment toward your brand or app. - Combine behavioral data with survey insights to refine targeting and personalization. # Installation For the integration to work, you need to use one of our plugins listed below: - [Survicate-FullStory iOS plugin](https://github.com/Survicate/survicate-fullstory-integration-ios) - [Survicate-FullStory Android plugin](https://github.com/Survicate/survicate-fullstory-integration-android) --- # JavaScript SDK Source: https://developers.survicate.com/javascript/ The Survicate JavaScript SDK allows you to collect feedback from your website and web app users. Installed in your app, the SDK allows you to trigger targeted micro-surveys to understand your users better and collect feedback about product or service you provide. **Requirements:** - Using Survicate JavaScript SDK requires an account at [survicate.com](https://survicate.com). You can create your account [here](https://panel.survicate.com/signup) for free, or become invited to your company account by one of your colleagues. - [Installation](/javascript/installation) - [Methods](/javascript/methods) - [Event Listeners](/javascript/events) - [Changelog](/javascript/js-sdk-changelog) --- # Installation Source: https://developers.survicate.com/javascript/installation/ ## Overview Survicate offers several installation methods to choose from, depending on your needs and preferences: - Manual JavaScript code installation - Survicate Web Package - Survicate Web Surveys Wrapper - Via Segment - Wordpress Plugin - Google Tag Manager Plugin - Braze ### Manual implementation By opting for Manual implementation or utilizing the Survicate Web Surveys Wrapper, you ensure automatic access to the latest SDK version. These methods negate the need for frequent updates whenever Survicate releases new SDK features. ### NPM packages Survicate offers two NPM packages for integrating surveys into your JavaScript applications: the Survicate Web Package, designed for embedding surveys directly within your code, and the Survicate Web Surveys Wrapper, optimized for easy installation of Survicate's tracking code in your codebase. - [Survicate Web Package on npmJS](https://www.npmjs.com/package/@survicate/survicate-web-package) - [Survicate Web Surveys Wrapper on npmJS](https://www.npmjs.com/package/@survicate/survicate-web-surveys-wrapper) ### Comparison: Web Package vs. Web Surveys Wrapper | Feature | Web Package | Web Surveys Wrapper | | ------------------------------| ---------------------------------------------------| ----------------------------------------------------------| | **Integration Type** | Direct integration in JavaScript applications | Installation of Survicate tracking code | | **HTML Impact** | Does not add any script to the HTML document | Adds script to the HTML document | | **Security** | Prioritizes security, no external scripts required | - | | **TypeScript Support** | Includes TypeScript type definitions | Includes TypeScript type definitions | | **Version Updates** | Manual updates for new SDK versions | Automatically uses the latest Survicate SDK version | ## Workspace Key Workspace key is a unique identifier of your teamspace on Survicate account. It will be needed to complete the installation. Your workspace key can be obtained via your Survicate account [here](https://panel.survicate.com/o/0/w/0/settings/access-keys) ## Installation methods ### Manual implementation Place this code right before the `` tag of your website or web app. ```html ``` Information about the code being installed is sent to Survicate the moment your site is loaded with our code on it. To verify installation on your own, you can use the _svc method in the browser console. It should return your Workspace Key. ### NPM packages This section applies only to users, who decided to install Survicate tracking code either via the npm web surveys package, or npm wrapper. **Installation** ```bash title="Web package" npm install @survicate/survicate-web-package --save ``` ```bash title="Web surveys wrapper" npm install @survicate/survicate-web-surveys-wrapper --save ``` **Initialization** ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' const key = "workspace key" // Your key from the panel Survicate.init({workspaceKey: key}); ``` ```javascript title="Web surveys wrapper" import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key' }; // Your key from the panel await initSurvicate(config) ``` ### Segment Survicate can be installed with Segment. Follow [these instructions](https://help.survicate.com/en/articles/3942525-segment-integration#installing-survicate-tracking-code-with-segment), to add Survicate as a destination in Segment. ### WordPress Use our WordPress plugin to install Survicate on your WordPress website. Follow [these instructions](https://help.survicate.com/en/articles/3937898-installing-survicate-on-wordpress-sites) and use this workspace key during the installation. ### Google Tag Manager To install Survicate using Google Tag Manager, follow [this article](https://help.survicate.com/en/articles/3937897-google-tag-manager). ### Braze To install Survicate using Braze, follow [this article](https://help.survicate.com/en/articles/9060740-braze-integration). Braze in-app messages are displayed in an iframe by default while the app's background is blocked. To allow interaction with your app, while Survicate surveys are displayed, you need to: 1. Add `opts.useBrazeIframeClipper = true` to your Survicate-Braze snippet. A sample snippet: ```html ``` 2. Integrate the Braze bridge using one of the following options: - **NPM package**: Install `@survicate/braze-bridge-npm` [package](https://www.npmjs.com/package/@survicate/braze-bridge-npm) in the file where you initialize Braze and use the `initBrazeBridge` function. - **Script snippet**: Add the following script to your page. With `data-auto-init="true"`, the Braze bridge will be automatically launched: ```html ``` A sample React implementation (NPM package): ```javascript import { initBrazeBridge } from '@survicate/braze-bridge-npm'; const setupBraze = () => { braze.changeUser('user@survicate.com'); braze.subscribeToInAppMessage((message) => { braze.showInAppMessage(message); }); braze.automaticallyShowInAppMessages(); braze.openSession(); }; const initializeBraze = () => { if (braze.isInitialized()) return; braze.initialize('BRAZE_APP_ID', { baseUrl: 'BRAZE_BASE_URL', enableLogging: true, allowUserSuppliedJavascript: true }); } useEffect(() => { initBrazeBridge(); initializeBraze(); setupBraze(); }, []); ``` ## Users identification Each time a user answers a Survicate survey they're assigned a unique, anonymous ID. For most companies it makes sense to have these responses identified. To do so, you can pass user IDs and attributes from your website or web app. Here's a sample implementation: ```javascript title="Manual implementation" // Define user IDs before the init of the tracking code. (function(opts) { opts.traits = { "user_id": "Your user ID here" }; })(window._sva = window._sva || {}); // Your tracking code goes here ``` ```javascript title="Web package" const traits = {'user_id': 'Your user ID here'}; Survicate.setVisitorTraits(traits); ``` ```javascript title="Web surveys wrapper" // Initialize survicate, then use: const survicate = getSurvicateInstance(); const traits = {'user_id': 'Your user ID here'}; // Set user attributes survicate.setVisitorTraits(traits); ``` ## User attributes Survicate lets you also pass other attributes. Attributes provide deeper insight into collected feedback. You can use them to target the right audiences and filter survey results. Some example attributes that can be passed to Survicate are: - Company name - Subscription name - Signed up date User attributes can be seen on their profile in the respondents tab. ### Supported Attribute Types - **String**: Any textual data, e.g. company names, user name, etc. - **Numbers**: Includes integers and decimals, both positive and negative. - **Boolean**: True or false values. - **Date**: Accepts date objects created using `Date()` constructor: `new Date('1995-12-17T03:24:00')` or dates in ISO 8601 format (e.g., `YYYY-MM-DDTHH:MM:SSZ`). ***Important to note:*** - Attribute name and value can have max length of 255 characters. Longer values will be truncated to 255 characters. - Strings should not be enclosed within the following characters: {}, *, [], %, ~, --, $ (e.g., 'name':'$john$'). - Attribute names are case sensitive. To pass user attributes to Survicate and use them for survey targeting, you should define these attributes when initializing Survicate. Please note that attribute names are case-sensitive, whereas attribute values are not. ```javascript title="Manual implementation" // Define attributes when initializing the tracking code (function(opts) { opts.traits = { "user_id": "Your user ID here", "company_name": "Value here", "subscription_status": "Value here", "signed_up": "Value here" }; })(window._sva = window._sva || {}); /// Your tracking code goes here ``` ```javascript title="Web package" const config = { workspaceKey: 'workspace key', traits: { 'user_id': 'Your user ID here', 'company_name': 'Value here', 'subscription_status': 'Value here', 'signed_up': 'Value here' } }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" const config = { workspaceKey: 'workspace key', traits: { 'user_id': 'Your user ID here', 'company_name': 'Value here', 'subscription_status': 'Value here', 'signed_up': 'Value here' } }; await initSurvicate(config); ``` ## Survey language By default, Survicate automatically detects the appropriate survey language using the following priority: 1. **`` attribute** - the language your page declares on its `` element (only when enabled via [`useHtmlLangAttribute`](#detect-language-from-the-html-lang-attribute)) 2. **URL language** - query parameters (e.g., `?lang=de`), path segments (e.g., `/de/page`), or top-level domain (e.g., `.de`) 3. **Browser language** - the user's browser language settings You can override this automatic detection by setting a forced language during initialization. This is useful when you know the user's preferred language from your application's settings or user profile. ```javascript title="Manual implementation" (function(opts) { opts.forcedLanguage = "de"; // ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pt-br") })(window._sva = window._sva || {}); // Your tracking code goes here ``` ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' const config = { workspaceKey: 'workspace key', // Your key from the panel forcedLanguage: 'de' // ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pt-br") }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key', // Your key from the panel forcedLanguage: 'de' // ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pt-br") }; await initSurvicate(config); ``` ***Important to note:*** - Forced language has the highest priority and overrides URL-based and browser-based language detection. - Forced language is session-based, so it will be applied only for the current session. - If user sets "pt-br" as language code, and only "pt" is available in your survey's translations, the survey will display in "pt" language. - If user sets "pt" as language code, and "pt-br" is available in your survey's translations, the survey will display in "pt-br" language. - The language code should be a valid [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code (e.g., `en`, `de`, `fr`, `es`, `pt`). - The specified language must be available in your survey's translations. If the language is not available, the survey will display in its default language. - To change the language dynamically after initialization, use the [`setSurveyLanguage`](/javascript/methods#set-survey-language) method. ### Detect language from the html lang attribute If your site declares its current language through the standard `lang` attribute on the `` element, you can opt in to using it as a language detection source with `useHtmlLangAttribute`. This is especially useful for single-page applications with an in-app language switcher, where the selected language is never reflected in the URL and the browser language may not match what the user picked. ```javascript title="Manual implementation" (function(opts) { opts.useHtmlLangAttribute = true; // read the survey language from })(window._sva = window._sva || {}); // Your tracking code goes here ``` ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' const config = { workspaceKey: 'workspace key', // Your key from the panel useHtmlLangAttribute: true // read the survey language from }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key', // Your key from the panel useHtmlLangAttribute: true // read the survey language from }; await initSurvicate(config); ``` ***Important to note:*** - The option is opt-in and off by default — without it, language detection works exactly as described above. - When enabled, the `` value is checked after a forced language ([`forcedLanguage`](#survey-language) / [`setSurveyLanguage`](/javascript/methods#set-survey-language)) but before URL-based and browser-based detection. - Language changes are picked up live: when your application updates the `` attribute (e.g., the user switches the language in your app, with no page reload), a survey that is currently open re-renders in the new language and any survey shown later uses it too. - An explicit language choice always wins: a language set via `setSurveyLanguage` or picked by the respondent in the survey's language selector is not overridden by later `` changes. - If the `` value has no matching survey translation, detection falls back to URL, browser, and default language as usual. - The option applies to website surveys (widget and feedback button). ## Survey theme By default, Survicate uses the `"auto"` theme mode, which follows the browser preference (light or dark). You can override this by setting a theme mode during initialization. This is useful when you want surveys to match your website's theme from the first load. Allowed values for `themeMode` are: - **`"light"`** – force surveys to use the light theme - **`"dark"`** – force surveys to use the dark theme For the dark theme to be applied, the survey's theme must have a dark mode variant configured in the Survicate panel. ```javascript title="Manual implementation" (function(opts) { opts.themeMode = "dark"; // "light", "dark" })(window._sva = window._sva || {}); // Your tracking code goes here ``` ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' const config = { workspaceKey: 'workspace key', // Your key from the panel themeMode: 'dark' // "light", "dark" }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key', // Your key from the panel themeMode: 'dark' // "light", "dark" }; await initSurvicate(config); ``` ***Important to note:*** - Theme mode is applied when the survey loads; behavior matches the [`setThemeMode`](/javascript/methods#set-theme-mode) method but is set at init. - To change the theme dynamically after initialization, use the [`setThemeMode`](/javascript/methods#set-theme-mode) method. ## Content Security Policy (CSP) Content Security Policy (CSP) serves as a safeguard against code injection attacks, where harmful content is executed within a trusted webpage. However, this security measure may interfere with the functionality of Survicate on your site. If you use CSP, you should update it with the following directives to ensure Survicate's surveys work effectively without compromising security: ```text script-src 'unsafe-inline' https://survey.survicate.com https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com https://survey-prd.survicate-cdn.com; style-src 'unsafe-inline' https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com; style-src-elem 'unsafe-inline' https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com; font-src https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com; img-src https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com https://assets.survicate.com https://img.survicate.com https://images.unsplash.com; connect-src https://respondent.survicate.com https://hv.survicate.com https://survey.survicate.com https://survey-prd.survicate-cdn.com https://production-respondent-uploads.s3.eu-west-1.amazonaws.com https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com; ``` ### Reducing the policy length If you are constrained by header size limits, you can shorten the policy in two ways. **Option 1 — Use wildcard subdomains** Replace the explicit subdomain lists with wildcard patterns. This reduces the policy by approximately 40%. Note that the full explicit list above is stricter — it allows only the exact subdomains Survicate currently uses, whereas wildcards would also cover any other subdomain under `survicate.com` and `survicate-cdn.com`. ```text script-src 'unsafe-inline' https://*.survicate.com https://*.survicate-cdn.com; style-src 'unsafe-inline' https://*.survicate.com https://*.survicate-cdn.com; style-src-elem 'unsafe-inline' https://*.survicate.com https://*.survicate-cdn.com; font-src https://*.survicate.com https://*.survicate-cdn.com; img-src https://*.survicate.com https://*.survicate-cdn.com https://images.unsplash.com; connect-src https://*.survicate.com https://*.survicate-cdn.com https://production-respondent-uploads.s3.eu-west-1.amazonaws.com; ``` **Option 2 — Remove entries that don't apply to your setup** Depending on your installation method and the features you use, some entries are not required: - **`script-src` Survicate domains** — only needed when loading Survicate via the remote script tag or the `@survicate/survicate-web-surveys-wrapper` NPM package. If you use the `@survicate/survicate-web-package` NPM package, no external scripts are fetched from Survicate servers, so you can remove the Survicate domains from `script-src` entirely. - **`img-src https://images.unsplash.com`** — only needed if your surveys contain images sourced from Unsplash (e.g. a background image selected from the Unsplash library in the survey editor). If none of your surveys use Unsplash images, you can remove this entry. - **`connect-src https://production-respondent-uploads.s3.eu-west-1.amazonaws.com`** — only needed if your surveys include a screenshot question. If you don't use the screenshot feature, you can remove this entry. ### Nonce Survicate allows users to implement nonce as an additional security measure when embedding scripts. A nonce (number used once) helps mitigate certain types of attacks, such as Cross-Site Scripting (XSS), by ensuring that each script request is authorized. **How to implement nonce with different installation types** ```javascript title="Manual implementation" ``` ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' const config = { workspaceKey: 'workspace key' // Your key from the panel nonce: 'nonce' // Your nonce }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key' // Your key from the panel nonce: 'nonce' // Your nonce }; await initSurvicate(config) ``` ### Disable sensitive data persistence The Disable Sensitive Data Persistence feature ensures that user data is stored only in Session Storage, not Local Storage. This means data is cleared when the browser or tab is closed, enhancing privacy by preventing long-term storage of sensitive information. ```javascript title="Manual implementation" ``` ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' const config = { workspaceKey: 'workspace key' // Your key from the panel disableSensitiveDataPersistence: true }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key' // Your key from the panel disableSensitiveDataPersistence: true }; await initSurvicate(config) ``` --- # Methods Source: https://developers.survicate.com/javascript/methods/ The Survicate JavaScript SDK allows you to trigger and adjust the behaviour of websites and web-app surveys. JavaScript methods used to trigger Survicate surveys, except `setVisitorTraits` can only be used on some of the paid plans. Check [our pricing page](https://survicate.com/pricing/#pricing-compare-plans) for more details. We refer to this feature as 'Advanced Targeting' or 'JavaScript Targeting'. ## Using NPM packages This section applies only to users, who decided to install Survicate tracking code either via the npm web surveys package, or npm wrapper. Before calling any of the methods or appending event listeners, you need to initialize the Survicate JavaScript SDK. ```javascript title="Web package" import Survicate from '@survicate/survicate-web-package/survicate_widget' // Initialize Survicate: const key = "..." // Workspace Key from the Survicate Panel Survicate.init({workspaceKey: key}); // Then you can use the Survicate object: Survicate.showSurvey('surveyId', { forceDisplay: true }); // In provided examples we will refer to the Survicate object. ``` ```javascript title="Web surveys wrapper" import { initSurvicate, getSurvicateInstance, ApiEvent } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper'; const config = { workspaceKey: 'workspace key' }; await initSurvicate(config).then(() => { const survicate = getSurvicateInstance(); survicate.showSurvey('surveyId', { forceDisplay: true }); }) //In provided examples for Web surveys wrapper we will refer to the survicate instance, as in provided example. ``` ***Please note***: In Web Surveys wrapper initSurvicate is asynchronous, so the user has to await its resolution. This should be done once, when initSurvicate hass been resolved, user can refer to `getSurvicateInstance()` as in provided example. Handling asynchronous code depends on the use case. # Methods ## Set visitor attributes To set the [visitor attributes](#traits) asynchronously after the script is loaded, you can use the `setVisitorTraits` method. ```javascript title="Manual implementation" _sva.setVisitorTraits({ "email": "Respondent's email", "first_name": "Respondent's name", "last_name": "Respondent's last name", "my_custom_attribute": "Custom attribute value" }); ``` ```javascript title="Web package" Survicate.setVisitorTraits({ "email": "Respondent's email", "first_name": "Respondent's name", "last_name": "Respondent's last name", "my_custom_attribute": "Custom attribute value" }); ``` ```javascript title="Web surveys wrapper" survicate.setVisitorTraits({ "email": "Respondent's email", "first_name": "Respondent's name", "last_name": "Respondent's last name", "my_custom_attribute": "Custom attribute value" }); ``` ***Please note***: The visitor attributes will be updated locally straight away, but the change will be visible in Survicate as soon as they answer any question. --- ## Set response traits Response traits are custom attributes tied to the current browser session. They are automatically included in survey answer payloads as part of the visit object and persist throughout the browser session. Response traits are stored in sessionStorage and are automatically cleared when the browser session ends. ### Widget surveys For Widget surveys, you can set response traits using the `setResponseTraits` method. The method accepts an array of objects, where each object contains: - `name` (required): The name of the attribute - `value` (required): The value of the attribute (string, number, boolean, or Date) - `provider` (optional): The source or integration that provided the attribute (e.g. `"hubspot"`) ```javascript title="Manual implementation" _sva.setResponseTraits([ { name: "campaign_id", value: "summer-2024", provider: "hubspot" }, { name: "promo_code", value: "SAVE20", provider: "salesforce" }, { name: "my_custom_attribute", value: "Custom attribute value" } ]); ``` ```javascript title="Web package" Survicate.setResponseTraits([ { name: "campaign_id", value: "summer-2024", provider: "hubspot" }, { name: "promo_code", value: "SAVE20", provider: "salesforce" }, { name: "my_custom_attribute", value: "Custom attribute value" } ]); ``` ```javascript title="Web surveys wrapper" survicate.setResponseTraits([ { name: "campaign_id", value: "summer-2024", provider: "hubspot" }, { name: "promo_code", value: "SAVE20", provider: "salesforce" }, { name: "my_custom_attribute", value: "Custom attribute value" } ]); ``` You can also initialize response traits for Widget surveys by setting them before the Survicate script loads: ```javascript window._sva = window._sva || {}; window._sva.responseTraits = [ { name: "campaign_id", value: "summer-2024", provider: "hubspot" }, { name: "promo_code", value: "SAVE20", provider: "salesforce" } ]; ``` --- ## Retarget Survicate triggers the targeting script to determine if a survey should be displayed to a user. This happens during events like a page load, the completion of a survey, or a path change in the Single Page Application. If you'd like to trigger an additional targeting script execution, you can use the `retarget` method. This feature can be especially useful for Single Page Applications / Progressive Web Applications or the callbacks of asynchronous methods. ```javascript title="Manual implementation" _sva.retarget(); ``` ```javascript title="Web package" Survicate.retarget(); ``` ```javascript title="Web surveys wrapper" survicate.retarget(); ``` --- ## Get visitor ID As soon as your user answers any survey's question, we assign a unique ID to them. Feel free to identify your users using that ID with the getVisitorId method ```javascript title="Manual implementation" var visitorId = _sva.getVisitorId(); ``` ```javascript title="Web package" var visitorId = Survicate.getVisitorId(); ``` ```javascript title="Web surveys wrapper" var visitorId = survicate.getVisitorId(); ``` ***Please note***: The output of this method can be `null`. As mentioned above, the value is assigned only to the visitors that have answered any question. --- ## Reset visitor Using the `destroyVisitor` method you can remove a user's browser data. This erases data like session history and survey responses from their localStorage and sessionStorage. However, responses already saved in our database remain untouched and can still be viewed in the survey results tab. Be cautious: - If a user matches a survey's targeting criteria, they might encounter the same survey again. - If you use this method while a survey is in progress, the survey will close and the user won't be able to complete it. ```javascript title="Manual implementation" _sva.destroyVisitor(function() { console.log('Data deleted'); }); ``` ```javascript title="Web package" Survicate.destroyVisitor(function() { console.log('Data deleted'); }); ``` ```javascript title="Web surveys wrapper" survicate.destroyVisitor(function() { console.log('Data deleted'); }); ``` When using the `destroyVisitor` method, you can include a callback function to execute a specific action afterward. In this example, the callback function triggers the retarget method, which will ‘check’ if there are surveys that should be shown to this 'new' user. ```javascript title="Manual implementation" _sva.destroyVisitor(_sva.retarget()); ``` ```javascript title="Web package" Survicate.destroyVisitor(Survicate.retarget()); ``` ```javascript title="Web surveys wrapper" survicate.destroyVisitor(survicate.retarget()); ``` --- ## Show survey For the customers that need a custom targeting system, we provide the `showSurvey` method, that makes it easy to show an arbitrary survey based on the given survey's id. The method ignores all targeting options, except checking whether this visitor has already answered the survey. The method returns `true` if the survey was rendered and `false` otherwise (e.g. another survey is already displayed or the visitor has answered the desired survey). ```javascript title="Manual implementation" _sva.showSurvey('f658c90277553239'); // You can get the Survey ID from the URL when editing it in the Survicate Panel ``` ```javascript title="Web package" Survicate.showSurvey('f658c90277553239'); // You can get the Survey ID from the URL when editing it in the Survicate Panel ``` ```javascript title="Web surveys wrapper" survicate.showSurvey('f658c90277553239'); // You can get the Survey ID from the URL when editing it in the Survicate Panel ``` Optionally, to change the default behavior of the survey, you can provide the `options` object as the second parameter. ```javascript title="Manual implementation" var options = { forceDisplay: true, displayMethod: 'delayed', displayOptions: { delay: 5 // The survey will appear with a delay of 5 seconds } }; ``` ```javascript title="Web package" const options = { forceDisplay: true, displayMethod: AppearMethod.delayed, displayOptions: { delay: 5 // The survey will appear with a delay of 5 seconds } }; ``` ```javascript title="Web surveys wrapper" const options = { forceDisplay: true, displayMethod: AppearMethod.delayed, displayOptions: { delay: 5 // The survey will appear with a delay of 5 seconds } }; ``` ```javascript title="Manual implementation" _sva.showSurvey('f658c90277553239', options); // You can get the Survey ID from the URL when editing it in the Survicate Panel ``` ```javascript title="Web package" Survicate.showSurvey('f658c90277553239', options); // You can get the Survey ID from the URL when editing it in the Survicate Panel ``` ```javascript title="Web surveys wrapper" survicate.showSurvey('f658c90277553239', options); // You can get the Survey ID from the URL when editing it in the Survicate Panel ``` ### options | Property | Type | Description | |----------------|---------| ------------------------------------------------------------------------------------------------------------------------------------------------------ | | forceDisplay | boolean | If true, currently rendered survey will be closed in favor of the new survey. Survey will be shown regardless of whether the user has already answered this survey. | | displayMethod | string | Use this option in order to overwrite the current displaying configuration. **Possible values: ['immediately', 'delayed', 'exitIntent', 'onScroll'].** | | displayOptions | object | See below for available options. **Applicable and required only for the displayMethod values 'delayed' and 'onScroll'.** | ### displayOptions | Property | Type | Description | |--------------------|---------|------------------------------------------------------------------------------------------------------------------| | delay | integer | Delay in seconds. **Applicable and required only for displayMethod = 'delayed'.** | | scrolledPercentage | integer | Percentage of the page that was already scrolled. **Applicable and required only for displayMethod = 'onScroll'.** | ## Close survey Use the `closeSurvey` method to programmatically close the currently displayed survey (widget or feedback button). This triggers the same close flow as when the user clicks the close button, including the `survey_closed` event and any configured integrations. ```javascript title="Manual implementation" _sva.closeSurvey(); ``` ```javascript title="Web package" Survicate.closeSurvey(); ``` ```javascript title="Web surveys wrapper" survicate.closeSurvey(); ``` Optionally, pass a survey ID to close only a specific survey. This is useful when multiple widgets are displayed on the same page. ```javascript title="Manual implementation" _sva.closeSurvey('f658c90277553239'); ``` ```javascript title="Web package" Survicate.closeSurvey('f658c90277553239'); ``` ```javascript title="Web surveys wrapper" survicate.closeSurvey('f658c90277553239'); ``` | Parameter | Type | Description | |-----------|--------|----------------------------------------------------------------------------------------------------------------| | surveyId | string | Optional. If provided, only the survey with that ID is closed. If omitted, all open surveys are closed. | --- # Disabling automatic targeting The targeting script is automatically executed to determine if a user fits the specified criteria. We recognize that some users might prefer a different approach, such as using custom targeting with the `showSurvey` method. If you'd like to turn off this automatic feature, use the `disableTargeting` property. ```javascript title="Manual implementation" (function(opts) { opts.disableTargeting = true; })(window._sva = window._sva || {}); // Survicate Tracking Code goes here ``` ```javascript title="Web surveys wrapper" const config = { workspaceKey: 'workspace key', disableTargeting: true }; await initSurvicate(config); ``` --- ## Event-based targeting If you need to display a survey after your site's visitor performs a specific action, use our event-based targeting. You can consider any action from your users' behavior as an event. For example, you might be interested in triggering a survey for those users who've just left the cart page without finishing the purchase. Or for those users who've just downgraded their subscription, etc. In order to show surveys based on triggered events you can use `invokeEvent` method. If only event name was provided in panel, pass it's name as an argument to `invokeEvent` method. ```javascript title="Manual implementation" _sva.invokeEvent("eventName") ``` ```javascript title="Web package" Survicate.invokeEvent("eventName") ``` ```javascript title="Web surveys wrapper" survicate.invokeEvent("eventName") ``` If also event properties were provided in panel, pass them as an object to `invokeEvent` method as second argument. ***Important to note:*** - Event name, properties keys and values are case sensitive. If there is any discrepancy between what's declared in the ‘Triggers’ tab of the Target section in the Survicate panel and the code, the survey will not appear. - Event name can have max length of 255 characters. Longer names will be truncated to 255 characters. - Event properties values can only be strings. ```javascript title="Manual implementation" _sva.invokeEvent("eventName", {a: "1", b: "2"}) ``` ```javascript title="Web package" Survicate.invokeEvent("eventName", {a: "1", b: "2"}) ``` ```javascript title="Web surveys wrapper" survicate.invokeEvent("eventName", {a: "1", b: "2"}) ``` ___ ## Submit survey answers without displaying a survey In advanced scenarios, you may want to programmatically submit answers to Survicate surveys without showing the survey widget to the user. This is possible using the `hiddenSurveys`, `getSurveyPointsMetadata` and `submitAnswer` method. This feature works for Text, Single, Rating, Numerical, CSAT and NPS. ### 1. Setting your survey frequency In order to accept multiple responses in a short time, you need to set your survey frequency to: "If the user has responded or closed the survey - Let the user take the survey multiple times on a recurring basis - Every time a respondent matches required criteria" ### 2. Hiding surveys from the UI To prevent specific surveys from being displayed, pass their IDs to the Survicate tracking code using the `hiddenSurveys` property. This ensures the surveys are hidden from the user interface, but remain accessible via the JavaScript SDK. ```javascript title="Manual implementation" (function(opts) { opts.hiddenSurveys = ['7d9d103a77b38925']; })(window._sva = window._sva || {}); ``` ```javascript title="Web package" const config = { workspaceKey: 'workspace key', hiddenSurveys: ['7d9d103a77b38925'] }; Survicate.init(config); ``` ```javascript title="Web surveys wrapper" const config = { workspaceKey: 'workspace key', hiddenSurveys: ['7d9d103a77b38925'] }; await initSurvicate(config); ``` You can verify which surveys are hidden by checking: ```javascript console.log(_sva.hiddenSurveys); ``` > **Note:** Hidden surveys will not appear on the page, but you can still interact with them programmatically. ### 3. Retrieving survey points metadata Before submitting an answer, you need to know the available questions (points) and possible answers for a given survey. Use the `getSurveyPointsMetadata` method: ```javascript const points = _sva.getSurveyPointsMetadata('7d9d103a77b38925'); ``` This returns an array of objects, each describing a survey point (question) and its possible answers: ```typescript interface SurveyPointInfo { pointId: number; answerType: 'text' | 'rating' | 'single_choice' | 'nps' | 'csat', 'numerical'; answers?: Array<{ id: number }>; } ``` - `pointId`: The unique ID of the question. - `answerType`: The type of answer expected (e.g., text, rating, single choice). - `answers`: Optional, an array of possible answer IDs (for choice-based questions). ### 4. Submitting an answer Once you have the point and answer IDs, use the `submitAnswer` method to send a response: ```typescript interface SubmitAnswerParams { surveyId: string; pointId: number; answerId?: number; // Required for choice-based questions answer?: string | number; // Required for Text or NPS questions } submitAnswer(params: SubmitAnswerParams, responseUuid?: string): void ``` **Parameters:** - `params`: Object containing `surveyId`, `pointId`, and either `answerId` (for choice-based questions) or `answer` (for text/NPS questions) - `responseUuid` (optional): UUID string to group multiple submissions as part of the same response. If omitted, each submission creates a new response. ### Example: Submitting a Rating answer ```javascript _sva.submitAnswer({ surveyId: "7d9d103a77b38925", pointId: 1319375, answerId: 2418281 }); ``` ### Example: Submitting a Text answer ```javascript _sva.submitAnswer({ surveyId: "7d9d103a77b38925", pointId: 1319373, answer: "This is my answer" }); ``` > **Tip:** For NPS questions, provide the score as the `answer` (a number between 0 and 10). ### 4.1. Connecting submissions to a single response You can group multiple submissions together as part of the same response by using a response UUID. This is useful when you want to submit multiple answers to the same survey and would like to see them in a single record in the Analyze tab. > **Important:** All submissions connected with the same response UUID must be from the same survey. #### Getting a response UUID Use the `getResponseUuid` method to either: - retrieve a response UUID from an active survey that was already shown to the user who submitted at least one answer or, - generate a new response UUID: ```typescript getResponseUuid(surveyType: 'WidgetSurvey' | 'FeedbackButton', connectResponse?: boolean): string ``` **Parameters:** - `surveyType`: The survey type (`'WidgetSurvey'` or `'FeedbackButton'`) - `connectResponse` (optional, default is `false`): - `true`: Returns the existing response UUID from an active, shown survey (requires at least one question to be answered) - `false` or omitted: Generates and returns a new unique UUID #### Example: Grouping multiple submissions Generate a UUID once and reuse it for multiple submissions: ```javascript // Generate a response UUID const responseUuid = _sva.getResponseUuid('WidgetSurvey'); // Submit multiple answers as part of the same response _sva.submitAnswer( { surveyId: '7d9d103a77b38925', pointId: 1319375, answerId: 2418281 }, responseUuid ); _sva.submitAnswer( { surveyId: '7d9d103a77b38925', pointId: 1319376, answerId: 2418282 }, responseUuid ); _sva.submitAnswer( { surveyId: '7d9d103a77b38925', pointId: 1319373, answer: 'Additional feedback' }, responseUuid ); ``` #### Example: Connecting to an active survey response Link programmatic submissions to a user's active survey session: ```javascript // Listen for when a question is answered window._sva.addEventListener('question_answered', function(surveyId, pointId) { if (surveyId === '7d9d103a77b38925' && pointId === 1319375) { // Get the response UUID from the active survey const responseUuid = _sva.getResponseUuid('WidgetSurvey', true); // Submit additional answers to the same response _sva.submitAnswer( { surveyId: '7d9d103a77b38925', pointId: 1319376, answerId: 2418282 }, responseUuid ); } }); ``` ### 5. Error handling The SDK provides informative console warnings if something goes wrong, such as: - `Survey with ID "7d9d103a77b389ss25" not found` - `Point with ID "1319371113" not found in survey "7d9d103a77b38925"` - `Answer ID "2418281111" not found in point "1319375" of survey "7d9d103a77b38925"` - `Response UUID "a584d128-f331-401b-808d-61bbf8d9ca90" is not a valid UUID` - `GetResponseUuid: invalid-survey-type is not supported. Please use one of the following survey types: WidgetSurvey, FeedbackButton`, Check the browser console for these messages during development and debugging. ### 6. Verifying Submissions All answers submitted via the SDK will be visible in the Survicate Analyze tab for your workspace. ### 7. Best Practices - Always retrieve the latest survey points metadata before submitting answers - Validate your input (IDs, answer types) to avoid unnecessary errors. - Use `hiddenSurveys` only for surveys you intend to control programmatically. --- ## Set survey language Use the `setSurveyLanguage` method to dynamically change the survey display language after the SDK has been initialized. This is useful when the user changes their language preference in your application. ```javascript title="Manual implementation" _sva.setSurveyLanguage("de"); // ISO 639-1 language code ``` ```javascript title="Web package" Survicate.setSurveyLanguage("de"); // ISO 639-1 language code ``` ```javascript title="Web surveys wrapper" survicate.setSurveyLanguage("de"); // ISO 639-1 language code ``` **Parameters:** | Parameter | Type | Description | |--------------|--------|-----------------------------------------------------------------------------------------------| | languageTag | string | A valid [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code (e.g., `en`, `de`, `fr`, `es`, `pt`). | ***Important to note:*** - The setSurveyLanguage method should be triggered after survey is displayed. - The language change takes effect immediately for any subsequent survey displays. - If the specified language is not available in the survey's translations, a warning will be logged to the console and the language will not be changed. - The forced language has the highest priority and overrides URL-based and browser-based language detection. - To set the language during initialization, use the [`forcedLanguage` configuration option](/javascript/installation#survey-language) instead. - If your site keeps the `` attribute up to date (typical for localized SPAs), you can enable the [`useHtmlLangAttribute` option](/javascript/installation#detect-language-from-the-html-lang-attribute) instead of calling this method on every language change — Survicate then follows the attribute automatically. --- ## Set theme mode Use the `setThemeMode` method to control whether surveys use light or dark theme. This is useful when you want to match your website's theme. The default theme mode is 'auto'. Meaning that the survey will use the browser's preference for the theme. For the dark theme to be applied, the survey's theme must have dark mode variant configured in the Survicate panel. To set the theme during initialization, use the [`themeMode` configuration option](/javascript/installation#survey-theme) ```javascript title="Manual implementation" _sva.setThemeMode('light'); // Force surveys to use light theme _sva.setThemeMode('dark'); // Force surveys to use dark theme ``` ```javascript title="Web package" Survicate.setThemeMode('light'); // Force surveys to use light theme Survicate.setThemeMode('dark'); // Force surveys to use dark theme ``` ```javascript title="Web surveys wrapper" survicate.setThemeMode('light'); // Force surveys to use light theme survicate.setThemeMode('dark'); // Force surveys to use dark theme ``` **Parameters:** | Parameter | Type | Description | |-----------|--------|-----------------------------------------------------------------------------------------------| | mode | string | Theme mode: `"light"` or `"dark"` (case-insensitive). | ***Important to note:*** - The mode parameter is case-insensitive (`"light"`, `"Light"`, `"LIGHT"` all work the same way). - When wrong type of parameter is provided, the method will log a warning to the console and the theme mode will not be changed. - Only `"light"` and `"dark"` modes are available via this method. --- --- # Event Listeners Source: https://developers.survicate.com/javascript/events/ Based on the respondent's interaction with our surveys you can trigger actions in your app or website, or even build custom integrations. You can set up listeners to hook into user interactions with our surveys. Event listeners can only be used on some of the paid plans. Check [our pricing page](https://survicate.com/pricing/#pricing-compare-plans) for more details. We refer to this feature as 'Advanced Targeting' or 'JavaScript Targeting'. ```javascript title="Manual implementation" const listenerId = _sva.addEventListener('event', callback); ``` ```javascript title="Web package" const listenerId = Survicate.addEventListener('event', callback); ``` ```javascript title="Web surveys wrapper" const listenerId = survicate.addEventListener('event', callback); ``` By calling the `addEventListener` method multiple times, you can set up more than one listener for a given event. If you don't need the listener anymore, you can use `removeEventListener` method to remove the previously registered listener. It is possible to remove either all the listeners that are hooked into a given event or a single listener based on the `listenerId` returned from the `addEventListener` method. ```javascript title="Manual implementation" // Remove an event listener based on its id _sva.removeEventListener(listenerId); // Remove all listeners hooked into a given event _sva.removeEventListener('question_answered'); ``` ```javascript title="Web package" // Remove an event listener based on its id Survicate.removeEventListener(listenerId); // Remove all listeners hooked into a given event Survicate.removeEventListener(Survicate.ApiEvent.questionAnswered); ``` ```javascript title="Web surveys wrapper" // Remove an event listener based on its id survicate.removeEventListener(listenerId); // Remove all listeners hooked into a given event survicate.removeEventListener(ApiEvent.questionAnswered); ``` ***Please note***: All events are emitted asynchronously - we cannot guarantee that the event has already been reflected in Survicate at the time of the emission. For instance, an answer for a certain question might not be present in Survicate yet. --- ## Survey displayed Every display of a survey is followed by the `survey_displayed` event emission. ```javascript title="Manual implementation" _sva.addEventListener('survey_displayed', function(surveyId, surveyName) { // do stuff }); ``` ```javascript title="Web package" Survicate.addEventListener(Survicate.ApiEvent.surveyDisplayed, function(surveyId, surveyName) { // do stuff }); ``` ```javascript title="Web surveys wrapper" survicate.addEventListener(ApiEvent.surveyDisplayed, function(surveyI, surveyName) { // do stuff }); ``` --- ## Question answered As soon as the visitor answers a question, Survicate emits the `question_answered` event. ```javascript title="Manual implementation" _sva.addEventListener('question_answered', function(surveyId, questionId, answer) { // do stuff }); ``` ```javascript title="Web package" Survicate.addEventListener(Survicate.ApiEvent.questionAnswered, function(surveyId, questionId, answer) { // do stuff }); ``` ```javascript title="Web surveys wrapper" survicate.addEventListener(ApiEvent.questionAnswered, function(surveyId, questionId, answer) { // do stuff }); ``` #### Example 1: Set a cookie after response to specific question ```javascript title="Manual implementation" _sva.addEventListener('question_answered', function(surveyId, questionId, answer) { if (questionId == 2836357) { // Question ID can be retrieved with Survicate Data Export API document.cookie = "surveyAnswered=true; expires=Fri, 31 Dec 9999 23:59:59 GMT"; } }); ``` ```javascript title="Web package" Survicate.addEventListener(Survicate.ApiEvent.questionAnswered, function(surveyId, questionId, answer) { if (questionId == 2836352) { // Question ID can be retrieved with Survicate Data Export API document.cookie = "surveyAnswered=true; expires=Fri, 31 Dec 9999 23:59:59 GMT"; } }); ``` ```javascript title="Web surveys wrapper" survicate.addEventListener(ApiEvent.questionAnswered, function(surveyId, questionId, answer) { if (questionId == 2836357) { // Question ID can be retrieved with Survicate Data Export API document.cookie = "surveyAnswered=true; expires=Fri, 31 Dec 9999 23:59:59 GMT"; } }); ``` #### Example 2: Open Intercom messenger after response to specific question ```javascript title="Manual implementation" _sva.addEventListener('question_answered', function(surveyId, questionId, answer) { if (questionId == 2836357) { // Question ID can be retrieved with Survicate Data Export API Intercom('showNewMessage', 'pre-populated content'); //replace pre-populated content with your content } }); ``` ```javascript title="Web package" Survicate.addEventListener(Survicate.ApiEvent.questionAnswered, function(surveyId, questionId, answer) { if (questionId == 2836357) { // Question ID can be retrieved with Survicate Data Export API Intercom('showNewMessage', 'pre-populated content'); //replace pre-populated content with your content } }); ``` ```javascript title="Web surveys wrapper" survicate.addEventListener(ApiEvent.questionAnswered, function(surveyId, questionId, answer) { if (questionId == 2836357) { // Question ID can be retrieved with Survicate Data Export API Intercom('showNewMessage', 'pre-populated content'); //replace pre-populated content with your content } }); ``` ### Answer object properties | Property | Type | Description | | | | ------------ | --------- | ---------------------------------------------------------------------------------------------- |---|---| | answer_type | string | Answer type. | | | | answer_id | integer | Answer ID. **Applicable only for type = ['single', 'smiley_scale', 'dropdown_list'].** | | | | answer_ids | integer[] | Array of answer IDs. **Applicable only for type = ['multiple'].** | | | | answer_value | string | Context value of the answer. **Applicable only for type = ['text', 'nps', 'date', 'rating'].** | | | ***Please note***: At the moment we support passing the `answer_id`, `answer_ids` and `answer_value` properties only for the cases enlisted in the table above. Therefore, expect that there might be answer objects that consist only of the `answer_type` property. --- ## Survey completed Once a survey has been completed, Survicate emits the `survey_completed` event. Survey is considered to be completed, when a visitor has answered every single question that was displayed to them in the configured flow. ```javascript title="Manual implementation" _sva.addEventListener('survey_completed', function(surveyId) { // Trigger any action that works with your workflow }); ``` ```javascript title="Web package" Survicate.addEventListener(Survicate.ApiEvent.surveyCompleted, function(surveyId) { // Trigger any action that works with your workflow }); ``` ```javascript title="Web surveys wrapper" survicate.addEventListener(ApiEvent.surveyCompleted, function(surveyId) { // Trigger any action that works with your workflow }); ``` --- ## Survey closed If at any stage of the survey, your visitor clicks the close button, Survicate will emit the `survey_closed` event. ```javascript title="Manual implementation" _sva.addEventListener('survey_closed', function(surveyId) { // Trigger any action that works with your workflow }); ``` ```javascript title="Web package" Survicate.addEventListener(Survicate.ApiEvent.surveyClosed, function(surveyId) { // Trigger any action that works with your workflow }); ``` ```javascript title="Web surveys wrapper" survicate.addEventListener(ApiEvent.surveyClosed, function(surveyId) { // Trigger any action that works with your workflow }); ``` ## Script loaded ***Important to note:*** This refers only to the manual installation of Survicate script. As soon as the Survicate script has been fully loaded and ready, you will be informed through the `SurvicateReady` window event. This event is especially useful for the Single Page Applications/Progressive Web Applications. ```javascript window.addEventListener('SurvicateReady', function() { // Trigger any action that works with your workflow }); ``` #### Example: Reset visitor after script has been loaded ```javascript window.addEventListener('SurvicateReady', function() { _sva.destroyVisitor(_sva.retarget); }); ``` ***Please note***: Due to its nature, unlike the other events, the `SurvicateReady` event is attached to the window object and not the `_sva` object. --- # Changelog Source: https://developers.survicate.com/javascript/js-sdk-changelog/ ## September 2026 (28.32.12 - 28.33.11) #### News **New** - 28.33.11 (2026-09-22): Render disclaimer title and consent label as text instead of raw HTML - 28.33.10 (2026-09-16): Render email footer copy from config and tag snippets by language - 28.33.9 (2026-09-16): Flush queued answers before the tab closes - 28.33.8 (2026-09-10): Show the comment field for an NPS answered from an email - 28.33.6 (2026-09-08): Send queued requests in the order they were added - 28.33.5 (2026-09-07): Capture screenshots as a frozen snapshot with nested scroll offsets - 28.33.4 (2026-09-07): Keep preview settings in sync when widget is closed - 28.33.3 (2026-09-07): Keep the closing survey off screen until it is hidden - 28.33.0 (2026-09-02): Allow multiple questions on multiple pages for Page Survey #### Fixes **Fix** - 28.32.15 (2026-09-01): Record welcome message clicks on Page Surveys - 28.32.14 (2026-09-01): Fix widget surveys still showing after they are removed on a live config refresh - 28.32.12 (2026-09-01): Fix screenshot selection mismatch on scrolled pages ## August 2026 (28.31.27 - 28.32.11) #### News **New** - 28.32.11 (2026-08-27): Keep survey targeting running when referrer access throws - 28.32.10 (2026-08-27): Enforce selection limit for optional multiple-answer questions - 28.32.9 (2026-08-27): Use PNG Survicate wordmark in managed email branding - 28.32.7 (2026-08-25): Hide cookie banners in captured survey screenshots - 28.32.6 (2026-08-21): Record Thank you button link clicks on grouped Page Surveys - 28.32.5 (2026-08-11): Decode URL-encoded identity params for all providers - 28.32.0 (2026-08-03): Add html lang as a language detection source - 28.31.29 (2026-08-03): Reset mobile Page Survey scroll container on group change - 28.31.27 (2026-08-03): Make the managed email branding a UTM-tagged link #### Fixes **Fix** - 28.31.28 (2026-08-03): Decode HTML entities in survey disclaimer title ## July 2026 (28.31.2 - 28.31.25) #### News **New** - 28.31.25 (2026-07-31): Reset Page Survey scroll on next question - 28.31.24 (2026-07-28): Restore Page Survey answers when navigating forward - 28.31.22 (2026-07-28): Inherit question color on StatusPage nested text - 28.31.20 (2026-07-24): Allow submitting optional Matrix with required comments - 28.31.19 (2026-07-24): Sanitize group disclaimer in PageSurvey preview - 28.31.15 (2026-07-21): Show newlines in choice answer preview - 28.31.13 (2026-07-16): Demote WebKit "Load failed" network errors to WARN - 28.31.12 (2026-07-16): Add sv_campaign response trait - 28.31.11 (2026-07-16): Remove uneditable text from email footer - 28.31.7 (2026-07-10): Finish on a mid-survey thank-you page instead of skipping it - 28.31.2 (2026-06-30): Keep outro CTAs out of one-page question groups #### Fixes **Fix** - 28.31.21 (2026-07-24): Fix completion messages to follow question color - 28.31.18 (2026-07-23): Fix black scrollbar track on mobile disclaimer - 28.31.17 (2026-07-21): Fix Page survey comment field breaking on long comment title - 28.31.16 (2026-07-21): Fix translation reactivity and state derivation - 28.31.8 (2026-07-10): Fix ranking drag freeze, excessive movement, and touch crash - 28.31.6 (2026-07-09): Fix e.match is not a function - 28.31.3 (2026-07-03): Fix disclaimers in web surveys — widget save + PageSurvey live preview ## June 2026 (28.26.4 - 28.31.0) #### News **New** - 28.31.0 (2026-06-30): Support pinned answers and "none of the above" selection - 28.30.1 (2026-06-30): Skip saving visitor attributes when identify_respondents is false - 28.30.0 (2026-06-30): Send distribution channel and bump payload version to 4.2 - 28.29.1 (2026-06-30): Suppress "don't show if engaged" surveys before backend targeting - 28.29.0 (2026-06-29): Allow multiple points on one page for Page Survey - 28.28.0 (2026-06-24): Adjust email preview for managed-flow distribution - 28.27.4 (2026-06-23): Restore underline on hyperlinks inside choice answer - 28.27.0 (2026-06-15): Drop uuid package in favour of native crypto.randomUUID for modern browsers - 28.26.22 (2026-06-15): Close survey on clicking overlay when enabled - 28.26.19 (2026-06-11): Add iterable_user_id to response attributes - 28.26.11 (2026-06-09): Support line breaks in survey messages #### Fixes **Fix** - 28.28.6 (2026-06-29): Remove close-button option from the default unbranded thank-you screen - 28.28.1 (2026-06-29): HTML-escape visitor & answer merge-tag values before innerHTML - 28.27.5 (2026-06-23): Fix Page Survey opening twice in meta in-app browsers - 28.27.3 (2026-06-16): Fix surveys dropped by Array.from under host polyfills - 28.26.21 (2026-06-15): Fix preview showing wrong translation language - 28.26.9 (2026-06-02): Preserve matrix row order on back-navigation when answers are randomized - 28.26.7 (2026-06-02): Fix matrix display logic with randomized rows - 28.26.6 (2026-06-02): Fix a missing disclaimer in mobile survey preview when not on the first question ## May 2026 (28.23.20 - 28.26.3) #### News **New** - 28.26.3 (2026-05-28): Gate all backend data sends on backend targeting enabled flag - 28.26.0 (2026-05-26): Add outlined and filled style variants to smiley scale - 28.25.1 (2026-05-21): Add order_id to response attributes for all providers - 28.25.0 (2026-05-20): Lazy-load screenshot feature - 28.24.0 (2026-05-19): Unify submit service - 28.23.32 (2026-05-19): Add ARIA labels and grouping roles to all question types - 28.23.31 (2026-05-13): Treat partial matrix answers as empty answer - 28.23.30 (2026-05-13): Announce form validation errors to screen readers #### Fixes **Fix** - 28.23.34 (2026-05-19): Restore textarea height on navigation revisit - 28.23.29 (2026-05-13): Fix redundant focus targets on choice and matrix answer buttons - 28.23.28 (2026-05-11): Fix delay not respected on re-trigger and SPA navigation - 28.23.21 (2026-05-05): Fix disclaimer accepted field missing in Numerical Scale answer ## April 2026 (28.22.2 - 28.23.19) #### News **New** - 28.23.13 (2026-04-21): Switch dependency updates to Dependabot - 28.23.6 (2026-04-15): Use sass forward instead of import - 28.23.0 (2026-04-13): Enable response traits for Page Survey - 28.22.13 (2026-04-13): Store user_id and uuid pairs for shared-device identity - 28.22.11 (2026-04-13): Use window.location.href for same-tab redirects #### Fixes **Fix** - 28.23.19 (2026-04-30): Fix storage key corruption in NPM package - 28.23.15 (2026-04-22): Fix consecutive Welcome Points missing submit button on PageSurvey - 28.23.14 (2026-04-21): Prevent UUID reuse across sessions with disableSensitiveDataPersistence - 28.23.11 (2026-04-17): Fallback to default language when browser language has no translation match - 28.23.10 (2026-04-17): Fix stale submit callback during Mobile Survey animation - 28.23.9 (2026-04-17): Handle cookie access in sandboxed iframes - 28.23.8 (2026-04-16): Fix component instance isolation - 28.23.5 (2026-04-15): Guard Salesforce integration lookup against non-object entries - 28.23.3 (2026-04-14): Fix sending closed interaction - 28.23.2 (2026-04-14): Persist retry counter in Storage across page reloads - 28.23.1 (2026-04-14): Apply nonce to all dynamically injected style elements - 28.22.10 (2026-04-13): Handle hasBrowserAPISupport error logging for patched console.error - 28.22.9 (2026-04-08): Handle hasBrowserAPISupport error logging for patched console.error - 28.22.8 (2026-04-08): Fix languages in the preview - 28.22.7 (2026-04-02): Auto-select dropdown option when typed text is matched - 28.22.6 (2026-04-02): Handle Bowser parse failures in unsupported-browser check - 28.22.5 (2026-04-01): Fix show submit button on branded Thank You with button redirect on mobile devices - 28.22.4 (2026-04-01): Fix show submit button in Single Choice when navigation is enabled ## March 2026 (28.18.0 - 28.22.1) #### News **New** - 28.22.0 (2026-03-30): Unify visitor object in Local Storage - 28.21.1 (2026-03-26): Map Bokmål and Nynorsk to Norwegian - 28.21.0 (2026-03-24): Add language selector - 28.20.2 (2026-03-18): Handle showSurvey for backend targeted surveys - 28.19.0 (2026-03-12): Add closeSurvey JS API method - 28.18.0 (2026-03-02): Use library and system fonts #### Fixes **Fix** - 28.22.1 (2026-03-30): Restore user id normalization - 28.21.5 (2026-03-30): Fix email preview wrong survey URL for GetResponse - 28.21.4 (2026-03-27): Fix handling user_id - 28.21.3 (2026-03-26): Fix clearing visitor issue - 28.20.6 (2026-03-18): Add polyfill for Mootools - 28.20.8 (2026-03-23): Fix thank you redirect autorefresh not being triggered - 28.20.9 (2026-03-23): Improve links security - 28.20.5 (2026-03-18): Remove agent from Zendesk identities - 28.20.4 (2026-03-18): Fix dropdown special characters in input - 28.20.3 (2026-03-18): Fix Numerical scale keyboard navigation - 28.19.3 (2026-03-16): Normalize URL param keys when query contains literal & - 28.18.11 (2026-03-12): Fix Feedback minimizing when clicking Widget submit button ## February 2026 (28.14.13 - 28.17.4) #### News **New** - 28.17.4 (2026-02-25): Add close button to a minimized Widget Survey - 28.17.0 (2026-02-23): Allow setting response attributes - 28.16.1 (2026-02-20): Fix BannerBear thumbnail - 28.16.0 (2026-02-11): Implement dark theme for Widget Survey and Feedback Button #### Fixes **Fix** - 28.17.3 (2026-02-25): Fix issue with updating submit text in the preview - 28.17.2 (2026-02-25): Fix issue with displaying HTML entities in Matrix and Dropdown - 28.14.17 (2026-02-03): Preserve state of a minimized survey - 28.14.14 (2026-02-03): Update unsupported browsers list - 28.14.13 (2026-02-02): Fix ranking question display logic ## January 2026 (28.13.6 - 28.14.12) #### News **New** - 28.14.0 (2026-01-12): Allow users to override the language auto detection ### Fixes **Fix** - 28.14.12 (2026-01-30): Remove comment from email snippet - 28.14.10 (2026-01-27): Remove CO language code from top level domain language codes list - 28.14.9 (2026-01-27): Fix multiple surveys throttling check issue - 28.14.7 (2026-01-21): Restore language key - 28.14.6 (2026-01-20): Fix branch logic for scale points - 28.14.3 (2026-01-19): Fix translations issue in the preview - 28.14.2 (2026-01-14): Fix survi local storage keys - 28.14.1 (2026-01-13): Fix intercom comment fields in the preview - 28.13.7 (2026-01-07): Fix issue with empty user agent parameter ## December 2025 (28.9.0 - 28.13.5) #### News **New** - 28.12.0 (2025-12-17): Detect language from URL - 28.11.1 (2025-12-15): Allow sending user events to backend - 28.10.6 (2025-12-11): Allow sending attributes to backend - 28.10.3 (2025-12-10): Allow hv for all users - 28.9.0 (2025-12-08): Implement backoff retry logic for requests - 28.8.0 (2025-12-08): Connect multiple answer submissions to the same response using submitAnswer ### Fixes **Fix** - 28.13.5 (2025-12-30): Fix load failed bug - 28.13.4 (2025-12-30): Reduce HTML size for Zendesk - 28.13.3 (2025-12-22): Remove space between buttons in NPS email - 28.13.2 (2025-12-22): Prevent checkboxes from being overwritten - 28.13.0 (2025-12-17): Optimize sending attributes to backend - 28.11.1 (2025-12-15): Align 3 emojis is Smiley Scale in the email preview - 28.10.5 (2025-12-11): Optimise the usage of the HV contacts endpoint - 28.10.4 (2025-12-10): Clean up existing user attributes calls from the queue - 28.10.2 (2025-12-10): Fix contacts endpoint path - 28.7.3 (2025-12-02): Fix contains condition for targeting events - 28.7.1 (2025-12-02): Fix http helper promise handling issue ## November 2025 (28.4.0 - 28.6.1) #### News **New** - 28.6.0 (2025-11-25): Add throttling when sending attributes to backend - 28.4.4 (2025-11-15): Add languages list for translating surveys ### Fixes **Fix** - 28.6.1 (2025-11-26): Refactor the preview sanitize function - 28.5.5 (2025-11-25): Preserve targeting triggers state - 28.5.4 (2025-11-25): Fix the progress bar and branding position in the preview in Page Survey - 28.5.3 (2025-11-24): Allow numbers in attribute name in merge tags - 28.5.2 (2025-11-20): Preserve delay trigger status - 28.4.7 (2025-11-18): Fix recurring survey refresh - 28.4.6 (2025-11-18): Optimize exit intent trigger - 28.4.5 (2025-11-17): Optimize scroll trigger for Widget Survey - 28.4.3 (2025-11-13): Do not capitalize buttons text in Page Survey - 28.4.2 (2025-11-12): Fix the delay interval issue - 28.4.1 (2025-11-06): Add automatic cleanup for old targeting requests in the queue - 28.4.0 (2025-11-05): Fix: targeting requests issue ## October 2025 (28.1.19 - 28.3.5) #### News **New** - 28.3.0 (2025-10-16): Send only new or updated attributes to Backend - 28.2.0 (2025-10-13): Support optional authentication mode for Backend targeting - 28.1.25 (2025-10-07): Enable Fullstory answer anonymisation ### Fixes **Fix** - 28.3.5 (2025-10-30): Fix backend interactions issue - 28.3.3 (2025-10-29): Fix backend targeting payload issue - 28.3.2 (2025-10-29): Retain survey progress on multiple refreshes - 28.2.1 (2025-10-15): Fix Matrix required comment issue - 28.1.29 (2025-10-10): Fix setting HTML language attribute value when default survey language is not set - 28.1.28 (2025-10-08): Fix default survey language in AI follow up questions - 28.1.27 (2025-10-08): Fix screenshots point ID mismatch - 28.1.26 (2025-10-07): Fix issue with adding Aria messages to DOM in AI Followup question ## September 2025 (28.1.4 - 28.1.18) ### Highlights - **Add documentation in NPM packages** - **Update NPM Survicate Web Package. Now available for all plans** - **Security improvements and XSS prevention** - **Development infrastructure updates** #### News **New** - 28.1.13 (2025-09-10): Add documentation in NPM packages - 28.1.8 (2025-09-04): Update NPM Survicate Web Package. Now available for all plans ### Fixes **Fix** - 28.1.18 (2025-09-24): Fix cookie targeting - 28.1.7 (2025-09-04): Fix scroll trigger - 28.1.6 (2025-09-04): Prevent XSS vulnerability in ErrorPage component ## August 2025 (27.3.4 - 28.1.3) ### Highlights - **Implement backend targeting for surveys** - **Implement Braze bridge** #### News **New** - 28.1.3 (2025-08-27): Truncate attributes names, values and event names to 255 characters - 28.1.0 (2025-08-25): Implement Braze bridge - 28.0.8 (2025-08-20): Trigger retarget on attributes change - 28.0.0 (2025-08-07): Implement backend targeting for surveys ### Fixes **Fix** - 28.1.1 (2025-08-26): Fix issue with radio buttons in Matrix question - 28.0.12 (2025-08-22): Fix max-height issue on mobile Widget Survey - 28.0.11 (2025-08-20): Fix Feedback survey logic - 28.0.7 (2025-08-13): Fix custom CSS issue - 28.0.6 (2025-08-12): Fix page targeting for non-latin characters - 28.0.3 (2025-08-12): Adjust h tags size for Page Survey - 28.0.2 (2025-08-11): Fix blocked screenshots issue - 28.0.1 (2025-08-07): Fix visitor validation timestamp - 27.3.4 (2025-08-04): Update Eslint configuration ## July 2025 (27.1.28 - 27.3.1) ### Highlights - **Implement a new JS method submitAnswer** - **Add new targeting operators** #### News **New** - 27.3.0 (2025-07-28): Add new targeting operators - 27.2.0 (2025-07-07): Implement a new JS method submitAnswer ### Fixes **Fix** - 27.3.1 (2025-07-31): Security update - 27.2.14 (2025-07-28): Fix NPS with disclaimer bug - 27.2.13 (2025-07-28): Check default survey language if no translations found - 27.2.11 (2025-07-28): Handle security error in Firefox LocalStorage - 27.2.9 (2025-07-23): Fix headers colors - 27.2.5 (2025-07-21): Security update - 27.2.3 (2025-07-10): Fix Rating question alignment for Zendesk - 27.1.32 (2025-07-07): Remove checking brazeBridge ## June 2025 (27.1.15 - 27.1.28) ### Highlights - **New:** Enhance translations' sanitization #### News **New** - 27.1.27 (2025-06-23): Enhance translations' sanitization ### Fixes **Fix** - 27.1.24 (2025-06-17): Fix partial survey translations resulting in survey errors - 27.1.23 (2025-06-17): Add important to media queries in custom CSS - 27.1.22 (2025-06-17): Fix difference between preview and real Widget Survey - 27.1.19 (2025-06-13): Fix freezing issue in Braze in-app messages survey - 27.1.18 (2025-06-05): Fix answering single question survey through email - 27.1.17 (2025-06-05): Set attribute to empty string when set to null - 27.1.16 (2025-06-04): After manual close do not close survey again automatically - 27.1.15 (2025-06-03): Fix mobile Matrix scroll behavior ## May 2025 (27.1.2 - 27.1.14) ### Highlights - **New:** Translate validation messages and aria labels #### News **New** - 27.1.6 (2025-05-07): Translate validation messages and aria labels ### Fixes **Fix** - 27.1.14 (2025-05-22): Prevent images from stretching in the split view - 27.1.13 (2025-05-13): Fix the unexpected token error on older browsers - 27.1.12 (2025-05-13): Use defer in NPM Wrapper - 27.1.10 (2025-05-08): Fix navigation in Page Survey - 27.1.7 (2025-05-07): Fix Survey unavailable screen - 27.1.5 (2025-05-07): Fix submit button issue in Page Survey on mobile devices ## April 2025 (26.3.7 - 27.1.1) ### Highlights - **New:** Add Braze in-app messages survey support - **New:** Add AI followup question - **New:** Support language variants #### News **New** - 27.1.1 (2025-04-25): Remove character limits for Text answers - 27.1.0 (2025-04-24): Add Braze in-app messages survey support - 27.0.0 (2025-04-17): Add AI followup question - 26.4.0 (2025-04-02): Support language variants ### Fixes **Fix** - 27.0.1 (2025-04-18): Fix non-mandatory AI followup question issue - 27.0.0 (2025-04-17): Fix navigation buttons alligment for RTL languages - 26.4.7 (2025-04-15): Fix mobile branded Thank You in Page Survey - 26.4.3 (2025-04-07): Fix Page Survey preview error - 26.4.2 (2025-04-07): Handle relative styles in screenshots - 26.4.1 (2025-04-02): Limit number of survey responses within an hour - 26.3.13 (2025-04-02): Fix the Rating Mobile Survey preview issue - 26.3.7 (2025-04-02): Fix screenshot button colors interception ## March 2025 (26.0.5 - 26.3.6) ### Highlights - **New:** Move all sensitive data to SessionStorage when disable sensitive data persistence is enabled - **New:** Update the disclaimer design #### News **New** - 26.3.3 (2025-03-20): Update Page navigation buttons - 26.3.0 (2025-03-13): Move all sensitive data to SessionStorage when disable sensitive data persistence is enabled - 26.2.0 (2025-03-11): Update the disclaimer design ### Fixes **Fix** - 26.3.6 (2025-03-20): Fix recurring Feedback - 26.3.4 (2025-03-20): Fix the navigation back button in RTL languages - 26.2.2 (2025-03-13): Fix minimized state issue in Preview for Widget Survey - 26.0.5 (2025-03-05): Change the navigation back button color in Page Survey ## February 2025 (25.0.2 - 26.0.3) ### Highlights - **New:** Update the disclaimer design - **New:** Add side images for Page Survey - **New:** Add a screenshot button for Dropdown - **New:** Add top and bottom images to Widget and Page Survey ### Detailed Changes #### News **New** - 26.0.0 (2025-02-27): Add side images for Page Survey - 25.1.6 (2025-02-27): Add a screenshot button for Dropdown - 25.1.3 (2025-02-20): Update Twitter logo - 25.1.0 (2025-02-13): Add top and bottom images to Widget and Page Survey #### Fixes **Fix** - 26.0.3 (2025-02-28): Fix navigation buttons - 26.0.3 (2025-02-28): Adjust logic for unanswered questions - 26.0.1 (2025-02-28): Fix back button styles in Widget Survey - 25.1.2 (2025-02-21): Add a timeout for a completed Mobile Survey in the preview - 25.1.2 (2025-02-19): Fix powered by text in the branded footer - 25.1.1 (2025-02-19): Fix stale attributes for the Page Survey kiosk mode - 25.0.4 (2025-02-06): Fix the mobile Rating selection - 25.0.2 (2025-02-05): Fix the disabled submit button for Mobile Survey NPS ## January 2025 (24.19.2 - 25.0.1) ### Highlights - **New:** Implement display logic ### Detailed Changes #### News **New** - 25.0.0 (2025-01-27): Implement display logic - 24.19.19 (2025-01-17): Improve Screen Reader Support - 24.19.7 (2025-01-02): Autofocus a text field when a comment is enabled #### Fixes **Fix** - 25.0.1 (2025-01-30): Change order of CSAT answers for Page Survey - 24.19.25 (2025-01-27): Fix autofocus in the preview of Widget Survey - 24.19.22 (2025-01-20): Fix the validation of a number input - 24.19.21 (2025-01-17): Fix Survey Activation Gate surveys check - 24.19.20 (2025-01-17): Do not minimize a Feedback Survey when in the screenshot mode - 24.19.12 (2025-01-08): Fix Ranking style error - 24.19.10 (2025-01-08): Fix overlapping theme colors in the preview - 24.19.8 (2025-01-02): Fix Feedback button autofocus when using keyboard - 24.19.5 (2025-01-02): Fix the tab accessibility for Multiple, Single and Form - 24.19.4 (2025-01-02): Fix translation refresh in the preview - 24.19.2 (2025-01-02): Fix the email logo position for ActiveCampaign ## December 2024 (24.18.21 - 24.19.1) ### Highlights - **New:** Add screenshot feature in Widget Survey ### Detailed Changes #### News **New** - 24.19.0 (2024-12-17): Add screenshot feature in Widget Survey - 24.18.29 (2024-12-16): Add aria-label for textarea in Text question - 24.18.28 (2024-12-16): Add survey name to survey_displayed event callback - 24.18.25 (2024-12-09): Add support for bold and italic in Disclaimer #### Fixes **Fix** - 24.19.1 (2024-12-17): Fix screenshots cache issue - 24.18.32 (2024-12-16): Fix mobile rating selection - 24.18.26 (2024-12-09): Fix labels alignment in Widget Survey - 24.18.26 (2024-12-09): Fix Matrix submit button states and its comment border color - 24.18.24 (2024-12-09): Fix Feedback minimizing in the preview - 24.18.21 (2024-12-09): Fix missing placeholder in the Date question comment field ## November 2024 (24.18.2 - 24.18.20) ### Detailed Changes #### News **New** - 24.18.5 (2024-11-06): Update disclaimer paddings in Page Survey - 24.18.4 (2024-11-05): Add links support for disclaimer #### Fixes **Fix** - 24.18.20 (2024-11-28): Fix Feedback position on mobile devices - 24.18.19 (2024-11-28): Fix Rule Engaged issue - 24.18.14 (2024-11-14): Fix multiple languages switching issue in translations in the preview - 24.18.13 (2024-11-14): Fix error object.values().flat() is not a function - 24.18.11 (2024-11-13): Fix mobile Widget Survey styles - 24.18.10 (2024-11-12): Do not pass attributes containing % to identities - 24.18.7 (2024-11-06): Fix Page Survey finish screen background color - 24.18.6 (2024-11-06): Fix Submit Button enabled issue in Smiley Scale - 24.18.3 (2024-11-04): Prevent overwriting Contact Form checkbox margins - 24.18.2 (2024-11-04): Fix Contact Form checkbox tick in Widget Survey ## October 2024 (24.15.1 - 24.18.1) ### Highlights - **New:** Add comments to NPS, Ranking and Date questions - **New:** Add disclaimer texts for all question types in Widget Survey, Feedback Button and Page Survey - **New:** Add comments to Matrix ### Detailed Changes #### News **New** - 24.18.0 (2024-10-30): Add comments to NPS, Ranking and Date questions - 24.17.0 (2024-10-22): Add comments to Matrix - 24.16.0 (2024-10-14): Add disclaimer texts for all question types in Widget Survey, Feedback Button and Page Survey #### Fixes **Fix** - 24.18.1 (2024-10-31): Fix navigation issue in NPS - 24.17.7 (2024-10-24): Fix exit intent issue on Safari - 24.17.3 (2024-10-24): Add error handling when decoding Page Survey URL params - 24.16.3 (2024-10-18): Fix skipping scale questions with logic - 24.16.2 (2024-10-17): Fix issue with selecting answers in consecutive rating questions on mobile devices - 24.15.1 (2024-10-1): Fix invokeEvent issue in the NPM package ## September 2024 (24.11.4 - 24.15.0) ### Highlights - **New:** Implement nonce for all instalation methods - **New:** Add comment fields for Smiley, Rating, Numerical, CSAT and Dropdown - **New:** Handle mandatory settings for multiple questions ### Detailed Changes #### News **New** - 24.15.0 (2024-09-30): Implement nonce for all instalation methods - 24.14.0 (2024-09-25): Add comment fields for Smiley, Rating, Numerical, CSAT and Dropdown - 24.12.0 (2024-09-10): Handle mandatory settings for multiple questions #### Fixes **Fix** - 24.13.2 (2024-09-20): Fix Page Survey retaking issue - 24.12.3 (2024-09-11): Fix dropdown list being cut on mobile devices - 24.11.4 (2024-09-04): Fix answering Page Survey in iframes ## August 2024 (24.7.12 - 24.11.3) ### Highlights - **New:** Add schedule Page Survey retake feature - **New:** Add expiring Page Survey link feature - **New:** Enhance event targeting for Widget Survey and Feedback Button ### Detailed Changes #### News **New** - 24.11.0 (2024-08-28): Schedule Page Survey retake - 24.10.0 (2024-08-28): Enchance event targeting - 24.8.0 (2024-08-22): Handle an expiring Page Survey link - 24.7.16 (2024-08-22): Validate phone number in the Contact Form field #### Fixes **Fix** - 24.11.3 (2024-08-30): Fix the issue with Active Campaign mobile rating - 24.9.1 (2024-08-26): Fix missing styles issue in the NPM package - 24.8.4 (2024-08-26): Fix fonts issue in the NPM package - 24.8.2 (2024-08-26): Fix adding questions to Dropdown in the preview - 24.7.13 (2024-08-08): Fix focus in the survey preview - 24.7.12 (2024-08-06): Fix overwritten label styles ## July 2024 (24.5.10 - 24.7.5) ### Highlights - **New:** Add navigation buttons in Widget Survey - **New:** Add CDN proxy support for Widget, Feedback and Page Surveys - **Fix:** Navigation issues when using keyboard to answer survey questions - **Fix:** Aria attributes in Widget Survey dialog to improve accessibility ### Detailed Changes #### News **New** - 24.7.0 (2024-07-11): Add CDN proxy support for Widget, Feedback and Page Surveys - 24.6.0 (2024-07-03): Add navigation buttons in Widget Survey - 24.5.10 (2024-07-03): Make the consent status in Contact Form available in the analysis #### Fixes **Fix** - 24.7.14 (2024-08-13): Fix accessibility issues - 24.7.12 (2024-08-06): Fix overwritten label styles - 24.7.7 (2024-07-30): Fix minimized survey preview on desktop - 24.7.6 (2024-07-25): Adjust Zendesk HTML snippet to fit the character limit - 24.7.5 (2024-07-23): Add display property to checkbox labels - 24.7.4 (2024-07-23): Prevent styles from being overwritten - 24.7.3 (2024-07-22): Fix navigation button colors - 24.7.1 (2024-07-16): Count survey views, not page views - 24.6.1 (2024-07-05): Fix Thank you questions progress rate ## June 2024 (24.0.2 - 24.5.9) ### Highlights - **New:** Improve keyboard handling when answering survey using the keyboard - **New:** Update focus states in Page and Widget Surveys - **New:** Store and send JS/Segment events - **New:** Implement proper handling for right-to-left languages - **Fix:** Resolved several issues with email and mobile forms ### Detailed Changes #### News **New** - 24.5.9 (2024-06-27): Handle Matrix answer in event listener - 24.5.8 (2024-06-27): Update three emojis in Smiley Scale question - 24.5.7 (2024-06-27): Minimize Feedback Button on an outside click - 24.5.6 (2024-06-26): Update labels size and width for rating and smiley questions for Widget Survey - 24.5.3 (2024-06-24): Keep focus in Widget Survey when answering a question - 24.5.2 (2024-06-24): Update tabindex for all interactive elements - 24.5.1 (2024-06-20): Add role dialog to Widget Survey - 24.5.0 (2024-06-20): Update focus states in Page and Widget Surveys - 24.4.9 (2024-06-18): Add Aria-labels to buttons, inputs and textareas. Add Aria-live for validation messages - 24.4.0 (2024-06-11): Update Matrix questions designs for Widget and Feedback Surveys in desktop view - 24.3.2 (2024-06-11): Add title attributes for links - 24.3.1 (2024-06-11): Update alt texts for images - 24.3.0 (2024-06-11): Implement proper handling for right-to-left languages - 24.2.0 (2024-06-07): Store and send JS/Segment events #### Fixes **Fix** - 24.5.5 (2024-06-26): Fix Matrix question width issue on iPad for Widget Survey - 24.5.4 (2024-06-25): Fix checkbox not reacting to click in Contact Form - 24.4.11 (2024-06-19): Fix company logo being cut in mobile Page Survey when navigation is enabled - 24.4.7 (2024-06-14): Fix the Survey installed issue for the Web Package - 24.4.6 (2024-06-13): Fix improper render of Numerical Scale question in Widget Survey on some pages - 24.4.4 (2024-06-12): Fix Feedback Button issue in single page applications - 24.4.1 (2024-06-11): Fix translation error for instantly apearing Widget Surveys - 24.0.3 (2024-06-03): Fix missing styles in the Widget Survey templates - 24.0.2 (2024-06-03): Fix text direction of a minimized Feedback Button ## May 2024 (23.0.6 - 24.4.1) ### Highlights - **New:** Implement the new Feedback Button, - **New:** Updated Matrix animation - **Fix:** Resolved several issues with email and mobile forms ### Detailed Changes #### News **New** - 24.0.0 (2024-05-27): Implement the new Feedback Button - 23.2.0 (2024-05-07): Update Matrix animation #### Fixes **Fix** - 24.0.1 (2024-05-27): Fix Mobile Survey preview - 23.2.2 (2024-05-09): Check for initial config in setPreview - 23.1.8 (2024-05-06): Fix response limit in translated MultipleChoice point - 23.1.7 (2024-05-06): Fix checkbox issue in mobile ContactForm - 23.1.6 (2024-04-19): Fix email snippet alignment - 23.1.5 (2024-04-19): Fix submit button issue in email - 23.1.4 (2024-04-19): Fix Contact Form loop updates for Page Survey - 23.1.3 (2024-04-19): Fix autorefresh issue in PageSurvey - 23.1.2 (2024-04-18): Handle SSR error in the NPM package - 23.0.6 (2024-04-16): Remove border from CTA button in the Email Preview ## April 2024 (22.10.5 - 23.0.4) ### Highlights - **New:** Use Web Components in the preview - **Fix:** Multiple improvements and bug fixes ### Detailed Changes #### News **New** - 23.0.0 (2024-04-10): Use Web Components in the preview #### Fixes **Fix** - 23.0.4 (2024-04-12): Fix PageSurvey email preview CTA button - 23.0.3 (2024-04-11): Fix jumping long choice questions issue - 23.0.2 (2024-04-11): Fix email snippet errors when added to Pardot email - 22.10.8 (2024-04-09): Fix Page Survey closing itself after 30 minutes - 22.10.5 (2024-04-02): Fix Widget close button position in finish screen ## March 2024 (22.7.3 - 22.10.4) ### Highlights - **New:** Handle mandatory toggle for Multiple and Single Choice - **New:** Implement last seen survey rule - **Update:** Changed link in branding and thank you screens - **Fix:** Multiple UI and functional fixes - **Fix:** Various UI fixes - **Fix:** Allow ampersand in submit button ### Detailed Changes #### Updates **Update** - 22.10.4 (2024-03-28): Change link in branding and thank you screens - 22.9.0 (2024-03-08): Handle mandatory toggle for Multiple and Single Choice - 22.8.0 (2024-03-05): Implement last seen survey rule #### Fixes **Fix** - 22.9.8 (2024-03-15): Prevent default and stop propagation when handling Submit button click - 22.9.6 (2024-03-14): Prevent exceeding response limit in instantly recurring and kiosk - 22.9.5 (2024-03-14): Fix submit button in Mobile Survey - 22.9.4 (2024-03-13): Fix Rating Scale buttons background - 22.9.1 (2024-03-12): Submit button default text - 22.8.2 (2024-03-08): Fix Feedback Survey font color - 22.8.1 (2024-03-06): Allow ampersand in submit button - 22.7.3 (2024-03-04): Fix overwriting window.dispatch event issue ## February 2024 (22.5.1 - 22.7.1) ### Highlights - **New:** Update mobile Page Survey Matrix design - **New:** Improve security - **New:** Add Matrix question type for Widget Survey - **Fix:** Various UI and functionality improvements - **Fix:** Multiple UI and functional fixes - **Fix:** Various UI and functionality improvements ### Detailed Changes #### News **New** - 22.7.0 (2024-02-27): Update mobile Page Survey Matrix design - 22.5.0 (2024-02-06): Add Matrix question type in for Widget Survey **Feat** - 22.6.0 (2024-02-21): Improve security #### Fixes **Fix** - 22.7.1 (2024-02-28): Fix invalid Date and Dropdown input colors - 22.6.1 (2024-02-26): Fix Thank You Redirect timeout - 22.5.10 (2024-02-20): Add min-width and height to Rating, Smiley, close and minimize buttons - 22.5.8 (2024-02-19): Add min width and height to the NPS button - 22.5.7 (2024-02-19): Fix background color for finished branded thank you screen - 22.5.6 (2024-02-13): Fix Survicate logo issue in branded finish screen for Widget Survey - 22.5.5 (2024-02-13): Fix mobile safari Page Survey unavailable issue - 22.5.4 (2024-02-08): Fix submit button moving up for mobile Page Survey - 22.5.3 (2024-02-08): Fix translated messages - 22.5.2 (2024-02-07): Fix link in Thank You button - 22.5.1 (2024-02-07): Fix styling discrepancies in date and dropdown inputs ## January 2024 (22.4.2 - 22.4.12) ### Highlights - **New:** Add matrix question type in web surveys - **Update:** Various dependency updates ### Detailed Changes #### New **New** - 22.4.4 (2024-01-15): Add traits and disable targeting to the NPM Web Package - 22.4.2 (2024-01-12): Update types naming in the NPM package #### Fixes **Fix** - 22.4.12 (2024-02-01): Fix npm package workspace key issue - 22.4.11 (2024-01-31): Fix cut off selections in dropdown question - 22.4.3 (2024-01-12): Fix submit button issue ## December 2023 (22.3.0) ### Highlights - **New:** `invokeEvent` method added to API ### Detailed Changes #### New **New** - 22.3.0 (2023-12-14): `invokeEvent` method added to API. --- # Data Export API Source: https://developers.survicate.com/data-export/ The Data Export API allows you to retrieve survey data from your Survicate account. You can use it to pass all the information collected with Survicate surveys to a database, CRM, or any other custom solution you built. In particular, Data Export API allows you to: - retrieve responses collected with your surveys - list surveys added to your workspace - list questions and possible answers to any particular survey - retrieve responses and attributes of each particular respondent - manage personal data for GDPR compliance and data privacy requirements Current version of Data Export API: v2. > **Note:** > Data Export API v1 will be turned off on September 15, 2026. If you still use v1, follow the [migration guide](/data-export/migration-v1-v2) to move to v2 before that date. --- - [Survey](/data-export/survey) - [Response](/data-export/response) - [Respondent](/data-export/respondent) - [Personal Data](/data-export/personal-data) --- # Setup Source: https://developers.survicate.com/data-export/setup/ In order to set up and use the Data Export API from Survicate, there are some prerequisites that must be fulfilled. ## Prerequisites 1. **Survicate Account:** First and foremost, you must have an account with Survicate. If you don't already have one, you can create your account at panel.survicate.com. Alternatively, you can join your company's account if you've received an invitation from a colleague. 2. **Proper Subscription:** Secondly, to use the Data Export API, your Survicate account must be subscribed to a plan that includes API access. Please note that without a valid subscription, any API requests will result in an error response. Please review Survicate's plans and make sure you're subscribed to the one that best suits your needs and includes API access. ## Endpoints To connect to the Data Export API endpoints, use the base URL: ``` https://data-api.survicate.com/v2/ ``` ## Authentication Once you've fulfilled the prerequisites, you're ready to start using the Data Export API. To authenticate yourself and begin your data exports, you'll need your API key. You can find it in the Survicate panel under **Settings → Organization → Access Keys**. Only organization owners and workspace admins can open that page. Once you have your API key, you'll need to provide it for authentication purposes. The API key should be included in the `Authorization` header of your API requests. The format for this should be `Basic {{apiKey}}`. Remember to replace `{{apiKey}}` with your actual API key when making requests. ```shell curl -H 'Authorization: Basic {{apiKey}}' ``` That's it! With your account set up, the right subscription, and your API key, you're ready to start using Survicate's Data Export API. Enjoy your journey in capturing and analyzing user feedback for better insights and business decisions! ## Pagination All list endpoints in the Data Export API are paginated. There are no page numbers - instead of asking for `page=2`, you follow the link the API gives you in each response. ### Result order and the date range Results are ordered from the latest to the oldest record. The `start` and `end` parameters mark the two ends of that range, in that order: - `start` is the **newer** bound and the point the page starts from. Records collected at or before it are included. - `end` is the **older** bound. Records collected at or after it are included. Both bounds are **inclusive**, and because of the ordering `start` must be later than `end`. Timestamps use ISO 8601 with microseconds, for example `2024-08-31T23:59:59.000000Z`. So to export everything collected between August 26 and August 31, 2024, the two timestamps are swapped compared to what you might expect: ```shell curl -H 'Authorization: Basic {{apiKey}}' \ 'https://data-api.survicate.com/v2/surveys/{survey_id}/responses?start=2024-08-31T23:59:59.000000Z&end=2024-08-26T00:00:00.000000Z' ``` ### Page size `items_per_page` accepts a value between 1 and 100. It is optional - if you omit it, the API applies its own default page size. ### Following `next_url` Every list response contains a `pagination_data` object: ```json { "pagination_data": { "has_more": true, "next_url": "/surveys/69f3dcf0d3220de7/responses?start=2024-08-29T09:12:44.128000Z&end=2024-08-26T00:00:00.000000Z" }, "data": [...] } ``` - `has_more` tells you whether another page exists. - `next_url` is **always a path relative to the base URL** `https://data-api.survicate.com/v2`, never an absolute URL. Prepend the base URL and request the path as-is, without rebuilding the query string yourself. Under the hood `next_url` moves the `start` timestamp back to where the previous page ended, keeping your original `end` and any filters intact. Because Survicate builds that link for you, you don't need to work out the next boundary or worry about skipping records. ### A complete walkthrough **Request 1** - the first page of responses collected between August 26 and August 31, 2024, 100 at a time: ```shell curl -H 'Authorization: Basic {{apiKey}}' \ 'https://data-api.survicate.com/v2/surveys/69f3dcf0d3220de7/responses?start=2024-08-31T23:59:59.000000Z&end=2024-08-26T00:00:00.000000Z&items_per_page=100' ``` ```json { "pagination_data": { "has_more": true, "next_url": "/surveys/69f3dcf0d3220de7/responses?start=2024-08-29T09:12:44.128000Z&end=2024-08-26T00:00:00.000000Z&items_per_page=100" }, "data": [...] } ``` **Request 2** - take `next_url`, prepend the base URL, and call it: ```shell curl -H 'Authorization: Basic {{apiKey}}' \ 'https://data-api.survicate.com/v2/surveys/69f3dcf0d3220de7/responses?start=2024-08-29T09:12:44.128000Z&end=2024-08-26T00:00:00.000000Z&items_per_page=100' ``` ```json { "pagination_data": { "has_more": true, "next_url": "/surveys/69f3dcf0d3220de7/responses?start=2024-08-27T16:40:02.905000Z&end=2024-08-26T00:00:00.000000Z&items_per_page=100" }, "data": [...] } ``` **Request 3** - keep going until `has_more` is `false`. That response is the last page; stop there even if a `next_url` is present: ```json { "pagination_data": { "has_more": false }, "data": [...] } ``` In code, the loop is simply: call the endpoint, process `data`, and while `has_more` is `true`, request `https://data-api.survicate.com/v2` + `next_url` again. > **Note:** > Keep the 5 concurrent request limit in mind - pages must be fetched one after another, since you only learn the next URL from the previous response. ## Attributes Responses and respondents can carry **attributes**: name/value pairs such as `order_id`, `store` or `state`. Every attribute is one you passed to Survicate yourself - through the [JavaScript SDK](/javascript/methods), a mobile SDK, an integration, or the survey link. The names you get back are the names you set, and the values are always returned as strings. Survicate does not add reserved or native attributes of its own, so there is no reserved vs. custom distinction to handle: if a field like `survey_type` shows up in an attributes array, it is there because it was sent to Survicate. A response carries two attribute arrays: `respondent.attributes` holds the attributes of the person, and the top-level `attributes` array holds attributes recorded with that specific response. On the [responses list endpoint](/data-export/response) both are returned only for the names you list in the `attributes[]` query parameter — when it is omitted, both arrays are empty. The single-response endpoint always returns the response-level `attributes` in full and applies the parameter only to `respondent.attributes`. ### Requesting attributes Repeat `attributes[]` once per attribute name — the bracket notation is required. When testing with curl, add `-g` so curl passes the brackets through instead of treating them as its own globbing syntax (some curl versions fail with `bad range in URL` otherwise): ```shell curl -g -H 'Authorization: Basic {{apiKey}}' \ 'https://data-api.survicate.com/v2/surveys/{survey_id}/responses?attributes[]=order_id&attributes[]=store' ``` Each response in `data` then carries the matching values inline, with no extra requests. A requested name is returned wherever it exists — an attribute recorded with the response lands in the top-level `attributes`, an attribute of the person under `respondent.attributes` (the other response fields are omitted from this example): ```json { "uuid": "15263384-6a46-47d3-bf4a-9aa3d05a5277", "attributes": [ { "name": "store", "value": "Berlin" } ], "respondent": { "uuid": "4a607bc1-a2ca-42a7-be37-b888a741ee31", "attributes": [ { "name": "order_id", "value": "A-1024" } ] } } ``` A requested attribute the response or respondent doesn't have is simply absent from the arrays. The parameter combines with all other parameters (`start`, `end`, `items_per_page`, `filters`), and `next_url` keeps it across pages. Fields that Survicate always returns - `uuid`, `collected_at`, `url`, `device_type`, `operating_system`, `platform`, `language`, `answers` and `respondent` - are top-level properties of a response, not attributes. See [Response](/data-export/response) for the full schema. ## Rate limiting Survicate implements a set of rate limiting measures designed to protect our infrastructure from overwhelming traffic spikes. Adhering to these limits ensures that our services remain stable and available for all users. The rate limits are as follows: - **Concurrent Request Limit:** You can make up to 5 concurrent (simultaneous) API requests. To avoid breaching this limit, design your system to wait for a response from your current request before initiating another. This mechanism helps ensure that your operations do not overload the system with multiple simultaneous demands. - **Workspace Request Limit:** There's a cap of 1000 requests per minute for each workspace. This limit safeguards the system from an excessive number of requests within a short timeframe, enabling the fair and efficient use of our resources across all users. In the event that you exceed any of these limits, our system will respond with a `429 Too Many Requests` status code. This code serves as a signal that your operation has been temporarily blocked due to excessive requests. It is, therefore, important to manage your requests to stay within these bounds, ensuring smooth operations and uninterrupted API access. If you have any questions or require assistance, our support team is ready to help. Please use the live chat feature located in the bottom right corner of your screen. We're here to ensure your experience is smooth and efficient. --- # Migrating from v1 to v2 Source: https://developers.survicate.com/data-export/migration-v1-v2/ Data Export API v1 will be turned off on **September 15, 2026**. This guide maps every v1 endpoint, parameter and response field to its v2 equivalent, so you can update your integration without guessing. Authentication is unchanged: pass your API key in the `Authorization` header as `Basic {{apiKey}}`. Only the base URL and the request/response shapes change. ``` v1 base URL: https://data-api.survicate.com/v1 v2 base URL: https://data-api.survicate.com/v2 ``` --- ## Endpoint map | v1 | v2 | |---|---| | `GET /surveys` | `GET /surveys` — now paginated, results wrapped in `data` | | `GET /surveys/{survey_id}` | Split in two: `GET /surveys/{survey_id}` for survey metadata, `GET /surveys/{survey_id}/questions` for the question list | | `GET /surveys/{survey_id}/visitors` | `GET /surveys/{survey_id}/responses` | | `GET /visitors/{visitor_uuid}` | Split in two: `GET /respondents/{respondent_uuid}/responses` for their responses, `GET /respondents/{respondent_uuid}/attributes` for their attributes | | — | New in v2: `GET /surveys/{survey_id}/responses/{response_uuid}` fetches a single response | Two naming changes run through the whole API: - **"Visitor" became "respondent".** Both versions identify a person by the same UUID — v1 called it `visitor_uuid`, v2 calls it `respondent_uuid` (or `respondent.uuid` inside a response). Numeric visitor IDs don't exist in v2; v1 itself stopped returning them in January 2025. - **Every list endpoint wraps results.** v1 returned a bare JSON array. v2 returns an object with `pagination_data` and `data`: ```json { "pagination_data": { "has_more": true, "next_url": "/surveys/69f3dcf0d3220de7/responses?start=2024-08-29T09:12:44.128000Z&end=2024-08-26T00:00:00.000000Z" }, "data": [...] } ``` --- ## Exporting responses: `/visitors` → `/responses` The most common v1 call: ```shell curl -H 'Authorization: Basic {{apiKey}}' \ 'https://data-api.survicate.com/v1/surveys/{survey_id}/visitors?since=2024-08-26T00:00:00Z&until=2024-08-31T23:59:59Z&page=1' ``` Its v2 equivalent: ```shell curl -H 'Authorization: Basic {{apiKey}}' \ 'https://data-api.survicate.com/v2/surveys/{survey_id}/responses?start=2024-08-31T23:59:59.000000Z&end=2024-08-26T00:00:00.000000Z' ``` ### Date range: `since`/`until` → `start`/`end` > **Note:** > The two timestamps swap places compared to v1. v2 orders responses from **latest to oldest**, so `start` is the **newer** bound (where the page starts) and `end` is the **older** bound. Passing your old `since` value as `start` returns an empty result. | | v1 | v2 | |---|---|---| | Older bound | `since` | `end` | | Newer bound | `until` (only honored together with `since`) | `start` | | Inclusivity | both inclusive | both inclusive | | Format | ISO 8601 (`2024-08-26T00:00:00Z`) | ISO 8601; seconds precision is accepted, timestamps in responses always carry microseconds (`2024-08-26T00:00:00.000000Z`) | ### Ordering v1 returned responses oldest-to-latest by default, with an optional `order=desc` parameter. v2 always returns latest-to-oldest; there is no `order` parameter. ### Pagination: `page` → `next_url` v1 pages were fixed at 1,000 responses each. In v2 there are no page numbers — instead of requesting `page=2`, follow the link the API builds for you: 1. Make the first request, optionally with `items_per_page` (1–100; omitted = default of 20). 2. Read `pagination_data` in the response. While `has_more` is `true`, request `next_url` — it is **always a path relative to the base URL** `https://data-api.survicate.com/v2`, so prepend the base URL and call it as-is. 3. Stop when `has_more` is `false`. Under the hood `next_url` shifts the `start` timestamp back to where the previous page ended, keeping your `end` and filters intact — you never compute page boundaries yourself. A full walkthrough with example requests is in [Setup → Pagination](/data-export/setup#pagination). ### Filtering v1 had no filters beyond the date range. v2 accepts an optional `filters` array (operating system, device type, platform, survey language, response URL, custom attributes, question answers) and an `attributes[]` parameter naming the attributes to include in each response — see the note in [Response object changes](#response-object-changes) below. See [Response](/data-export/response) for the schemas. --- ## Response object changes v1 returned one flat object per visitor, mixing identifiers, profile fields and answers. v2 returns a response object with a fixed set of native fields, a nested `respondent` object, and attribute arrays. | v1 field | v2 equivalent | |---|---| | `response_uuid` | `uuid` | | `visitor_uuid` | `respondent.uuid` | | `page_url` | `url` | | `language` | `language` (unchanged) | | `answers` | `answers` (same name, new per-type structure, see below) | | `custom_attributes` (object of key/value) | `respondent.attributes` — an array of `{ "name": ..., "value": ... }` pairs (values are always strings), returned only for the names you list in the `attributes[]` query parameter | | Profile fields at top level (`first_name`, `last_name`, `email`, `organization`, `phone`, `country`, and the rest) | Removed as dedicated fields. If you pass them to Survicate, they come back in `respondent.attributes` like any other attribute — v2 makes no distinction between profile and custom attributes | | `identity`, `first_seen_date`, `first_response_date` | Not returned in v2 | | — | New in v2: `collected_at` (response timestamp), `device_type`, `operating_system`, `platform` (a device platform identifier such as `MacIntel` or `Win32`), and a top-level `attributes` array holding attributes recorded for that specific response | Note there are **two** attribute arrays in a v2 response: `respondent.attributes` (attributes of the person, the v1 `custom_attributes`) and the top-level `attributes` (attributes recorded with that one response). > **Note:** > v1 returned all of a visitor's `custom_attributes` with every response by default. On the v2 responses list, attributes are returned **only when you ask for them**: list the attribute names in the `attributes[]` query parameter (`?attributes[]=order_id&attributes[]=store`). Without it, both attribute arrays come back empty — if your import suddenly sees no attributes after migrating, this is why. (The single-response endpoint differs: it always returns the response-level `attributes` and applies the parameter only to `respondent.attributes`.) --- ## Fetching one person's data: `/visitors/{uuid}` → `/respondents/{uuid}` The v1 `GET /visitors/{visitor_uuid}` endpoint returned one object combining the visitor's profile fields, `custom_attributes`, `tags`, `comment`, and a `reports` array with their responses across surveys. In v2 that splits into two paginated endpoints: - `GET /respondents/{respondent_uuid}/attributes` returns what v1 kept in the profile fields and `custom_attributes` — as `{ "id": ..., "name": ..., "value": ... }` entries. `tags` and `comment` are not returned in v2. - `GET /respondents/{respondent_uuid}/responses` returns what v1 kept in `reports`. Each `data` entry pairs a `survey` object with a `response` object. Response objects on this endpoint always carry empty attribute arrays — the respondent's attributes come only from the attributes endpoint above: | v1 (`reports[]` entry) | v2 (`data[]` entry) | |---|---| | `survey_name` | `survey.name` (plus `survey.id` and `survey.type`, which v1 did not return) | | `platform` (`desktop` or `mobile`, detected from the user agent) | `response.device_type` | | `date` | `response.collected_at` | | `response_uuid` | `response.uuid` | | `answers` | `response.answers` (new per-type structure, see [Answer format changes](#answer-format-changes)) | --- ## Answer format changes Each entry in the v1 `answers` array had the same wrapper regardless of question type: ```json { "survey_point": { "id": 2542, "type": "question", "pretty_type": "Single choice", "answer_type": "single" }, "question": "What prevents you from signing up?", "content": "I can't find pricing details" } ``` The `content` handling varied by type, though: `multiple` joined the selections into one string with `" | "`, `matrix` combined a joined string with a nested `answers` array, `ranking` had no `content` at all (only a nested `answers` array), and a contact form produced one entry per form field. v2 replaces all of that with one explicit payload per question type: ```json { "question_id": 2542, "question_type": "single", "answer": { "id": 75834, "content": "I can't find pricing details", "comment": null, "translated_comment": null, "disclaimer_accepted": null, "insight": null } } ``` What moved where: | v1 | v2 | |---|---| | `survey_point.id` | `question_id` | | `survey_point.answer_type` | `question_type` — renamed, but the values are the same strings as in v1 | | `survey_point.type`, `survey_point.pretty_type` | Removed | | `question` (question text repeated in every answer) | Not repeated per answer. Fetch the survey's questions once via `GET /surveys/{survey_id}/questions` and join by `question_id` | | `content` | `answer` / `answers` / `fields`, structured per question type (table below) | ### Answer payload by question type | `question_type` | v2 payload | |---|---| | `single`, `dropdown_list` | `answer`: `{ id, content, comment }` | | `multiple` | `answers`: array of `{ id, content, comment }` | | `rating`, `smiley_scale`, `numerical_scale`, `csat` | `answer`: `{ id, content, rating }` — `rating` is the numeric value | | `text`, `date` | `answer`: the entered text as a string | | `nps` | `answer`: `{ content, tag }` (see below) | | `matrix` | `answers`: array of `{ id, content, score }` — one entry per matrix row, `score` is the selected column label | | `ranking` | `answers`: array of `{ id, content, rank }` — `rank` is the position given by the respondent | | `form` | `fields`: array of `{ type, content }` — one entry per contact-form field | | `empty`, `button_close`, `button_link`, `button_next`, `redirect_timeout`, `social_cta` | `action_performed`: `true` — welcome/thank-you screen interactions. The entry only appears when the action happened | Payloads also carry auxiliary fields serialized as `null` when they don't apply — `comment`, `translated_comment` and `disclaimer_accepted` on most types, plus `insight` on choice answers and `translated_answer` / `ai_followups` / `translated_ai_followups` on `text` answers. Parse the fields you need and ignore unknown keys rather than validating against a closed set. ### NPS `question_type` is `nps`. `answer.content` is the 0–10 score as a string, and `answer.tag` is the NPS group derived from it: | `tag` | Score | |---|---| | `detractor` | 0–6 | | `passive` | 7–8 | | `promoter` | 9–10 | ```json { "question_id": 372624, "question_type": "nps", "answer": { "content": "9", "tag": "promoter", "comment": null, "translated_comment": null, "disclaimer_accepted": null } } ``` ### `dropdown_list` and `ranking` Neither is a new question type — both existed in v1 under the same `answer_type` strings. What changed is the payload shape: `dropdown_list` answers arrive like single-choice answers (one `answer` object), and `ranking` answers arrive as an `answers` array ordered by the respondent, each with its `rank`. ### Skipped questions This behavior **changed** between versions. v1 emitted an entry for every question of the survey in every response — a skipped question still appeared, just with `content` missing or empty. In v2 a skipped question does not appear in the `answers` array at all: no placeholder entries, no `null` answers. If your import expects every question to be present, join the response against the survey's question list and treat missing `question_id`s as skipped. --- ## Rate limits | Limit | v2 | |---|---| | Concurrent requests | 5 | | Requests per minute per workspace | 1,000 | Exceeding either returns `429 Too Many Requests`. Because pagination follows `next_url`, pages must be fetched sequentially — you learn the next URL only from the previous response. --- ## Migration checklist 1. Switch the base URL to `https://data-api.survicate.com/v2` — the API key and `Authorization` header stay the same. 2. Replace `/surveys/{survey_id}/visitors` with `/surveys/{survey_id}/responses`. 3. Swap the date parameters: your old `until` value becomes `start`, your old `since` value becomes `end`. 4. Replace `page`-based pagination with the `has_more` / `next_url` loop, prepending the base URL to `next_url`. 5. Read list results from the `data` field instead of the top-level array. 6. Rename fields per the tables above (`response_uuid` → `uuid`, `visitor_uuid` → `respondent.uuid`, `page_url` → `url`, `answer_type` → `question_type`). 7. Read respondent profile fields and custom attributes from `respondent.attributes` instead of top-level fields — and request them explicitly via the `attributes[]` query parameter, or they won't be returned at all. 8. Parse answers per question type instead of the v1 `content` conventions. 9. Expect skipped questions to be absent from `answers` — v1 emitted placeholder entries for them, v2 does not. 10. If you rely on ascending order, sort by `collected_at` on your side — v2 always returns latest first. --- # Survey Source: https://developers.survicate.com/data-export/survey/ Surveys represent individual questionnaires within your workspace. Each survey contains a series of questions designed to gather information or opinions from respondents. This section of the API allows you to retrieve information about the surveys in your workspace ## List all surveys GET /surveys This endpoint allows you to fetch a list of all surveys within your workspace, including their associated metadata and configuration parameters. ### Optional parameters Name: items_per_page Type: integer Description: The number of items to display per page in the response. This parameter helps manage the size of each response, making it easier to work with large datasets by breaking them into smaller, paginated results. The minimum value for this parameter is 1, and the maximum is 100. If omitted, the API applies its default page size. Name: start Type: string Description: Optional newer bound of the creation date range, and the point the page starts from. Surveys are ordered from latest to oldest, so 'start' is the later of the two timestamps: surveys created at or before it are included (inclusive). The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). Name: end Type: string Description: Optional older bound of the creation date range. Surveys are ordered from latest to oldest, so 'end' is the earlier of the two timestamps: surveys created at or after it are included (inclusive). The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). ### Response 200 The operation was successful, and the requested data has been returned in the response. #### Response properties Name: pagination_data.has_more Type: boolean Description: Specifies if additional pages are available for retrieval (True or False). Name: pagination_data.next_url Type: string Description: Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true. Name: data[0].id Type: string Description: The survey's unique unchangeable identifier. Name: data[0].type Type: PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey Description: The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents: * PageSurvey is Email & Sharable Link Survey * WidgetSurvey is Web & In-Product Survey * MobileSurvey is Mobile App Survey * IntercomSurvey is Intercom Messenger Survey Name: data[0].name Type: string Description: The name of the survey. Name: data[0].created_at Type: string Description: The timestamp when the survey was creatd. The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). Name: data[0].enabled Type: boolean Description: Indicates whether a survey is available for respondents (true or false). Name: data[0].responses Type: integer Description: The total number of survey responses. Name: data[0].launch.start_at Type: string Description: Date when the survey will start appearing to respondents. Name: data[0].launch.end_at Type: string Description: Date when the survey will stop appearing to respondents. Name: data[0].launch.responses_limit Type: integer Description: The survey will stop being available to respondents after collecting that amount of responses. ```json { "pagination_data": { "has_more": { "value": true, "description": "Specifies if additional pages are available for retrieval (True or False)." }, "next_url": { "value": "/surveys?start=2023-01-01T00:00:00.000000Z", "description": "Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true." } }, "data": [ { "id": { "value": "69f3dcf0d3220de7", "description": "The survey's unique unchangeable identifier." }, "type": { "value": "PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey", "description": "The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents:\n* PageSurvey is Email & Sharable Link Survey\n* WidgetSurvey is Web & In-Product Survey\n* MobileSurvey is Mobile App Survey\n* IntercomSurvey is Intercom Messenger Survey\n" }, "name": { "value": "Customer satisfaction survey", "description": "The name of the survey." }, "created_at": { "value": "2023-01-13T00:00:00.000000Z", "description": "The timestamp when the survey was creatd. The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z')." }, "enabled": { "value": true, "description": "Indicates whether a survey is available for respondents (true or false)." }, "responses": { "value": 34206, "description": "The total number of survey responses." }, "launch": { "value": { "start_at": { "value": "2023-06-13T00:00:00.000000Z", "description": "Date when the survey will start appearing to respondents." }, "end_at": { "value": "2023-06-31T00:00:00.000000Z", "description": "Date when the survey will stop appearing to respondents." }, "responses_limit": { "value": 1400, "description": "The survey will stop being available to respondents after collecting that amount of responses." } }, "description": "Indicates whether the survey is scheduled to start or stop being available at a specific date." } } ] } ``` --- ## Retrieve survey information GET /surveys/{survey_id} Fetches the details and parameters of a specific survey using its unique survey ID. ### Required parameters Name: survey_id Type: string Description: The unique identifier of the survey you wish to retrieve. ### Response 200 The operation was successful, and the details of the requested survey have been returned. #### Response properties Name: id Type: string Description: The survey's unique unchangeable identifier. Name: type Type: PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey Description: The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents: * PageSurvey is Email & Sharable Link Survey * WidgetSurvey is Web & In-Product Survey * MobileSurvey is Mobile App Survey * IntercomSurvey is Intercom Messenger Survey Name: name Type: string Description: The name of the survey. Name: created_at Type: string Description: The timestamp when the survey was creatd. The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). Name: enabled Type: boolean Description: Indicates whether a survey is available for respondents (true or false). Name: responses Type: integer Description: The total number of survey responses. Name: launch.start_at Type: string Description: Date when the survey will start appearing to respondents. Name: launch.end_at Type: string Description: Date when the survey will stop appearing to respondents. Name: launch.responses_limit Type: integer Description: The survey will stop being available to respondents after collecting that amount of responses. Name: author.name Type: string Description: The full name of the individual who created the survey. Name: author.email Type: string Description: The email address of the individual who created the survey. Name: folder Type: string Description: The name of the folder in which the survey is stored. Name: first_response_at Type: string Description: This is the timestamp indicating when the first response to the survey was received. It should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). Name: last_response_at Type: string Description: This is the timestamp indicating when the last response to the survey was received. It should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). ```json { "id": { "value": "69f3dcf0d3220de7", "description": "The survey's unique unchangeable identifier." }, "type": { "value": "PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey", "description": "The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents:\n* PageSurvey is Email & Sharable Link Survey\n* WidgetSurvey is Web & In-Product Survey\n* MobileSurvey is Mobile App Survey\n* IntercomSurvey is Intercom Messenger Survey\n" }, "name": { "value": "Customer satisfaction survey", "description": "The name of the survey." }, "created_at": { "value": "2023-01-13T00:00:00.000000Z", "description": "The timestamp when the survey was creatd. The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z')." }, "enabled": { "value": true, "description": "Indicates whether a survey is available for respondents (true or false)." }, "responses": { "value": 34206, "description": "The total number of survey responses." }, "launch": { "value": { "start_at": { "value": "2023-06-13T00:00:00.000000Z", "description": "Date when the survey will start appearing to respondents." }, "end_at": { "value": "2023-06-31T00:00:00.000000Z", "description": "Date when the survey will stop appearing to respondents." }, "responses_limit": { "value": 1400, "description": "The survey will stop being available to respondents after collecting that amount of responses." } }, "description": "Indicates whether the survey is scheduled to start or stop being available at a specific date." }, "author": { "value": { "name": { "value": "John Doe", "description": "The full name of the individual who created the survey." }, "email": { "value": "john.doe@example.com", "description": "The email address of the individual who created the survey." } }, "description": "Provides basic information about the creator of the survey." }, "folder": { "value": "Marketing Team Surveys", "description": "The name of the folder in which the survey is stored." }, "first_response_at": { "value": "2023-06-13T00:00:00.000000Z", "description": "This is the timestamp indicating when the first response to the survey was received. It should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z')." }, "last_response_at": { "value": "2023-06-31T00:00:00.000000Z", "description": "This is the timestamp indicating when the last response to the survey was received. It should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z')." } } ``` ### Response 404 The specified survey could not be found. --- ## List questions GET /surveys/{survey_id}/questions This endpoint fetches all questions included in a specified survey, making it easy to review or analyze the survey structure. ### Required parameters Name: survey_id Type: string Description: The unique identifier of the survey. ### Optional parameters Name: items_per_page Type: integer Description: The number of items to display per page in the response. This parameter helps manage the size of each response, making it easier to work with large datasets by breaking them into smaller, paginated results. The minimum value for this parameter is 1, and the maximum is 100. If omitted, the API applies its default page size. Name: start Type: string Description: The unique identifier of the question, used to return paginated results. This identifier is included in the response for each request, as part of the 'next_url' parameter. ### Response 200 The operation was successful, and the details of the requested survey have been returned. #### Response properties Name: pagination_data.has_more Type: boolean Description: Specifies if additional pages are available for retrieval (True or False). Name: pagination_data.next_url Type: string Description: Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true. Name: data[0].id Type: integer Description: The question's unique unchangeable identifier. Name: data[0].type Type: single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat Description: The question's type Name: data[0].question Type: string Description: Text of the question as displayed to the respondent. Name: data[0].introduction Type: string Description: Introduction to the question as displayed to the respondent. Name: data[0].answer_choices[0].id Type: integer Description: The answer's unique unchangeable identifier. Name: data[0].answer_choices[0].content Type: string Description: Text of the answer option as displayed to the respondent. Name: data Type: [{"id":{"value":"integer","description":"The question's unique unchangeable identifier."},"type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"question":{"value":"string","description":"Text of the question as displayed to the respondent."},"introduction":{"value":"string","description":"Introduction to the question as displayed to the respondent."},"answer_choices":[{"id":{"value":"integer","description":"The answer's unique unchangeable identifier."},"content":{"value":"string","description":"Text of the answer option as displayed to the respondent."}}]},{"id":{"value":"integer","description":"The question's unique unchangeable identifier."},"type":"text | date","question":{"value":"string","description":"Text of the question as displayed to the respondent."},"introduction":{"value":"string","description":"Introduction to the question as displayed to the respondent."}},{"id":{"value":"integer","description":"The question's unique unchangeable identifier."},"type":"matrix","question":{"value":"string","description":"Text of the question as displayed to the respondent."},"introduction":{"value":"string","description":"Introduction to the question as displayed to the respondent."},"answer_choices":[{"id":{"value":"integer","description":"The answer's unique unchangeable identifier."},"content":{"value":"string","description":"Text of the answer option as displayed to the respondent."}}],"columns":["string"]},{"id":{"value":"integer","description":"The question's unique unchangeable identifier."},"type":"form","question":{"value":"string","description":"Text of the question as displayed to the respondent."},"introduction":{"value":"string","description":"Introduction to the question as displayed to the respondent."},"fields":[{"type":"string","label":"string"}]},{"id":{"value":"integer","description":"The question's unique unchangeable identifier."},"type":"nps","question":{"value":"string","description":"Text of the question as displayed to the respondent."},"introduction":{"value":"string","description":"Introduction to the question as displayed to the respondent."}},{"id":{"value":"integer","description":"The question's unique unchangeable identifier."},"type":"empty | button_close | button_link | button_next | redirect_timeout | social_cta","question":{"value":"string","description":"Text of the question as displayed to the respondent."},"introduction":{"value":"string","description":"Introduction to the question as displayed to the respondent."}}] Description: List of the survey's questions and possible answers. ```json { "pagination_data": { "has_more": { "value": true, "description": "Specifies if additional pages are available for retrieval (True or False)." }, "next_url": { "value": "/surveys/69f3dcf0d3220de7/questions?start=2345", "description": "Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true." } }, "data": { "value": [ { "id": { "value": 372624, "description": "The question's unique unchangeable identifier." }, "type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "question": { "value": "Would you recommend us to your friend?", "description": "Text of the question as displayed to the respondent." }, "introduction": { "value": "One more quick question.", "description": "Introduction to the question as displayed to the respondent." }, "answer_choices": [ { "id": { "value": 0, "description": "The answer's unique unchangeable identifier." }, "content": { "value": "Very happy", "description": "Text of the answer option as displayed to the respondent." } } ] }, { "id": { "value": 372624, "description": "The question's unique unchangeable identifier." }, "type": "text | date", "question": { "value": "Would you recommend us to your friend?", "description": "Text of the question as displayed to the respondent." }, "introduction": { "value": "One more quick question.", "description": "Introduction to the question as displayed to the respondent." } }, { "id": { "value": 372624, "description": "The question's unique unchangeable identifier." }, "type": "matrix", "question": { "value": "Would you recommend us to your friend?", "description": "Text of the question as displayed to the respondent." }, "introduction": { "value": "One more quick question.", "description": "Introduction to the question as displayed to the respondent." }, "answer_choices": [ { "id": { "value": 0, "description": "The answer's unique unchangeable identifier." }, "content": { "value": "Very happy", "description": "Text of the answer option as displayed to the respondent." } } ], "columns": [ "sample string" ] }, { "id": { "value": 372624, "description": "The question's unique unchangeable identifier." }, "type": "form", "question": { "value": "Would you recommend us to your friend?", "description": "Text of the question as displayed to the respondent." }, "introduction": { "value": "One more quick question.", "description": "Introduction to the question as displayed to the respondent." }, "fields": [ { "type": "sample string", "label": "sample string" } ] }, { "id": { "value": 372624, "description": "The question's unique unchangeable identifier." }, "type": "nps", "question": { "value": "Would you recommend us to your friend?", "description": "Text of the question as displayed to the respondent." }, "introduction": { "value": "One more quick question.", "description": "Introduction to the question as displayed to the respondent." } }, { "id": { "value": 372624, "description": "The question's unique unchangeable identifier." }, "type": "empty | button_close | button_link | button_next | redirect_timeout | social_cta", "question": { "value": "Would you recommend us to your friend?", "description": "Text of the question as displayed to the respondent." }, "introduction": { "value": "One more quick question.", "description": "Introduction to the question as displayed to the respondent." } } ], "description": "List of the survey's questions and possible answers." } } ``` ### Response 404 The specified survey could not be found. --- # Response Source: https://developers.survicate.com/data-export/response/ Responses are the answers submitted by respondents to a specific survey. Each response is associated with a particular survey and respondent. This section of the API enables you to access responses collected for each survey, as well as filter and export them for further analysis. ## List all responses GET /surveys/{survey_id}/responses Fetches the list of responses for a specific survey identified by its unique ID. ### Required parameters Name: survey_id Type: string Description: The unique identifier of the survey containing the responses. ### Optional parameters Name: items_per_page Type: integer Description: The number of items to display per page in the response. This parameter helps manage the size of each response, making it easier to work with large datasets by breaking them into smaller, paginated results. The minimum value for this parameter is 1, and the maximum is 100. If omitted, the API applies its default page size. Name: filters Type: array Description: Apply specific filters to narrow down the results. This parameter accepts an array of filter objects, where each filter can be based on different criteria such as operating system, device type, platform, survey translation language, URL, custom attribute, or question answer. Use the appropriate filter schema from the available options, including OsFilter, DeviceFilter, PlatformFilter, TranslationFilter, UrlFilter, CustomAttributeFilter, or QuestionAnswerFilter, to define the desired filtering conditions. Name: start Type: string Description: Optional newer bound of the time range, and the point the page starts from. Responses are ordered from latest to oldest, so 'start' is the later of the two timestamps: responses collected at or before it are included (inclusive). The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). See the Pagination section of the setup guide for a full walkthrough. Name: end Type: string Description: Optional older bound of the time range. Responses are ordered from latest to oldest, so 'end' is the earlier of the two timestamps: responses collected at or after it are included (inclusive). Because of the ordering, 'end' must be earlier than 'start'. The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). Name: attributes[] Type: array Description: An optional list of attribute names to include in each response - repeat the parameter once per name, e.g. '?attributes[]=order_id&attributes[]=store'. When provided, matching attributes are included in both the response-level 'attributes' field and the 'respondent.attributes' field. When omitted, both fields are returned empty. Attribute names are the ones you defined yourself when passing the attributes to Survicate; there is no fixed set of names to choose from. ### Response 200 The operation was successful, and the list of responses for the requested survey has been returned. #### Response properties Name: pagination_data.has_more Type: boolean Description: Specifies if additional pages are available for retrieval (True or False). Name: pagination_data.next_url Type: string Description: Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true. Name: data[0].uuid Type: string Description: A unique, unchangeable identifier for the response. Name: data[0].collected_at Type: string Description: This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z'). Name: data[0].url Type: string Description: The URL where the survey was displayed to the respondent. Name: data[0].device_type Type: Desktop | Mobile | Tablet | Tv Description: The type of device used by the respondent to submit the response. Name: data[0].operating_system Type: Android | OS | iOS | Linux | macOS | Windows | Other Description: The operating system of the device used by the respondent. Name: data[0].platform Type: string Description: The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32'). Name: data[0].language Type: string Description: If present, the language of the survey translation presented to the respondent. Name: data[0].answers[0].question_id Type: integer Description: The question's unique unchangeable identifier. Name: data[0].answers[0].question_type Type: single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat Description: The question's type Name: data[0].answers[0].answer.id Type: integer Description: An abstract entity to build other classes. The answer's unique unchangeable identifier. Name: data[0].answers[0].answer.content Type: string Description: The respondent's selected answer content. Name: data[0].answers[0].answer.comment Type: string Description: Optional text input provided by the respondent as an additional comment to the selected response. Name: data[0].answers[0].answers[0].id Type: integer Description: An abstract entity to build other classes. The answer's unique unchangeable identifier. Name: data[0].answers[0].answers[0].content Type: string Description: The respondent's selected answer content. Name: data[0].answers[0].answers[0].comment Type: string Description: Optional text input provided by the respondent as an additional comment to the selected response. Name: data[0].answers[0].answer.rating Type: integer Description: Numerical value representing the respondent's rating. Name: data[0].answers[0].fields[0].type Type: string Description: The type of field in the contact form, as chosen by the user through the Survicate interface. Name: data[0].answers[0].fields[0].content Type: string Description: The respondent's input for a specific field. Name: data[0].answers[0].answer.tag Type: detractor | passive | promoter Description: This represents the NPS group associated with the score selected by the respondent. The options include: * detractor (score 0-6) * passive (score 7-8) * promoter (score 9-10) Name: data[0].answers[0].answers[0].score Type: string Description: Label of the selected option in a matrix choice question. Name: data[0].answers[0].answers[0].rank Type: integer Description: The selected position of the respondent's choice in the ranking question. Name: data[0].answers Type: [{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rating":{"value":"integer","description":"Numerical value representing the respondent's rating."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"fields":[{"type":{"value":"string","description":"The type of field in the contact form, as chosen by the user through the Survicate interface."},"content":{"value":"string","description":"The respondent's input for a specific field."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":"string"},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"content":{"value":"string","description":"Numerical value of the Net Promoter Score (NPS) chosen by the respondent."},"tag":{"value":"detractor | passive | promoter","description":"This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n"}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"score":{"value":"string","description":"Label of the selected option in a matrix choice question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rank":{"value":"integer","description":"The selected position of the respondent's choice in the ranking question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"action_performed":"boolean"}] Description: An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included. Name: data[0].respondent.uuid Type: string Description: A unique, unchangeable identifier for the respondent. Name: data[0].respondent.attributes[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: data[0].respondent.attributes[0].value Type: string Description: The attribute's value, always returned as a string. Name: data[0].respondent.attributes Type: [{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}] Description: The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it. Name: data[0].attributes[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: data[0].attributes[0].value Type: string Description: The attribute's value, always returned as a string. Name: data[0].attributes Type: [{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}] Description: Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes. ```json { "pagination_data": { "has_more": { "value": true, "description": "Specifies if additional pages are available for retrieval (True or False)." }, "next_url": { "value": "/surveys/69f3dcf0d3220de7/responses?start=2023-01-01T00:00:00.000000Z", "description": "Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true." } }, "data": [ { "uuid": { "value": "sample string", "description": "A unique, unchangeable identifier for the response." }, "collected_at": { "value": "sample string", "description": "This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z')." }, "url": { "value": "https://survicate.com/", "description": "The URL where the survey was displayed to the respondent." }, "device_type": { "value": "Desktop | Mobile | Tablet | Tv", "description": "The type of device used by the respondent to submit the response." }, "operating_system": { "value": "Android | OS | iOS | Linux | macOS | Windows | Other", "description": "The operating system of the device used by the respondent." }, "platform": { "value": "MacIntel", "description": "The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32')." }, "language": { "value": "en", "description": "If present, the language of the survey translation presented to the respondent." }, "answers": { "value": [ { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "comment": { "value": "sample string", "description": "Optional text input provided by the respondent as an additional comment to the selected response." } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "comment": { "value": "sample string", "description": "Optional text input provided by the respondent as an additional comment to the selected response." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "rating": { "value": 0, "description": "Numerical value representing the respondent's rating." } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "fields": [ { "type": { "value": "sample string", "description": "The type of field in the contact form, as chosen by the user through the Survicate interface." }, "content": { "value": "sample string", "description": "The respondent's input for a specific field." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": "sample string" }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "content": { "value": "sample string", "description": "Numerical value of the Net Promoter Score (NPS) chosen by the respondent." }, "tag": { "value": "detractor | passive | promoter", "description": "This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n" } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "score": { "value": "sample string", "description": "Label of the selected option in a matrix choice question." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "rank": { "value": 0, "description": "The selected position of the respondent's choice in the ranking question." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "action_performed": true } ], "description": "An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included." }, "respondent": { "value": { "uuid": { "value": "sample string", "description": "A unique, unchangeable identifier for the respondent." }, "attributes": { "value": [ { "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, always returned as a string." } } ], "description": "The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it." } }, "description": "The respondent who submitted the response." }, "attributes": { "value": [ { "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, always returned as a string." } } ], "description": "Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes." } } ] } ``` ### Response 404 The specified survey could not be found. --- ## Retrieve a response GET /surveys/{survey_id}/responses/{response_uuid} Fetches the details of a single response for a given survey, including the survey information, respondent details, response collection timestamp, device and operating system, language, answers to the survey questions, and any custom attributes associated with the response. ### Required parameters Name: survey_id Type: string Description: The unique identifier of the survey containing the response. Name: response_uuid Type: string Description: The unique identifier (UUID) of the response to be retrieved. ### Optional parameters Name: attributes[] Type: array Description: An optional list of respondent attribute names to include under 'respondent.attributes' - repeat the parameter once per name, e.g. '?attributes[]=order_id&attributes[]=store'. When omitted, 'respondent.attributes' is returned empty. Unlike on the response list endpoint, the response-level 'attributes' field is always returned in full here, regardless of this parameter. ### Response 200 The operation was successful, and the details of the requested response have been returned. #### Response properties Name: uuid Type: string Description: A unique, unchangeable identifier for the response. Name: collected_at Type: string Description: This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z'). Name: url Type: string Description: The URL where the survey was displayed to the respondent. Name: device_type Type: Desktop | Mobile | Tablet | Tv Description: The type of device used by the respondent to submit the response. Name: operating_system Type: Android | OS | iOS | Linux | macOS | Windows | Other Description: The operating system of the device used by the respondent. Name: platform Type: string Description: The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32'). Name: language Type: string Description: If present, the language of the survey translation presented to the respondent. Name: answers[0].question_id Type: integer Description: The question's unique unchangeable identifier. Name: answers[0].question_type Type: single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat Description: The question's type Name: answers[0].answer.id Type: integer Description: An abstract entity to build other classes. The answer's unique unchangeable identifier. Name: answers[0].answer.content Type: string Description: The respondent's selected answer content. Name: answers[0].answer.comment Type: string Description: Optional text input provided by the respondent as an additional comment to the selected response. Name: answers[0].answers[0].id Type: integer Description: An abstract entity to build other classes. The answer's unique unchangeable identifier. Name: answers[0].answers[0].content Type: string Description: The respondent's selected answer content. Name: answers[0].answers[0].comment Type: string Description: Optional text input provided by the respondent as an additional comment to the selected response. Name: answers[0].answer.rating Type: integer Description: Numerical value representing the respondent's rating. Name: answers[0].fields[0].type Type: string Description: The type of field in the contact form, as chosen by the user through the Survicate interface. Name: answers[0].fields[0].content Type: string Description: The respondent's input for a specific field. Name: answers[0].answer.tag Type: detractor | passive | promoter Description: This represents the NPS group associated with the score selected by the respondent. The options include: * detractor (score 0-6) * passive (score 7-8) * promoter (score 9-10) Name: answers[0].answers[0].score Type: string Description: Label of the selected option in a matrix choice question. Name: answers[0].answers[0].rank Type: integer Description: The selected position of the respondent's choice in the ranking question. Name: answers Type: [{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rating":{"value":"integer","description":"Numerical value representing the respondent's rating."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"fields":[{"type":{"value":"string","description":"The type of field in the contact form, as chosen by the user through the Survicate interface."},"content":{"value":"string","description":"The respondent's input for a specific field."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":"string"},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"content":{"value":"string","description":"Numerical value of the Net Promoter Score (NPS) chosen by the respondent."},"tag":{"value":"detractor | passive | promoter","description":"This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n"}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"score":{"value":"string","description":"Label of the selected option in a matrix choice question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rank":{"value":"integer","description":"The selected position of the respondent's choice in the ranking question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"action_performed":"boolean"}] Description: An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included. Name: respondent.uuid Type: string Description: A unique, unchangeable identifier for the respondent. Name: respondent.attributes[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: respondent.attributes[0].value Type: string Description: The attribute's value, always returned as a string. Name: respondent.attributes Type: [{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}] Description: The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it. Name: attributes[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: attributes[0].value Type: string Description: The attribute's value, always returned as a string. Name: attributes Type: [{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}] Description: Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes. ```json { "uuid": { "value": "sample string", "description": "A unique, unchangeable identifier for the response." }, "collected_at": { "value": "sample string", "description": "This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z')." }, "url": { "value": "https://survicate.com/", "description": "The URL where the survey was displayed to the respondent." }, "device_type": { "value": "Desktop | Mobile | Tablet | Tv", "description": "The type of device used by the respondent to submit the response." }, "operating_system": { "value": "Android | OS | iOS | Linux | macOS | Windows | Other", "description": "The operating system of the device used by the respondent." }, "platform": { "value": "MacIntel", "description": "The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32')." }, "language": { "value": "en", "description": "If present, the language of the survey translation presented to the respondent." }, "answers": { "value": [ { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "comment": { "value": "sample string", "description": "Optional text input provided by the respondent as an additional comment to the selected response." } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "comment": { "value": "sample string", "description": "Optional text input provided by the respondent as an additional comment to the selected response." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "rating": { "value": 0, "description": "Numerical value representing the respondent's rating." } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "fields": [ { "type": { "value": "sample string", "description": "The type of field in the contact form, as chosen by the user through the Survicate interface." }, "content": { "value": "sample string", "description": "The respondent's input for a specific field." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": "sample string" }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "content": { "value": "sample string", "description": "Numerical value of the Net Promoter Score (NPS) chosen by the respondent." }, "tag": { "value": "detractor | passive | promoter", "description": "This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n" } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "score": { "value": "sample string", "description": "Label of the selected option in a matrix choice question." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "rank": { "value": 0, "description": "The selected position of the respondent's choice in the ranking question." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "action_performed": true } ], "description": "An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included." }, "respondent": { "value": { "uuid": { "value": "sample string", "description": "A unique, unchangeable identifier for the respondent." }, "attributes": { "value": [ { "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, always returned as a string." } } ], "description": "The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it." } }, "description": "The respondent who submitted the response." }, "attributes": { "value": [ { "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, always returned as a string." } } ], "description": "Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes." } } ``` ### Response 404 The specified response or survey could not be found. --- # Respondent Source: https://developers.survicate.com/data-export/respondent/ Respondents are the individuals who participate in your surveys by providing their answers. In this section of the API, you can retrieve responses of a particular respondent and their attributes passed to Survicate. ## List respondent's attributes GET /respondents/{respondent_uuid}/attributes Retrieves the names and values of custom attributes associated with a specific respondent, which have been passed to Survicate through the JavaScript API, integrations, or embedded within the survey link. ### Required parameters Name: respondent_uuid Type: string Description: The unique identifier (UUID) of the selected respondent. ### Optional parameters Name: items_per_page Type: integer Description: The number of items to display per page in the response. This parameter helps manage the size of each response, making it easier to work with large datasets by breaking them into smaller, paginated results. The minimum value for this parameter is 1, and the maximum is 100. If omitted, the API applies its default page size. Name: start Type: string Description: The unique identifier of the attribute, used to return paginated results. This identifier is included in the response for each request, as part of the 'next_url' parameter. ### Response 200 The operation was successful, and the list of attributes for the requested respondent has been returned. #### Response properties Name: pagination_data.has_more Type: boolean Description: Specifies if additional pages are available for retrieval (True or False). Name: pagination_data.next_url Type: string Description: Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true. Name: data[0].id Type: integer Description: The attribute's unique identifier. Name: data[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: data[0].value Type: string Description: The attribute's value, returned as a string. Name: data Type: [{"id":{"value":"integer","description":"The attribute's unique identifier."},"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, returned as a string."}}] Description: A collection of custom attributes that provide additional information about the respondent ```json { "pagination_data": { "has_more": { "value": true, "description": "Specifies if additional pages are available for retrieval (True or False)." }, "next_url": { "value": "/respondents/7232ddb7-d08a-4fcb-9de8-f77ab73f227e/attributes?start=2", "description": "Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true." } }, "data": { "value": [ { "id": { "value": 2345, "description": "The attribute's unique identifier." }, "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, returned as a string." } } ], "description": "A collection of custom attributes that provide additional information about the respondent" } } ``` ### Response 404 The specified respondent could not be found. --- ## List respondent's responses GET /respondents/{respondent_uuid}/responses Retrieves a list of survey responses provided by a specific respondent identified by their unique identifier (UUID). Response objects on this endpoint carry empty attribute arrays - both 'respondent.attributes' and the response-level 'attributes' are always empty here; use the respondent attributes endpoint to retrieve the respondent's attributes. ### Required parameters Name: respondent_uuid Type: string Description: The unique identifier (UUID) of the respondent whose responses are being requested. ### Optional parameters Name: items_per_page Type: integer Description: The number of items to display per page in the response. This parameter helps manage the size of each response, making it easier to work with large datasets by breaking them into smaller, paginated results. The minimum value for this parameter is 1, and the maximum is 100. If omitted, the API applies its default page size. Name: start Type: string Description: Optional newer bound of the time range, and the point the page starts from. Responses are ordered from latest to oldest, so 'start' is the later of the two timestamps: responses collected at or before it are included (inclusive). The timestamp should be in the ISO 8601 format, including microseconds (e.g., '2023-01-01T00:00:00.000000Z'). See the Pagination section of the setup guide for a full walkthrough. ### Response 200 The operation was successful, and the list of responses for the requested respondent has been returned. #### Response properties Name: pagination_data.has_more Type: boolean Description: Specifies if additional pages are available for retrieval (True or False). Name: pagination_data.next_url Type: string Description: Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true. Name: data[0].survey.id Type: string Description: The survey's unique unchangeable identifier. Name: data[0].survey.type Type: PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey Description: The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents: * PageSurvey is Email & Sharable Link Survey * WidgetSurvey is Web & In-Product Survey * MobileSurvey is Mobile App Survey * IntercomSurvey is Intercom Messenger Survey Name: data[0].survey.name Type: string Description: The name of the survey. Name: data[0].response.uuid Type: string Description: A unique, unchangeable identifier for the response. Name: data[0].response.collected_at Type: string Description: This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z'). Name: data[0].response.url Type: string Description: The URL where the survey was displayed to the respondent. Name: data[0].response.device_type Type: Desktop | Mobile | Tablet | Tv Description: The type of device used by the respondent to submit the response. Name: data[0].response.operating_system Type: Android | OS | iOS | Linux | macOS | Windows | Other Description: The operating system of the device used by the respondent. Name: data[0].response.platform Type: string Description: The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32'). Name: data[0].response.language Type: string Description: If present, the language of the survey translation presented to the respondent. Name: data[0].response.answers[0].question_id Type: integer Description: The question's unique unchangeable identifier. Name: data[0].response.answers[0].question_type Type: single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat Description: The question's type Name: data[0].response.answers[0].answer.id Type: integer Description: An abstract entity to build other classes. The answer's unique unchangeable identifier. Name: data[0].response.answers[0].answer.content Type: string Description: The respondent's selected answer content. Name: data[0].response.answers[0].answer.comment Type: string Description: Optional text input provided by the respondent as an additional comment to the selected response. Name: data[0].response.answers[0].answers[0].id Type: integer Description: An abstract entity to build other classes. The answer's unique unchangeable identifier. Name: data[0].response.answers[0].answers[0].content Type: string Description: The respondent's selected answer content. Name: data[0].response.answers[0].answers[0].comment Type: string Description: Optional text input provided by the respondent as an additional comment to the selected response. Name: data[0].response.answers[0].answer.rating Type: integer Description: Numerical value representing the respondent's rating. Name: data[0].response.answers[0].fields[0].type Type: string Description: The type of field in the contact form, as chosen by the user through the Survicate interface. Name: data[0].response.answers[0].fields[0].content Type: string Description: The respondent's input for a specific field. Name: data[0].response.answers[0].answer.tag Type: detractor | passive | promoter Description: This represents the NPS group associated with the score selected by the respondent. The options include: * detractor (score 0-6) * passive (score 7-8) * promoter (score 9-10) Name: data[0].response.answers[0].answers[0].score Type: string Description: Label of the selected option in a matrix choice question. Name: data[0].response.answers[0].answers[0].rank Type: integer Description: The selected position of the respondent's choice in the ranking question. Name: data[0].response.answers Type: [{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rating":{"value":"integer","description":"Numerical value representing the respondent's rating."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"fields":[{"type":{"value":"string","description":"The type of field in the contact form, as chosen by the user through the Survicate interface."},"content":{"value":"string","description":"The respondent's input for a specific field."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":"string"},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"content":{"value":"string","description":"Numerical value of the Net Promoter Score (NPS) chosen by the respondent."},"tag":{"value":"detractor | passive | promoter","description":"This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n"}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"score":{"value":"string","description":"Label of the selected option in a matrix choice question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rank":{"value":"integer","description":"The selected position of the respondent's choice in the ranking question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"action_performed":"boolean"}] Description: An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included. Name: data[0].response.respondent.uuid Type: string Description: A unique, unchangeable identifier for the respondent. Name: data[0].response.respondent.attributes[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: data[0].response.respondent.attributes[0].value Type: string Description: The attribute's value, always returned as a string. Name: data[0].response.respondent.attributes Type: [{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}] Description: The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it. Name: data[0].response.attributes[0].name Type: string Description: The attribute's name, exactly as you passed it to Survicate. Name: data[0].response.attributes[0].value Type: string Description: The attribute's value, always returned as a string. Name: data[0].response.attributes Type: [{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}] Description: Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes. Name: data Type: [{"survey":{"id":{"value":"string","description":"The survey's unique unchangeable identifier."},"type":{"value":"PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey","description":"The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents:\n* PageSurvey is Email & Sharable Link Survey\n* WidgetSurvey is Web & In-Product Survey\n* MobileSurvey is Mobile App Survey\n* IntercomSurvey is Intercom Messenger Survey\n"},"name":{"value":"string","description":"The name of the survey."}},"response":{"uuid":{"value":"string","description":"A unique, unchangeable identifier for the response."},"collected_at":{"value":"string","description":"This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z')."},"url":{"value":"string","description":"The URL where the survey was displayed to the respondent."},"device_type":{"value":"Desktop | Mobile | Tablet | Tv","description":"The type of device used by the respondent to submit the response."},"operating_system":{"value":"Android | OS | iOS | Linux | macOS | Windows | Other","description":"The operating system of the device used by the respondent."},"platform":{"value":"string","description":"The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32')."},"language":{"value":"string","description":"If present, the language of the survey translation presented to the respondent."},"answers":{"value":[{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"comment":{"value":"string","description":"Optional text input provided by the respondent as an additional comment to the selected response."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rating":{"value":"integer","description":"Numerical value representing the respondent's rating."}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"fields":[{"type":{"value":"string","description":"The type of field in the contact form, as chosen by the user through the Survicate interface."},"content":{"value":"string","description":"The respondent's input for a specific field."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":"string"},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answer":{"content":{"value":"string","description":"Numerical value of the Net Promoter Score (NPS) chosen by the respondent."},"tag":{"value":"detractor | passive | promoter","description":"This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n"}}},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"score":{"value":"string","description":"Label of the selected option in a matrix choice question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"answers":[{"id":{"value":"integer","description":"An abstract entity to build other classes. The answer's unique unchangeable identifier."},"content":{"value":"string","description":"The respondent's selected answer content."},"rank":{"value":"integer","description":"The selected position of the respondent's choice in the ranking question."}}]},{"question_id":{"value":"integer","description":"The question's unique unchangeable identifier."},"question_type":{"value":"single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat","description":"The question's type"},"action_performed":"boolean"}],"description":"An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included."},"respondent":{"value":{"uuid":{"value":"string","description":"A unique, unchangeable identifier for the respondent."},"attributes":{"value":[{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}],"description":"The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it."}},"description":"The respondent who submitted the response."},"attributes":{"value":[{"name":{"value":"string","description":"The attribute's name, exactly as you passed it to Survicate."},"value":{"value":"string","description":"The attribute's value, always returned as a string."}}],"description":"Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes."}}}] Description: Responses of the respondent. ```json { "pagination_data": { "has_more": { "value": true, "description": "Specifies if additional pages are available for retrieval (True or False)." }, "next_url": { "value": "/respondents/7232ddb7-d08a-4fcb-9de8-f77ab73f227e/responses?start=2023-01-01T00:00:00.000000Z", "description": "Path to the next set of paginated results. It is always returned as a path relative to the API base URL (https://data-api.survicate.com/v2), never as an absolute URL, so prepend the base URL and request it as-is. Only present when 'has_more' is true." } }, "data": { "value": [ { "survey": { "id": { "value": "69f3dcf0d3220de7", "description": "The survey's unique unchangeable identifier." }, "type": { "value": "PageSurvey | WidgetSurvey | MobileSurvey | IntercomSurvey", "description": "The survey's unchangeable type. The type of survey corresponds to the distribution method the survey is delivered to your respondents:\n* PageSurvey is Email & Sharable Link Survey\n* WidgetSurvey is Web & In-Product Survey\n* MobileSurvey is Mobile App Survey\n* IntercomSurvey is Intercom Messenger Survey\n" }, "name": { "value": "Customer satisfaction survey", "description": "The name of the survey." } }, "response": { "uuid": { "value": "sample string", "description": "A unique, unchangeable identifier for the response." }, "collected_at": { "value": "sample string", "description": "This timestamp marks the moment a survey response was received, formatted in ISO 8601 with microseconds included (e.g., '2023-01-01T00:00:00.000000Z')." }, "url": { "value": "https://survicate.com/", "description": "The URL where the survey was displayed to the respondent." }, "device_type": { "value": "Desktop | Mobile | Tablet | Tv", "description": "The type of device used by the respondent to submit the response." }, "operating_system": { "value": "Android | OS | iOS | Linux | macOS | Windows | Other", "description": "The operating system of the device used by the respondent." }, "platform": { "value": "MacIntel", "description": "The platform identifier of the device used by the respondent (e.g., 'MacIntel', 'Win32')." }, "language": { "value": "en", "description": "If present, the language of the survey translation presented to the respondent." }, "answers": { "value": [ { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "comment": { "value": "sample string", "description": "Optional text input provided by the respondent as an additional comment to the selected response." } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "comment": { "value": "sample string", "description": "Optional text input provided by the respondent as an additional comment to the selected response." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "rating": { "value": 0, "description": "Numerical value representing the respondent's rating." } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "fields": [ { "type": { "value": "sample string", "description": "The type of field in the contact form, as chosen by the user through the Survicate interface." }, "content": { "value": "sample string", "description": "The respondent's input for a specific field." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": "sample string" }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answer": { "content": { "value": "sample string", "description": "Numerical value of the Net Promoter Score (NPS) chosen by the respondent." }, "tag": { "value": "detractor | passive | promoter", "description": "This represents the NPS group associated with the score selected by the respondent. The options include:\n* detractor (score 0-6)\n* passive (score 7-8)\n* promoter (score 9-10)\n" } } }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "score": { "value": "sample string", "description": "Label of the selected option in a matrix choice question." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "answers": [ { "id": { "value": 0, "description": "An abstract entity to build other classes. The answer's unique unchangeable identifier." }, "content": { "value": "sample string", "description": "The respondent's selected answer content." }, "rank": { "value": 0, "description": "The selected position of the respondent's choice in the ranking question." } } ] }, { "question_id": { "value": 0, "description": "The question's unique unchangeable identifier." }, "question_type": { "value": "single | multiple | dropdown_list | rating | ranking | smiley_scale | numerical_scale | csat", "description": "The question's type" }, "action_performed": true } ], "description": "An array of answers provided by the respondent for each specific question in the survey. Questions the respondent skipped are not included." }, "respondent": { "value": { "uuid": { "value": "sample string", "description": "A unique, unchangeable identifier for the respondent." }, "attributes": { "value": [ { "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, always returned as a string." } } ], "description": "The respondent's customer-defined attributes. Which names appear here depends on the endpoint's 'attributes[]' query parameter - see the endpoint descriptions. These are name/value pairs you passed to Survicate yourself; Survicate does not add attributes of its own, so a field such as 'survey_type' only appears here if you set it." } }, "description": "The respondent who submitted the response." }, "attributes": { "value": [ { "name": { "value": "order_id", "description": "The attribute's name, exactly as you passed it to Survicate." }, "value": { "value": "A-1024", "description": "The attribute's value, always returned as a string." } } ], "description": "Customer-defined attributes recorded with this specific response, as name/value pairs - for example campaign identifiers passed with the survey link. What is returned here depends on the endpoint: the response list returns only the names listed in the 'attributes[]' query parameter (empty when omitted), the single-response endpoint always returns all of them - see the endpoint descriptions. Attributes of the person are returned under 'respondent.attributes' instead. Native response fields (for example 'uuid', 'collected_at', 'url', 'device_type', 'operating_system' and 'language') are returned as top-level properties of the response, not as attributes." } } } ], "description": "Responses of the respondent." } } ``` ### Response 404 The requested respondent was not found. --- # Personal Data Source: https://developers.survicate.com/data-export/personal-data/ Personal data management endpoints allow you to retrieve and delete user data across all services for GDPR compliance and data privacy requirements. These endpoints work with email addresses to identify and manage user data. ## Get personal data counters GET /personal-data Retrieves the count of personal data associated with a specific email address across all services. This includes local survey data (respondents, responses) and data from connected services (Insights Hub). This endpoint helps assess the scope of data before deletion for GDPR compliance. ### Required parameters Name: email Type: string Description: The email address to search for across all data sources. The search is case-insensitive and handles whitespace. ### Response 200 Successfully retrieved personal data counters from all sources. #### Response properties Name: responses Type: integer Description: Total number of survey responses associated with this email address. Name: respondents Type: integer Description: Total number of unique respondents records associated with this email address. Name: insights_hub.authors Type: integer Description: Number of author records. Name: insights_hub.author_attributes Type: integer Description: Number of author attribute records. Name: insights_hub.notes Type: integer Description: Number of note records. Name: insights_hub.notes_attributes Type: integer Description: Number of note attribute records. Name: insights_hub.total Type: integer Description: Total number of records in Insights Hub. ```json { "responses": { "value": 15, "description": "Total number of survey responses associated with this email address." }, "respondents": { "value": 3, "description": "Total number of unique respondents records associated with this email address." }, "insights_hub": { "value": { "authors": { "value": 2, "description": "Number of author records." }, "author_attributes": { "value": 3, "description": "Number of author attribute records." }, "notes": { "value": 1, "description": "Number of note records." }, "notes_attributes": { "value": 4, "description": "Number of note attribute records." }, "total": { "value": 10, "description": "Total number of records in Insights Hub." } }, "description": "Data from Insights Hub service. Contains detailed information about records in the Insights Hub system." } } ``` ### Response 400 Invalid email format provided. ### Response 403 Access denied. Check your API credentials and permissions. ### Response 429 Rate limit exceeded. Maximum 100 requests per minute, 5 parallel requests allowed. --- ## Delete personal data by email DELETE /personal-data Permanently deletes all personal data associated with the specified email address across all services. This includes survey responses, respondent records, custom attributes, and data in connected services like Insights Hub. This endpoint is designed for GDPR compliance and data deletion requests. ### Required parameters Name: email Type: string Description: The email address for which to delete all associated data. The search is case-insensitive and handles whitespace. ### Response 200 Successfully processed data deletion request. Returns summary of deleted records from each service. #### Response properties Name: message Type: string Description: Confirmation message about the deletion process completion. Name: result.deleted_respondents Type: integer Description: Number of records deleted from survicate database (responses, respondents, attributes). Name: result.deleted_insights_hub Type: integer Description: Number of records deleted from Insights Hub service. Name: result.total_deleted Type: integer Description: Total number of records deleted across all services. ```json { "message": { "value": "Personal data deletion completed", "description": "Confirmation message about the deletion process completion." }, "result": { "value": { "deleted_respondents": { "value": 150, "description": "Number of records deleted from survicate database (responses, respondents, attributes)." }, "deleted_insights_hub": { "value": 2, "description": "Number of records deleted from Insights Hub service." }, "total_deleted": { "value": 152, "description": "Total number of records deleted across all services." } }, "description": "Detailed results of the deletion operation across all services." } } ``` ### Response 400 Invalid email format provided. ### Response 403 Access denied. Check your API credentials and permissions. ### Response 429 Rate limit exceeded. Maximum 50 requests per minute, 3 parallel requests allowed. ### Response 500 Internal server error during deletion process. Some data may have been partially deleted. --- # Webhooks Source: https://developers.survicate.com/webhooks/ Webhooks are notifications that are triggered automatically when a specific event occurs. Use Survicate Webhooks to send automatically triggered notifications whenever respondents interact with your surveys. When a new submission comes in, a notification that contains respondent's answer is immediately sent to your chosen destination: the endpoint URL you set. - [Security](/webhooks/security) - [Events](/webhooks/events) - [Answer types](/webhooks/answer-types) --- # Security Source: https://developers.survicate.com/webhooks/security/ Survicate signs the webhook events it sends to your endpoints by including a signature in each event’s header. This allows you to verify that the events were sent by Survicate, not by a third party. Before you can verify signatures, you need to retrieve your `Verification Token` and/or `Signing Secret` from your [Webhooks Settings](https://panel.survicate.com/o/0/w/0/settings/integrations/webhooks?tab=settings) section in the Survicate panel. ### Verification token The **verification token** is proof that the request is coming from Survicate on your behalf. You’ll find this value in the [Webhooks Settings](https://panel.survicate.com/o/0/w/0/settings/integrations/webhooks?tab=settings) section of you app. Each webhook includes a **verification token** in `Token` header. Be noted that the token is sent as plain text and **hmac signature** verification, which is described in the [section below](#signing-secret-recommended), is more secure. ### Signing secret (recommended) Survicate creates a unique string for your workspace and shares it with you. You can verify requests from Survicate with confidence by verifying signatures using your signing secret. Before you can verify signatures, you need to retrieve your webhooks **Signing Secret** from [Webhooks Settings](https://panel.survicate.com/o/0/w/0/settings/integrations/webhooks?tab=settings) section in the Survicate panel. Each webhook sent from Survicate on your behalf is signed with Signing Secret. Survicate generates signatures using a hash-based message authentication code ([HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)) with SHA-256. You can verify webhook events signatures by following these steps. 1. Extract signature from the header Each webhook includes a **hmac signature** in `Hmac` header. 2. Determine the expected signature Compute an HMAC with the SHA256 hash function. Use the **signing secret** as the key, and use the request body as the data to hash. Example: ```php hash_hmac(‘sha256’, $body, $signing_secret); ``` Make sure that the hash function in the programming language of your choice will return the hash in lowercase hexits. 3. Compare the signatures Compare the signature extracted from the `Hmac` header to the expected signature. --- # Events Source: https://developers.survicate.com/webhooks/events/ ## Question answered Question answered event is triggered upon each respondent's answer. Each answer to every single question will be sent along with respondent data. ```json title="Sample payload" { "messageId": "c0101a21572ca643fd9f9ad40a5a4650", "deliveryTries": 0, "event": { "questionAnswered": { "responseUuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "survey": { "id": "b92b6ecae6dd7207", "name": "Satisfaction" }, "url": "https://survey.survicate.com/43f2d5789346d6ad", "timestamp": "2019-05-10T06:46:02+00:00", "respondent": { "id": "534759", "uuid": "279cd4ab-8a07-4e9e-ac79-bcea32792bbc", "platform": "OSX", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36", "attributes": [], "links": [] }, "question": { "id": 12123, "body": "How would you rate our customer service?" }, "choice": { "id": 21573, "body": "Great", "comment": null } } } } ``` Object | Attribute | Type | Description | -------------- | -------------- | -------------- | -------------- | messageId | | string | Webhook ID deliveryTries | | number | Number of attempts to send a webhook questionAnswered | responseUuid | string | Unique identifier of the survey response questionAnswered | type | string | Question type - described in detail below the table questionAnswered | timestamp | string | Timestamp of the event occurrence questionAnswered | url | string | URL where the response was given survey | id | string | Survey ID survey | name | string | Survey name respondent | attributes | object | All respondent custom attributes question | body | string | Question content question | id | number | Question ID choice | body | string | Answer content choice | comment | string | Respondent comment To see payloads for all answer types, please refer to the [question types](/webhooks/answer-types) section. --- ## Survey answered Survey answer event sends webhooks upon each survey completion. Please note that this event will be triggered only when the whole survey is completed. ```json title="Sample payload" { "messageId": "c0101a21572ca643fd9f9ad40a5a4650", "deliveryTries": 0, "event": { "surveyCompleted": { "responseUuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "survey": { "id": "b92b6ecae6dd7207", "name": "Satisfaction" }, "url": "https://survey.survicate.com/43f2d5789346d6ad", "timestamp": "2019-05-10T06:46:02+00:00", "respondent": { "id": "534759", "uuid": "279cd4ab-8a07-4e9e-ac79-bcea32792bbc", "platform": "OSX", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36", "attributes": [], "links": [] }, "questionsAnswered": [ { "choice": { "id": 21573, "body": "Great", "comment": null }, "survey": { "id": "b92b6ecae6dd7207", "name": "Satisfaction" }, "url": "https://survey.survicate.com/43f2d5789346d6ad", "timestamp": "2019-05-10T06:46:02+00:00", "respondent": { "id": "534759", "platform": "OSX", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36", "attributes": [] }, "question": { "id": 12123, "body": "How would you rate our customer service?" } }, { "text": "Sample answer to your text question", "survey": { "id": "b92b6ecae6dd7207", "name": "Satisfaction" }, "url": "https://survey.survicate.com/43f2d5789346d6ad", "timestamp": "2019-05-10T06:46:02+00:00", "respondent": { "id": "534759", "platform": "OSX", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36", "attributes": [] }, "question": { "id": 12122, "body": "What was the reason for your score?" } } ] } } } ``` --- # Answer types Source: https://developers.survicate.com/webhooks/answer-types/ Survicate supports numerous question types. ### Choice This is an answer that will be sent to following question types: * Single choice * Net Promoter Score * Rating * Smiley scale * Dropdown ```json title="For single choice, rating, smiley scale, and dropdown" "choice": { "id": 201139, "body": "Companies or organizations (B2B)", "comment": "mostly SMBs" } ``` ```json title="For NPS" "choice": { "id": 9, "body": "promoter", "comment": null } ``` Attributes: * `id` is answer id in Survicate * `body` contains answer presented as a string * `comment` is additional comment provided by respondent Attributes for NPS: * `id` is answer value * `body` contains answer presented as a string ### Fields Fields are answers to contact form added to your survey. ```json "fields": { "firstName":"Alan", "lastName":"Fresco", "email":"alan@example.com", "organization":"Example Corp", "department":"Product", "jobTitle":"Product Manager", "phone":"+48 123456789", "comment":"Comment", "addressOne":"Example Street", "addressTwo":"00000 City", "city":"Nashville", "state":"Tennessee", "annualRevenue":"0", "employees":"50", "industry":"IT" } ``` `fields` attribute contains all answers collected through fields in contact form. ### Choices Choices are answers to multiple answer question - checkboxes. ```json "choices": [ { "id": 1021, "body": "IT/Product", "comment": "most important for our company" }, { "id": 1022, "body": "Customer support", "comment": null }, { "id": 1023, "body": "Marketing", "comment": null } ] ``` Choices are presented as an array of responses. `body` contains answer presented as a string. `comment` is additional comment provided by respondent ### Text Question type: Text question ```json "text": "Awesome platform and great support!" ``` `text` contains answer presented as a string. ### Date Question type: Date ```json "date": "2019-05-22" ``` `date` contains answer presented as a string. ### Matrix Question type: Matrix ```json "matrix": [ { "id": 43393, "body": "Ease of use", "value": "Significant" }, { "id": 43394, "body": "Price", "value": "Neutral" } ] ``` Answers to a matrix question are available in a form of an array of responses. `body` contains the content of each matrix question row, described as `answer choice` in the survey editor. `value` is the answer to the particular matrix question row selected by the respondent. Values possible for a respondent to select are defined as `Columns` in the survey editor. ### Ranking Question type: Ranking ```json "ranking": [ { "id": 3234397, "body": "Ease of use", "rankingPosition": 1 }, { "id": 3234396, "body": "Customer service", "rankingPosition": 2 }, { "id": 3234399, "body": "Price", "rankingPosition": 3 } ] ``` An answer to a ranking question is available as an array. `body` contains the `Answer choice` content. `value` is the position of the particular 'answer choice', set by the respondent, in the ranking of all other answer choices. --- # Installation Source: https://developers.survicate.com/installation/ The Survicacte Tracking Code needs to be installed to show surveys on your website. The installation is only required for website & web app surveys. [Learn more here](https://help.survicate.com/en/articles/3933915-getting-a-survey-appear-on-your-website-installing-and-testing-tracking-code). ### Segment Survicate can be installed with Segment. Follow [these instructions](https://help.survicate.com/en/articles/3942525-segment-integration#installing-survicate-tracking-code-with-segment), to add Survicate as a destination in Segment. ### WordPress Use our WordPress plugin to install Survicate on your WordPress website. Follow [these instructions](https://help.survicate.com/en/articles/3937898-installing-survicate-on-wordpress-sites) and use this workspace key during the installation. ``` {CODE} ``` ### Google Tag Manager To install Survicate using Google Tag Manager, follow [this article](https://help.survicate.com/en/articles/3937897-google-tag-manager). ### Manual installation Place this code right before the `` tag of your website. Once you've added the code to your site, you will need to wait a few minutes for Survicate to check if it is installed correctly. This usually happens the moment your site is loaded with the Survicate code on it. ```html ``` ## Identify your respondents & pass custom data Anytime you want to record custom user data or integrate with external tools call sva.setVisitorTraits function. This will enable you to associate respondent ID in Survicate with user ID they have in your app. Or simply to pass any additional information about your website visitors or app users. Here's a sample implementation: ```html ```