# ReachOut — Agent-driven marketing automation ## Positioning The marketing stack your AI agent can actually run. Contacts, campaigns, segments, analytics, and automations — all exposed through two equal surfaces (the ReachOut Studio and an MCP server) on top of the same primitives and the same audit log. Built on Cloudflare's edge: Hyperdrive to Neon Postgres for relational data, KV for cache, R2 for object storage, Durable Objects for stateful queues/buffers, Email Workers for transactional and campaign sends. ## Who it's for 1. Agent builders putting Claude / GPT / custom agents into production and needing a real marketing backend. 2. Marketing teams who already live in an AI chat and want to run campaigns from there rather than clicking through a traditional SaaS GUI. 3. Forward-leaning marketing teams using the Studio, aware the real leverage is the agent running underneath. ## Architecture principles - **Two-surface, one-primitive.** Every capability ships in both the Studio and the MCP server on day one. - **Audit log is the product.** Every write — by human or by agent — lands in a filterable audit trail scoped to the tenant, the agent session, and the tool call. - **Multi-tenant by default.** Per-tenant API keys, usage metering, and rate limits. Each tenant gets isolated Postgres rows, isolated R2 object prefixes, and queue/event buffering through Durable Objects. - **Cloudflare-native operations.** The app runs on Workers, Hyperdrive, KV, R2, Durable Objects, and Email Workers, with Neon Postgres as the primary data plane and Polar as the billing dependency. ## Pricing (authoritative) | Tier | Price | Included | Overage | |------------|----------------------|------------------------------------------------------------------------------------------|-----------------------------------------------------------| | Starter | Free (no CC) | 200 emails / mo · 100 MCP tool calls / mo · 40 insight generations | Volume overage | | Pro | $20 / user / month | 10,000 emails / mo · 1,000 MCP tool calls / mo · 1,000 insight generations | Volume overage | | Max | $100 / user / month | 100,000 emails / mo · 5,000 MCP tool calls / mo · 5,000 insight generations | Volume overage | Starter requires email verification and opting in to product updates. Volume above included limits is tracked in Activity and Settings and billed as line items: emails $2 / 1,000, MCP tool calls $5 / 1,000, insights $10 / 1,000. ## Interfaces ### Studio — https://usereachout.com/studio Visual overview, campaign composer, segment builder, live delivery charts, audit-log viewer, agent stream. ### REST API — https://reachout-pulse-api.usereachout.com JSON over HTTPS. Auth: `Authorization: Bearer `. All writes accept idempotency keys via `Idempotency-Key` header. Representative endpoints: - `GET /api/campaigns` - `POST /api/campaigns/:id/send` - `GET /api/contacts` - `POST /api/contacts` - `GET /api/segments` - `POST /api/segments/:id/estimate` - `GET /api/segments/:id/contacts` - `GET /api/assets` - `POST /api/assets` - `GET /api/analytics/query` - `GET /api/audit/query` - `GET /api/billing/usage` - `GET /api/billing/seats` ### MCP — https://reachout-pulse-api.usereachout.com/mcp (v1.1.0) Model Context Protocol endpoint. JSON-RPC over SSE + HTTP. Authenticated with the same API keys as the REST interface. Full structured manifest (inputs, outputs, side-effects, idempotency per tool): https://usereachout.com/mcp-manifest.json Reference (auth, scoping, response envelope): https://usereachout.com/docs/mcp Local AI setup guide (Ollama, LM Studio, Claude Desktop, Cursor): https://usereachout.com/docs/local-ai **Authentication & organization scoping.** Every `tools/call` requires `Authorization: Bearer `. Three token shapes are accepted: per-user API keys (switch_organization works across the user's memberships), legacy org-scoped keys (single-org, created before 2026-04), and the master `PULSE_API_KEY` server secret (full system access). The active organization is implicit — no tool accepts an `organizationId` parameter. Resolution order per request: KV session override (set by `switch_organization`, 24h TTL) → key's default org → first-org fallback for master keys. Stale overrides are validated and cleared automatically. **Response envelope.** Every successful tool response is a single text block prefixed with `[organization] (id: )` followed by a JSON body `{ organization: {...}, result: }`. The header is part of the text the model sees, so clients always surface the active tenant to the user. Tool surface (v1.1.0): Organization management: - `get_current_organization` — returns the active org and the auth source. - `list_organizations` — orgs the caller can see (memberships / all / single). - `switch_organization(organizationId)` — write 24h KV override. Domain: - `list_contacts(status?, limit?)`, `get_contact(contactId)`, `create_contact(email, firstName?, lastName?, company?)` - `list_campaigns(status?, limit?)`, `get_campaign_stats(campaignId)`, `send_campaign(campaignId)` - `list_segments()` - `get_analytics(type?)` — daily / weekly / monthly summaries Error codes: `-32001` auth required, `-32002` invalid/expired key, `-32003` active org not found, `-32601` unknown method/tool, `-32602` invalid params. Every write-side tool emits an audit-log entry linked to the agent session and is rate-limited per tenant. ## Data model (summary) - `organizations` — tenants. One per workspace. - `members` — user ↔ organization with role (owner, admin, member). - `contacts` — individual records with custom attributes. - `segments` — rule- or list-based contact collections. - `campaigns` — email sends, with status `DRAFT | SCHEDULED | SENDING | SENT | FAILED`. - `assets` — dashboard-managed public campaign/template images served from reachout-pulse-assets.usereachout.com. - `email_suppressions` — bounces, complaints, unsubscribes, manual suppressions, and resubscribe state. - `automations` — trigger → action flows. - `data_sources` — external integrations (CSV, webhooks, Polar, Segment, Shopify — webhook-driven). - `audit_logs` — every mutating action, indexed by tenant + session + tool call. - `usage_records` — per-tenant counters for emails, MCP calls, insight generations, and payments. ## Agent guidance When using ReachOut via MCP: 1. Call `get_current_organization` first if you're unsure which tenant the user expects you to operate on. The `[organization]` header on every subsequent response confirms the active tenant. 2. If the user mentions an org name you don't see in the active context, call `list_organizations` to find the target ID, then `switch_organization`. The switch persists 24h across calls with the same key. 3. Read before writing — confirm what already exists (`list_contacts`, `list_campaigns`) before calling `create_contact` or `send_campaign`. 4. Prefer `get_campaign_stats` + reporting over kicking off new sends unless the user explicitly asks to send. 5. Suppressions are authoritative — suppressed contacts must not receive further campaigns. Human unsubscribe pages can explicitly resubscribe unsubscribe-only suppressions, but agents should treat suppression state as the source of truth. ## Contact - Company: Reach Out Labs GmbH - Homepage: https://reachoutlabs.ch - Email: hello@usereachout.com — we read every email.