Bullhorn Workflow Automation: A Practical Guide

TL;DR: Bullhorn Automation is built on one pattern, trigger then conditions then action, and almost every problem agencies have with it is configuration rather than product. The two that do the most damage are using "field equals X on save" where you meant "value changes to X", which re-fires every time the record is saved, and building rules with no exclusion conditions, so the next bulk import emails 3,000 historical candidates. It has no conditional branching, no outbound webhook and no cross-object logic, so anything that needs those belongs in an external orchestration layer rather than in Bullhorn.
This guide covers the actual architecture of Bullhorn workflow automation, the five sequences UK agencies build first, where the configuration goes wrong, and where Bullhorn Automation runs out of road and you need something else. It's written from the build side, not the sales side.
If you're an ops manager, a CRM admin, or a consultant who's been handed the Bullhorn keys, this is the practical reference I wish existed when I started building these.
How is Bullhorn Automation structured?
Bullhorn Automation - the product formerly known as Herefish before Bullhorn acquired it - is built around three components: triggers, conditions, and actions. Every automation you build is a variation on the same pattern: something happens (trigger), filter which records it applies to (conditions), then do something (action).
Triggers are event-based. The main types you'll work with are: record creation, field value change, list membership change, and date-relative triggers (e.g. "7 days before placement end date"). The distinction that matters most - and causes the most problems - is between "value changes to X" and "field equals X on save". The first fires only when the field transitions to that value. The second fires every time the record is saved while that value is present. These behave completely differently, and the UI doesn't make the difference obvious. More on this in the mistakes section.
Conditions sit between the trigger and the action. They use AND/OR logic with field-level filters - for example: candidate status equals "Placed", job type equals "Contract", record owner equals a specific user. Worth noting that condition depth is flat. You cannot build nested logic. There's no "if A is true, check B, else check C" - that kind of branching requires two separate automations with inverse conditions, or an external tool.
Actions include: send email, send SMS, update a field, create a task, add to a list, remove from a list. Actions can be chained with delays, which is how you build multi-step sequences - for example, send an email at T+0 and create a follow-up task at T+96 hours.
That's the mental model. Trigger → conditions → action. Everything else is configuration detail.
The five Bullhorn workflow automations UK agencies build first
New applicant intake acknowledgement
Trigger: record created on the Application object - not the Contact object. This distinction matters. Agencies that set this on Contact creation fire it at every candidate they've ever imported.
Condition: source is not "Internal Referral" (avoids sending to staff put forward internally).
Action: send candidate acknowledgement email immediately.
Simple automation, frequently misconfigured. If you're seeing acknowledgement emails going to candidates who applied three years ago, the trigger object is wrong.
Compliance document chasing
Trigger: candidate status changes to "Placed" (or your instance's equivalent - worth noting that most agencies customise status labels, so verify the exact field value before you build).
Conditions: compliance document field is empty OR document expiry date is null.
Action: send chase email at +48 hours, not immediately. Give the consultant a window to upload what they already have. Create a follow-up task assigned to record owner at +96 hours.
The +48 hour delay is important. Firing immediately means you're chasing for documents the consultant uploaded ten minutes after placement confirmation.
Interview confirmation sequence
Trigger: appointment record created (the calendar/interview object in Bullhorn).
Conditions: interview type equals "First Interview", status equals "Scheduled".
Actions: confirmation email to candidate immediately; reminder email at -24 hours relative to the interview datetime.
The -24 hour reminder requires a date-relative trigger, not an event trigger. These are set up differently in the UI - if you try to build this as a standard event trigger you won't get the timing right.
Post-placement check-in task
Trigger: date-relative, 5 working days after placement start date.
Condition: placement status equals "Active".
Action: task created for the consultant to call the candidate.
I'd keep this as a task rather than an automated message to the candidate. The first week of a placement is when most issues surface - you want a human making that call, not an automated email that lands regardless of how the start went.
Contract renewal reminder
Trigger: date-relative, 28 days before placement end date.
Conditions: placement type equals "Contract", placement status equals "Active".
Actions: task assigned to consultant at 28 days; second task at 14 days if the first task hasn't been completed.
The conditional follow-up at 14 days - checking whether the first task was completed - is where some agencies hit a wall with Bullhorn Automation alone. If you need that conditional logic, you're looking at an external tool to check task status and branch accordingly.
Contract vs. permanent vs. healthcare: where the logic differs
Contract
Date-triggered logic dominates. The key fields are end date, start date, and timesheet submission deadlines. Renewal reminders at 28 and 14 days are standard. Timesheet chasing - firing on Monday morning if no timesheet has been submitted for the prior week - sounds straightforward but requires a "no action taken by date X" condition. Bullhorn Automation struggles here. You generally need a calculated field updated by an external process, or a separate tool polling Bullhorn on a schedule to check submission status.
Permanent
Status-change logic matters more than date logic. The useful automations are: task creation when a candidate reaches "Offer" stage and no offer amount is recorded on the placement, or a feedback request to the hiring manager 24 hours after an interview record is marked "Completed". The failure mode on perm desks is over-automating early-stage candidate touchpoints. If a candidate gets an automated acknowledgement, an automated screening request, and an automated stage-update email before a human has read their CV, response rates to genuine outreach drop. Automate the logistics, not the relationship.
Healthcare
Healthcare adds a compliance layer that contract and perm don't have. DBS renewal reminders (date-relative off DBS expiry date, fire at 90 and 30 days), professional registration expiry (NMC, HCPC - same pattern), mandatory training records. Worth noting that healthcare agencies typically have more automation rules active than any other recruitment vertical - and they're also the most likely to have conflicts and gaps, because the rules have been built incrementally over years by different people with different naming conventions. An audit before you touch anything is not optional in healthcare.
The practical filter before you start building: is your desk date-logic-heavy or status-change-heavy? Contract is mostly date logic. Perm is mostly status logic. Healthcare is both, plus a compliance layer on top. Map that first, then decide where to start.
What are the most common Bullhorn Automation configuration mistakes?
Four mistakes account for most of the damage: dirty triggers that fire on every record save rather than on a genuine state change, missing exclusion conditions that let a bulk import email thousands of historical candidates, over-automated early-stage candidate touchpoints, and tasks created without a dynamic owner so nobody picks them up. None of these are product limitations. All four show up in the automation logs before anyone complains about them.
1. Dirty triggers - automations firing on every save. If you set your trigger as "candidate status = Placed" (field equals, on save) rather than "candidate status changes to Placed" (value changes to), the automation re-fires every time the record is saved while the status is still Placed. A candidate on a 6-month contract whose record gets touched regularly can receive the same compliance email 40 or 50 times. The fix is straightforward - use the "value changes to" trigger type - but the UI presents both options without making the behavioural difference obvious, and this is the mistake I see most consistently on inherited Bullhorn instances.
2. Missing exclusion conditions. An agency builds a new applicant email automation and it runs cleanly for months. Then someone does a bulk import of 3,000 historical candidates to clean up the database. The automation fires on all 3,000 of them. Exclusion conditions - source is not "Bulk Import", date added is after your go-live date, email opt-in status is confirmed - need to be designed into every automation from the start. They're not something you add after the first incident.
3. Over-automating early-stage candidate touchpoints. There's no hard rule here, but the pattern is consistent. Automated contact at application, acknowledgement, and initial screening stages feels like efficiency. In practice, it erodes response rates when a real person eventually reaches out, because the candidate has already mentally categorised your messages as automated. Save the automation for the stages that are genuinely admin-heavy - compliance, logistics, renewal reminders - and keep the early relationship-building steps human.
4. Task routing without dynamic ownership. Creating a task "for the consultant" without specifying a dynamic owner means it routes to a default user or sits in a queue nobody monitors. Always set task owner to "record owner" using the dynamic field option - Bullhorn supports this in the action configuration. If the record has no owner (common on inbound applications before assignment), set a fallback - a named ops user or a team inbox. A task with no clear owner is the same as no task.
What can Bullhorn Automation not do?
Bullhorn Automation cannot branch conditionally inside a single rule, cannot push data out to another system when a trigger fires, and cannot build cross-object logic. Its email builder also has no dynamic content blocks or conditional HTML. Everything that happens inside Bullhorn, meaning record-level triggers, emails and SMS, task creation and field updates, it handles well. Those four gaps are where an external orchestration layer takes over.
Bullhorn Automation has hard limits that are worth being clear about before you start designing complex sequences.
There's no conditional branching within a single automation. If X is true, do A; if X is false, do B - that requires two separate automations with inverse conditions. Manageable for simple cases, but it creates maintenance overhead and increases the risk of gaps or overlaps as your rule set grows.
There's no native outbound webhook. Bullhorn Automation can't push data to an external system when a trigger fires. It operates within Bullhorn. If you need a Slack notification to fire when a placement goes Active, or an invoice record created in Xero when a placement is confirmed, Bullhorn Automation can't do that.
Email formatting is limited. There's no support for dynamic content blocks or complex conditional HTML. What you see in the email builder is broadly what you get.
Cross-object logic is not available. You can't build a rule that says "when a placement is created, check the associated company's credit status in your finance system and branch accordingly."
This is where n8n (or Zapier, if you're not running volume) picks up the slack. Three patterns I'd implement with an external orchestration layer:
Bullhorn API polling every 5 minutes → n8n → Slack alert to #placements channel when placement status changes to Active. Fast, reliable, keeps the team informed without anyone needing to check Bullhorn.
Placement created in Bullhorn → n8n → create draft invoice in Xero with placement details pre-populated. Reduces manual finance admin on every new placement.
Candidate DBS expiry date approaching → n8n → check current compliance status via Bullhorn API, select the correct email variant based on what's missing, send it, and write a log entry back to the candidate record. This is a sequence that Bullhorn Automation can approximate with multiple separate rules, but n8n handles it in one workflow with proper branching.
The principle is straightforward: use Bullhorn Automation for record-level triggers, standard emails and SMS, task creation, and field updates within Bullhorn. Bring in an external orchestration layer when you need conditional branching, multi-system logic, or output that Bullhorn's email builder can't produce. Worth noting that the Bullhorn Marketplace has native connectors for tools like Cube19 and Idibu - but these are data sync integrations. They're not workflow automation and they don't replace the orchestration layer.
How do you audit Bullhorn automations that are already running?
Build a full inventory before you change anything: every active rule with its trigger object, trigger type, condition summary, last modified date and creator. Then read the log data for three tells: zero sends in the last 90 days, send volumes higher than the record count justifies, and rules with no conditions at all. Check as well for two automations sharing a trigger object and trigger type with overlapping conditions. Treat an inherited automation the way you would treat inherited production code and understand it before you touch it.
Most agencies that have had Bullhorn for more than two years have active automations that nobody on the current team remembers building. Inherited automations are high-risk to ignore and even higher-risk to touch without understanding first.
Start with a full inventory. In the Automation module, filter by status (active/inactive) and document every rule: name, trigger object, trigger type, condition summary, last modified date, created by. If you can export this list, do it. If not, build a spreadsheet manually - you need the full picture before you change anything.
Then look at the log data. Flag three patterns immediately:
Zero sends in the last 90 days - the automation may be broken, or the trigger condition is structured in a way that's never met.
Unusually high send rates relative to what you'd expect - often a dirty trigger firing on every record save rather than on a genuine state change.
Automations with no conditions at all - these fire on every instance of the trigger object with no filtering. If the trigger is "candidate record saved", that's firing constantly.
Check for conflicts: two automations on the same trigger object and trigger type with overlapping conditions. A common example is two separate automations both triggered by "candidate status changes to Placed" - if the conditions overlap even partially, both fire and the candidate gets duplicate emails.
Before touching anything live, ask: is this automation part of a compliance-critical sequence? Who built it and when? Is there a suppression or opt-out list associated with it? What breaks downstream if it stops firing? Treat an inherited automation the same way you'd treat inherited code in production. You don't refactor it before you understand what it does.
What should you not automate in Bullhorn?
Three things: rejection communications with no human review step, first-contact outreach to cold or imported candidates who have not confirmed marketing consent, and any rule built on a field consultants routinely leave blank. Each of those fails for the same underlying reason. A Bullhorn automation is only ever as reliable as the data feeding it.
Rejection communications without a human review step. Automated rejections fire on a status change. If that status value is used inconsistently across desks - and it usually is - candidates get rejection emails for roles they were actually being considered for. I've seen this happen. It's recoverable but it damages trust with the candidate and creates a support burden for the consultants who then have to explain what went wrong.
First-contact outreach on cold or imported candidates. If a candidate has been in the database for two or three years without recent engagement and hasn't confirmed marketing consent, an automated email is a GDPR issue. The data quality has to be verified before any outreach automation fires on that segment. Running a list-clean and consent check first is not optional - it's what makes the automation legal.
Anything built on a field with low completion rates. If your "placement end date" field is routinely left blank because consultants forget to fill it in, a renewal reminder automation built on that field will either never fire or fire at the wrong time when a date is eventually added. Automating a broken process doesn't fix the process. Check the field completion rate before you build the rule. If it's below around 80%, the automation will be unreliable and you'll spend more time investigating misfires than the automation saves.
The automation is only as reliable as the data feeding it. That's not a caveat - it's the primary constraint on every Bullhorn workflow automation project. Fix the field completion rate first, then build the rule.
If you're not sure which of your current automations are working correctly, which are conflicting with each other, or where the data gaps are that will cause problems when you start building, that's exactly what a Bullhorn systems audit covers.