---
name: gentic-surveys
description: "Give your AI agent your Fairing post-purchase survey data. Sync survey responses and questions — self-reported attribution joined to real order revenue and UTM trail — into your Brain with bounded, resumable syncs, then reconcile said-vs-measured attribution in natural language or SQL via query_data. Free to sync."
license: MIT
metadata:
  author: gentic
  version: "1.0.0"
---

# Gentic Surveys

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.

## 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.

## Tools

| Tool | Description | Cost |
|------|-------------|------|
| `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. | Free |
| `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. | Free |

## 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.

## 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.

## Tool details

- `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.
- `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.
  - `resources` (array of 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.
  - `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.
  - `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.
  - `cursor` — Resume point from a prior call's `next_cursor` — { resource, starting_after }. Omit/null to start from the first requested resource at the beginning.

---

_This SKILL.md is generated from the live Gentic MCP manifest. Tool names, descriptions, and pricing are always current. Connect Gentic Surveys at https://gentic.co/surveys._
