How it works
CrewPass keeps watch on the data behind your fleet. When something relevant changes — a certificate finishes processing, compliance moves, a status or profile updates — CrewPass builds the matching event and delivers it to the callback URL you registered, usually within 15 minutes of the change. There is nothing to run on your side beyond an HTTPS endpoint that accepts aPOST, verifies the
signature, and returns 2xx.
Five things worth knowing:
- You don’t poll. CrewPass checks your fleet for changes every 15 minutes and pushes what has changed; you react to it.
- Delivery is at-least-once. The same event may arrive more than once (e.g.
after a retry), so deduplicate on
event_id. - Events are not ordered. Treat each one as “this changed, here is how it looks now” rather than as a step in a sequence.
- You will not receive a backlog. When your endpoint is first registered you are not sent an event for every certificate already on file. Read the current state through the API once, and webhooks keep you in step from there.
- Crew who join your fleet arrive in full. When a crew member is added to one
of your vessels, you receive a
crew.document.processedfor each document they already hold, plus their current compliance, status and profile.
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.updated, crew.compliance.changed and crew.status.changed are
sent only when a value in their payload changes. A recalculation that leaves
every figure the same sends nothing.
crew.document.processed / crew.document.updated
classification block. The fields from review_status onwards were added on
2026-09-17. Ignore any fields you don’t need.
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) and its classification, so you can file it straight
away. 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 once CrewPass has finished processing a document, not
when a crew member uploads it. Expect a short delay between the upload and the
event — processing, then up to 15 minutes until the next check.
crew.document.updated covers any change you can see: a re-verification, a
corrected date, a newer edition replacing it (is_current, superseded_by), or
a change to its classification.
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.