GET /trips — List your trips
Returns your upcoming trips by default. Add `?past=true` to include past trips.
**For "who should I meet on this trip?"** fetch `GET /trips/:tripID` (or the discovery-only `GET /trips/:tripID/discovery`) — both return the ranked top-10 DCers + AI-written summaries + the full pool of locals and visitors in town during the trip window. The list response below does NOT include the discovery block (lazy by design — discovery is a much heavier payload).
Query parameters
Response
-
trips object[]
Array of your trips. List responses ship a lean trip shape — `discovery` is always `null` on list reads to keep payloads small; fetch `GET /trips/:tripID` to get the enriched discovery block.
-
tripID string
Trip ID
-
note string
Trip note/description
-
location object
Trip destination (city-level)
-
startDate string
Start date (ISO 8601)
-
endDate string
End date (ISO 8601)
-
eventID string
DC event ID if this trip was created from an event, otherwise `null`.
-
createdAt string
Trip created-at (ISO 8601).
-
updatedAt string
Trip updated-at (ISO 8601).
-
points object[]
Embedded venue/idea notes (up to 20 per trip). Each `{ note, place }` where `place` is the full resolved Google Place object or `null` for note-only items.
-
roomID string
Linked auto-created chat room for this trip, or `null` if no room was provisioned.
-
discovery object
Always `null` on list reads. Fetch `GET /trips/:tripID` for the enriched discovery block.
-
nextCursor string
Cursor for the next page, or `null` if no more trips.
Example: List upcoming trips
{
"data": {
"trips": [
{
"endDate": "2026-04-17T00:00:00.000Z",
"location": {
"city": "Bangkok",
"country": "Thailand",
"countryCode": "TH",
"description": "Bangkok, Thailand",
"lat": 13.7563309,
"latLon": "13.7563309,100.5017651",
"lon": 100.5017651,
"name": "Bangkok",
"placeID": "ChIJ82ENKDJgHTERIEjiXbIAAQE",
"region": "Bangkok",
"regionCode": "10",
"utcOffsetMins": 420
},
"note": "DCBKK week",
"startDate": "2026-04-10T00:00:00.000Z",
"tripID": "abc123"
}
]
},
"ok": true
}
POST /trips — Create a trip
Create a new trip. Provide exactly one of `placeID` or `eventID` — the server resolves the location (city, country, country code) automatically. Use `GET /places/search` to find a placeID by city/country name first, or pass an `eventID` from `/events` to create a trip to that event's city.
**Trip points** (optional `points` array, up to 20 per trip): each item is `{ note: string (max 280 chars), noteHTML?: string, placeID?: string }`. The optional `placeID` is resolved against Google Places at write time and the full Place object (city, country, lat/lon, name, etc.) is stored on the trip — so reads don't do any lookups. `noteHTML` preserves the same rich text field the web trip editor stores for formatted notes, links, and mentions; `note` remains the required plain-text fallback. Notes without a placeID are valid ("remember to book a coworking space"). Pass an unknown / expired Google placeID → 400 with a clear error.
Request body
-
startDate string required
Start date (ISO 8601)
-
endDate string required
End date (ISO 8601)
-
placeID string
Google Place ID for the destination. Look one up via `GET /places/search`. **Pass exactly one of `placeID` or `eventID`** — sending both rejects with 400.
-
eventID string
DC event ID. Server uses the event's city placeID. **Pass exactly one of `placeID` or `eventID`** — sending both rejects with 400.
-
note string
Trip note
-
points object[]
Optional. Up to 20 trip points (venues / ideas / notes). Each item: `{ note: string (max 280 chars), noteHTML?: string, placeID?: string }`. The optional `placeID` is resolved against Google Places at write time. Notes without a place are valid.
Response
-
trip ApiTrip
The created trip
Example: Create a trip to Lisbon by placeID
{
"endDate": "2026-05-10",
"note": "Co-working week",
"placeID": "ChIJ-ZRLfIQzMBQR2bAQQ8sZh90",
"startDate": "2026-05-01"
}
{
"data": {
"trip": {
"endDate": "2026-05-10T00:00:00.000Z",
"eventID": null,
"location": {
"city": "Lisbon",
"country": "Portugal",
"countryCode": "PT",
"description": "Lisbon, Portugal",
"lat": 38.7222524,
"latLon": "38.7222524,-9.1393366",
"lon": -9.1393366,
"name": "Lisbon",
"placeID": "ChIJ-ZRLfIQzMBQR2bAQQ8sZh90",
"region": "Lisbon",
"regionCode": "11",
"utcOffsetMins": 60
},
"note": "Co-working week",
"startDate": "2026-05-01T00:00:00.000Z",
"tripID": "new123"
}
},
"ok": true
}
Example: Create a trip linked to an event
{
"endDate": "2026-05-22",
"eventID": "sWnllj1DW2jLMZ1n2KWB",
"note": "Attending DCBKK",
"startDate": "2026-05-18"
}
{
"data": {
"trip": {
"endDate": "2026-05-22T00:00:00.000Z",
"eventID": "sWnllj1DW2jLMZ1n2KWB",
"location": {
"city": "Bangkok",
"country": "Thailand",
"countryCode": "TH",
"description": "Bangkok, Thailand",
"lat": 13.7563309,
"latLon": "13.7563309,100.5017651",
"lon": 100.5017651,
"name": "Bangkok",
"placeID": "ChIJ82ENKDJgHTERIEjiXbIAAQE",
"region": "Bangkok",
"regionCode": "10",
"utcOffsetMins": 420
},
"note": "Attending DCBKK",
"startDate": "2026-05-18T00:00:00.000Z",
"tripID": "new456"
}
},
"ok": true
}
GET /trips/overlaps — Find overlapping trips
Find other members whose trips overlap with yours by city + date range. **This is a narrow date-window match, NOT the AI-ranked discovery pool.** For the full set of DCers you could meet on a trip — including locals in town and AI-written "why you should meet them" summaries — fetch `GET /trips/:tripID/discovery` (or `GET /trips/:tripID`, which embeds the same `discovery` block). The discovery pool is typically 5–10× larger than `/trips/overlaps` because it includes locals and event attendees in addition to date-overlap visitors, and it carries ranked top-10 picks with AI summaries that this endpoint does not.
Use `/trips/overlaps` for the simple "who is travelling here at the same time as me" question. Use `/trips/:tripID/discovery` for "who should I meet on this trip?".
Query parameters
Response
Example: Find who else is in Bangkok during your trip
{
"data": {
"overlaps": [
{
"matches": [
{
"member": {
"displayName": "Jane Doe",
"profileURL": "https://dc.dynamitecircle.com/profile/JaneDoe",
"userID": "123"
},
"overlapDays": 5,
"trip": {
"endDate": "2026-04-20T00:00:00.000Z",
"startDate": "2026-04-12T00:00:00.000Z",
"tripID": "theirtrip1"
}
}
],
"trip": {
"endDate": "2026-04-17T00:00:00.000Z",
"location": {
"city": "Bangkok"
},
"startDate": "2026-04-10T00:00:00.000Z",
"tripID": "mytrip1"
}
}
]
},
"ok": true
}
GET /trips/:tripID — Get a single trip
Single-trip read with the full payload. **This is the canonical endpoint for "who should I meet on this trip?"** — the response embeds a complete `discovery` block (ranked top-10 picks with AI summaries, the full pool of locals + visitors, events in town, and date-overlapping trips). If you only want the discovery block without the trip body, use `GET /trips/:tripID/discovery`.
**Key discovery fields agents almost always want:**
- `discovery.people` — **ranked top-10 DCers to meet** on this trip, each carrying `score` (higher = better match), mini `profile` (userID, userName, displayName, photo, headline), `reason` (`local` / `visiting` / `event-attendee`), `overlapDays`, `detail`. Sourced from a vector-search + business-context ranking, not just date overlap.
- `discovery.whyToMeet` — **AI-written "why you should meet them" paragraph** for each of the top-10, keyed by userID, each `{ text, generatedAt }`. The most useful AI signal in the whole trip product — agents should surface this verbatim when introducing a match.
- `discovery.fullPool` — every visible DCer travelling or local during the trip window (typically 5–10× larger than `/trips/overlaps`, which only returns date-window matches). Same row shape as `people` but no `score`.
- `discovery.overlappingTrips` — other DCers travelling at the same time/place, each with mini profile attached so no second fetch is needed. This is the same data that `/trips/overlaps` returns, embedded here for convenience.
- `discovery.events` — events in the destination city during the trip window.
- `discovery.generatedAt` — when the discovery cache was last refreshed.
**Also included:** `points` — up to 20 venue/idea notes with optional Google Place data, plus a linked `roomID` for the auto-created trip coordination room.
Hidden + guest profiles are filtered out from all discovery lists. The `discovery` block is `null` for newly-created trips until the background sync task runs (~seconds — call `POST /trips/:tripID/refresh` to force-recompute). Open to any authenticated DCer (you can read other DCers' trips too).
Path parameters
-
tripID e.g. abc123
The trip ID
Response
POST /trips/:tripID/refresh — Trigger a trip refresh
Owner-only sync trigger. Enqueues a deduped background job that recomputes the trip's discovery (overlapping people, events, AI blurbs). Spammy reloads coalesce. Returns 202 Accepted immediately; the cached `discovery` block on the trip doc updates when the job completes.
Path parameters
-
tripID e.g. abc123
The trip ID to refresh
Response