Proposals
Last verified: 2026-06-20 (Task #390 — User APIs documentation).
A proposal is a set of candidate entities (plus optional ranked scheduling options) raised by the planning agent for member review. Members list, inspect, and then accept or reject each one. All proposal endpoints require trip membership.
List proposals
GET /v1/trips/{tripId}/proposals?status={status}
status is optional (pending, accepted, rejected, expired).
{
"trip_id": 42,
"proposals": [
{ "proposal_id": "7b3c0e6e-…", "status": "pending", "actor_agent_id": "stay_agent", "created_at": "2026-06-20T11:00:00.000Z" }
]
}
Create a proposal
POST /v1/trips/{tripId}/proposals
curl -s -X POST "https://api.travelmode.ai/v1/trips/42/proposals" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"actor_agent_id": "stay_agent",
"entities": [ { "type": "accommodation", "title": "Hotel Quirinale" } ],
"options": [ { "id": "opt_1", "score": 0.92 } ]
}'
Responds 201 with the created proposal, including its server-assigned
proposal_id.
Get a single proposal
GET /v1/trips/{tripId}/proposals/{proposalId}
Returns the full proposal, including entities and ranked options.
Accept or reject
POST /v1/trips/{tripId}/proposals/{proposalId}?action=accept
POST /v1/trips/{tripId}/proposals/{proposalId}?action=reject
The action query parameter selects the outcome.
Accept (optionally choose one ranked option) applies the proposal and returns the created event ids:
curl -s -X POST \
"https://api.travelmode.ai/v1/trips/42/proposals/7b3c0e6e-…?action=accept" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "selected_option_id": "opt_1" }'
{
"proposal_id": "7b3c0e6e-…",
"status": "accepted",
"created_event_ids": [903, 904],
"accepted_at": "2026-06-20T12:00:00.000Z"
}
Reject records an optional reason:
curl -s -X POST \
"https://api.travelmode.ai/v1/trips/42/proposals/7b3c0e6e-…?action=reject" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "reason": "Hotel is outside budget" }'
{
"proposal_id": "7b3c0e6e-…",
"status": "rejected",
"rejection_reason": "Hotel is outside budget",
"rejected_at": "2026-06-20T12:00:00.000Z"
}
A proposal that is already resolved or has expired returns 400, as does
an unrecognised action.