Gentic Surveys — Documentation
Connect any AI agent to your Fairing post-purchase surveys. Sync your zero-party survey data — every "how did you hear about us?" answer joined to the order it came from — into your organization's Brain, then ask in natural language: 'which channel actually drives revenue?', 'what do customers say vs what Meta claims?', 'which survey answers correlate with the highest AOV?'. Bounded, resumable syncs keep it current without re-reading everything.
1. Getting Started
Sign Up & Get Your API Key
Before you can use Gentic Surveys, you need an API key to authenticate your requests.
- Go to gentic.co/surveys and create an account.
- Create an organization from your dashboard. API keys and billing are scoped to the organization.
- Generate an API key and use it as a Bearer token in your MCP client.
2. Connecting to the MCP Server
The server is available at https://mcp.gentic.co/surveys. For Claude Code:
claude mcp add gentic-surveys \
--transport http \
https://mcp.gentic.co/surveys \
--header "Authorization: Bearer YOUR_API_KEY"For Claude Web and ChatGPT you can also connect via OAuth — no API key needed. See the connect section on the landing page for other MCP clients (n8n, OpenClaw).
3. Agent Skill
For the best results, pair the MCP server with the Gentic Surveys agent skill. The MCP server gives your agent tool access; the skill teaches it the optimal workflow order. Both the raw SKILL.md and a ready-to-upload .skill bundle are generated on demand from the live manifest, so they always reflect the current tools and pricing.
Add the skill directly via URL:
https://gentic.co/surveys/SKILL.mdOr upload a .skill bundle to Claude Managed Agents:
https://gentic.co/surveys/gentic-surveys.skillDownload this file and upload it wherever Claude Managed Agents asks for a .skill file. It's a zip bundle generated on demand from the latest SKILL.md.
4. When to Apply
- User wants to know how customers say they heard about the brand ("how did you hear about us?").
- User wants to reconcile self-reported attribution against measured attribution (Meta/Google/UTM) — said vs measured.
- User wants to find which channels drive the most revenue or highest AOV by survey answer.
- User wants to sync their Fairing post-purchase survey data into their Brain for analysis.
- User wants to count or aggregate survey responses by question, answer, channel, or time.
- User wants to feed survey attribution into a digest, marketing-mix review, or spend-allocation decision.
5. Workflow
1. Connect Fairing once, then sync without credentials
The Surveys server sources the Fairing connection (the Secret Token) from the org's connected integration (Gentic dashboard → Integrations → Fairing). You never pass credentials to the tools — connect once in the dashboard and the server reads the encrypted connection automatically. Call `fairing_connection_status` first (it's free) to confirm the org is connected; if it returns `{ connected: false }`, point the user to Integrations → Fairing. It never returns the API key.
2. Sync survey data into the Brain with `fairing_sync`
`fairing_sync` is **free**. It is READ-ONLY and warehouses two resources into vendor-neutral per-org tables — `survey_responses` and `survey_questions` — deduped on `source` + the provider's id, so a re-sync refreshes existing rows in place rather than duplicating them. Each response row carries the customer's self-reported answer ALONGSIDE the order's real revenue and its measured UTM trail. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted, latest_inserted_at }` — store `latest_inserted_at` as your watermark for the next incremental run.
3. First, do a full BACKFILL — omit `since`
For the initial load, call `fairing_sync` with NO `since` argument. Each call is BOUNDED: it pages only until `max_pages_per_run` pages OR `max_seconds_per_run` seconds, then returns `has_more: true` and a `next_cursor: { resource, starting_after }`. Call again passing that `next_cursor` back as `cursor` — repeat until `has_more` is false. That walks the whole store, oldest-first. ⚠️ Do NOT pass `since` on the first run: `since` is Fairing's incremental filter, so a `since` on the initial backfill permanently skips every response older than that timestamp — you can't get them back without re-walking from scratch.
4. Then keep it fresh with an incremental `since` watermark
For scheduled refreshes AFTER the backfill is complete, pass `since` set to the high-water mark from your last run so you pull only new responses instead of re-walking the whole store. Store the `latest_inserted_at` the sync reports and pass it back as `since` next time. If a run reports `latest_inserted_at: null` (no new rows seen), keep your previous watermark rather than overwriting it. Between the bounded-cursor backfill and the `since` watermark, you never re-read data you already have and never miss a new response.
5. Reconcile said-vs-measured with `query_data`
The survey tools warehouse data; they don't analyze it. For attribution reconciliation — which channels customers credit vs what Meta/Google/UTM claimed, revenue by survey answer, AOV by "how did you hear?" — use `query_data` (Gentic Data MCP) over `survey_responses` and `survey_questions`. Because each response already carries the answer, the revenue, and the UTM trail in one row, said-vs-measured is a single-table GROUP BY — no join to a separate orders table required. Sync first (or re-sync incrementally) so the numbers are current.
6. Present results clearly
Don't dump raw JSON. Summarize the attribution picture — top self-reported channels, where customers and the pixels disagree, revenue and AOV by answer — and cite the counts. After a sync, tell the user how many rows were `persisted` per resource and whether `has_more` is true (there's more to page through). For recurring checks, re-run `fairing_sync` with your `since` watermark to refresh before querying.
6. Tool Reference
2 tools, rendered live from the Gentic MCP manifest. Parameter tables come directly from each tool's JSON Schema.
fairing_connection_status
Check whether the calling organization has connected Fairing (the post-purchase survey app). Returns `{ connected, shop_domain, updated_at }` when connected, or `{ connected: false }` otherwise. Free. Call before fairing_sync to give the user actionable guidance when the integration is missing. Never returns the API key.
This tool takes no parameters.
fairing_sync
Sync post-purchase survey data from Fairing into this organization's data backend — READ-ONLY, verbatim, one BOUNDED chunk per call. Uses the org's connected Fairing integration (dashboard → Integrations; no API key is passed here). Warehouses two resources into the vendor-neutral per-org tables `survey_responses` and `survey_questions` (deduped on source + the provider's id, so re-syncs refresh rows in place). Each response row carries the customer's self-reported answer (e.g. "how did you hear about us") ALONGSIDE the order's real revenue (order_total_usd) and its measured UTM trail — so self-reported vs measured attribution is a single-table query, no join. BOUNDED + RESUMABLE: each call pages only until `max_pages_per_run` pages OR `max_seconds_per_run` seconds are reached, then returns `has_more` + `next_cursor: { resource, starting_after }`. The recommended flow: call again passing that `next_cursor` back as `cursor` until `has_more` is false. For scheduled refreshes pass `since` to pull only new responses. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted }`. FREE.
| Parameter | Type | Description |
|---|---|---|
resources | string[] | Subset of resources to sync this run (in order). Any of: responses, questions. Omit to sync both. |
since | string | ISO 8601 date/timestamp — pull only responses inserted at or after this point (Fairing's incremental filter). Use this for scheduled refreshes instead of re-walking the whole store. |
page_size | integer | Rows per Fairing page (1–1000, default 250). Fairing caps this at 1000; larger pages are cheaper against the 100 req/min limit. 1 – 1000 |
max_pages_per_run | integer | Cap on pages fetched this call (default 20, hard max 50). Keeps a single call bounded — page more via next_cursor, never a bigger run. 1 – 50 |
max_seconds_per_run | integer | Wall-clock budget in seconds for this call (default 20, hard max 30). The walk stops after the current page once exceeded; resume with next_cursor. 1 – 30 |
cursor | any | Resume point from a prior call's `next_cursor` — { resource, starting_after }. Omit/null to start from the first requested resource at the beginning. |
7. Pricing
Pricing is pulled live from the Gentic MCP manifest. All prices are per call and deducted from your Gentic credits.
| Tool | Cost |
|---|---|
| fairing_connection_status | Free |
| fairing_sync | Free |
8. Notes
- Organization-scoped: the Fairing connection comes from the org's connected integration (dashboard → Integrations → Fairing). No credential is ever passed to the tools.
- Cost: both `fairing_connection_status` and `fairing_sync` are **free**. You pay only for analytics you run over the synced data (e.g. `query_data`). Pricing is pulled live from the Gentic MCP manifest.
- `fairing_sync` is READ-ONLY — it warehouses Fairing data into your Brain and never writes back to Fairing.
- Rows are deduped on `source` + the provider's id: re-syncing refreshes the same row (mutable fields and all) rather than duplicating it.
- Backfill vs incremental: omit `since` for the first full walk (page the bounded `next_cursor` as `cursor` until `has_more` is false); pass `since` = your stored `latest_inserted_at` only for scheduled refreshes. A `since` on the FIRST run permanently skips older responses.
- The two tables — `survey_responses` and `survey_questions` — are queried with `query_data` for all counts, aggregations, and said-vs-measured attribution.