---
title: "Participant Placement Notifications"
slug: participant-placement-notifications
section: Placement & Matching
status: draft
description: "Canonical specification for the participant-facing placement journey — from application submission through host hire — and the communications each milestone should trigger."
last-updated: 2026-10-07
---

# Participant Placement Notifications

Canonical specification for the participant-facing placement journey — from application submission through host hire — and the communications each milestone should trigger. This page reconciles the documented applicant lifecycle, current Globus event and template behavior, host reservation and placement actions, and the n8n/HubSpot delivery path.

## Overview

> **Status: DRAFT — pending Devon's review.**
>
> The six-stage journey and the notification decisions below are proposals grounded in current documented behavior. Nothing in the *Proposed* column of any table is implemented, and no proposed decision is approved until Devon confirms it in the [review section](#devon-review). Current-state claims are limited to behavior already evidenced in the event registry, notification catalog, and reservation/placement services.

Two framing rules govern this page:

- **Participant milestones vs hidden host operations.** The Applicant Portal deliberately hides host matching, host interviews, and reservation management from the applicant ([Applicant Lifecycle → Portal Phase Mapping](/docs/applicant-lifecycle)). A stage below is a *participant* milestone only when we decide it should be participant-visible — several of the underlying Globus operations (talent-pool search, reservation holds) are host/partner-side mechanics today.
- **Current behavior vs proposed contract.** Every row explicitly says whether it describes what Globus does today or what this spec proposes. Presenting an unimplemented email as live is a defect in this page.

## The Six-Stage Participant Journey

The journey in participant language, mapped to the documented application, market/talent-pool, reservation, hire-request, and placement concepts:

| # | Stage | Participant meaning | Underlying Globus concept |
| --- | --- | --- | --- |
| 1 | Application submitted | "My application is in — the sponsor has it." | `application.submitted` event; Portal Phase 1 completion |
| 2 | Application approved | "The sponsor accepted me into the program pipeline." | Sponsor review outcome; `application.approved` notification catalog entry |
| 3 | Talent-pool entry | "Camps can now discover my profile." | Eligibility/readiness filtering surfaced via the host talent-pool endpoints |
| 4 | Camp reservation | "A camp is holding a position for me." | `reservation_holds` row (status `active`, `expiresAt` deadline) |
| 5 | Hire request | "A camp wants to hire me — I may need to respond." | No documented Globus contract today — proposed concept |
| 6 | Hired / placement confirmed | "My placement is confirmed — next steps begin." | Confirmed placement; `placement.confirmed` / `applicant.placement_confirmed` events; lifecycle Phase 4 (Placement) |

### Stage 1 — Application Submitted

| Attribute | Value |
| --- | --- |
| Business meaning | The participant has completed and submitted their program application for sponsor review. |
| Trigger — actor / action | Participant submits the application in the Applicant Portal. |
| Canonical Globus state | `application.submitted` event — implemented, n8n handler active per the [Webhook Event Registry](/docs/webhook-event-registry). |
| Participant-visible portal state | Portal Phase 1 (Apply) complete; application shows as submitted. |
| Email / message decision | **Current behavior** — submission confirmation email documented in the [Notification Catalog](/docs/notification-model). |
| Purpose | Acknowledge receipt; set review-timeline expectation. |
| Urgency / timing | Normal — immediate on submission. |
| Call to action | None (informational); keep profile documents current. |
| Owning system / team | Globus (event + outbox); n8n → HubSpot delivery; sponsor ops owns template copy. |

### Stage 2 — Application Approved

| Attribute | Value |
| --- | --- |
| Business meaning | Sponsor review has accepted the application; the participant is in the active program pipeline. |
| Trigger — actor / action | Sponsor staff (or rules-driven review outcome) approves the application. |
| Canonical Globus state | `application.approved` — used as the event key in the notification outbox examples and listed in the notification catalog; exact approval semantics are a Devon decision below. |
| Participant-visible portal state | Portal advances toward Phase 2 (Documents & Compliance) steps. |
| Email / message decision | **Current behavior** — approval email (+ SMS, high priority) documented in the [Notification Catalog](/docs/notification-model). |
| Purpose | Celebrate the milestone; direct the participant to the next required steps. |
| Urgency / timing | High — same day as approval. |
| Call to action | Complete Phase 2 documents (contract, background check, passport, references). |
| Owning system / team | Globus decision + outbox; n8n → HubSpot delivery; sponsor ops owns copy. |

### Stage 3 — Talent-Pool Entry

| Attribute | Value |
| --- | --- |
| Business meaning | The participant's profile becomes discoverable by host camps searching for candidates. |
| Trigger — actor / action | System — the participant satisfies the eligibility/readiness criteria the host talent-pool endpoints filter on ([Job Orders → Talent Pool Endpoint Contract](/docs/job-orders)). There is no documented discrete "enrollment" event today; pool membership is a filtered query outcome, not a stored state transition. |
| Canonical Globus state | **Gap** — no event, no stored membership row, no participant notification exists. Nearest equivalent: candidate appears in `/api/partner/host/search-participants` results (also served at `/api/partner/host/talent-pool/search-participants`). |
| Participant-visible portal state | Nothing — matching is hidden back-office work in the portal today. |
| Email / message decision | **Proposed** — a one-time "your profile is now visible to camps" message, *contingent on Devon deciding talent-pool entry should be participant-visible at all*. |
| Purpose | Set expectations for the matching period; prompt profile polish. |
| Urgency / timing | Normal — once, on first entry. |
| Call to action | Review showcase profile; upload optional media. |
| Owning system / team | Proposed: Globus would need to define the entry condition and emit the event; n8n → HubSpot would deliver. |

### Stage 4 — Camp Reservation

| Attribute | Value |
| --- | --- |
| Business meaning | A camp has placed a hold on the participant against a job order — a position is being reserved while the camp evaluates or processes. |
| Trigger — actor / action | Host (or staff on the host's behalf) creates a reservation hold. |
| Canonical Globus state | `reservation_holds` row, status `active` with an `expiresAt` deadline; the placement service emits `partner.reservation.created` ([Placements Overview](/docs/placements-overview-engineering)). Host-side notices exist today: `host.reservation_three_day_digest` tells the host when 3 days remain and `host.reservation_expiring_am` tells the account manager when 24 hours remain. |
| Participant-visible portal state | Nothing — reservation management is hidden from the applicant today. |
| Email / message decision | **Gap / Proposed** — no participant notification exists. Proposed: notify the participant that a camp is holding a position, *contingent on Devon deciding reservations are participant-visible* (they expire and get cancelled, so premature exposure risks disappointment churn). |
| Purpose | Keep the participant engaged and responsive during the hold window. |
| Urgency / timing | Normal — on reservation creation, if approved. |
| Call to action | None or "keep documents moving" — Devon decision. |
| Owning system / team | Globus reservation service is the state authority; any participant send would follow the standard outbox → n8n → HubSpot path. |

### Stage 5 — Hire Request

| Attribute | Value |
| --- | --- |
| Business meaning | A camp formally asks to hire the participant; depending on policy the participant may need to accept, or the sponsor accepts on their behalf. |
| Trigger — actor / action | Host initiates a hire against the reservation/job order. |
| Canonical Globus state | **Gap** — there is no participant-facing hire-request entity or event and no participant response step. A host-side hire endpoint does exist (`POST /api/partner/host/reservations/:id/hire`, audit action `reservation.hired`; `/convert` turns a host earmark into a job-order reservation) and it confirms the placement directly (reservation `active → confirmed`). This stage is a *proposed contract* for the participant side, not current behavior. |
| Participant-visible portal state | Nothing today. Proposed: a portal action/response surface if participants must accept offers — Devon decision. |
| Email / message decision | **Proposed** — high-priority "a camp wants to hire you" message with an explicit response expectation and deadline, if participant response is required. |
| Purpose | Obtain (or inform of) the hire decision quickly so the position is not lost. |
| Urgency / timing | High — immediate; deadline policy is an open decision. |
| Call to action | Accept/decline in the portal (if response required) — otherwise informational. |
| Owning system / team | Proposed: Globus would own the hire-request state machine and notification decision; portal UI and delivery path follow standard boundaries. |

### Stage 6 — Hired / Placement Confirmed

| Attribute | Value |
| --- | --- |
| Business meaning | The placement is confirmed: the participant knows which camp they are going to and pivots to visa/travel preparation. |
| Trigger — actor / action | Placement confirmation in Globus (host hire completed and recorded). |
| Canonical Globus state | Confirmed placement (placement status `confirmed`); `placement.confirmed` emitted by the placement service. The participant-facing key `applicant.placement_confirmed` is *emitted but has no dispatcher handler* — the [Webhook Event Registry](/docs/webhook-event-registry) marks it Needs Action, so no participant email flows from it today. Lifecycle derives to Phase 4 (Placement). |
| Participant-visible portal state | Portal progresses toward Phase 3 (Visa & Travel) steps; "Awaiting Placement" state ends. |
| Email / message decision | **Documented intent, not wired end-to-end** — the [Notification Catalog](/docs/notification-model) lists "Placement confirmed" (Applicant + Host, high priority), but the participant dispatcher handler for `applicant.placement_confirmed` is missing. Proposed: close that gap. |
| Purpose | Confirm the match, name the camp, hand off to next steps (Wave 2 documents, SEVIS prep). |
| Urgency / timing | High — same day as confirmation. |
| Call to action | Review placement details; begin post-placement document wave. |
| Owning system / team | Globus placement service (state + decision); n8n → HubSpot delivery; sponsor ops owns copy. |

## Current State vs Required State

What is evidenced in Globus today versus what this spec proposes. **Live** means documented, implemented behavior; **Partial** means the state change exists but the participant communication does not; **Gap** means neither exists.

| Stage | Current state (evidenced) | Required state (proposed) | Status |
| --- | --- | --- | --- |
| 1. Application submitted | `application.submitted` implemented with n8n handler; submission confirmation documented in the notification catalog. | Keep as-is. | Live |
| 2. Application approved | `application.approved` used in catalog and outbox examples; approval email + SMS documented. | Keep; Devon to confirm exact approval semantics (which review outcome fires it). | Live (semantics open) |
| 3. Talent-pool entry | Pool membership is a host-side filtered query; no event, no stored transition, no participant message, no portal visibility. | New participant event + optional one-time message, only if Devon approves participant visibility. | Gap |
| 4. Camp reservation | `reservation_holds` with statuses `active / confirmed / cancelled / declined / expired`; `partner.reservation.created` emitted; host-side reservation notices (`host.reservation_three_day_digest`, `host.reservation_expiring_am`) notify the *partner/host side only*. | New participant event + message on reservation creation, only if Devon approves visibility; expiry/cancel comms deferred to exception scope. | Partial (host-side only) |
| 5. Hire request | No documented hire-request entity, event, or endpoint. | New Globus hire-request contract (state, event, participant response policy) + high-priority participant message. | Gap |
| 6. Hired / placement confirmed | `placement.confirmed` emitted; `applicant.placement_confirmed` emitted but **no dispatcher handler** (Needs Action); catalog documents the intended applicant email. | Wire the dispatcher handler + participant template so the documented send actually happens. | Partial |

Host-facing notification keys are out of scope here and unchanged: they continue to use the canonical `host.*` prefix (see [Employer Notifications](/docs/employer-notifications)); no legacy `employer.*` keys are introduced.

## Delivery & Reliability Boundaries

The authority and delivery model for every send on this page is the existing one — this spec adds no new infrastructure:

- **Globus is the state and notification-decision authority.** Application, reservation, and placement state transitions happen only in Globus services. Globus decides *whether* to notify and writes the row to the durable notification outbox.
- **n8n orchestrates, never decides and never advances state.** n8n consumes outbox events, routes applicant sends to HubSpot (transactional email / SMS / WhatsApp), and POSTs delivery acknowledgements back to Globus (`PATCH /api/notifications/:id/delivery-status`, idempotent on the HubSpot event id). n8n never advances application, reservation, or placement state.
- **HubSpot is the applicant channel.** Channel preference is ordered WhatsApp, email, SMS, based on the contact's opt-in flags and available contact details (WhatsApp and email count as opted in unless explicitly set to false; SMS only when explicitly true); if no channel is available the Notification Domain handler's Determine Preferred Channel node throws an error and the send fails (no `communication.outbound_suppressed` event is logged). Retries, idempotency keys, dead-lettering, and the audit trail follow the outbox contract on the [Notification Model](/docs/notification-model) page.
- **Adding a participant communication requires both halves.** A new send needs (a) a registered, subscribed event contract — the event emitted by the owning Globus service *and* a dispatcher/domain handler in the event registry — and (b) a versioned participant template plus the HubSpot delivery path. `applicant.placement_confirmed` is the cautionary example: the event exists, the handler does not, so no email goes out.

## Proposed Participant Event Contracts

Requirements each proposed contract must satisfy before implementation tickets are cut. **None of these runtime changes exist today.**

| Consideration | `participant.talent_pool_entered` (proposed) | `participant.reservation_created` (proposed) | `participant.hire_requested` (proposed) | `applicant.placement_confirmed` (exists, unhandled) |
| --- | --- | --- | --- | --- |
| Event catalog / subscription | Register in the event registry; add n8n Notification Domain handler subscription. | Same; emit from the reservation service alongside `partner.reservation.created`. | Requires the hire-request state machine to exist first; then register + subscribe. | Already emitted; needs the dispatcher handler only. |
| Template | New applicant template (versioned, DB-stored). | New applicant template. | New applicant template with response-deadline merge fields. | New/activated applicant template for the documented catalog entry. |
| Audience | Applicant only. | Applicant only (host already has `host.*` coverage). | Applicant only. | Applicant (host side already covered by `host.participant_matched`). |
| Idempotency / dedup | Once per applicant lifetime (dedupe on applicant id). | Dedupe on reservation id — one send per hold, none on re-extends. | Dedupe on hire-request id. | Dedupe on placement id via outbox `idempotency_key`. |
| Audit | Standard outbox audit row per send. | Same. | Same, plus participant response captured in Globus (not in n8n). | Same. |
| Retry | Standard outbox retry → dead-letter policy. | Same. | Same; escalation on unanswered requests is exception-path scope. | Same. |
| Channel preference | HubSpot opt-in order; suppressed-send logging applies. | Same. | Same — high priority may justify multi-channel, Devon decision. | Same. |
| Acknowledgement | Standard delivery-status PATCH loop back to Globus. | Same. | Same. | Same. |

## Devon Review — Approval Status & Open Decisions

> **Approval status: NOT YET REVIEWED.** Devon must confirm each decision below before any implementation ticket is filed from this page. Until then every "Proposed" item on this page is a draft recommendation, not policy.

| # | Decision needed | Question for Devon | Draft recommendation |
| --- | --- | --- | --- |
| 1 | Application approval semantics | Which review outcome constitutes "approved" for Stage 2 — sponsor review pass, interview pass, or rules-engine clearance? Does the existing approval email fire at the right moment? | Sponsor review pass, as the catalog implies today. |
| 2 | Talent-pool visibility | Should participants know when they become discoverable to camps? If yes, is entry a real stored transition (requiring a new event) or derived? | Yes, one-time informational message; define entry as a stored transition. |
| 3 | Reservation notice | Are reservations participant-visible at all? If yes, does the participant learn the camp's identity, and is the hold deadline shared? | Notify without deadline detail; name the camp only at hire request. |
| 4 | Reservation deadline policy | Should reservation expiry ever be communicated to the participant, or is it purely host-side? | Host-side only for the happy path; revisit in exception scope. |
| 5 | Hire request & participant response | Does the participant accept/decline hires, or does the sponsor accept on their behalf? If the participant responds, what is the deadline and the default on timeout? | Participant informational only in v1; sponsor accepts. |
| 6 | Hired vs placement-confirmed semantics | Are "hired" (lifecycle stage) and "placement confirmed" (placement service state) the same participant milestone, or two? Which one triggers the Stage 6 message? | One milestone; `placement.confirmed` is the trigger. |

## Exception Paths — Follow-On Scope

The following journeys are deliberately **not** defined in this spec. They are recorded so they are decided explicitly later rather than silently assumed inside the happy path:

- Reservation expiry and cancellation — whether/how the participant is told a hold ended.
- Declined or expired hire requests — participant messaging and portal state.
- Re-placement after a cancelled placement — the documented "Re-placement required" catalog entry needs a full journey definition.
- Placement cancellation comms sequencing across applicant, host, and partner.
- Reminder/escalation cadence for unanswered hire requests.

Each becomes its own decision set once Devon approves the six-stage happy path above.

## Related Pages

- [Notification Model](/docs/notification-model) — outbox, templates, HubSpot applicant channel, delivery acknowledgement loop this spec builds on.
- [Applicant Lifecycle](/docs/applicant-lifecycle) — phases, stages, and the portal's 3-phase mapping that hides back-office matching.
- [Job Orders](/docs/job-orders) — talent-pool endpoint contract and reservation/placement counters.
- [Matching Engine](/docs/matching-engine) — how candidates are ranked for job orders behind the scenes.
- [Placements Overview (Engineering)](/docs/placements-overview-engineering) — reservation hold statuses and the placement events emitted today.
- [Employer Notifications](/docs/employer-notifications) — the host-side `host.*` notification contracts, unchanged by this page.
- [Automation (n8n)](/docs/automation) — dispatcher, domain handlers, and delivery workflows.
- [Webhook Event Registry](/docs/webhook-event-registry) — implementation status of every emitted event referenced here.
