Webhooks

Use webhooks to be notified about events that happen in a Follow Up Boss account.

🚧

Require Owner Permissions

Only the owner has access to Webhooks.

Webhooks post JSON to a specific URL every time an event listed below is triggered. Webhooks remove the need to poll for changes. When an event occurs--for example a person is assigned to a different agent, this event will be sent to your system as an HTTP POST to the webhook URL configured for the peopleUpdated event.

Examples of what you might use webhooks for:

  • Update a person's name in your database when it is changed in Follow Up Boss
  • Update a person's email or phone in your database when it is changed in Follow Up Boss
  • Re-assign a person in your system when it is re-assigned in Follow Up Boss
  • When a Zillow lead is added to Follow Up Boss you add it to your IDX search website

📘

Batch Updates

The following actions can result in a large number of people updates:

  • Tags added or removed
  • Stage updated
  • Source updated
  • Agent re-assigned
  • Lender re-assigned

If one of these actions result in a large number of people being updated, the webhook event notification may be split into multiple requests.

Supported webhook events

People

peopleCreated, peopleUpdated, peopleDeleted, peopleTagsCreated, peopleStageUpdated,peopleRelationshipCreated,peopleRelationshipUpdated,peopleRelationshipDeleted

peopleUpdated

One or more of the following fields are updated in a person:

  • Name name firstName lastName
  • Emails emails
  • Phone Numbers phones
  • Address addresses
  • Price price
  • Background background
  • Assigned Agent assignedTo assignedUserId
  • Assigned Lender assignedLenderName assignedLenderId
  • Contacted contacted
  • Stage stage stageId
  • Lead Source source sourceUrl
  • Tags tags
  • Custom Fields
  • Relationship is created, updated, or deleted

📘

Custom Fields

If you want to view custom field data following a peopleUpdated event, make sure you add the query parameter fields=allFields to your GET /people request, custom fields are not returned by default.

peopleDeleted

When a person is deleted all associated data is deleted as well e.g. notes, calls, text messages, etc. There will not be any delete events triggered for these resources when this happens.

JSON sample of event notification:

{
    "eventId": "64d0ad74-3aab-4b30-89c9-7337398cf8b4",
    "eventCreated": "2016-12-12T15:19:21+00:00",
    "event": "peopleDeleted",
    "resourceIds": [1234,5322,29456],
    "uri": null
}

peopleTagsCreated

When a tag is added to a person, the payload will include the name of the new tag. Multiple tags and person ids may be included. Note: The webhook will fire regardless of whether a tag was previously removed and re-added to a contact.

JSON sample of event notification:

{
    "eventId": "e8d9f150-5dac-4c53-8c0f-06560dc4ec08",
    "eventCreated": "2019-07-01T17:22:28+00:00",
    "event": "peopleTagsCreated",
    "resourceIds": [
        40773,
        40772
    ],
    "uri": "https://api.followupboss.com/v1/people?id=40773,40772",
    "data": {
        "tags": [
            "Kingsbury"
        ]
    }
}

peopleStageUpdated

When a person's stage is updated, the payload will include the name of the new stage.

JSON sample of event notification:

{
    "eventId": "e0ac086a-879a-4d8b-869a-fe53151e34f4",
    "eventCreated": "2019-07-01T17:12:32+00:00",
    "event": "peopleStageUpdated",
    "resourceIds": [
        40942
    ],
    "uri": "https://api.followupboss.com/v1/people?id=40942",
    "data": {
        "stage": "Free Trial"
    }
}

Notes

notesCreated, notesUpdated, notesDeleted

Emails

emailsCreated, emailsUpdated, emailsDeleted

Tasks

tasksCreated, tasksUpdated, tasksDeleted

Appointments

appointmentsCreated, appointmentsUpdated, appointmentsDeleted
These webhooks only fires when the appointment was created in Follow Up Boss, not when we sync appointments created on Integrated Calendars (i.e. Google or Office 365 calendars).

Text Messages

textMessagesCreated, textMessagesUpdated, textMessagesDeleted

Calls

callsCreated, callsUpdated, callsDeleted

Email Marketing Events

emEventsOpened
People open an email marketing email.

emEventsClicked
People click a link in an email marketing email.

emEventsUnsubscribed
People unsubscribe from email marketing emails.

Deals

dealsCreated, dealsUpdated, dealsDeleted

People Events

eventsCreated
People perform an action on your IDX website, e.g. view a property.

Registering a webhook

Send an HTTPS POST to the /v1/webhooks endpoint with a JSON object that specifies the event and callback URL.

POST /v1/webhooks HTTP/1.1
Content-Type: application/json
X-System: AcmeLeadProvider
...
{
  "event": "peopleCreated",
  "url": "https://acmeLeadProvider.com/callbacks/fub/peopleCreated"
}

The response will be JSON encoded representation of the webhook created.

{
  "id": 1244,
  "status": "Active",
  "event": "peopleCreated",
  "url": "https://acmeLeadProvider.com/callbacks/fub/peopleCreated"
}

🚧

Limited number of webhooks per event

There is a limit to the amount of web hooks per event which can be registered. Unused webhooks should be disabled to prevent hitting the limit. If multiple endpoints for an event are desired, a single web hook should be registered which in turn handles the fan out to multiple endpoints. Keep in mind the best practices below about de-coupling the message receiving and workload so that the initial call does not timeout.

❗️

HTTPS Only

Callback URLs must be a secure endpoint

❗️

X-System Header is Required

The X-System HTTP Header is required for all requests to /v1/webhooks endpoints.

See /webhooks for detailed documentation of the /v1/webhooks endpoint.

Receiving webhook events

Create an endpoint that accepts HTTP POST requests at the URL specified in the registered webhook. The body of the request will be JSON encoded. To acknowledge the receipt, your endpoint should respond within 10 seconds with a 2XX HTTP status code such as 200 or 204. Any other response will indicate that you did not receive the webhook and we will continue to retry at various intervals for up to 8 hours.

For example, the endpoint at https://acmeleadprovider.com/callbacks/fub/peoplecreated would receive the following HTTP POST when a person is created in Follow Up Boss:

POST /callbacks/fub/peoplecreated HTTP/1.1
Content-Type: application/json
...
{
  "eventId": "152d60c0-79da-4018-a9af-28aec8a71c94",
  "eventCreated": "2016-12-12T15:19:21+00:00",
  "event": "peopleCreated",
  "resourceIds": [1234,3244,3232],
  "uri": "https://api.followupboss.com/v1/people?id=1234,3244,3232"
}

Verify the request

With each request, we pass along a FUB-Signature header. You can use this string value to verify the request is from us using your X-System-Key provided when you registered your system.

You will want to base64 encode the JSON payload you received from the request (non-prettified), then produce a SHA256 hash with this base64 encode value and your X-System-Key , this value should match the FUB-Signature value.

function isFromFollowUpBoss(string $context, string $signature): boolean {
    $calculated = hash_hmac('sha256', base64_encode($context), YOUR_X-SYSTEM-KEY);

    return $signature === $calculated;
}

if (isFromFollowUpBoss($jsonPayload, $signatureFromHeader)) {
    // do something
}

Handling webhook events

The endpoint that handles events should do an HTTP GET to the resource URI specified in the event. Then compare the response to the local database and apply changes that are found. The response format for the people endpoint can be found at /people

See the code samples below for handling webhook events:

<?php
const FUB_API_KEY = 'API Key for an Admin user in the Follow Up Boss Account';

// Retrieve the request's body and parse it as JSON
$input = @file_get_contents("php://input");
$event_json = json_decode($input);

$event = $event_json->{'event'};
$resource_uri = $event_json->{'uri'};

// for peopleCreated and peopleUpdated events fetch the people
// at the resource URI

$curl = curl_init($resource_uri);

$headers = array(
    'Authorization: Basic '. base64_encode(FUB_API_KEY . ":")
);

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($curl);
curl_close($curl);

$remote_records = json_decode($result);

// Compare the remote record with your local record

http_response_code(200); // PHP 5.4 or greater

echo('OK');

Requesting webhook events

Individual webhook events can be requested from /webhookEvents/:id . This can useful if your system was unavailable to receive events for some reason and there are events older than 3 days that were missed.

🚧

Webhook Event Retries

If your system is unavailable or responds with an HTTP status code other than 2XX such as 200 or 204, FUB will continue to retry for up to 8 hours. HTTP status codes of 406 or 410 result in the webhook being disabled.

Webhook best practices

Setup your system to de-couple receiving webhook events from fetching the resource specified in the event. For example--the web service that receives events could record the event in a local database table. A separate backend process could be created to monitor this table for new rows and fetch the resource specified in the event. By separating these, the web service that handles receiving webhooks is doing less and is, therefore less likely to fail. The process that processes the events can contain all the complex logic to fetch the resource from Follow Up Boss, reconcile with your local system and mark the event as processed in the table. If this process fails or breaks it can be debugged independently of the web service. The table that stores events is the source of truth as to what webhook events have been received and processed.

Debugging webhooks

Since webhooks require a publicly accessible URL to function they can be hard to test from your local machine. It is recommended that you use a service like Request Bin when you are developing your webhook endpoints.

Common webhook mistakes

  • Make sure you provide the correct URL when registering a webhook. You can list all your webhooks at the /webhooks endpoint.
  • Make sure the webhook endpoint is returning a 2XX HTTP status code such as 200
  • When registering a webhook make sure you are setting the X-System header. You can also include the system param in the query string or post data. For example: https://api.followupboss.com/v1/webhooks/32?system=AcmeCo
  • If you are setting up webhooks for multiple Follow Up Boss accounts be sure to include a Follow Up Boss account identifier in the registered webhook URLs. Your webhook URLs should look like this: https://acmeLeadProvider.com/callbacks/fub/account12/peopleCreated or https://acmeLeadProvider.com/callbacks/fub/peopleCreated?fub_account=12