Have a Follow Up Boss Integration? Start Here
Add Every Real Estate CRM Integration in < 1 Hour (While Keeping Your Existing FUB Code)
Scenario: Your product currently talks to Follow Up Boss (FUB) directly via the FUB API. You want to add other CRMs (e.g., BoldTrail/kvCORE, Lofty, Brivity, CINC, Sierra, Real Geeks, Hubspot, Salesforce, HighLevel, etc.) without refactoring your data model.
Outcome: In under an hour, Connect more CRMs using Rollout. Keep your FUB integration as‑is. Rollout normalizes the rest; you add a thin adapter that maps Rollout records to your existing FUB‑shaped objects and routes webhook events into your current pipelines.
What You’ll Build
-
Credential connect UI to add non‑FUB CRMs.
-
Routing switch that calls Rollout for non‑FUB tenants.
-
One webhook endpoint for Rollout events that feeds your existing FUB upsert logic.
Keep using native FUB API for FUB customers. Use Rollout only for the other CRMs.
Prereqs (5–10 min)
-
Create a Rollout app (Client ID/Secret). Add:
-
ROLLOUT_CLIENT_ID
,ROLLOUT_CLIENT_SECRET
-
ROLLOUT_WEBHOOK_SECRET
-
-
Small table for Rollout connections:
tenant_id
,connection_id
,category='crm'
,provider
,status
.
Step 1 — Drop in the Connect UI (5–10 min)
Render Rollout’s credential manager on your Integrations page so customers can add CRMs beyond FUB.
// IntegrationsPage.jsx
<CredentialsManager
apiCategories={{ crm: true }}
onConnected={(conn) => saveConnection({ tenantId, connectionId: conn.id, category: 'crm' })}
/>
-
Store
connection_id
when the OAuth/API‑key flow finishes.
Step 2 — Update your FUB Code for Reads/Writes (10–15 min)
Keep your FUB client for FUB tenants. For other CRMs, call Rollout with the same FUB‑shaped payloads and responses.
// peopleService.ts (minimal, no client wrapper)
import fetch from 'node-fetch';
async function rolloutHeaders(tenantId: string, credentialId: string) {
const authToken = await getRolloutToken(tenantId); // server-side per Rollout docs
return {
Authorization: `Bearer ${authToken}`,
'x-rollout-credential-id': credentialId,
'Content-Type': 'application/json'
};
}
export async function listPeople(tenantId: string) {
const cred = await getActiveCrmCredential(tenantId);
if (cred?.provider === 'fub') return fubClient.listPeople();
const res = await fetch('https://crm.universal.rollout.com/api/people', {
headers: await rolloutHeaders(tenantId, cred.credentialId)
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || 'Failed to fetch people');
return data.items; // same shape you already use
}
export async function createPerson(tenantId: string, fubPayload: any) {
const cred = await getActiveCrmCredential(tenantId);
if (cred?.provider === 'fub') return fubClient.createPerson(fubPayload);
const res = await fetch('https://crm.universal.rollout.com/api/people', {
method: 'POST',
headers: await rolloutHeaders(tenantId, cred.credentialId),
body: JSON.stringify(fubPayload)
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || 'Failed to create person');
return data; // same shape
}
Tip: Keep your domain types untouched. Just pick the right client based on the active connection.
Step 3 — One Webhook for All Non‑FUB CRMs (10 min)
Subscribe connections to Rollout webhooks. Verify HMAC, fetch via uri
, then run your existing FUB upsert.
// webhooks/rollout.ts
app.post('/webhooks/rollout', verifyHmac(ROLLOUT_WEBHOOK_SECRET), async (req, res) => {
const { event, uri } = req.body; // e.g., peopleCreated, peopleUpdated, peopleDeleted
// Identify the tenant & related credential for this webhook (use your own mapping)
const { tenantId, credentialId } = await resolveTenantAndCredential(req);
const resp = await fetch(uri.startsWith('http') ? uri : `https://crm.universal.rollout.com${uri}`, {
headers: await rolloutHeaders(tenantId, credentialId)
});
const data = await resp.json();
if (!resp.ok) throw new Error(data.error || 'Fetch via webhook URI failed');
for (const item of data.items) {
await upsertPerson(item); // same handler you use for FUB
}
res.sendStatus(200);
});
Event names and payloads match your FUB expectations for CRM entities.
Optional — Extra Entities (5 min)
If you already support FUB tasks/notes/emails/calls, enable them for Rollout connections and reuse the same code paths (same shapes & event names).