Recruitment BPMN example
Recruitment covers the path from an approved vacancy to an accepted offer, and it is mapped because it leaks time at every handoff: adverts sit unposted, applications wait for screening, and offers stall in inboxes while candidates accept jobs elsewhere. Writing the process down exposes who owns each wait and where candidates fall out of the funnel.
This example uses two pools: a Recruitment pool with Hiring manager, Recruiter, and Interview panel lanes, and a black box Candidate pool with no visible internals. The candidate is a genuinely independent participant, so message flows (the offer letter out, the acceptance back) cross between the pools while sequence flows stay inside. Notice that both rejection points route into the same regret email task rather than duplicating it.
Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.
The process at a glance
How to read this diagram
A vacancy approval in the Hiring manager lane starts the process. The Recruiter posts the job advert and screens the applications that come in, leading to the exclusive gateway "Candidate shortlisted?". Its No branch, the default flow, goes to the "Send regret email" task and the "Candidate rejected" end event. On the Yes branch the Interview panel runs interviews, after which the Hiring manager answers a second gateway, "Offer the role?". A No there joins the same regret path.
When the answer is Yes, the Recruiter sends the offer letter, shown as a send task with a message flow to the Candidate pool. The process then waits at the "Offer accepted" message catch event until the candidate replies, with the acceptance arriving as a message flow from the Candidate pool. The flow closes at the "Candidate hired" end event, so every token ends either in a hire or a polite rejection.
BPMN elements used
| Element | Count | In this diagram |
|---|---|---|
| Start event | 1 | Vacancy approved |
| End event | 2 | Candidate rejected, Candidate hired |
| Intermediate catch event | 1 | Offer accepted |
| Task | 1 | Post job advert |
| User task | 2 | Screen applications, Run interviews |
| Send task | 2 | Send regret email, Send offer letter |
| Exclusive gateway | 2 | Candidate shortlisted?, Offer the role? |
View the BPMN 2.0 XML for this diagram
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="swimdraft" exporterVersion="1.0">
<bpmn2:collaboration id="Collaboration_1">
<bpmn2:participant id="pool_rec" name="Recruitment" processRef="Process_pool_rec" />
<bpmn2:participant id="pool_rec_cand" name="Candidate" processRef="Process_pool_rec_cand" />
<bpmn2:messageFlow id="mfrec1" name="Offer letter" sourceRef="t_rec_offer" targetRef="pool_rec_cand" />
<bpmn2:messageFlow id="mfrec2" name="Acceptance" sourceRef="pool_rec_cand" targetRef="ev_rec_accept" />
</bpmn2:collaboration>
<bpmn2:process id="Process_pool_rec" isExecutable="false">
<bpmn2:laneSet id="LaneSet_pool_rec">
<bpmn2:lane id="lane_rec_mgr" name="Hiring manager">
<bpmn2:flowNodeRef>start_rec</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_rec_offer</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_rec_rcr" name="Recruiter">
<bpmn2:flowNodeRef>t_rec_advert</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_rec_screen</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_rec_short</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_rec_regret</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_rec_rejected</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_rec_offer</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>ev_rec_accept</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_rec_hired</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_rec_panel" name="Interview panel">
<bpmn2:flowNodeRef>t_rec_interview</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="start_rec" name="Vacancy approved">
<bpmn2:outgoing>frec1</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="t_rec_advert" name="Post job advert">
<bpmn2:incoming>frec1</bpmn2:incoming>
<bpmn2:outgoing>frec2</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:userTask id="t_rec_screen" name="Screen applications">
<bpmn2:incoming>frec2</bpmn2:incoming>
<bpmn2:outgoing>frec3</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:exclusiveGateway id="g_rec_short" name="Candidate shortlisted?" default="frec5">
<bpmn2:incoming>frec3</bpmn2:incoming>
<bpmn2:outgoing>frec4</bpmn2:outgoing>
<bpmn2:outgoing>frec5</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sendTask id="t_rec_regret" name="Send regret email">
<bpmn2:incoming>frec5</bpmn2:incoming>
<bpmn2:incoming>frec9</bpmn2:incoming>
<bpmn2:outgoing>frec6</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:endEvent id="end_rec_rejected" name="Candidate rejected">
<bpmn2:incoming>frec6</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:userTask id="t_rec_interview" name="Run interviews">
<bpmn2:incoming>frec4</bpmn2:incoming>
<bpmn2:outgoing>frec7</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:exclusiveGateway id="g_rec_offer" name="Offer the role?" default="frec9">
<bpmn2:incoming>frec7</bpmn2:incoming>
<bpmn2:outgoing>frec8</bpmn2:outgoing>
<bpmn2:outgoing>frec9</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sendTask id="t_rec_offer" name="Send offer letter">
<bpmn2:incoming>frec8</bpmn2:incoming>
<bpmn2:outgoing>frec10</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:intermediateCatchEvent id="ev_rec_accept" name="Offer accepted">
<bpmn2:incoming>frec10</bpmn2:incoming>
<bpmn2:outgoing>frec11</bpmn2:outgoing>
<bpmn2:messageEventDefinition id="ev_rec_accept_def" />
</bpmn2:intermediateCatchEvent>
<bpmn2:endEvent id="end_rec_hired" name="Candidate hired">
<bpmn2:incoming>frec11</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="frec1" sourceRef="start_rec" targetRef="t_rec_advert" />
<bpmn2:sequenceFlow id="frec2" sourceRef="t_rec_advert" targetRef="t_rec_screen" />
<bpmn2:sequenceFlow id="frec3" sourceRef="t_rec_screen" targetRef="g_rec_short" />
<bpmn2:sequenceFlow id="frec4" name="Yes" sourceRef="g_rec_short" targetRef="t_rec_interview">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="frec5" name="No" sourceRef="g_rec_short" targetRef="t_rec_regret" />
<bpmn2:sequenceFlow id="frec6" sourceRef="t_rec_regret" targetRef="end_rec_rejected" />
<bpmn2:sequenceFlow id="frec7" sourceRef="t_rec_interview" targetRef="g_rec_offer" />
<bpmn2:sequenceFlow id="frec8" name="Yes" sourceRef="g_rec_offer" targetRef="t_rec_offer">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="frec9" name="No" sourceRef="g_rec_offer" targetRef="t_rec_regret" />
<bpmn2:sequenceFlow id="frec10" sourceRef="t_rec_offer" targetRef="ev_rec_accept" />
<bpmn2:sequenceFlow id="frec11" sourceRef="ev_rec_accept" targetRef="end_rec_hired" />
</bpmn2:process>
<bpmn2:process id="Process_pool_rec_cand" isExecutable="false">
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
<bpmndi:BPMNShape id="pool_rec_di" bpmnElement="pool_rec" isHorizontal="true">
<dc:Bounds x="20" y="20" width="1420" height="500" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_rec_mgr_di" bpmnElement="lane_rec_mgr" isHorizontal="true">
<dc:Bounds x="50" y="20" width="1390" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_rec_rcr_di" bpmnElement="lane_rec_rcr" isHorizontal="true">
<dc:Bounds x="50" y="150" width="1390" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_rec_panel_di" bpmnElement="lane_rec_panel" isHorizontal="true">
<dc:Bounds x="50" y="390" width="1390" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="pool_rec_cand_di" bpmnElement="pool_rec_cand" isHorizontal="true">
<dc:Bounds x="20" y="580" width="1420" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="start_rec_di" bpmnElement="start_rec">
<dc:Bounds x="112" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="83" y="101" width="94" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_rec_advert_di" bpmnElement="t_rec_advert">
<dc:Bounds x="230" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_rec_screen_di" bpmnElement="t_rec_screen">
<dc:Bounds x="380" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_rec_short_di" bpmnElement="g_rec_short">
<dc:Bounds x="555" y="182" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="524" y="162" width="112" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_rec_regret_di" bpmnElement="t_rec_regret">
<dc:Bounds x="980" y="277" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_rec_rejected_di" bpmnElement="end_rec_rejected">
<dc:Bounds x="1162" y="299" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1133" y="341" width="95" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_rec_interview_di" bpmnElement="t_rec_interview">
<dc:Bounds x="680" y="407" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_rec_offer_di" bpmnElement="g_rec_offer">
<dc:Bounds x="855" y="52" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="844" y="32" width="73" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_rec_offer_di" bpmnElement="t_rec_offer">
<dc:Bounds x="980" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ev_rec_accept_di" bpmnElement="ev_rec_accept">
<dc:Bounds x="1162" y="189" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1143" y="231" width="75" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_rec_hired_di" bpmnElement="end_rec_hired">
<dc:Bounds x="1312" y="189" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1290" y="231" width="80" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="frec1_di" bpmnElement="frec1">
<di:waypoint x="148" y="77" />
<di:waypoint x="210" y="77" />
<di:waypoint x="210" y="207" />
<di:waypoint x="230" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec2_di" bpmnElement="frec2">
<di:waypoint x="330" y="207" />
<di:waypoint x="380" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec3_di" bpmnElement="frec3">
<di:waypoint x="480" y="207" />
<di:waypoint x="555" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec4_di" bpmnElement="frec4">
<di:waypoint x="605" y="207" />
<di:waypoint x="660" y="207" />
<di:waypoint x="660" y="447" />
<di:waypoint x="680" y="447" />
<bpmndi:BPMNLabel><dc:Bounds x="611" y="187" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec5_di" bpmnElement="frec5">
<di:waypoint x="605" y="207" />
<di:waypoint x="960" y="207" />
<di:waypoint x="960" y="317" />
<di:waypoint x="980" y="317" />
<bpmndi:BPMNLabel><dc:Bounds x="611" y="213" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec6_di" bpmnElement="frec6">
<di:waypoint x="1080" y="317" />
<di:waypoint x="1162" y="317" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec7_di" bpmnElement="frec7">
<di:waypoint x="780" y="447" />
<di:waypoint x="810" y="447" />
<di:waypoint x="810" y="77" />
<di:waypoint x="855" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec8_di" bpmnElement="frec8">
<di:waypoint x="905" y="77" />
<di:waypoint x="960" y="77" />
<di:waypoint x="960" y="207" />
<di:waypoint x="980" y="207" />
<bpmndi:BPMNLabel><dc:Bounds x="911" y="57" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec9_di" bpmnElement="frec9">
<di:waypoint x="905" y="77" />
<di:waypoint x="960" y="77" />
<di:waypoint x="960" y="317" />
<di:waypoint x="980" y="317" />
<bpmndi:BPMNLabel><dc:Bounds x="911" y="83" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec10_di" bpmnElement="frec10">
<di:waypoint x="1080" y="207" />
<di:waypoint x="1162" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="frec11_di" bpmnElement="frec11">
<di:waypoint x="1198" y="207" />
<di:waypoint x="1312" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="mfrec1_di" bpmnElement="mfrec1">
<di:waypoint x="980" y="207" />
<di:waypoint x="960" y="207" />
<di:waypoint x="960" y="550" />
<di:waypoint x="960" y="580" />
<bpmndi:BPMNLabel><dc:Bounds x="966" y="543" width="54" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="mfrec2_di" bpmnElement="mfrec2">
<di:waypoint x="1260" y="580" />
<di:waypoint x="1260" y="550" />
<di:waypoint x="1260" y="207" />
<di:waypoint x="1198" y="207" />
<bpmndi:BPMNLabel><dc:Bounds x="1266" y="543" width="60" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>Frequently asked questions
Why is the candidate a black box pool instead of a lane?
Lanes share one process instance and one organisation; the candidate belongs to neither. You do not control or observe how a candidate decides, so their pool is collapsed to a black box and only the messages you exchange (offer out, acceptance in) are modelled. This is the standard BPMN pattern for external participants.
Is it correct to point both No branches at the same regret task?
Yes. BPMN allows several sequence flows to target one activity, which acts as an implicit merge. Reusing the regret task keeps the diagram compact and makes a useful statement: rejected at screening or rejected after interview, the candidate experience should be identical. A converging exclusive gateway would work too but adds a symbol without adding meaning.
How would I extend this model for a second interview round?
Insert another exclusive gateway after "Run interviews", asking something like "Further round needed?", with the Yes branch looping back to the interview task and the No branch continuing to the offer decision. Loops back to an earlier task are perfectly legal in BPMN and are the natural way to model repeatable stages.
Related BPMN examples
Employee onboarding
An employee onboarding process diagram in BPMN 2.0: background checks, parallel IT setup, and induction. View the swimlane diagram and download the .bpmn file free.
Employee offboarding
Employee offboarding as a BPMN 2.0 diagram: handover planning, a last day timer, parallel access revocation, and final pay. Download the .bpmn file free.
Leave request
A leave request process as a BPMN 2.0 diagram: balance check, manager approval, and booking confirmation. View the swimlanes and download the .bpmn file free.
Performance review
A performance review process in BPMN 2.0: parallel self and manager assessments, a review meeting, and an objectives rework loop. Download the .bpmn file free.
Generate your own version of this diagram
Describe how the process works in your organisation: plain English, meeting notes, a transcript, or a spreadsheet. Swimdraft turns it into a spec-validated BPMN 2.0 diagram you can edit in the browser and export as .bpmn, SVG, or PNG.
Start freeNo credit card required