Working with trips
The trip object, the four status fields worth tracking, and how to keep an integration in sync.
A trip is the central object in premote. It ties a traveler to a destination and a set of dates, and everything else — approvals, risk assessment, A1 certificates, posted-worker notifications, generated documents — hangs off it.
This section covers what a trip looks like over the wire, the states it moves through, and the other status fields you need to read alongside it.
| Guide | What it covers |
|---|---|
| Trip statuses | Every value status can take, what each means, and which transitions you can drive |
| Trip types | BUSINESS_TRIP, WORKATION, ASSIGNMENT — and why assignments track their state differently |
| Compliance and risk statuses | Process runs, workflow runs, and the risk assessment lifecycle |
| Create a trip via the API | The end-to-end happy path, step by step |
Before you startAll requests need a bearer token — see Authentication. Base URL is
https://api.premote.io/v1.
Two ways to read a trip
premote exposes the same trip in two shapes. Pick the one that matches what you're doing.
GET /trips/{id}/object — the flattened trip
GET /trips/{id}/object — the flattened tripGET /trips/{id}/object — API Reference
Returns a single flat object: a stable envelope plus the trip's field values inlined as extra camelCase keys.
curl https://api.premote.io/v1/trips/456/object \
-H 'Authorization: Bearer <token>'{
"id": 456,
"type": "BUSINESS_TRIP",
"status": "APPROVED",
"travelerId": 123,
"origin": "DE",
"destination": "FR",
"startDate": "2026-09-01",
"endDate": "2026-09-05",
"locationAbroad": "12 Rue de Rivoli, Paris",
"riskResult": { "overall_risk": "LOW" },
"travel_reason": "CLIENT_MEETING"
}Use it when you want the trip's data. It's the simplest shape to map into your own system.
GET /trips/{id} — the full trip
GET /trips/{id} — the full tripGET /trips/{id} — API Reference
Returns the relational trip: the same core record plus approvals, policy, traveler, files, and — most importantly for status tracking — processRuns, each with its nested workflowRuns.
Use it when you need to know why a trip is in the state it's in: who still has to approve it, which compliance process is running, which certificate has come back.
The extra keys are per-companyTrip fields are configured per company, so the inlined keys in
/object(and the entries intripFieldValueson the full trip) differ between customers. Discover the keys available to you withGET /trip-fields— API Reference. Which keys you receive also depends on your API user's permissions: sensitive fields such as salary may be omitted.
Four statuses, not one
It's a common integration bug to treat trip.status as the whole picture. It isn't — a trip carries four independent status signals, and they answer different questions.
| Field | Where it lives | Answers |
|---|---|---|
status | trip.status | Has this trip been approved, declined, or cancelled? |
riskAssessmentStatus | trip.riskAssessmentStatus | Has the risk assessment finished running? |
processRuns[].status | each process run | Is a given compliance obligation (A1, PWD…) handled? |
processRuns[].workflowRuns[].status | each workflow run | How far along is the actual filing with the authority? |
A trip can be APPROVED while its A1 process run is still IN_PROGRESS and its risk assessment is PENDING. All three are normal, simultaneous, and mean different things.
status is documented in Trip statuses; the other three in Compliance and risk statuses.
The lifecycle at a glance
┌─────────┐
│ DRAFT │ traveler is still filling the form
└────┬────┘
│ submit
▼
auto-approval ──▶ ┌─────────┐ ◀── approval rules outstanding
│ PENDING │
└────┬────┘
approve ────┼──── decline
▼ ▼
┌──────────┐ ┌──────────┐
│ APPROVED │ │ DECLINED │ (terminal)
└────┬─────┘ └──────────┘
│
├──▶ APPROVED_MISSING_DATA compliance needs more data
├──▶ APPROVED_EDIT_PENDING a change request is open
├──▶ CANCEL_REQUESTED ──▶ CANCELED
└──▶ COMPLETED (terminal)
Once a trip reaches APPROVED, APPROVED_MISSING_DATA, APPROVED_EDIT_PENDING or COMPLETED, premote starts its compliance processes for that trip. Nothing runs before then.
There is no status webhook — poll
premote does not currently push trip status changes to your endpoint, and the API exposes no webhook subscription route. Track changes by polling.
Practical advice:
- Poll the list, not each trip.
GET /trips— API Reference — accepts the same filters as the dashboard, including status. One call per sweep beats one call per trip. - Compliance is slow. Approvals happen in minutes-to-days; authority filings can take days-to-weeks. Polling every few minutes is plenty — there is nothing to gain from polling harder.
- Treat unknown status values as non-fatal. New values get added. Log-and-skip rather than throwing, so a new state never takes your sync down.
- Store the trip
id, and send your own key asexternalIdwhen you create the trip.externalIdis also used to de-duplicate on re-import.
Group trips
Creating trips for several travelers at once (POST /trips/multiple — API Reference) produces one independent trip per traveler, all sharing a groupId.
Each trip then has its own status, its own approvals, and its own compliance processes — approving one does not approve the others. Fetch the members of a group with GET /group-trips/{id} — API Reference.
Recap
| Task | Endpoint |
|---|---|
| Read a trip, flattened | GET /trips/{id}/object |
| Read a trip in full (approvals, process runs) | GET /trips/{id} |
| List and filter trips | GET /trips |
| Discover available trip fields | GET /trip-fields |
| List the trips in a group | GET /group-trips/{id} |
Updated 19 days ago
