The agentic survey system for Shopify

Search for the articles here or browse the categories below.

Browse by topic

Find guides, tutorials, and answers organised by category.

Popular articles

What other people are reading right now.

πŸ›’ Checkout Surveys

Checkout Extensibility

UserLoop supports Shopify's checkout extensibility, letting you add surveys to the thank you page and order status page through Shopify's drag-and-drop editor. Watch: UserLoop Shopify Checkout Extensibility Adding UserLoop to Your Checkout Pages Step 1. In Shopify Admin, go to Settings > Checkout and find the checkout customization option. Step 2. Select either the Order Status or Thank You page. We recommend adding the survey to both. Click Add App Block. Step 3. Select UserLoop from the list to add the survey block. Step 4. Drag the block to position it on the page. For best visibility, place it at the top of the Order Details section. Step 5. Save your changes. Which Survey Is Displayed? UserLoop displays whichever checkout survey you've marked as active in your UserLoop account. To change which survey appears, go to Surveys, select a different checkout survey, and click Activate Survey. Features Checkout extensibility surveys support: - Multi-language translations - Follow-up questions - Info Screens with headings, multi-line text, optional images, and no response field - Customer targeting (all, new, or returning customers) - Discount code rewards - Auto Proceed mode Need Help? If you have any questions about checkout extensibility, reach out to us via live chat and we'll be happy to help.

πŸ’» Developer Documentation

MCP Server

The UserLoop MCP server connects Claude, ChatGPT, and other compatible AI clients to your UserLoop survey data through the Model Context Protocol. You can explore feedback, compare answer counts, review NPS, find individual responses, and chart response volume by asking questions in natural language. All UserLoop MCP tools are read-only. They can retrieve and analyse survey data, but they cannot create, edit, or delete anything in your UserLoop account. What You Can Ask Try prompts such as: - β€œChart response volume across all surveys for the last 90 days and break it down by survey.” - β€œHow did customers answer β€˜How did you hear about us?’ this month?” - β€œShow the NPS score and promoter, passive, and detractor breakdown for our quarterly survey.” - β€œSummarise the main themes in open-text responses from the post-purchase survey.” - β€œCompare answer counts, revenue, and average order value for this question.” Your AI client chooses the appropriate UserLoop tools automatically. Interactive Charts Clients that support MCP Apps can display UserLoop results as interactive charts directly in the conversation. Clients without MCP Apps support still receive the same data as compact JSON. Response Volume Over Time View response volume for one survey, one question, or every survey combined. Switch between 7 days, 30 days, 90 days, 12 months, or all time, and use automatic, daily, weekly, or monthly grouping. Company-wide results also include a per-survey breakdown and a data-table view. UserLoop MCP response-volume chart showing weekly responses across all surveys Answer Counts Multiple-choice results are shown as a horizontal bar chart with response counts and share. Hover over a result to see more detail, including revenue and average order value when available. UserLoop MCP answer-count chart for a multiple-choice survey question NPS Number Score and NPS questions include the headline NPS score, average score, promoter/passive/detractor split, 0–10 score distribution, and revenue metrics when available. UserLoop MCP NPS chart showing score and promoter, passive, and detractor segments The screenshots above use example data. When connected, the charts use your UserLoop survey data. Available Tools The server currently provides eight tools: | Tool | What it does | |---|---| | userloop_health | Checks the connection and confirms your API key is valid | | userloop_list_surveys | Lists all surveys, including their questions and question types | | userloop_get_survey | Retrieves one survey and its questions | | userloop_analytics_counts | Returns answer counts for a question, including NPS and revenue metrics when available | | userloop_responses_timeseries | Charts response volume by day, week, or month for one survey, one question, or all surveys | | userloop_responses_open | Retrieves paginated open-text responses for a question | | userloop_responses_raw | Retrieves paginated raw responses for a survey | | userloop_get_response | Retrieves one response by its ID | Before You Connect Create a UserLoop API key in your UserLoop account. API keys start with ul_live and are shown only once, so create a new one if you no longer have the full key. See UserLoop API for more information. Your MCP server URL is: https://mcp.userloop.io/mcp?api_key=ul_live_... Replace ul_live_... with your complete API key. Keep this URL private. It contains your UserLoop API key. Do not share it, publish it, or include it in screenshots. Rotate the key immediately if it is exposed. Connect to Claude or Claude Desktop Remote MCP connectors are available on supported Claude plans. 1. Open Settings > Connectors in Claude or Claude Desktop. 2. Select Add custom connector. 3. Name the connector UserLoop. 4. Paste the complete MCP server URL, including ?api_key=.... 5. Select Add. 6. In a conversation, open Search and tools and enable the UserLoop connector. Remote servers in Claude Desktop are configured through Settings > Connectors, not claude_desktop_config.json. See Anthropic’s custom connector guide for current plan and workspace requirements. Connect to ChatGPT Custom MCP apps are available to supported ChatGPT workspace plans and may need to be enabled by a workspace administrator. 1. Enable developer mode if your workspace requires it. 2. Open Settings > Apps > Create, or ask a workspace administrator to open Workspace settings > Apps > Create. 3. Enter the complete MCP server URL, including ?api_key=.... 4. Choose No authentication if prompted. The UserLoop API key is already included in the URL you entered. 5. Scan the available tools and create the app. 6. Enable UserLoop from the app menu in a conversation. See OpenAI’s developer mode and MCP apps guide for current availability and administrator controls. Connect from Another MCP Client Use the complete URL above with a client that supports remote MCP servers over Streamable HTTP. A typical configuration looks like this: { "mcpServers": { "userloop": { "type": "http", "url": "https://mcp.userloop.io/mcp?api_key=ul_live_..." } } } The exact configuration format depends on your MCP client. Privacy and Email Redaction Email redaction is enabled by default for open-text, raw-response, and individual-response tools. For example, [email protected] is returned in a masked form. This helps protect customer privacy when data is sent to a third-party AI service. The response tools support redact_emails: false, but only disable redaction when you have a clear reason and are comfortable sharing those addresses with your AI provider. Response-Volume Notes - Response-volume charts can combine all surveys in a single request and include totals for each survey. - A response-volume row represents an answer given to a question, rather than a completed survey submission. Use a question filter when you want to count answers to one specific question. - The server reads up to 2,000 response rows for a time-series request. If a result is marked as truncated, narrow the date range or select a specific survey. Troubleshooting The connection or health check fails - Confirm that the URL includes the complete ?api_key=ul_live_... query parameter. - The MCP server no longer accepts the old X-UserLoop-Key header method. - Create a new UserLoop API key if the original key has been revoked, lost, or exposed. The new time-series tool is missing Refresh or rescan the connector’s tools. In ChatGPT, newly added tools may need to be enabled by a workspace administrator. If refreshing does not work, remove and re-add the connector using the current URL. Charts are not displayed Your client may not support MCP Apps, or it may need to refresh the UserLoop connector. The tool still returns the underlying data, which the AI assistant can analyse and present as text or a table. Need Help? If you have questions about the UserLoop MCP server, contact us through live chat and we’ll be happy to help.

🧩 App Block & Popup Surveys

App Block Surveys

App Block Surveys let you place a survey directly into any page of your Shopify store as an inline section β€” not a popup or overlay. The survey sits naturally within your page content, matching your theme's look and feel, and is visible to every visitor who scrolls to that section. An app block survey embedded on a product page Because app blocks are placed directly into your page layout, they're incredibly versatile. Here are just a few ideas: - Product pages β€” ask visitors about their product preferences, what features matter most, or what they're looking for. Place it below the product description or after the reviews section. - Home page β€” collect "How did you hear about us?" attribution data, or gather email addresses with a discount incentive. - Collection pages β€” understand what shoppers are browsing for, or ask about their style preferences to help guide them. - Blog posts β€” ask readers if the content was helpful, or what topics they'd like to see covered next. - Landing pages β€” capture leads or gather feedback on a specific campaign or new product launch. - Contact / About pages β€” ask visitors what brought them to your store, or what they're looking for help with. The possibilities are endless β€” anywhere you can add a Shopify app block, you can add a UserLoop survey. How App Block Surveys Work Unlike popup surveys, app blocks don't wait for a trigger. They render immediately as part of the page content wherever you place them. Visitors see the survey as a natural section of the page and can answer questions without any interruption to their browsing. App block surveys display every time the page loads β€” they don't disappear after a visitor completes them. This means you can collect ongoing feedback from repeat visitors over time. Setting Up Your App Block Survey Step 1. Create an App Block Survey In your UserLoop dashboard, click Create Survey and select the App Block option. Create a new app block survey in the UserLoop dashboard Add your questions, configure your design and settings, then move on to activation. Step 2. Activate Your Survey Once your survey is ready, click the Activate Survey button in the top-right corner. If this is your first app block survey, it will automatically be set as your live one. If you have multiple app block surveys, use the Activate button to choose which one is currently live. Click Activate Survey to make your app block live Step 3. Add to Shopify Once your survey is active, you'll see a green Add App Block to Shopify button appear. Click this to go directly to your Shopify theme editor. Click the green Add App Block to Shopify button Step 4. Position and Style in the Theme Editor You'll be taken to the Shopify theme editor where the UserLoop Survey block has been added. From here you can: - Drag the block to position it exactly where you want it on the page β€” for example, below the product description, after a hero banner, or at the bottom of a blog post. - Configure styling β€” adjust the width, background style, text alignment, border radius, and padding to match your theme. App block survey settings in the Shopify theme editor Click Save to publish your changes β€” your app block survey is now live on your store. Adding to Multiple Pages You can add the UserLoop Survey app block to as many pages as you like. Simply go to each page in the theme editor and add the block. This is one of the key advantages of app blocks β€” you have full control over exactly where surveys appear. Styling Your App Block Survey App block surveys are designed to blend into your store's design. You have several customization options available directly in the theme editor: Max Width Set the maximum width of the survey container, from 300 to 800 pixels (default is 600px). The survey is centered on the page within this width. On mobile devices, it automatically scales to fit the screen. Background Style Choose how the survey container looks: - None β€” fully transparent, the survey blends directly into the page background. - Card (default) β€” a white background with a subtle shadow, giving the survey a clean, elevated appearance. - Bordered β€” a light border around the survey with no shadow, for a more understated look. Text Alignment Control how questions and answer choices are aligned: - Left (default) β€” questions and choices align to the left, which feels natural for longer text. - Center β€” everything is centered, which works well for short questions and fewer answer options. Border Radius Set the corner rounding from 0 to 24 pixels (default is 12px). Use 0 for sharp corners or a higher value for a softer, more rounded look. This applies to the survey container and buttons. Padding Set the internal spacing from 12 to 48 pixels (default is 24px). This controls the space between the survey content and the edges of the container. Theme Font Inheritance App block surveys automatically inherit your theme's fonts, so the survey text matches the rest of your store without any extra configuration. Selecting Which Survey to Display The app block displays whichever survey you have set as active in your UserLoop dashboard. The active survey is the one shown on your store across all pages where you've added the app block. To change which survey is displayed, go to the survey you want to use in your UserLoop dashboard and click the Activate Survey button. This makes it the live survey β€” only one app block survey can be active at a time. Supported Question Types App block surveys support all of UserLoop's question types: - Single select β€” radio button choices - Multi select β€” checkbox choices - NPS / number scale β€” 0-10 rating buttons - Open-ended text β€” free text input - Email β€” email address collection - Date β€” date picker You can also enable the "Other" option on choice questions to let visitors type in their own answer. Smart Question Targeting App block surveys support the same question targeting as other UserLoop survey types: - All customers β€” shown to everyone. - New customers only β€” shown only to visitors who have never placed an order. - Returning customers only β€” shown only to visitors who have ordered before. How Customer Type Is Determined If your survey includes an email question, something special happens: after the visitor enters their email, UserLoop checks their order history in real time. This means subsequent questions in the survey can be dynamically shown or hidden based on whether that visitor is a new or returning customer. If no email question is included, customer-type-restricted questions are skipped for anonymous visitors. Follow-Up Questions Follow-up questions work the same way as in other survey types. If a visitor selects an answer that has a follow-up configured, the follow-up question appears inline immediately, keeping the flow smooth and natural. Discount Codes If you've enabled discount codes on your survey, a unique code is displayed to the visitor after they complete all the questions. The code is tied to the visitor's email address (if collected) and can be copied to the clipboard with a single click. This is a great way to incentivize survey completion β€” offer a small discount in exchange for feedback. Progress Bar When enabled in your survey settings, a progress bar appears at the top of the survey showing visitors how far through they are. This is especially helpful for longer surveys to set expectations and encourage completion. Auto Proceed If Auto Proceed is enabled on your survey, the survey automatically advances to the next question when a visitor selects a single-choice answer. This creates a faster, more engaging experience that feels less like filling out a form. Mobile Experience App block surveys are fully responsive. On mobile devices: - The survey scales to fit the screen width. - Buttons and inputs are sized for easy tapping. - The layout adjusts to ensure readability on smaller screens. Since app blocks are inline content (not overlays), they feel completely natural on mobile β€” just another section of the page. Best Practices Where to Place App Blocks The best placement depends on what you're trying to learn: - Home page β€” place below the fold for general brand feedback or email collection. Great for "How did you hear about us?" type questions. - Product pages β€” place below the product description or reviews section to ask about purchase intent or product preferences. - Blog posts β€” place at the end of articles to ask if the content was helpful. - Landing pages β€” place prominently to capture leads or gather feedback about a specific campaign. - About page β€” place at the bottom to ask visitors what brought them to your store. Design Tips - Use the Card background for most themes β€” it gives the survey a clean, defined boundary that draws attention without clashing. - Match your border radius to your theme's style. If your theme uses rounded corners on buttons and cards, use a similar radius for the survey. - Keep the width between 500-700px for the best readability on desktop. Too narrow and it feels cramped; too wide and it can look sparse. - Center alignment works best for short surveys (1-2 questions). For longer surveys, left alignment is easier to read. Content Tips - Keep it relevant to the page: Ask about products on product pages, ask about content on blog pages. - Shorter is better: 2-4 questions gets the best completion rates. - Lead with value: If you're offering a discount, mention it in the first question or in a heading above the survey. App Block Surveys vs. Popup Surveys Not sure which to use? Here's a quick comparison: | | App Block | Popup | |---|---|---| | Display | Inline on the page | Modal overlay | | Placement | You choose exactly where | Appears on all enabled pages | | Trigger | Immediate β€” visible on page load | Timer, exit intent, or scroll | | Repeat visits | Shows every time | Shows once per visitor | | Intrusiveness | Low β€” part of the page | Higher β€” interrupts browsing | | Best for | Ongoing feedback, email capture, page-specific questions | Quick feedback, exit surveys, site-wide questions | You can use both at the same time. For example, run a popup survey site-wide for "How did you hear about us?" while placing app block surveys on specific product pages to ask about purchase intent. FAQs Can I place multiple app block surveys on the same page? You can add the block multiple times, but they will all display the same active survey since only one survey can be active for the app block surface at a time. Will the survey show again if a visitor already completed it? Yes. Unlike popup surveys, app block surveys display every time the page loads. This is by design β€” it allows you to collect ongoing feedback from repeat visitors. Does it work with Shopify's section groups and templates? Yes. The UserLoop Survey app block works anywhere Shopify allows app blocks β€” in sections, templates, and section groups. Can I hide the survey on mobile? The app block doesn't have a built-in mobile hide option, but you can use your theme's built-in CSS visibility controls or section settings if your theme supports them. Does it slow down my page? No. App block surveys use deferred loading, which means they initialize after the rest of your page has loaded. This ensures zero impact on your store's page speed. Need Help? If you have any questions about setting up app block surveys or need assistance choosing the right placement for your store, don't hesitate to reach out to our support team.

❓ Survey Questions

Question Types

UserLoop offers a flexible range of question types to help you collect different kinds of feedback. Each type is designed for a specific purpose, from simple multiple choice to video responses and data collection. Adding Questions to a Survey 1. Go to Surveys and select your survey (or create a new one). 2. Click the Questions tab, then click Add Question. 3. Choose your question type from the list. Add a question type 4. Type your question and click Suggest Answers to get AI-generated answer options (for Single Select and Multi Select questions). 5. Drag and drop questions to reorder them. Single Select Single Select questions let customers choose exactly one answer from a list of options. This is the most common question type. Single Select question When to use it: - Attribution β€” "How did you hear about us?" - Demographics β€” "What is your age range?" - Preferences β€” "Which product category are you most interested in?" - Satisfaction β€” "How would you describe your experience?" Click Suggest Answers to get AI-generated options tailored to your question, or add answers manually. You can drag and drop answers to reorder them. Single Select questions support the Other toggle (adds a free-text option at the end of the list) and Randomize Order (shuffles answer positions each time the survey is shown). You can also add follow-up questions to individual answers. Multi Select Multi Select questions let customers choose one or more answers from a list of options. Use this when multiple answers could apply. Multi Select question When to use it: - Product interests β€” "Which of these products are you interested in?" - Feature feedback β€” "Which features do you use the most?" - Pain points β€” "What challenges are you facing?" - Shopping habits β€” "Where else do you shop for similar products?" Click Suggest Answers to get AI-generated options, or add answers manually. Multi Select also supports the Other toggle, Randomize Order, and follow-up questions. Open Ended Open Ended questions give customers a free-text field to write their response in their own words. This is the best way to collect detailed, qualitative feedback. Open Ended question When to use it: - General feedback β€” "Is there anything else you'd like to share with us?" - Product suggestions β€” "What features would you like to see?" - Experience details β€” "What almost stopped you from buying today?" Keep the question focused so customers know what kind of response you're looking for. Open Ended responses are analyzed in the Analytics section, where UserLoop uses AI to identify common themes across responses. Open Ended settings 1. Sub Heading β€” Add extra text below the question heading to provide instructions or context. 2. Placeholder Text β€” Sets the hint text shown inside the text field before the customer starts typing. Use this to guide customers on what kind of response you're looking for. Number Score Number Score questions let customers select a number on a scale. This is useful for any kind of rating or satisfaction question. Number Score question When to use it: - Overall experience β€” "How would you rate your overall experience?" - Product satisfaction β€” "How would you rate this product?" - Effort score β€” "How easy was it to complete your purchase?" - Any custom rating β€” Use the label fields to define what the low and high ends mean. Number Score settings 1. Scale β€” Choose the range and direction of the number scale: 1–10 (default), 10–1 (reversed), 1–5 (shorter scale), or 5–1 (shorter, reversed). 2. Left Label β€” The label shown at the low end of the scale (e.g. "Least", "Poor", "Very Difficult"). 3. Right Label β€” The label shown at the high end of the scale (e.g. "Most", "Excellent", "Very Easy"). NPS NPS (Net Promoter Score) is a widely used metric for measuring customer loyalty. It asks customers how likely they are to recommend your brand on a scale of 1 to 10. NPS question When to use it: - Post-purchase β€” "How likely are you to recommend us to a friend or family member?" - Ongoing tracking β€” Add an NPS question to your checkout survey to track loyalty over time. Responses are automatically grouped into three categories: - Detractors (1–6) β€” Unhappy customers who are unlikely to recommend you. - Passives (7–8) β€” Satisfied but unenthusiastic customers. - Promoters (9–10) β€” Loyal customers who will actively recommend you. Your NPS score is calculated as: % Promoters - % Detractors, ranging from -100 to 100. Go to Analytics to see your score and trend over time. NPS uses a fixed 1–10 scale with customizable Left Label and Right Label (pre-filled with "Not Likely" and "Very Likely"). Unlike Number Score, the scale cannot be changed. Date Date questions let customers select a specific date using dropdown selectors for day, month, and year. Date question When to use it: - Birthdays β€” "When is your birthday?" Use this to send personalized birthday offers or discounts. - Anniversaries β€” "When did you first start using our products?" - Event dates β€” "When is the event you're shopping for?" Video Video questions let customers record a short video response using their device's camera and microphone, or upload an existing video file. Video question When to use it: - Testimonials β€” "Record a short video telling us about your experience." - Product feedback β€” "Show us how you use our product." - Unboxing reactions β€” "Record your first impressions when opening your order." Customers can record up to 2 minutes of video, review and re-record before submitting, or upload a file instead. Video questions are available in Link and Popup surveys. They are not currently supported in Checkout surveys. CSAT CSAT (Customer Satisfaction) questions measure how satisfied a customer is with a specific experience. Customers choose from a set of satisfaction levels like "Very Satisfied", "Satisfied", "Neutral", etc. CSAT question When to use it: - Post-purchase β€” "How satisfied are you with your purchase?" - Support interactions β€” "How would you rate your experience with our support team?" - Delivery experience β€” "How satisfied were you with the delivery?" CSAT works like a Single Select question with satisfaction-focused answer options. Unlike NPS (which measures loyalty on a 1-10 scale), CSAT measures satisfaction with a specific touchpoint. It supports the Other toggle, Randomize Order, and follow-up questions. Email Email questions let you collect a customer's email address as part of your survey. This is especially useful for App Block and Popup surveys where visitors may not be logged in. Email question When to use it: - Lead capture β€” Collect emails from anonymous visitors. - Identify visitors β€” Link anonymous survey responses to a customer record. - Enable targeting β€” Once an email is collected, subsequent questions can target new or returning customers based on order history. When an email is collected, all previous responses from that survey session are linked to the email address. Info Screen Info Screens display content without asking the customer for an answer. They are useful for introducing a survey, separating it into sections, setting expectations, or explaining a reward before the next question. An Info Screen with a heading, image, explanatory copy, and Continue button An Info Screen can contain a heading, multi-line supporting text, and an optional image. Customers select Continue to move to the next step. - It collects no answer and creates no row in response exports. - It advances the progress bar, but is not numbered as a question. - Required and skip settings do not apply. - It cannot be used as a conditional follow-up question. - Product, new-customer, and returning-customer targeting can still be applied. Info Screens are supported in JavaScript SDK, Shopify Checkout, Popup Survey, and App Block survey experiences. Question Settings Every question type has the following settings, available in the settings panel on the right side when you click a question. Question settings panel 1. Other β€” Available on Single Select and Multi Select questions only. When enabled, an "Other" option is added to the end of the answer list. If a customer selects it, a text field appears where they can type their own answer. 2. Required β€” When enabled, customers must answer the question before they can move to the next one. The submit button stays disabled until they select or type an answer. 3. Allow Skip β€” Shows a Skip button below the submit button, letting customers skip the question without answering. Skipped questions don't record a response. If both Required and Allow Skip are enabled, customers can still skip using the skip button β€” but they can't proceed without answering unless they explicitly choose to skip. 4. Randomize Order β€” Shuffles the order of answer choices each time the survey is shown. This helps reduce bias from answer position. If you have an Other option, it always stays at the end of the list regardless of randomization. This setting applies to Single Select and Multi Select questions. 5. Sub Heading β€” Add extra text below the main question heading. This is useful for providing instructions or additional context without cluttering the main question. Need Help? If you have any questions about question types, reach out to us via live chat and we'll be happy to help.

πŸ’» Developer Documentation

UserLoop API

Getting Started - Base URL: https://api.userloop.io - Generate API keys inside the UserLoop dashboard. Keys are tied to a company, scoped by feature, and shown only once at creation time. - Keep keys private. Rotate immediately if you suspect compromise. Authenticate Every Request Send the full key string exactly as issued using the X-API-Key header: curl https://api.userloop.io/health \ -H "X-API-Key: " The API validates scopes, survey allowlists, and optional origin restrictions before serving any protected data. Date & Pagination Helpers - start_date and end_date must use YYYY-MM-DD format. When omitted, endpoints default to the broadest safe range (from 1970-01-01 through the current day) so analytics always receive explicit boundaries. - limit and offset control pagination. limit defaults to 50 (maximum 200). offset defaults to 0. Endpoint Reference 1. Health Check β€” GET /health Verifies the service is reachable. No authentication required. { "status": "ok" } 2. Survey Catalog β€” GET /surveys Lists surveys accessible to the calling API key. Query parameters: | Name | Type | Description | | ---- | ---- | ---- | | company_id | string (optional) | Validate the company owning the key. If provided it must match the key’s company; otherwise it defaults automatically. | Example request: curl "https://api.userloop.io/surveys" \ -H "X-API-Key: " Example response (trimmed for brevity): { "company_id": "1621...", "count": 2, "surveys": [ { "id": "1624...", "title": "Post Purchase Email Survey", "format": "Email", "status": "active", "question_count": 6, "created_at": "2021-05-19T10:52:50.657Z", "updated_at": "2025-10-10T12:10:34.630Z", "toggles": { "progress_bar": true, "discount_enabled": true }, "schedule": { "post_purchase": "in 2 days" }, "discount": { "header": "Your 10% Coupon Awaits", "shopify_price_rules": [ { "api_c2_id": "1032299675825" } ] } } ] } Response fields | Field | Type | Description | | ---- | ---- | ---- | | company_id | string | Company ID | | count | integer | Number of surveys returned. | | surveys | array | Collection of survey summaries ordered by last update. | | surveys[].id | string | Unique survey identifier. | | surveys[].title | string | Human readable survey name. | | surveys[].format | string | Channel (Email, Checkout, Link, etc.). | | surveys[].status | string | active or archived. | | surveys[].question_count | integer | Number of questions associated with the survey. | | surveys[].question_ids | array | List of question IDs. | | surveys[].created_at / updated_at | ISO 8601 string | Creation and last modification timestamps. | | surveys[].toggles, schedule, triggers, discount, colors, recipients, flags, incentives, sharing, integrations | object | Grouped metadata copied from the survey configuration. Keys are normalized to snake_case. | 3. Survey Metadata β€” GET /surveys/{survey_id} Retrieves the full configuration (questions, answer choices, metadata) for a single survey. curl "https://api.userloop.io/surveys/1710884429805x361876466030084100" \ -H "X-API-Key: " { "survey_id": "1710884429805x361876466030084100", "survey": "Post Purchase Email Survey", "company_id": "1621...", "questions": [ { "question": "How satisfied were you with your recent order?", "question_id": "1710884436289x589566297607766000", "type": "CSAT", "answers": [ { "answer": "1", "answer_id": "1658..." }, { "answer": "2", "answer_id": "1659..." } ] } ] } Response fields | Field | Type | Description | | ---- | ---- | ---- | | survey_id | string | Survey identifier. | | survey | string | Survey title. | | company_id | string | Owning company. | | questions | array | Ordered list of questions in the survey. | | questions[].question_id | string | Question identifier used in analytics queries. | | questions[].question | string | Question text. | | questions[].type | string | Question type (CSAT, NPS, etc.). | | questions[].answers | array | Answer options (when applicable). | | answers[].answer_id | string | Answer identifier used in analytics filters. | | answers[].answer | string | Display text for the answer choice. | 4. Aggregated Analytics β€” GET /responses?view=counts Calculates response counts, percentages, and revenue metrics per answer option. Required query parameters: | Name | Type | Description | | ---- | ---- | ---- | | survey_id | string | Survey to analyze. Must be enabled for the calling key. | | question_id | string | Question to aggregate. | Optional query parameters: | Name | Type | Description | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | answer_ids | comma-separated strings | Restrict analytics to specific answer IDs. Defaults to all answers in the question. | | start_date, end_date | YYYY-MM-DD | Restrict analytics to a date window. Defaults to full history. | Example request: curl "https://api.userloop.io/responses?view=counts&survey_id=1710884429805x361876466030084100&question_id=1710884436289x589566297607766000&start_date=2025-09-01&end_date=2025-09-30" \ -H "X-API-Key: " Example response (abridged): { "data": [ { "answer_id": "1658...", "answer_text": "1", "count": 75, "percentage": 50, "revenue": 15000, "aov": 200, "currency": "USD" } ], "meta": { "survey_id": "1710884429805x361876466030084100", "survey": "Post Purchase Email Survey", "question": { "id": "1710884436289x589566297607766000", "text": "How satisfied were you with your recent order?", "type": "CSAT" }, "totals": { "responses": 150, "unique_customers": 120, "sum_responses": 150 }, "filters": { "answer_ids": ["1658...", "1659..."], "start_date": "2025-09-01", "end_date": "2025-09-30" } } } Response fields | Field | Type | Description | | ---- | ---- | ---- | | data | array | Aggregated metrics per answer option (sorted by count desc). | | data[].answer_id | string | Answer identifier. | | data[].answer_text | string | Answer label (resolved from survey config when available). | | data[].count | integer | Number of responses recorded for the answer. | | data[].percentage | number | Share of total responses for the answer (0–100). | | data[].revenue | integer | Sum of order_total values associated with the answer (rounded). | | data[].aov | integer | Average order value for the answer (rounded). | | data[].currency | string | Currency code used for revenue metrics. | | meta | object | Contextual metadata for the aggregation. | | meta.survey_id | string | Survey identifier. | | meta.survey | string | Survey title (if available). | | meta.question | object | Question metadata (id, text, type). | | meta.totals.responses | integer | Count of responses returned by analytics (count_survey_responses). | | meta.totals.unique_customers | integer | Unique respondent count. | | meta.totals.sum_responses | integer | Sum of data[].count; falls back to total responses when rows are empty. | | meta.filters | object | Effective filters applied to the analytics call. | | meta.filters.answer_ids | array | Answer IDs used for aggregation. | | meta.filters.start_date / end_date | string | ISO dates bounding the analytics query. | 5. Open-Ended Feedback β€” GET /responses?view=open Fetches paginated free-text responses with associated metadata. Required query parameters: survey_id, question_id Optional query parameters: start_date, end_date, limit, offset Example request: curl "https://api.userloop.io/responses?view=open&survey_id=1710884429805x361876466030084100&question_id=1658178244899x246576140312903680&limit=50" \ -H "X-API-Key: " Example response (first record shown): { "data": [ { "id": "abc123", "unique_id": "abc123", "recipient": "[email protected]", "survey": "1710884429805x361876466030084100", "creation_date": "2025-09-10T12:00:00Z", "open_ended_response": "Great product!", "line_items": ["Product A"], "line_items_count": 1, "order_total": 199.99, "currency": "USD" } ], "pagination": { "total_count": 150, "page_size": 50, "current_page": 1, "total_pages": 3, "has_next_page": true, "has_previous_page": false }, "filters": { "survey_id": "1710884429805x361876466030084100", "question_id": "1658178244899x246576140312903680", "start_date": "1970-01-01", "end_date": "2025-09-30" } } Response fields | Field | Type | Description | | ---- | ---- | ---- | | data | array | Open-text responses ordered by creation_date desc. | | data[].id / unique_id | string | Stable response identifier. | | data[].recipient | string | Email (when captured). | | data[].survey | string | Survey identifier. | | data[].creation_date | string | ISO timestamp of the response. | | data[].open_ended_response | string | Free-text answer content. | | data[].line_items | array | Associated products/items (if present). | | data[].line_items_count | integer | Number of items in line_items. | | data[].order_total | number | Monetary value associated with the response. | | data[].currency | string | Currency code. | | pagination | object | Pagination metadata supplied by the endpoint. | | pagination.total_count | integer | Total open-text responses matching the filters. | | pagination.page_size | integer | Page size applied to the request. | | pagination.current_page | integer | 1-indexed page number based on offset. | | pagination.total_pages | integer | Total calculated pages. | | pagination.has_next_page / has_previous_page | boolean | Convenience flags for pagination UI. | | filters | object | Effective filters included in the request. | | filters.survey_id | string | Survey identifier. | | filters.question_id | string | Question identifier. | | filters.start_date / end_date | string | Date range applied to the query. | 6. Raw Responses β€” GET /responses Provides tabular response data similar to the CSV export. Supports standard pagination and filtering. Sample request: curl "https://api.userloop.io/responses?survey_id=1710884429805x361876466030084100&start_date=2025-09-01&limit=25" \ -H "X-API-Key: " { "responses": [ { "id": "abc123", "unique_id": "abc123", "survey": "1710884429805x361876466030084100", "question_id": "1658...", "question_text": "How satisfied were you with your recent order?", "creation_date": "2025-09-10T12:00:00Z", "answer_id": "1658...", "answer_text": "5", "order_total": 99.99, "currency": "USD" } ], "pagination": { "total_count": 1500, "limit": 25, "offset": 0, "has_next_page": true } } Response fields | Field | Type | Description | | ---- | ---- | ---- | | responses | array | Tabular response data matching the export schema. | | responses[].id / unique_id | string | Response identifier. | | responses[].survey | string | Survey identifier. | | responses[].question_id | string | Question identifier. | | responses[].question_text | string | Question text captured at response time. | | responses[].creation_date | string | ISO timestamp of the response. | | responses[].answer_id | string | Answer identifier (if structured). | | responses[].answer_text | string | Selected answer text (or numeric/NPS value). | | responses[].open_ended_response | string | Free-text answer (when relevant). | | responses[].order_total | number | Order total associated with the response. | | responses[].currency | string | Currency code. | | responses[].utm_*, environment, surface, landing_site, etc. | string | Additional marketing and contextual metadata captured by UserLoop. | | pagination | object | Pagination metadata mirroring the request. | | pagination.total_count | integer | Total number of responses matching filters (may be null when exact count unavailable). | | pagination.limit | integer | Page size used for the query. | | pagination.offset | integer | Offset applied to the query. | | pagination.has_next_page | boolean | Indicates whether more pages are available. | 7. Single Response β€” GET /responses/{response_id} Retrieves one record by its unique ID. Useful when cross-referencing from webhooks or CRM. curl "https://api.userloop.io/responses/abc123" \ -H "X-API-Key: " { "response": { "id": "abc123", "unique_id": "abc123", "survey": "1710884429805x361876466030084100", "question_id": "1658...", "answer_text": "5" } } Response fields | Field | Type | Description | | ---- | ---- | ---- | | response | object | Response record matching the structure in the raw responses endpoint. | | response.id / unique_id | string | Response identifier. | | response.survey | string | Survey identifier. | | response.question_id | string | Question identifier. | | response.answer_text | string | Selected answer. Additional fields (e.g., order_total, utm_*) may be present depending on the record. | Error Handling Errors are returned with a consistent envelope: { "error": "Forbidden", "code": "FORBIDDEN", "detail": "Survey not allowed for this key" } Common error codes: - UNAUTHORIZED – Invalid, revoked, or expired key. - FORBIDDEN – Missing scope, survey not in allowlist, or origin not permitted. - BAD_REQUEST – Invalid parameters (missing IDs, malformed dates, etc.). - NOT_FOUND – Record does not exist or is not accessible to the caller. - INTERNAL – Upstream failure (e.g., Supabase error). Retry or contact support. All errors are safe to expose to clients; sensitive details (such as decrypted tokens) never appear in responses. Best Practices 1. Cache survey metadata when possible; the schema only changes when you update surveys in UserLoop. 2. Respect pagination limits. Use limit/offset for large exports. 3. Filter by date to speed up analytics calls, especially when embedding reporting dashboards. 4. Secure your keys. Store them in encrypted configuration stores and rotate periodically. 5. Monitor rate limits. Contact UserLoop if you expect sustained high throughput so we can tune allocations. Support If you encounter issues: 1. Confirm your key has the correct scopes and survey access inside the dashboard. 2. Double-check parameter spelling and formats (particularly survey_id, question_id, and date strings). 3. Review HTTP status codes and error payloads for hints. 4. Reach out to your UserLoop contact or support team with the request timestamp, key_id, and the full response body for faster troubleshooting. Happy building!

βœ‰οΈ Email Surveys

Survey 'From' Email Address

By default, your email surveys are sent from your store name at @shop-survey.com. This is how it appears to your customers in their inbox β€” your store name shows as the "From" name. Custom Email Addresses You can send survey emails from your own domain name by setting up a custom domain. This gives your emails a more professional, branded appearance. To set up a custom domain for your survey emails, go to your survey's Settings tab and look for the Custom Domain section. For full setup instructions, see our Custom Domains article. Need Help? If you have any questions about configuring your survey email address, reach out to us via live chat and we'll be happy to help.