Rex Automaton
All posts
CRM & Pipeline AutomationSeptember 25, 20269 min read

Follow Up Boss AI Calling Writeback: Sync Outcomes & Recordings

How we log AI dialing outcomes into Follow Up Boss: POST /v1/calls with disposition, duration, and recordingUrl, update stage/owner, and use /v1/events for routing so reps never double-enter.

By Jacky Lei

We built an AI-calling writeback that logs every outcome into Follow Up Boss: POST /v1/calls with disposition, duration, and a recordingUrl, plus stage and owner updates on the person, and POST /v1/events for new-lead routing. In production it removed double entry for real estate teams while preserving clean routing and action plans.

Definition: Follow Up Boss AI calling writeback is a service that converts AI dialer results into native FUB calls, recordings, and person updates so automations fire without reps retyping notes.

The problem it solves

Sales teams lose time copying call outcomes and links into the CRM. When AI dialers run outside the CRM, agents still have to select a disposition, paste a recording link, and update stage or owner. That delay hurts speed to lead and breaks action plans.

A Harvard Business Review study found contacting a lead within five minutes makes reps 21 times more likely to qualify that lead versus waiting 30 minutes. Source: https://hbr.org/2011/03/the-short-life-of-online-sales-leads

TaskManual workflowAutomated writeback
Log the callAgent opens FUB, selects contact, clicks Log Call, types notesService POSTs /v1/calls with outcome, duration, notes, recordingUrl
Save recordingPaste cloud link, hope it is not private or expiredRecording URL stored with the call, consistent host policy
Update stage/ownerAgent changes Stage or reassignsPUT /v1/people applies stage or owner rules on outcome
Trigger plansManually start an action planPOST /v1/events fires routing and plans automatically
DeduplicateHope no duplicate calls or contactsWebhooks confirm writebacks and reconcile IDs

How the automation works

Our architecture sits between the AI dialer and FUB. The dialer emits a structured result. We normalize it to FUB's allowed call outcomes, create the call with POST /v1/calls, update the person's stage or owner when rules require it, and use POST /v1/events for any net-new lead so FUB deduplicates and routes correctly. Webhooks from FUB close the loop for idempotency and audit.

  • AI dialer result: contains phone, external lead ID, disposition, duration, transcript path, and recording URL. We never guess dispositions at write time; we map them to FUB's allowed values.
  • Follow Up Boss REST API: Basic Auth with the API Key as username, blank password, plus X-System and X-System-Key headers. OAuth 2.0 Authorization Code is also supported for partner apps. We use POST /v1/calls, PUT /v1/people, and POST /v1/events.
  • Webhooks and reconciliation: we subscribe to events like callsCreated and peopleStageUpdated. We fetch with fields=allFields when we need custom fields after a peopleUpdated.
  • Routing via events: we do not create people directly for inbound leads. We send a lead event so FUB auto-assigns agents, fires action plans, and de-duplicates.
  • Rate-limit safety: we respect 429 with Retry-After and batch low-volume updates into sliding 10-second windows.

AI dialer to FUB writeback: outcomes and recordings flow through a writeback service into Follow Up Boss calls and events, which trigger automations and routing

Step-by-step: how to build it

1) Authenticate to Follow Up Boss

Use HTTP Basic with the API Key as the username and an empty password. Include your registered system headers. We prefer a server-side service account.

curl -X GET \
  https://api.followupboss.com/v1/people \
  -u "$FUB_API_KEY:" \
  -H "X-System: your-system-name" \
  -H "X-System-Key: your-system-key"

Key gotcha: production partner apps can also use OAuth 2.0 Authorization Code. We use Basic for server-to-server flows and rotate keys on a schedule.

2) Normalize AI dialer outcomes to FUB dispositions

Map your dialer's dispositions to FUB's allowed outcomes before logging the call. Keep this list in code and fail closed on unknowns.

const mapDisposition = d => ({
  CONNECTED: "answered",
  VOICEMAIL: "voicemail_left",
  NO_ANSWER: "no_answer",
  BUSY: "busy",
  WRONG_NUMBER: "wrong_number"
}[d] || "other");

Key gotcha: if you send an unsupported outcome, the API will reject or coerce it. Always map explicitly.

3) Log the call with POST /v1/calls

Send duration, outcome, notes, and a stable recordingUrl. Attach person and user IDs as appropriate.

curl -X POST https://api.followupboss.com/v1/calls \
  -u "$FUB_API_KEY:" \
  -H "Content-Type: application/json" \
  -H "X-System: your-system-name" \
  -H "X-System-Key: your-system-key" \
  -d '{
    "personId": 123456,
    "userId": 7890,
    "outcome": "answered",
    "duration": 142,
    "recordingUrl": "https://calls.example.com/r/abc123.mp3",
    "note": "Reached lead. Confirmed interest. Send follow-up deck."
  }'

Key gotcha: host recordings where URLs will not expire immediately. If your provider rotates links, mint a long-lived proxy URL.

4) Update stage and owner when rules require it

Use PUT /v1/people after a qualifying outcome to move stage or reassign the owner.

curl -X PUT https://api.followupboss.com/v1/people/123456 \
  -u "$FUB_API_KEY:" \
  -H "Content-Type: application/json" \
  -H "X-System: your-system-name" \
  -H "X-System-Key: your-system-key" \
  -d '{
    "stage": "Hot",
    "assignedTo": 7890
  }'

Key gotcha: if your playbooks depend on action plans, consider using events to trigger them rather than only mutating stage.

5) Route new leads with POST /v1/events

Do not create contacts with POST /v1/people if you want native routing, de-duplication, and action plans. Send an event instead.

curl -X POST https://api.followupboss.com/v1/events \
  -u "$FUB_API_KEY:" \
  -H "Content-Type: application/json" \
  -H "X-System: your-system-name" \
  -H "X-System-Key: your-system-key" \
  -d '{
    "type": "new_inquiry",
    "source": "AI Dialer",
    "person": {
      "firstName": "Alex",
      "lastName": "Buyer",
      "phones": [{"value": "+16045551234"}],
      "emails": [{"value": "alex@example.com"}]
    }
  }'

Key gotcha: events handle dedupe and assignment automatically. Creating people directly can bypass routing.

6) Handle webhooks and rate limits

Listen for callsCreated and peopleStageUpdated to reconcile state. Respect Retry-After on 429 to stay within the sliding 10-second window.

app.post('/webhooks/fub', async (req, res) => {
  const evt = req.body;
  if (evt.event === 'callsCreated') {
    // mark external call-id as synced
  }
  if (evt.event === 'peopleStageUpdated') {
    // update local stage cache or trigger follow-ups
  }
  res.sendStatus(200);
});
 
async function fubFetch(url, opts = {}) {
  const res = await fetch(url, opts);
  if (res.status === 429) {
    const retry = parseInt(res.headers.get('Retry-After') || '2', 10) * 1000;
    await new Promise(r => setTimeout(r, retry));
    return fubFetch(url, opts);
  }
  return res;
}

Key gotcha: only the account Owner can manage webhooks. Coordinate setup with the FUB owner user.

7) Pull full person fields when you need custom data

After peopleUpdated, fetch with fields=allFields to include custom fields.

curl -G https://api.followupboss.com/v1/people \
  -u "$FUB_API_KEY:" \
  -H "X-System: your-system-name" \
  -H "X-System-Key: your-system-key" \
  --data-urlencode "id=123456" \
  --data-urlencode "fields=allFields"

Key gotcha: custom fields are not returned by default. Use the query flag when your downstream rules depend on them.

Where it gets complicated

  • Disposition vocabulary alignment: the dialer's result labels rarely match FUB's allowed outcomes. We solved this with a strict mapper and a fail-closed policy that blocks unknown values instead of guessing.
  • Recording URL lifetime: many telephony vendors issue short-lived links. We front a stable recordingUrl through our domain so the link on the FUB call does not die a day later.
  • Events vs people creates: if you create people directly, routing and action plans will not fire the way teams expect. POST /v1/events is the safe path for new leads.
  • Webhook ownership and custom fields: only the FUB Owner can manage webhooks and custom fields are omitted unless you request fields=allFields. Without this, your stage logic will act on incomplete data.
  • Rate limits and bursts: FUB uses sliding 10-second windows. We saw 429s during large backfills and added an exponential backoff that honors Retry-After to keep writebacks smooth.
  • API key hygiene: one client's stale key caused 401s on more than 580 writebacks until rotated. We added a key-rotation check and alerting after any 401 series to prevent silent drops.

What this actually changes

In production for a real estate brokerage, our AI dialer and writeback stack processed 3,130 of 3,130 callable leads and recorded 5,573 total calls, with outcomes and recordings written to Follow Up Boss so agents did not double-enter. After we tightened classification prompts and added server-side guards, no new false bookings were observed and stage updates reflected ground truth.

Sales time is the goal. Salesforce reported reps spend only about 28 percent of their week actually selling, with the rest on non-selling work like admin and data entry. Source: https://www.salesforce.com/resources/research-reports/state-of-sales/

By logging outcomes, recordings, and stage changes automatically, the AI dialer becomes an activity engine that feeds FUB without adding work to the team. Action plans and routing fire as if a human had done the logging, but faster.

Frequently asked questions

Does Follow Up Boss have an API for call logging?

Yes. Follow Up Boss exposes a v1 REST API. You can log calls with POST /v1/calls, update people with PUT /v1/people, and send new-lead routing with POST /v1/events. Authentication supports HTTP Basic with an API Key and OAuth 2.0 Authorization Code for partner apps.

Will this auto-assign agents and start action plans?

For new leads, send POST /v1/events instead of creating people directly. Events let FUB de-duplicate, auto-assign, and fire action plans according to your rules. For existing people, you can still update stage and owner via PUT /v1/people.

Can it save call recordings in FUB?

Yes. Include a stable recordingUrl when you POST /v1/calls. If your telephony host issues short-lived links, proxy them so the URL on the FUB call remains accessible for QA and coaching.

How do you prevent duplicates or missed updates?

We confirm every write with webhooks like callsCreated and peopleStageUpdated, and we reconcile IDs locally. For new leads we use POST /v1/events so Follow Up Boss handles de-duplication.

Does this work in real time?

Effectively yes. The writeback runs immediately after the AI dial completes. Follow Up Boss webhooks return confirmation almost instantly, subject to rate limits. We back off on 429 and retry per Retry-After.

What does it cost to run monthly?

The FUB API has no per-call charge. Your cost is the dialer minutes, any LLM classification spend, and modest hosting. Most teams see the time saved outweigh those costs because reps are not retyping notes or pasting links.

If you run AI calling and want outcomes, recordings, and routing written into Follow Up Boss without agents doing double entry, we have shipped this in production. See our related breakdown on automating Follow Up Boss AI calling, explore our CRM automation services, or book a 15-minute call.

Want us to build this for you?

Nine questions, about 90 seconds. You see the hours it is costing you, then pick a time. No pitch.

Get your free assessment

Related reading