How it works
CrewPass continuously watches the data behind your fleet. When something relevant changes — a certificate finishes verifying, compliance flips, a status or profile updates — CrewPass builds the matching event and delivers it to the callback URL you registered. There is nothing to run on your side beyond an HTTPS endpoint that accepts aPOST, verifies the signature, and returns 2xx.
Two things worth knowing:
- You don’t poll. Events are pushed in near-real-time off CrewPass’s own change feed; you react to them.
- Delivery is at-least-once. The same event may arrive more than once (e.g.
after a retry), so deduplicate on
event_id.
Subscribing
Webhook registration is not self-serve. Ask your CrewPass contact to register your callback URL and the events you want; they set it up for you during onboarding, or whenever you need it changed. CrewPass then issues a webhook signing secret used to sign every delivery (this is separate from your API key; reads are not signed).The envelope
Every delivery is a JSON body with this shape:Signature scheme
Verifying a delivery
Python
Node
Receiver requirements
- Verify the signature against the raw bytes.
- Deduplicate on
event_id— delivery is at-least-once, so the same event may arrive more than once. - Respond
2xxquickly and process asynchronously. - Anything else is retried with exponential backoff (up to 8 attempts), then
dead-lettered. A
4xx(other than408/429) is treated as a permanent rejection and not retried.
Event catalogue (v1)
crew.document.processed / crew.document.updated
crew.compliance.changed
crew.status.changed
crew.profile.updated
Reacting to an event
Every payload carries acrew_unique_id: the join key between CrewPass and
your own records. You learn it once, store it against your own crew record, then
use it to look up the detail behind any event.
Discover a crew member’s crew_unique_id once, then keep it:
GET /api/v2/employers/me/fleetreturns the fleet roster, where every crew member arrives with theircrew_unique_id.POST /api/v2/employers/me/crew/lookupresolves a single known crew member to theircrew_unique_id.
crew_unique_id tells you exactly which of your records
changed. An event is a signal, not a full snapshot: the document events carry
their metadata inline, and for the others you call the matching read endpoint to
fetch the current detail.
crew.document.processed and crew.document.updated. The payload already
has the document metadata (type, category, issuer, verification status, issue and
expiry dates, document number). To fetch the file, call
GET /api/v2/employers/me/crew/{crew_unique_id}/documents/{document_id}/download
and follow the download_url it returns; that link is short-lived, so use it
straight away rather than storing it. Both crew_unique_id and document_id come
from the event payload.
Document events fire on verification completion
(
processingStatus.overall == "completed"), not on raw upload. Expect a short
delay between a crew member uploading a certificate and the matching event
arriving.crew.compliance.changed. The payload is a summary (overall status plus the
requirement counts). For the full role, STCW, and medical breakdown, call
POST /api/v2/employers/me/crew/{crew_unique_id}/compliance-checks. The
overall_status values
(compliant, at_risk, non_compliant, no_role)
mean the same here as on the compliance read.
crew.profile.updated. The event is a change signal, not a diff: it tells you
the profile changed, not what changed. Call
GET /api/v2/employers/me/crew/{crew_unique_id}/profile to read the current
profile.
crew.status.changed. The payload carries the new verification_status and
background_check_status directly, so update your own record straight from the
payload. No follow-up read is required.
Background-check status uses CrewPass’s standardised, provider-agnostic
vocabulary.