Gentic Loyalty — Documentation
Connect any AI agent to your loyalty program. Sync your Rivo data — points events, redemptions, rewards, referrals, and VIP tiers — into your organization's Brain, then ask in natural language: 'which VIP tier actually repurchases?', 'what are we paying out in points versus getting back?', 'how much revenue came from referrals last quarter?'. Bounded, resumable syncs keep the picture current without re-reading everything.
1. Getting Started
Sign Up & Get Your API Key
Before you can use Gentic Loyalty, you need an API key to authenticate your requests.
- Go to gentic.co/loyalty 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/loyalty. For Claude Code:
claude mcp add gentic-loyalty \
--transport http \
https://mcp.gentic.co/loyalty \
--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 Loyalty 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/loyalty/SKILL.mdOr upload a .skill bundle to Claude Managed Agents:
https://gentic.co/loyalty/gentic-loyalty.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 analyze their loyalty program — points earned, redeemed, or outstanding.
- User wants to know how VIP tiers differ in repurchase rate, order value, or retention.
- User wants to measure referral performance — how many, and what revenue they drove.
- User wants to understand reward economics: what a reward costs versus what it returns.
- User wants to sync their Rivo loyalty data into their Brain for analysis.
- User wants to join loyalty data against subscriptions, orders, or survey responses.
5. Workflow
1. Connect Rivo once, then sync without credentials
The Loyalty server sources the Rivo connection (the REST API key) from the org's connected integration (Gentic dashboard → Integrations → Rivo). You never pass credentials to the tools — connect once in the dashboard and the server reads the encrypted connection automatically. Call `rivo_connection_status` first (it's free) to confirm the org is connected; if it returns `{ connected: false }`, point the user to Integrations → Rivo. It never returns the API key. Pass `check_live` when you want it to actually probe Rivo rather than just report that a key is stored.
2. Sync loyalty data into the Brain with `rivo_sync`
`rivo_sync` is **free**. It is READ-ONLY and warehouses five resources into per-org tables — `rivo_points_events`, `rivo_points_redemptions`, `rivo_rewards`, `rivo_referrals`, `rivo_vip_tiers` — dedupe-upserted on their natural key, so a re-sync refreshes existing rows in place rather than duplicating them. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted, pages_fetched, stalled }`.
3. Walk the data with bounded, resumable pagination
Each `rivo_sync` call is BOUNDED: it pages the requested resources only until `max_pages_per_run` pages OR `max_seconds_per_run` seconds are reached, then returns `has_more` and a `next_cursor: { resource, since_id }`. To finish a large backfill, call again passing that `next_cursor` back as `cursor` until `has_more` is false — the walk resumes exactly where it stopped, and because it's an id cursor rather than a page offset, rows inserted mid-walk can't shift the window under you. Use `resources` to sync only the tables you need. Check `stalled` before you trust a walk as complete: a non-empty `stalled` means a resource stopped because its cursor could not advance, not because it ran out of rows — that needs a look rather than another call.
4. Count and aggregate with `query_data`
The loyalty tools warehouse data; they don't analyze it. For points issued versus redeemed, redemption rate by reward, referral counts and revenue, or tier distribution, use `query_data` (Gentic Data MCP) over the `rivo_*` tables — standard SQL GROUP BY / COUNT / SUM over the synced rows. Sync first (or re-sync incrementally) so the numbers are current.
5. Join loyalty against the rest of the business — this is the point
A loyalty dashboard can tell you redemption counts. It cannot tell you whether the program works, because the answer lives in tables it has never seen. Since everything lands in the same per-org Brain, join `rivo_*` against what you've synced elsewhere: VIP tier against subscription retention (`skio_*` / `loop_*`) for LTV by tier, points redemptions against order history for whether earning actually drives repurchase, referrals against your ad-attributed revenue to see what you were already paying for, and tier or redemption behaviour against survey responses (`fairing_*`) for why. Compose it across tables with `query_data`.
6. Present results clearly
Don't dump raw JSON. Summarize the numbers — points issued and redeemed, top rewards, referral counts and revenue, tier distribution — and cite the counts. After a sync, report three things, not two: how many rows were `persisted` per resource, whether `has_more` is true (there's more to page through), and whether anything `stalled`. The third is the one that changes what you say. A stalled resource means the walk is INCOMPLETE even when `has_more` is false, so a summary of persisted counts alone would read as a finished sync when it isn't — name the stalled resources and say the data is partial rather than presenting the run as successful. For recurring checks, re-run `rivo_sync` to refresh the tables before querying.
6. Tool Reference
2 tools, rendered live from the Gentic MCP manifest. Parameter tables come directly from each tool's JSON Schema.
rivo_connection_status
Check whether the calling organization has connected Rivo (the rivo.io loyalty app). Returns `{ connected, shop_domain, updated_at }` when connected, or `{ connected: false }` with a hint otherwise. Free. Call before rivo_sync so a missing integration produces actionable guidance rather than a failed sync. Never returns the API key. Set check_live to true to also VERIFY the stored key against Rivo with a single one-row read. Worth doing once after connecting a new Rivo account: a key that is present is not the same as a key that works, and the cheapest time to learn the difference is before a sync.
| Parameter | Type | Description |
|---|---|---|
check_live | boolean | When true, make one minimal read against Rivo to verify the stored key actually works. Adds a round-trip; still free. |
rivo_sync
Sync loyalty data from Rivo (rivo.io) into this organization's data backend — READ-ONLY, verbatim, one BOUNDED chunk per call. Uses the org's connected Rivo integration (dashboard → Integrations; no API key is passed here, and there is no shop argument — a Rivo key is scoped to one store). Warehouses five resources into per-org tables: `rivo_points_events`, `rivo_points_redemptions`, `rivo_rewards`, `rivo_referrals`, `rivo_vip_tiers`, upserted on their id so re-syncs refresh rows in place. Covers redemption trends, earning velocity, reward economics, referral performance and tier structure — and joins against the org's other connector tables (subscriptions, orders, surveys) in the same warehouse. 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, since_id }`. Call again passing that back as `cursor` until `has_more` is false — the walk resumes exactly where it stopped. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted, pages_fetched, stalled }`. A non-empty `stalled` means a resource stopped because its cursor could not advance rather than because it finished — that is not a complete walk, and it needs a look rather than another call. FREE.
| Parameter | Type | Description |
|---|---|---|
resources | string[] | Subset of resources to sync this run, in order. Any of: points_events, points_redemptions, rewards, referrals, vip_tiers. Omit to sync all five. |
page_size | integer | Rows per Rivo page (1–100, default 100). 1 – 100 |
max_pages_per_run | integer | Cap on pages fetched this call (default 20, hard max 50). Page more via next_cursor, never via a bigger run. 1 – 50 |
max_seconds_per_run | integer | Wall-clock budget in seconds for this call (default 60, hard max 120). The walk stops after the current page once exceeded; resume with next_cursor. 1 – 120 |
cursor | any | Resume point from a prior call's `next_cursor` — { resource, since_id }. Omit or null to start from the first requested resource. |
7. Pricing
Pricing is pulled live from the Gentic MCP manifest. All prices are per call and deducted from your Gentic credits.
| Tool | Cost |
|---|---|
| rivo_connection_status | Free |
| rivo_sync | Free |
8. Notes
- Organization-scoped: the Rivo connection comes from the org's connected integration (dashboard → Integrations → Rivo). No credential is ever passed to the tools.
- Cost: both `rivo_connection_status` and `rivo_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.
- `rivo_sync` is READ-ONLY. It warehouses your loyalty data and never writes back to Rivo — it cannot grant points, issue rewards, or change a customer's tier. That boundary is deliberate: a connector that can award value is a different product with a different risk profile.
- Rows are deduped on their natural key: re-syncing refreshes the same row (mutable fields and all) rather than duplicating it.
- Syncs are bounded and resumable: each call stops at `max_pages_per_run` / `max_seconds_per_run` and returns `next_cursor: { resource, since_id }`; pass it back as `cursor` to continue until `has_more` is false. A non-empty `stalled` in the result means a resource stopped because its cursor could not advance — that is not a finished walk, and calling again will not fix it.
- The five tables — `rivo_points_events`, `rivo_points_redemptions`, `rivo_rewards`, `rivo_referrals`, `rivo_vip_tiers` — are queried with `query_data` for all counts and aggregations.
- A Rivo API key is scoped to a single store, so which store the data belongs to is captured automatically when you connect and there is nothing to select per call.