-->
If your systems are consuming data from many rec-tech source APIs, chances are you’re going to want a consistent model on your end so that you can rely on that, rather than a plethora of disparate and very different source models.
One of the first problems you’re going to run into: how do I know when I need to update?
At a glance, not a particularly hard problem - but with each non-standardised API you need to integrate with: hic sunt dracones.
Fortunately Bullhorn is among the better rec-tech APIs when it comes to change, so let’s get started.
You will have various concerns depending on what you’re building, but you will definitely care about these benefits of using a unified model:
✅ Reduced Coupling and Vendor Lock-in:
✅ Simplified Business Logic:
✅ Future-Proofing:
Let’s keep things simple for now, and we’ll go into more detail in future posts. You might have a model for a placement in your system that looks a little bit like this:
public class Placement
{
public string SourceId { get; private set; }
public DateOnly StartDate { get; private set; }
public Amount Fee { get; private set; } = new Amount("GBP", 0);
public record Amount(string Currency, decimal Value);
public void SetFee(Amount amount)
{
Fee = amount;
}
public void SetStartDate(DateOnly date)
{
StartDate = date;
}
}
To keep your internal Placements in the same state as those on Bullhorn you will need to know when the last time you looked at Bullhorn was:
public class BullhornIntegration
{
public Guid Id { get; private set; }
public DateTime LastExecutedAt { get; private set; }
}
We’ve now defined what state we need for our systems, and we’ve defined where we can track when the last time we executed our integration was. Onward!
We need to query the placements collection to get our data. Here’s what your query might look like:
GET {your-bullhorn-url}/query/Placement?count=200&start=0&fields=id,customText22,dateBegin,dateLastModified,flatFee
You’re probably very familiar with this, but if not, things to note here are:
✅ Include the fields you need:
fields
section of the querystring tells Bullhorn which fields you’d like include on your placements.dateBegin
will be our StartDate
flatFee
will contain our feecustomText22
will contain our currency here. Problems with currencies? Check our other post on this!dateLastModified
will let us work our magic…✅ The structure of the data:
{
"id": 156626,
"flatFee": 13200.0,
"dateBegin": 1753675200000,
"dateLastModified": 1752187762203,
"customText22": "USD"
}
DateTime.UnixEpoch.AddMilliseconds(1753675200000)
From this we can populate our unified model, but how can we best update our models when Bullhorn changes? Step 3!
Too soon (still)?
When things change on Bullhorn you want to update your systems? Earlier we defined LastExecutedAt
on our integration. We can use that to filter our query to only include placements that were last modified after the last time we executed the integration.
GET {your-bullhorn-url}/query/Placement?count=200&start=0&where=dateLastModified > {your-last-executed-date}&fields=id,customText22,dateBegin,dateLastModified,flatFee
As always when using the Bullhorn API you’ll need to convert to Unix timestamps for dates. In C# we could do this like so:
var unitTimeMilliseconds = new DateTimeOffset(integration.LastExecutedAt).ToUnixTimeMilliseconds();
You’re left at this point to update your unified models, with whatever you’re interested in that may have changed.
Last of all - make sure you update the LastExecutedAt
date on your integration to this execution.
Of course, this says nothing of managing your own codebase, infrastructure, correctness and keeping all of this backwards compatible…