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}/objectAPI 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.

📘

status is about approval, not compliance

A trip's status tracks 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 on processRuns — see Compliance and risk statuses.


At a glance

StatusMeaningWhat you should do
DRAFTTraveler started a trip but hasn't submitted itNothing — not yet a real trip. Excluded from policy counting and duplicate checks
PENDINGSubmitted, waiting on one or more approversPoll. Read approvals on the full trip to see progress
APPROVEDFully approved. Compliance processes may now runStart tracking processRuns
APPROVED_MISSING_DATAApproved, but compliance needs data that is still missingAct. Fill the missing fields, then the trip returns to APPROVED on its own
APPROVED_EDIT_PENDINGApproved, but a change request is awaiting a decisionPoll. Reverts to APPROVED once the change is accepted or rejected
CANCEL_REQUESTEDCancellation requested, awaiting admin approvalPoll. Becomes CANCELED, or reverts if the request is withdrawn
CANCELEDCancelled. TerminalStop tracking. Cancellation filings may still run
DECLINEDAn approver rejected it. TerminalStop tracking
COMPLETEDManually marked done after travel. TerminalStop tracking

Two further values, INCOMPLETE and ASSIGNED, are legacy — see Legacy values below.

🚧

There is no "successful" trip status

That 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. COMPLETED is manual bookkeeping an administrator applies after travel, so it is not a reliable completion signal.

SUCCESSFUL does exist in the premote API — but on a different field. It is a run status, found on processRuns[].status and workflowRuns[].status, and it describes a filing with an authority, not the trip. See Compliance and risk statuses.


The statuses in detail

DRAFT

A 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: trueAPI 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

Submitted 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

Fully 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

The 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:

  1. Ask what's missing — GET /processes/{tripId}/missing-dataAPI Reference.
  2. Fill traveler profile fields with POST /users/{id}/dataAPI Reference — and trip fields with POST /trips/{id}/dataAPI Reference.
  3. premote re-checks automatically and returns the trip to APPROVED once 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

An 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-changeAPI 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

Someone 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-statusAPI Reference.

CANCELED

Terminal. 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

An 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

Set 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.

FromToNotes
(new)DRAFT, PENDING, APPROVEDAPPROVED only when the policy or integration auto-approves
DRAFTPENDING, APPROVEDVia update-draft with upgrade: true; same row, same id
DRAFT(deleted)Hard delete — drafts only
PENDINGAPPROVED, DECLINEDMulti-step chains stay PENDING until the last approver signs
PENDINGCANCELED, CANCEL_REQUESTED
APPROVEDCOMPLETEDOnly from APPROVED
APPROVEDAPPROVED_MISSING_DATASet by premote, not by you
APPROVEDAPPROVED_EDIT_PENDINGSet by opening a change request
APPROVEDCANCELED, CANCEL_REQUESTEDHard-cancelling an approved trip requires an admin or super-admin token
APPROVED_MISSING_DATAAPPROVEDAutomatic, once the missing data is supplied
APPROVED_EDIT_PENDINGAPPROVEDOn accept or reject of the change request
CANCEL_REQUESTEDCANCELEDAdmin approves the cancellation
CANCEL_REQUESTED(previous status)Via restore-status
CANCELED, DECLINED, COMPLETEDTerminal
🚧

Three statuses cannot be set directly

DRAFT, APPROVED_MISSING_DATA and APPROVED_EDIT_PENDING are never accepted by the status endpoint. DRAFT is 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}/statusAPI 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 for DECLINED and CANCELED, where it's shown to the traveler.
  • saveStatus (optional, default false) — when requesting cancellation, set true to remember the current status so restore-status can 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 silent

When 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. Set externalId when 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.

StatusNotes
INCOMPLETEPredates 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
ASSIGNEDNot 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

TaskEndpoint
Read the current statusGET /trips/{id} or GET /trips/{id}/object
List trips by statusGET /trips
Approve / decline / cancelPOST /trips/{id}/status
Restore after a cancellation requestPOST /trips/{id}/restore-status
Find out what data is missingGET /processes/{tripId}/missing-data
Supply missing trip dataPOST /trips/{id}/data
Supply missing profile dataPOST /users/{id}/data
Open a change requestPOST /trips/{id}/request-change
Decide a change requestPOST /trips/{tripId}/change/{requestId}


Did this page help you?