Integrations · Client Setup Guide

Connecting FoxFlow with Blackbaud

How to connect FoxFlow (your lead pipeline) to Blackbaud (your student and family system of record), with Mailchimp handling email.

For schools and organizations that use Blackbaud as their student and family system of record and want it connected to FoxFlow.

How the connection works

FoxFlow connects to Blackbaud in two parts:

  1. Mailchimp — a built-in, one-click integration for email.
  2. A Blackbaud bridge — FoxFlow sends every lead and conversion event to a URL you control via outbound webhooks, and a small connector on that end writes the data into Blackbaud through the Blackbaud SKY API. You provide the connector — Zapier, Make, or a simple script.

Together these give you a working, duplicate-safe pipeline from first inquiry to enrolled constituent.

1. The big picture

Inquiry Form, ad, or SMS reply
FoxFlow

Lead (pipeline) → convert → Contact

FlowSend SMS — replies route back to the lead by phone

Mailchimp (email)
Your connector (Zapier / Make / script)
Blackbaud (SKY API)
                 ┌──────────────────────────── FoxFlow ───────────────────────────┐
                 │                                                                 │
  Inquiry  ──►   │  Lead (pipeline)  ──► convert ──►  Contact (org database)       │
  (form, ad,     │      │                                  │                       │
   SMS reply)    │      │ FlowSend SMS/iMessage            │                       │
                 │      ▼                          ┌───────┴────────┐              │
                 │  (replies route back            │ auto-sync       │ webhook on  │
                 │   to the lead by phone)         ▼                 ▼ events       │
                 └─────────────────────────┌───────────┐   ┌──────────────────────┘
                                           │ Mailchimp │   │ Your connector
                                           │  (email)  │   │ (Zapier/Make/script)
                                           └───────────┘   ▼
                                                      ┌────────────┐
                                                      │ Blackbaud  │
                                                      │ (SKY API)  │
                                                      └────────────┘
  • FoxFlow captures and works the inquiry (top of funnel).
  • Mailchimp sends email to those contacts (built-in sync).
  • Blackbaud is the system of record for students and families. Your connector receives FoxFlow events and creates/updates the matching constituent.
Golden rule: Blackbaud is the source of truth. The connector should fill in blanks and link records — never blindly overwrite data your school has already curated in Blackbaud.

2. Before you start (prerequisites)

  • FoxFlow organisation on the Pro plan — required for both Mailchimp and webhooks.
  • You are an owner or admin of the FoxFlow organisation.
  • A Mailchimp account (for the email piece).
  • Blackbaud SKY API access: a developer account, a registered app (Client ID / Secret / Redirect URI), and a subscription key. Your Blackbaud admin usually arranges this.
  • A connector that can receive an HTTPS webhook and call the Blackbaud API:
    • No-code: Zapier or Make (Integromat) — "Webhook → Blackbaud" scenario.
    • Low-code: a small cloud function / serverless endpoint your IT writes.
  • Agreement on your matching rule (how to decide a lead is an existing constituent — email first, then phone; details in Section 6).

3. A quick note on Blackbaud's vocabulary

Blackbaud is precise about wording, and mismatched terms are a common source of confusion. Line up the language before you line up the data.

In FoxFlowIn BlackbaudNote
Lead(no equivalent)A prospect being worked; lives only in FoxFlow until converted.
ContactConstituent / IndividualBlackbaud assigns a unique ID to every individual.
(no equivalent)StudentHas its own Student ID, separate from the constituent record.
(no equivalent)Household / RelationshipFamilies = linked individuals. FoxFlow has no household concept.
TagCustom field / listFoxFlow contact tags travel in the webhook so you can map them.
The unique-ID nuance. A parent and their child are separate individuals with separate IDs in Blackbaud, even when they share a household and a phone number. Each student also has its own Student ID and login, distinct from the constituent record. A "Request Info" lead is almost always the parent — so your connector should create or match the parent constituent, and link the student (a different record with its own Student ID) separately during enrollment. Never let a shared phone number merge a parent and a student into one record.

4. Step 1 — Connect Mailchimp (email)

This one is fully built in — no connector required.

  1. Open Org Settings → Integrations → Mailchimp.
  2. Click Connect and authorize via Mailchimp (OAuth). Tokens are stored securely server-side; no keys are exposed in the browser.
  3. Choose the audience to sync into.
  4. Done. From now on, when a lead converts into a Contact, FoxFlow automatically:
    • Upserts the subscriber in Mailchimp, and
    • Syncs tags (adds new ones, removes ones you've cleared).

Why this stays clean: Mailchimp subscribers are keyed by the email address — the exact same key FoxFlow uses for contacts — so the same person never lands in Mailchimp twice.

Keep the roles clear: Mailchimp = broadcast email, Blackbaud = system of record. Don't try to make Mailchimp a second database of constituent data.

5. Step 2 — Connect Blackbaud via the webhook bridge

FoxFlow can POST a signed JSON event to any HTTPS URL you control whenever a lead is created, changes status, or converts. Your connector receives it and writes to Blackbaud.

5.1 Add the webhook endpoint in FoxFlow

  1. Open Org Settings → Integrations → API & Webhooks.
  2. Click Add endpoint and enter:
    • URL: your connector's HTTPS address (e.g. your Zapier/Make webhook URL, or your function URL). Must be https:// and publicly reachable.
    • Events: pick what to send. For Blackbaud most schools use:
      • lead.converted — the main one: a family has become a real enrollment prospect, create/update the constituent.
      • (optional) lead.created — if you want every raw inquiry mirrored into Blackbaud.
      • (optional) lead.status_changed — to track pipeline movement.
    • Flows: all flows, or scope to specific ones (e.g. just your "Admissions" flow).
  3. Save. FoxFlow shows the signing secret (whsec_…) exactly once — copy it now and store it in your connector. (You can rotate it later if needed.)
  4. Use the "Send test" button to fire a sample event at your connector and confirm it's wired up.
Limits worth knowing: up to 5 endpoints per org; URLs must be public HTTPS (internal/private addresses are blocked for security).

5.2 What FoxFlow sends (payload)

A POST with JSON like this:

{
  "id": "del_abc123",
  "event": "lead.converted",
  "created_at": "2026-06-20T11:30:00.000Z",
  "data": {
    "lead": {
      "id": "lead_xyz",
      "flow_id": "flow_admissions",
      "flow_name": "Admissions",
      "name": "Jane Parent",
      "email": "jane@example.com",
      "phone": "+15715551234",
      "status": "enrolled",
      "status_label": "Enrolled",
      "source": "public_form",
      "created_at": "2026-06-18T09:00:00.000Z",
      "form_data": { "grade_applying_for": "5th", "student_name": "Sam Parent" }
    },
    "previous_status": "touring",
    "previous_status_label": "Touring"
  }
}

Notes:

  • email and phone are best-effort extracted from the lead; phone is normalized to E.164.
  • form_data carries the raw inquiry fields (great place to pull student name, grade, Student ID, etc. into Blackbaud custom fields).
  • previous_status only appears on lead.status_changed / lead.converted.

5.3 Headers and verifying authenticity

Every delivery includes:

HeaderPurpose
X-FoxFlow-Eventthe event name (e.g. lead.converted)
X-FoxFlow-Delivery-Idunique delivery ID — use it as your idempotency key
X-FoxFlow-Signaturet={unix_timestamp},v1={hmac}

Verify the signature so you only accept genuine FoxFlow calls. The signature is a Stripe-style HMAC-SHA256:

v1 = HMAC_SHA256(secret = whsec_…, message = "{t}.{raw_request_body}")

Recompute v1 from the timestamp t and the exact raw body; compare to the header value. (In Zapier/Make you can do this in a code step, or rely on a shared secret path/header for a simpler setup.)

5.4 What your connector should do with Blackbaud

This is where the match-before-create logic lives (see next section for why it matters):

  1. Read email (and phone) from the payload.
  2. Search Blackbaud for an existing constituent by email, then phone.
    • Exactly one match → update it, filling blanks only.
    • No match → create a new constituent.
    • Two or more matches → don't guess; route to a human to resolve (e.g. a "needs review" list or an email to admissions).
  3. Map FoxFlow fields → Blackbaud fields (suggested mapping):
FoxFlow payloadBlackbaud constituent
name / form_data.*nameFirst / last name
emailPrimary email
phone (E.164)Primary phone
form_data.grade_applying_forCustom field / attribute
form_data (student info)Linked student record / custom fields
FoxFlow tagsCustom field or constituent list
  1. Store the resulting Blackbaud constituent ID on your side, keyed by email, so repeat events for the same family always update the same record.
  2. Respond HTTP 2xx quickly. Anything else is treated as a failure and retried (below).

5.5 Delivery reliability (built in)

You don't have to build retry logic — FoxFlow handles it:

  • Timeout: 5 seconds per attempt (respond fast; do heavy work asynchronously if needed).
  • Retries: up to 5 attempts with backoff (~5 min → 15 min → 1 hr → 6 hr).
  • Idempotency: the same X-FoxFlow-Delivery-Id may arrive more than once — dedupe on it so a retry never creates a second constituent.
  • Auto-disable: an endpoint that fails 20 times in a row is disabled (check the deliveries log in the same settings tab to diagnose).

6. Keeping records clean (no duplicates)

Keeping a single clean record per person — especially when texting is involved — is handled at three layers:

Layer 1 — Inside FoxFlow (automatic)

  • Contacts are keyed by email, so the same email can't create two contacts — it updates.
  • Lead import / re-engagement can skip duplicates by email.
  • Phone numbers are normalized to E.164 everywhere, so the same number is always stored identically.

Layer 2 — SMS / FlowSend (automatic)

FoxFlow's built-in texting (FlowSend) is designed so messaging never creates duplicates:

  • An inbound reply is matched back to the existing lead by phone number — it does not create a new lead or contact.
  • If a text matches no lead, it goes to an unmatched queue for someone to review — never auto-created as a duplicate.
  • FoxFlow guards against sending the same message twice.

Result: texting a family and getting replies will not spawn duplicate leads/contacts — so it won't push duplicate constituents to Blackbaud either.

Layer 3 — At Blackbaud (your connector — Section 5.4)

The match-before-create step is the final guard: search before you create, fill blanks instead of overwriting, store the Blackbaud ID so future updates hit the same record, and send ambiguous matches to a human. This is what honors Blackbaud's "one unique ID per individual" model.

7. The full journey (verify all the pieces are connected)

Trace one family end-to-end — this is the checklist to walk through with your team:

  1. Inquiry — a parent submits a form / Meta lead ad → a Lead appears on the Kanban board in real time.
  2. Worked — the team texts via FlowSend; replies attach to the same lead (no duplicates); the lead moves through stages.
  3. Email — if synced to Mailchimp, the family receives email campaigns; tags keep segments accurate.
  4. Converted — the lead hits the conversion status → FoxFlow stamps it converted and (if enabled) adds it to Contacts.
  5. Mailchimp sync — the contact is upserted into Mailchimp with tags. (Automatic.)
  6. Blackbaud bridge — FoxFlow fires lead.converted to your connector → it matches or creates the constituent, fills blanks, and remembers the Blackbaud ID.
  7. Enrollment — your team links/creates the student record in Blackbaud and proceeds as usual.

Checkpoints

  • Form submission creates a lead within seconds.
  • Inbound + outbound SMS both attach to the one lead.
  • Conversion creates exactly one Contact.
  • Contact appears in Mailchimp with correct tags.
  • Connector links to exactly one Blackbaud constituent.
  • Re-submitting the same email does not create a second Blackbaud record.

8. Troubleshooting

SymptomLikely causeWhat to do
Mailchimp/webhooks options missingFree plan, or not an adminConfirm a Pro plan and owner/admin role.
Contact not appearing in MailchimpMailchimp not connected, or no email on contactReconnect Mailchimp; ensure the lead has an email.
Connector never receives eventsWrong URL, endpoint disabled, or non-2xx responsesCheck the deliveries log; use Send test; verify your URL is public HTTPS.
Signature check failsHashing the wrong string, or wrong secretSign "{t}.{rawBody}" with the exact whsec_…; use the raw body, not re-serialized JSON.
Duplicate constituent in BlackbaudConnector created instead of matched, or retry not dedupedMatch by email→phone before creating; dedupe on X-FoxFlow-Delivery-Id; store the Blackbaud ID.
Endpoint got auto-disabled20 consecutive failuresFix the connector, re-enable the endpoint, re-send.
SMS reply created a "new" leadInbound phone matched no existing leadIt lands in the unmatched queue; confirm the original lead's phone is stored.
Student vs parent confusionTreating them as one recordMatch the parent as the constituent; link the student (separate Student ID) separately.
Some inquiry fields missing in BlackbaudNot mapped from form_dataPull extra fields (student name, grade, Student ID) from data.lead.form_data.

9. Who does what

TaskResponsibility
Connect MailchimpOrg admin — click Connect, pick the audience
Add the webhook endpointOrg admin — add endpoint, store the signing secret
Build & host the connector (webhook → Blackbaud)Your IT, or a Zapier/Make scenario
Blackbaud SKY API app + keysYour Blackbaud account admin
Field mapping decisionsYour team — you know your data
Matching rules (email → phone)Your team — implement in the connector
Verifying the end-to-end journeyYour team — confirm with real data
Ongoing record merges in BlackbaudYour team

Questions?

Start with the API & Webhooks deliveries log to see exactly what FoxFlow sent and how your connector responded — it's the fastest way to see which piece needs attention.

Book a Demo