Retrieve & Delete Travel Data
Read stored trips, activities, and calculations back — and delete a trip — with the /v2/travel-data/trips endpoints.
After ingestion, the trip endpoints let you read back exactly what SQUAKE stored, and delete a trip you shouldn't have sent.
Use them to reconcile your system against SQUAKE, to fetch the calculations of additional methodologies, to look up the audit log of a stored calculation, or to clean up test and duplicate data.
Endpoints
GET /v2/travel-data/trips
Paginated list of your stored trips, newest ingested first.
GET /v2/travel-data/trips/{id}
A single trip.
GET /v2/travel-data/trips/{trip_id}/activities
All activities of a trip, each with its traveler and calculations.
GET /v2/travel-data/trips/{trip_id}/activities/{activity_id}
A single activity with its traveler and calculations.
DELETE /v2/travel-data/trips/{id}
Deletes the trip, its activities, and their calculations.
Authentication
Bearer Token or HTTP Basic Auth (API key as username, no password) — the same credentials you use for
POST /v2/travel-data.
Environments
Sandbox
https://api.sandbox.squake.earth
Production
https://api.squake.earth
ℹ️ Ingesting travel data must be enabled for your account — until it is,
POST /v2/travel-dataand the CSV imports respond with404and error codetravel_data_not_found. The read endpoints serve whatever is stored for you; a client with nothing stored gets an empty list.
The two-level shape
A trip response carries the trip's own attributes and the IDs of its activities, never the activities themselves. The activities — with their traveler, calculations, and audit references — live one request away:
This keeps a trip response small and predictable: no matter how many activities a trip holds, reading it costs one bounded response, and every endpoint that returns a trip returns the same set of fields.
The one exception is the trips array of a submission, which reports the trip's identity only — id, trip_reference, client_id, submitted_by_client_id, activity_ids. A read returns those five fields plus the descriptive ones above, and a shared field means the same thing in both, so a submission response and a later read of the same trip never disagree.
Addressing a trip by your own reference
Everywhere a trip is addressed, you can pass either SQUAKE's id (a UUID) or your own trip_reference:
That means you do not have to store SQUAKE's IDs to read your data back — if you set trip_reference on ingestion, your own reference is enough. Activities, by contrast, are always addressed by their SQUAKE id, as listed in the trip's activity_ids.
Getting the IDs from a submission
POST /v2/travel-data returns a trips array next to the flat items, with the ID of every trip the request persisted and the IDs of the activities written under it:
Three details worth knowing:
One entry per trip, not per payload entry. Two payload entries sharing a
trip_referenceresolve to the same trip and are reported once.activity_idscovers what this request wrote. Re-using atrip_referenceappends activities to an existing trip, so that trip holds more activities than the submission response lists. Read the trip to get the full list.A submission echoes identity, not content. The five fields above are all a
tripsentry carries — it does not repeat the trip name, dates, amount or cost center you just sent. Read the trip to get those back as SQUAKE stored them.
Trip fields
id
string (UUID)
SQUAKE's identifier for the trip.
trip_reference
string | null
Your own reference, echoed from ingestion. Usable in place of id.
client_id
string (UUID)
The client that owns the trip.
submitted_by_client_id
string (UUID) | null
The client whose credentials submitted the trip. null for trips that did not arrive through POST /v2/travel-data (e.g. CSV imports or TMC integrations).
activity_ids
array (UUID)
IDs of the trip's activities, in ingestion order, across all activity types.
client_id and submitted_by_client_id differ when you submit on behalf of a descendant client: the target client owns the trip, your credential is recorded as the submitter. See Submitting on behalf of another client.
Reads return more. On top of the five fields above, GET /v2/travel-data/trips and GET /v2/travel-data/trips/{id} return the trip as you described it on ingestion:
trip_name
string | null
The trip's name, echoed from ingestion.
trip_purpose
string | null
The trip's purpose, echoed from ingestion.
trip_status
string | null
The status the source reported (e.g. completed). Free-form — SQUAKE neither constrains nor normalizes it.
booking_provider
string | null
The provider the trip was booked through, echoed from ingestion.
start_date_utc
string (date-time) | null
Start of the trip, in UTC. Ingestion accepts a date (2026-03-10); reads return a date-time (2026-03-10T00:00:00Z).
end_date_utc
string (date-time) | null
End of the trip, in UTC, same format.
amount_in_cents
integer | null
The booking's own amount, in the minor unit of currency (10000 is 100.00 USD).
currency
string | null
3-letter ISO 4217 code of amount_in_cents.
cost_center
object | null
The cost center the trip is booked against, as { "name", "purpose", "email" }. The key is always present; it is null for a trip booked against none.
These fields are echoed as stored, so a field you did not send on ingestion reads back as null. Two values SQUAKE keeps internally are deliberately not here: the amount converted into your base currency for reporting, and the cost center's department and internal id.
List trips
GET /v2/travel-data/trips
Returns your stored trips as a bare array, most recently ingested first. Trips from every source are listed — API submissions, CSV imports, and TMC integrations alike.
Pagination
page
Page number, starting at 1.
items
Trips per page. Defaults to 20, capped at 100.
Pagination metadata is returned in the response headers:
Current-Page
The page returned.
Page-Items
Trips per page.
Total-Pages
Total number of pages.
Total-Count
Total number of trips.
Link
RFC 8288 links to the first, prev, next, and last page.
Example
The second trip shows what a sparsely described source looks like: every field it did not carry reads back as null, and the keys are still there.
Multi-client accounts. If submitting on behalf of other clients is enabled for you, the list spans the authenticated client and all of its descendants — never a parent, a sibling, or an unrelated client. Read client_id on each trip to see which client owns it. Without that capability, you only ever see your own trips.
Retrieve a single trip
GET /v2/travel-data/trips/{id}
A single trip read and a trip in the list return the same fields — the list is the same shape, paginated.
List the activities of a trip
GET /v2/travel-data/trips/{trip_id}/activities
Returns every activity of the trip, in ingestion order, each with its traveler and the calculations persisted for it. A trip is a single booking, so the list is bounded and returned in full — this endpoint isn't paginated.
The example is truncated to two of the trip's four activities. Note that the hotel stay has no origin/destination keys at all — see Keys that depend on the activity type.
Activity fields
id
string (UUID)
Identifier of the activity, as listed in the trip's activity_ids.
type
string
flight, hotel, car, or train.
trip_id
string (UUID)
The trip this activity belongs to.
client_id
string (UUID)
The client that owns the activity — always the owner of its trip.
external_reference
string | null
Your own reference, echoed from ingestion.
origin
string | null
Where the activity started, echoed from ingestion in the format you sent it (airport code, address, UN/LOCODE, lat/long). flight, car, train only.
destination
string | null
Where it ended, same format as origin. flight, car, train only.
fuel_type
string | null
The fuel the activity was calculated with, echoed from ingestion. Accepted values depend on the methodology. car and train only.
traveler
object | null
Who travelled, as { "name", "email", "traveler_type" }. Always present; null for an activity submitted without a traveler.
calculations
array
One entry per methodology calculated for this activity, oldest first.
Keys that depend on the activity type
Route and fuel are only stored for the activity types that have them, and a key a type cannot have is omitted rather than returned as null:
Type
origin / destination
fuel_type
flight
✅
—
car
✅
✅
train
✅
✅
hotel
—
—
So read type first, and treat a missing key as "not applicable to this type" rather than "no value". traveler, by contrast, is present on every activity type — a null there means the activity was submitted without a traveler, which is common for CSV and TMC rows.
Traveler fields
name
string | null
Name of the traveler, echoed from ingestion.
email
string | null
Email of the traveler, echoed from ingestion and lower-cased. SQUAKE matches travelers on this within a client, so two activities for the same person return the same traveler.
traveler_type
string | null
employee, contractor, or guest.
The traveler's department, your external employee id and SQUAKE's internal traveler id are not part of this response.
Calculation fields
id
string (UUID)
Identifier of the calculation.
methodology
string
The methodology this calculation ran under (e.g. TIM, DEFRA).
methodology_version
string | null
Published version of that methodology for this activity type. null for methodologies that are not versioned.
co2_in_grams
number
Emissions in grams of CO₂ equivalent.
audit
object | null
The audit log this calculation produced, as { "id": "..." }, or null for an activity submitted without audit mode.
⚠️ Note the unit.
co2_in_gramsis in grams, whilePOST /v2/travel-dataand the calculation endpoints reportcarbon_quantityin kilograms by default.
Reading the full audit log. audit carries only the ID — pass it to /v2/audits/{id} for the immutable record of the request, response, distances, and emission factors behind the calculation.
Routing legs are not listed. For a flight activity submitted with routing (e.g. BER-FRA-JFK), the individual legs are internal segments: the routed activity carries the itinerary total, and legs appear neither in activity_ids nor in this list. Addressing a leg ID directly returns 404.
Retrieve a single activity
GET /v2/travel-data/trips/{trip_id}/activities/{activity_id}
Activities are always addressed through their trip, so both identifiers are required.
The response is a single activity object, in the shape shown above — including its traveler and, where the type has them, origin, destination and fuel_type.
Additional methodologies
If your account is configured with more than one methodology for an activity type, SQUAKE persists one calculation per methodology. The flat items array of a submission only reports the primary methodology — the others are readable here:
Delete a trip
DELETE /v2/travel-data/trips/{id}
Deletes the trip and everything hanging off it — all of its activities, routing legs included, and their calculations. Responds with 204 No Content and an empty body. Like the reads, it accepts a trip_reference in place of the id.
Three things to keep in mind:
Audit logs are kept. They are an immutable record of what was calculated, so deleting a trip does not remove the audit logs its calculations produced.
Reporting lags a delete. Dashboards and reporting views refresh periodically, so a deleted trip can still appear in them until the next refresh.
This cannot be undone. Re-submitting the trip to
POST /v2/travel-datarestores the data, but recalculates its emissions and creates new IDs.
Errors
204
Delete succeeded — empty body.
401
Missing or invalid API key.
404
travel_data_not_found — see below. Nothing is deleted.
500
Internal server error.
Every miss on these endpoints collapses into the same response:
You get it when the trip does not exist, when it belongs to a client you cannot reach, when the identifier is neither a known trip id nor a known trip_reference, and when the activity belongs to a different trip or is a routing leg. A trip you cannot access is deliberately indistinguishable from one that does not exist.
The trip list is the exception: it never 404s on an empty result — a client with no reachable trips gets 200 and [].
Implementation notes
Set trip_reference on ingestion and you never need to store SQUAKE's IDs. Your own reference addresses the trip on every read and on delete. Activity IDs, however, only come from SQUAKE — take them from the submission response or from a trip read.
Reconcile through the trip, not the submission response. The trips array of a submission reports only the identity of what that request wrote. For the complete picture of a trip — its stored attributes, its cost center, and activities added by earlier or later submissions — read the trip.
Branch on type before reading an activity's route. origin, destination and fuel_type are absent, not null, for the types that do not have them, so a parser that assumes a fixed key set will break on the first hotel stay.
Use the activities endpoint for anything beyond the primary methodology. Additional methodologies and audit references are not in the flat items array of a submission; they are here.
Reads are eventually visible in reporting, deletes too. These endpoints read the stored records directly and are immediately consistent; dashboards and reporting views refresh on a schedule.
Related
Create Travel Data Items — ingest trips and activities.
Retrieve a specific Audit log — the full record behind a calculation's
audit.id.
Last updated