Build with Ravetell
Everything in Ravetell — campaigns, testimonials, consent — is available to your AI agents and automations. One MCP server, a REST API, and signed webhooks. No SDK required.
MCP — connect an AI assistant
The Ravetell MCP server lives at one URL:
https://mcp.ravetell.comClaude (web, Desktop, mobile): Settings → Connectors → Add custom connector → paste the URL. Claude walks you through a Ravetell sign-in and an Allow access screen — that's it. No API keys.
CLI clients (Claude Code, Codex, Cursor): authenticate with an API key
from Settings → API keys sent as Authorization: Bearer rvt_live_…. Per-client setup snippets live on the connect page.
Tools
All tools are prefixed ravetell_. Read tools (safe, no side effects): list_campaigns, get_testimonials, get_response, get_campaign_stats, get_person, get_account_settings, get_share_link, get_errors, help. Write tools (need the write scope): create_campaign, update_campaign (rename, archive, or set a
custom /t2/<slug> link), update_testimonial, delete_response, restore_response. report_bug files a support report (read scope — telemetry, not data mutation).
Creation is consent-shaped by design: create_campaign shows a preview card
and creates nothing until it is called again with confirm: true.
REST API
Same data, plain HTTP. Authenticate every request with Authorization: Bearer rvt_live_….
GET /api/campaigns | List campaigns |
POST /api/campaigns | Create a campaign (returns the share URL) |
GET /api/campaigns/:id | Campaign detail |
PATCH /api/campaigns/:id | Edit / archive / reactivate; send customSlug to set /t2/<slug>, or "" to clear it |
GET /api/campaigns/:id/responses | Response summaries (status, final text, hasTranscript) |
GET /api/campaigns/:id/responses/:rid | Single response incl. full transcript + consent |
PATCH /api/campaigns/:id/responses/:rid | Owner edits to a response |
GET/POST /api/webhooks | Manage webhooks (below) |
Rate limits are generous for normal use; 429s carry a Retry-After header.
Webhooks — push events to Zapier, Make, n8n, or your server
Register an endpoint and Ravetell POSTs signed JSON events to it:
testimonial.approved | A giver approved their testimonial (the big one — full text, attribution, and consent in the payload) |
testimonial.consent_updated | Consent changed — re-check before publishing |
campaign.created | New campaign (includes the share URL) |
campaign.updated | Campaign edited, archived, or reactivated |
Register
POST /api/webhooks
Authorization: Bearer rvt_live_…
{ "url": "https://hooks.zapier.com/hooks/catch/…", "events": ["testimonial.approved"] }The response includes a whsec_… signing secret — shown once.
Endpoints must be https. Five webhooks per account.
Verify signatures
Every delivery carries Ravetell-Signature: t=<unix>,v1=<hex> where v1 = HMAC-SHA256(secret, t + "." + rawBody). Reject requests older than ~5
minutes and dedupe on the envelope id:
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyRavetell(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(signatureHeader.split(',').map((p) => p.split('=')));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false; // replay window
const expected = createHmac('sha256', secret).update(parts.t + '.' + rawBody).digest('hex');
return timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}Delivery semantics (the honest version)
At-least-once, with gaps: deliveries retry on a 0/2/6-second schedule and then stop —
there is no out-of-band retry queue. A 7-day delivery log and a manual POST /api/webhooks/:id/redeliver cover misses. Zapier users: this is exactly
what "Webhooks by Zapier" expects — create a Catch Hook trigger, paste its URL
into the register call above, and your Zap fires on every approved testimonial.
For agents
A machine-readable summary of everything on this page lives at /llms.txt. The MCP server is self-describing —
connect and call ravetell_help.