Authentication
Last verified: 2026-06-20 (Task #390 — User APIs documentation).
The Trips & Itinerary, Agent Runs,
and Events APIs all share the same
end-user authentication model. This is deliberately different from the
developer-key features (Weather, Visa, Platform), which authenticate with a
tm_ API key. There are no tm_ keys here.
Two ways to authenticate
| Credential | How it's sent | Typical caller |
|---|---|---|
| Session cookie | Cookie: session_token=… (set automatically by the browser after login) | First-party web app |
| Bearer token | Authorization: Bearer <token> | Mobile app (access token) and browser extension (session token) |
The server resolves the caller from whichever is present. A request with
neither returns 401 with { "error": "Authentication required" }.
# Bearer token (works from any client)
curl -s "https://api.travelmode.ai/v1/trips/42/itinerary" \
-H "Authorization: Bearer <token>"
# Session cookie (browser sends it automatically; shown explicitly here)
curl -s "https://api.travelmode.ai/v1/trips/42/itinerary" \
-H "Cookie: session_token=<session>"
Authorization: trip membership and roles
Authentication only proves who you are. Access to a specific trip is then gated by your membership and role on that trip:
| Role | Can read | Can mutate timeline | Can manage permissions |
|---|---|---|---|
owner | ✅ | ✅ | ✅ |
planner | ✅ | ✅ | ❌ |
editor | ✅ | ✅ | ❌ |
viewer | ✅ | ❌ | ❌ |
- Reads (itinerary, diff, summary, permissions list, proposals) require membership of the trip.
- Timeline operations require a mutating role.
- Permission changes are owner-only.
- A user's primary trip (
/v1/users/{userId}/trip) is self-only:userIdmust equal the authenticated user.
A caller who is authenticated but not authorized for the trip gets 403
({ "error": "Access denied" }), never a 401.
Using the Try It console
The interactive API reference ships a Try It console.
Because the in-browser console does not forward cookies, authorize it with
a bearer token: click Authorize, paste your token, and the console
sends Authorization: Bearer <token> on each call.