My Money Vision integrations
Two ways to connect My Money Vision to your CRM, notetaker or Zapier. Both are set up by your firm lead or office admin in Settings > Integrations.
- Webhooks: My Money Vision tells your system when a family does something worth a call.
- Invite API: your system invites a family, or checks on one, without anyone opening the dashboard.
Webhooks
Create one: Settings > Integrations > Add webhook. Enter an https URL, pick the events, and save. The signing secret is shown once; store it where your receiver can read it. A firm can have 3 webhooks.
Each event is sent as a JSON POST with these headers:
X-MMV-Event: the event nameX-MMV-Delivery: the delivery id (alsoevent_idin the body; use it to ignore a retry you already handled)X-MMV-Signature:sha256=followed by the hex HMAC-SHA256 of the raw body, keyed with your signing secret
Reply with any 2xx within 10 seconds. Anything else is tried again, 6 tries in all, waiting 2, 4, 8, 16 and 32 minutes between them. After 20 failures in a row the webhook is switched off; switch it back on in Settings.
Events
member.joined: a family accepted their invitation.
{ "event": "member.joined", "event_id": "4f0c...", "org_id": "9a1e...", "occurred_at": "2026-10-30T15:04:05Z",
"member": { "id": "b2d4...", "email": "ana@example.com", "full_name": "Ana Lopez" },
"invited_by": { "id": "77c1...", "full_name": "Dana Reed" },
"course_instance_id": "c91f..." }lesson.completed: a family finished a lesson.
{ "event": "lesson.completed", "event_id": "...", "org_id": "...", "occurred_at": "...",
"member": { "id": "...", "email": "ana@example.com", "full_name": "Ana Lopez" },
"lesson_id": "5e2a...", "lesson_title": "Emergency fund basics", "completed_at": "2026-10-30T15:04:01Z" }account.opened: a family reported opening an account (for example a Roth IRA).
{ "event": "account.opened", "event_id": "...", "org_id": "...", "occurred_at": "...",
"member": { "id": "...", "email": "ana@example.com", "full_name": "Ana Lopez" },
"milestone_type": "roth_ira", "reported_date": "2026-10-30" }Verify the signature
Node:
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return header.length === expected.length && crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}Python:
import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(header, expected)Always verify against the raw request body, before parsing the JSON.
Zapier recipes
Zapier needs no My Money Vision app: "Webhooks by Zapier" catches the POST.
Wealthbox: a note on the contact when a family finishes a lesson
- Trigger: Webhooks by Zapier > Catch Hook. Copy the URL Zapier gives you and add it in Settings > Integrations with only
lesson.completedticked. - Action: Wealthbox > Find Contact, search by
member__email. - Action: Wealthbox > Create Note on that contact: "Finished {{lesson_title}} on My Money Vision ({{completed_at}})."
Redtail: the same, in Redtail
- The same Catch Hook trigger.
- Action: Redtail CRM > Find Contact by
member__email. - Action: Redtail CRM > Create Note (some Redtail connections list this as an activity) with the same text.
Use the same pattern for member.joined ("Joined My Money Vision") and account.opened ("Reported opening a {{milestone_type}}"). Zapier's Catch Hook does not check signatures; add a "Code by Zapier" step with the Node snippet above if you want it to.
Invite API
Create a key: Settings > Integrations > Create key. The full key (mmv_live_...) is shown once. A firm can have 5 active keys; revoke one any time.
Endpoint: https://yxjgxyxzcypppxzarnrl.supabase.co/functions/v1/api-invite-member
Invite a family:
curl -X POST "$URL" -H "Authorization: Bearer $MMV_KEY" -H "Content-Type: application/json" \
-d '{"email":"ana@example.com","first_name":"Ana","last_name":"Lopez","advisor_email":"dana@yourfirm.com"}'| Field | ||
|---|---|---|
email | required | |
first_name, last_name | optional | |
advisor_email | optional | Must be an advisor, coach or office admin at your firm. The invitation email names them and replies go to them. Without it, the person who created the key. |
course_instance_id | optional | A course that advisor can use. |
send | optional, default true | false creates the invitation without emailing it. |
Responses:
201:{ "invitation_id", "invite_code", "signup_url", "status", "email_status" }401: missing, wrong or revoked key402: your firm has used all of its family seats409:{ "error": "already_invited", "invitation_id", "status" }422: bad email, unknown advisor, or a course that advisor cannot use429: more than 60 invitations from this key in the last hour (seeRetry-After)
Check before inviting:
curl "$URL?email=ana@example.com" -H "Authorization: Bearer $MMV_KEY"Returns 200 { "invitation_id", "status", "email_status", "created_at", "accepted_at", "expires_at" }, or 404 when that email has no invitation at your firm.
The invitation email is the same one your dashboard sends. Everything a family sees is education only, never financial advice.
