SwimdraftPricingSign inStart free

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.

Recruitment: BPMN 2.0 diagram
Recruitment process modelled as a BPMN 2.0 diagram

Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.

The process at a glance

Starts when
Vacancy approved
Ends with
Candidate rejected · Candidate hired
Lanes
Hiring manager · Recruiter · Interview panel
Decisions
Candidate shortlisted? · Offer the role?

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

ElementCountIn this diagram
Start event1Vacancy approved
End event2Candidate rejected, Candidate hired
Intermediate catch event1Offer accepted
Task1Post job advert
User task2Screen applications, Run interviews
Send task2Send regret email, Send offer letter
Exclusive gateway2Candidate 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

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 free

No credit card required