Trip statuses
Every value status can take, what each one means, and which transitions you can drive.
Every trip carries a status. It is returned by GET /trips/{id} — API Reference — and GET /trips/{id}/object — API Reference — and it is the field to key your integration off.
This page is the complete reference: what each value means, how a trip arrives there, and what you can do about it.
statusis about approval, not complianceA trip's
statustracks its journey through your company's approval flow. Whether an A1 certificate has come back, or a posted-worker notification has been filed, is tracked separately onprocessRuns— see Compliance and risk statuses.
At a glance
| Status | Meaning | What you should do |
|---|---|---|
DRAFT | Traveler started a trip but hasn't submitted it | Nothing — not yet a real trip. Excluded from policy counting and duplicate checks |
PENDING | Submitted, waiting on one or more approvers | Poll. Read approvals on the full trip to see progress |
APPROVED | Fully approved. Compliance processes may now run | Start tracking processRuns |
APPROVED_MISSING_DATA | Approved, but compliance needs data that is still missing | Act. Fill the missing fields, then the trip returns to APPROVED on its own |
APPROVED_EDIT_PENDING | Approved, but a change request is awaiting a decision | Poll. Reverts to APPROVED once the change is accepted or rejected |
CANCEL_REQUESTED | Cancellation requested, awaiting admin approval | Poll. Becomes CANCELED, or reverts if the request is withdrawn |
CANCELED | Cancelled. Terminal | Stop tracking. Cancellation filings may still run |
DECLINED | An approver rejected it. Terminal | Stop tracking |
COMPLETED | Manually marked done after travel. Terminal | Stop tracking |
Two further values, INCOMPLETE and ASSIGNED, are legacy — see Legacy values below.
There is no "successful" trip statusThat is the whole list. If you're looking for a value meaning this trip completed successfully, it doesn't exist — use
APPROVED, which is the state that matters operationally and the one that unlocks compliance filings.COMPLETEDis manual bookkeeping an administrator applies after travel, so it is not a reliable completion signal.
SUCCESSFULdoes exist in the premote API — but on a different field. It is a run status, found onprocessRuns[].statusandworkflowRuns[].status, and it describes a filing with an authority, not the trip. See Compliance and risk statuses.
The statuses in detail
DRAFT
DRAFTA trip the traveler has started but not submitted. It is a real row with a real id, so you can read and update it, but premote treats it as provisional: drafts are excluded from policy quota counting and duplicate detection, and they trigger no approvals, no risk assessment and no compliance processes.
Drafts are the only trips that can be hard-deleted (DELETE /trips/{id} — API Reference) and the only trips where edits apply immediately instead of going through a change request.
Submitting a draft (POST /trips/{id}/update-draft with upgrade: true — API Reference) upgrades the same row in place — the id does not change — and moves it to PENDING, or straight to APPROVED if the matching policy auto-approves.
PENDING
PENDINGSubmitted and awaiting approval. This is the default landing state for a new trip.
For multi-step approval chains, the trip stays PENDING as each approver signs off, and only flips to APPROVED once the final one does. To show progress, read approvals on the full trip (GET /trips/{id}) and compare its length against the approval rules on policy.approvalRules.
APPROVED
APPROVEDFully approved. Either every approval rule was satisfied, or the matching policy auto-approves, or the trip arrived from an integration configured to auto-approve.
This is the state that matters most for compliance: reaching it is what triggers premote to start filing A1 applications, posted-worker notifications, and the rest.
APPROVED_MISSING_DATA
APPROVED_MISSING_DATAThe one status that needs you to do something.
The trip is approved, but a compliance process — or an administrator's explicit request — needs field values that aren't filled in yet. premote parks the trip here rather than filing an incomplete application with an authority. The workflow does not start until the data arrives.
To resolve it:
- Ask what's missing —
GET /processes/{tripId}/missing-data— API Reference. - Fill traveler profile fields with
POST /users/{id}/data— API Reference — and trip fields withPOST /trips/{id}/data— API Reference. - premote re-checks automatically and returns the trip to
APPROVEDonce everything required is present. You do not call a status endpoint to leave this state — and you can't.
Note that missing data can be on the traveler's profile rather than the trip itself, so filling only trip fields may not clear it. The missing-data response tells you which is which.
APPROVED_EDIT_PENDING
APPROVED_EDIT_PENDINGAn already-approved trip has an open change request. The trip's previous status is retained internally and restored once the request is decided.
Approved trips can't simply be edited — changes go through POST /trips/{id}/request-change — API Reference — and are then accepted or rejected with POST /trips/{tripId}/change/{requestId} — API Reference. Either outcome returns the trip to APPROVED; accepting also applies the new values.
Change requests are automatically rejected if the trip is cancelled or declined while one is open.
CANCEL_REQUESTED
CANCEL_REQUESTEDSomeone asked to cancel a trip that requires an administrator to sign the cancellation off. Whether cancellation needs approval is a policy setting, so the same call can produce CANCELED for one company and CANCEL_REQUESTED for another — handle both.
From here the trip either becomes CANCELED, or is restored to its previous status via POST /trips/{id}/restore-status — API Reference.
CANCELED
CANCELEDTerminal. premote records who cancelled it, when, and why, rejects any open change request, and — importantly — kicks off cancellation runs for compliance filings that were already submitted, so a withdrawn notification is properly retracted with the authority.
So: the trip is finished, but its processRuns may still be doing work. Don't tear down tracking the instant you see CANCELED if you care about the cancellation filings.
DECLINED
DECLINEDAn approver rejected the trip. Terminal — a declined trip cannot be re-approved. Any open change request is rejected. Create a new trip if the traveler still needs to go.
COMPLETED
COMPLETEDSet manually by an administrator after travel has happened, as a bookkeeping step. Only reachable from APPROVED. premote does not set it automatically when the end date passes, so don't rely on it to mean "the trip has ended" — compare endDate against today for that.
Transitions
Only these moves are legal. Anything else is rejected.
| From | To | Notes |
|---|---|---|
| (new) | DRAFT, PENDING, APPROVED | APPROVED only when the policy or integration auto-approves |
DRAFT | PENDING, APPROVED | Via update-draft with upgrade: true; same row, same id |
DRAFT | (deleted) | Hard delete — drafts only |
PENDING | APPROVED, DECLINED | Multi-step chains stay PENDING until the last approver signs |
PENDING | CANCELED, CANCEL_REQUESTED | |
APPROVED | COMPLETED | Only from APPROVED |
APPROVED | APPROVED_MISSING_DATA | Set by premote, not by you |
APPROVED | APPROVED_EDIT_PENDING | Set by opening a change request |
APPROVED | CANCELED, CANCEL_REQUESTED | Hard-cancelling an approved trip requires an admin or super-admin token |
APPROVED_MISSING_DATA | APPROVED | Automatic, once the missing data is supplied |
APPROVED_EDIT_PENDING | APPROVED | On accept or reject of the change request |
CANCEL_REQUESTED | CANCELED | Admin approves the cancellation |
CANCEL_REQUESTED | (previous status) | Via restore-status |
CANCELED, DECLINED, COMPLETED | — | Terminal |
Three statuses cannot be set directly
DRAFT,APPROVED_MISSING_DATAandAPPROVED_EDIT_PENDINGare never accepted by the status endpoint.DRAFTis set at creation, and the other two are set by premote in response to something else — a compliance process needing data, or a change request being opened.
Driving a transition
POST /trips/{id}/status — API Reference
curl -X POST https://api.premote.io/v1/trips/456/status \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"status": "APPROVED",
"reason": ""
}'status— the target status.reason(optional) — free text, stored against the trip. Worth sending forDECLINEDandCANCELED, where it's shown to the traveler.saveStatus(optional, defaultfalse) — when requesting cancellation, settrueto remember the current status sorestore-statuscan bring it back.
Authorization matters here: approve and decline are limited to the trip's designated approvers (administrators can generally act in their place), hard-cancelling an already-approved trip requires an admin or super-admin token, and a personal-assistant token can only ever request cancellation, never cancel outright.
To restore a trip parked in CANCEL_REQUESTED:
curl -X POST https://api.premote.io/v1/trips/456/restore-status \
-H 'Authorization: Bearer <token>'Status changes and traveler emails
premote emails the traveler when a trip is submitted, approved, declined, cancelled, or cancellation is requested. APPROVED_MISSING_DATA additionally drives reminder emails until the data is supplied.
Integration-created trips are silentWhen a trip is created with an
externalId— which is how trips imported from a travel or HR system arrive — premote suppresses the traveler status email, on the assumption that the source system already notified them. SetexternalIdwhen you want that behaviour, and leave it off when you want premote to handle traveler comms.
Legacy values
Two values exist in the schema and may appear on older records. Accept them; don't build on them.
| Status | Notes |
|---|---|
INCOMPLETE | Predates DRAFT as the "not yet finished" state. Not set on new trips. Can still be moved to PENDING once a destination and travel dates are present |
ASSIGNED | Not written by any current code path |
This is the general rule for status handling: treat the set as open. Log and skip values you don't recognise rather than throwing, so a newly-introduced status never breaks your sync.
Recap
| Task | Endpoint |
|---|---|
| Read the current status | GET /trips/{id} or GET /trips/{id}/object |
| List trips by status | GET /trips |
| Approve / decline / cancel | POST /trips/{id}/status |
| Restore after a cancellation request | POST /trips/{id}/restore-status |
| Find out what data is missing | GET /processes/{tripId}/missing-data |
| Supply missing trip data | POST /trips/{id}/data |
| Supply missing profile data | POST /users/{id}/data |
| Open a change request | POST /trips/{id}/request-change |
| Decide a change request | POST /trips/{tripId}/change/{requestId} |
Updated 19 days ago
