# Real Deals Snap

Connection hub: https://real-deals.app/snap/

MCP: https://real-deals.app/api/v1/mcp

REST: https://real-deals.app/api/v1

OpenAPI: https://real-deals.app/snap/openapi.json

## Account access

Customers use their existing Real Deals sign-in. ChatGPT, Claude and Grok custom connections use OAuth authorization-code flow with S256 PKCE. Dynamic client registration and protected-resource metadata are available. The consent page displays the app name, callback host and permissions. Access tokens expire after one hour; refresh tokens rotate and expire after 30 days. Connections can be revoked from the hub, invalidating the connection's refresh tokens too.

REST automation clients use a personal, scoped key created in the hub. The key is shown once, stored server-side as a hash and expires in 30 days. Keys are never saved in browser storage. Keep them in your platform's secret manager. Available permissions: `leads:read`, `leads:write`, `events:read`.

## Working tools

- List, create and update account-scoped Snap leads.
- Poll lead-created and lead-updated events (newest first, stable IDs).
- Calculate an illustrative offer from supplied ARV, repairs, ratio and fees.
- Export a Canva property brief and Bulk Create CSV.
- Export an ICS appointment file for Google, Outlook and Apple Calendar.
- Read integration setup instructions.

Existing shared-backend leads are not automatically exposed to this connector. Snap leads live in a separate member-owned workspace. The hub supports creating and searching these leads. The main Real Deals saved-lead list also has an explicit “Save to my Snap workspace” button on each lead; it copies only that selected record into the signed-in member’s workspace, with duplicate prevention. It does not provide live comps, skip tracing, dialer access, messaging, external booking, Canva publishing or paid provider calls.

## REST examples

Send `Authorization: Bearer YOUR_SNAP_KEY` to protected endpoints. Bodies use `Content-Type: application/json`. Send a stable `Idempotency-Key` for each source record when creating/updating leads; reuse it on retries. A different payload with the same key returns 409. The last 1,000 request keys are retained per workspace.

- `GET /leads?query=Beaumont&limit=50` — bare array, newest first.
- `POST /leads` — `{ "address": "YOUR ADDRESS", "note": "Optional notes", "source": "Zapier" }`.
- `PATCH /leads` — `{ "id": "LEAD_UUID", "status": "Contacted" }`.
- `GET /events?limit=50` — bare array, newest first; deduplicate by `id`.
- `POST /calculate-offer` — `{ "arv": 250000, "repairs": 40000, "offerRatio": 0.7, "fees": 5000 }`.
- `POST /canva-brief` — `{ "address": "YOUR ADDRESS", "headline": "Property walkthrough", "description": "Details" }`.
- `POST /calendar-file` — `{ "title": "Walkthrough", "start": "2026-10-01T14:00:00-05:00", "end": "2026-10-01T15:00:00-05:00" }`.

Limits: 32 KB JSON bodies; 2,000 leads and 1,000 recent events per member; 100 results per request; 1,000 authenticated operations per member per hour; 60 public utility calls per IP per minute. Poll at a frequency that catches fewer than 100 new records per poll. Higher-volume pagination and billing entitlements are not yet implemented. Provider and platform fees apply through the customer's own accounts. Snap makes no billable property, AI, mail or phone calls.

## Zapier, Slack, Calendly and Calendar

`zapier/index.cjs` contains a private CLI app with API-key authentication, New Lead and Lead Activity polling triggers, Find Lead search and Create Lead action. Authenticate with a key containing `leads:read`, plus `events:read` / `leads:write` for the corresponding steps. Validate/test/push it from a Zapier developer account. Public Zapier directory publication has not been performed.

Example recipes:

1. Snap Lead Activity → Slack Send Channel Message.
2. Calendly Invitee Created → Snap Create Lead (map a property-address booking question).
3. Snap New Lead → Google Calendar Create Event (add your chosen scheduling fields).
4. Snap property brief CSV → Canva Bulk Create.

These recipes use the customer's provider connections inside Zapier/Make. Native Slack, Canva Connect, Google Calendar and Calendly OAuth apps have not been registered, and no connection to an individual customer's provider account is implied.

## Replit and Grok API

`examples/replit.mjs` works with Node 20+ and the `REAL_DEALS_SNAP_KEY` secret. `examples/grok.mjs` additionally requires `XAI_API_KEY` and `XAI_MODEL`; it explicitly allows only the lead-listing tool. AI API charges use that customer's xAI account. Grok users can also use the custom connector UI at https://grok.com/connectors.

## Deployment

Netlify Functions use the MCP TypeScript SDK's stateless Streamable HTTP transport. Netlify Blobs uses strong consistency and conditional writes for code/refresh consumption and workspace updates. Production data uses a site-scoped store; previews use deploy-scoped stores. The MCP connection requires authentication; the REST utility endpoints are public and do not access private data. No additional provider secrets are needed for the Snap API itself.

OAuth metadata lives at `/.well-known/oauth-authorization-server` and `/.well-known/oauth-protected-resource/api/v1/mcp`. The resource audience is the full MCP URL. REST keys and OAuth tokens are accepted by the same account-scoped permission checks. OAuth client authentication is `none` with mandatory PKCE. Dynamic registration accepts HTTPS callbacks and localhost loopback callbacks.

ChatGPT public plugin submission, public Zapier listing, provider-native OAuth app registration and external account connection tests remain separate rollout gates. A custom-connector URL does not install an app automatically for everyone.
