Travel Companions

Travel Companions API and MCP server

One set of tools, two interfaces: a remote MCP server for AI assistants and a REST API described by OpenAPI 3.1. Both are generated from the same schemas, so they never drift apart.

Quickstart

Search without an account

curl "https://travel.coticsy.com/v1/trips?to.city=Lisbon&to.country=PT&startDate=2027-03-01&endDate=2027-03-10"

Call any tool

curl -X POST https://travel.coticsy.com/v1/tools/search_travelers \
  -H 'content-type: application/json' \
  -d '{"to":{"city":"Lisbon","country":"PT"},"languages":["pt"]}'

Connect an MCP client

Endpoint https://travel.coticsy.com/mcp (Streamable HTTP, stateless, JSON responses). Public tools work without auth; account tools prompt the user to sign in. Clients that only start OAuth when challenged at connect time should use https://travel.coticsy.com/mcp/auth.

{
  "mcpServers": {
    "travel-companions": {
      "type": "http",
      "url": "https://travel.coticsy.com/mcp"
    }
  }
}

Authentication

Trust ladder

  1. Public: search and browse masked trips and travelers.
  2. Account: profile, post trips, personal matches, webhooks.
  3. Terms + 18+ (accept_terms): connection requests, relayed messages, reviews.
  4. ID verified (start_id_verification): verified badge and contact exchange.

When a call needs a higher level, the error says exactly what to do next:

{"error":{"code":"TRUST_REQUIRED","message":"This action requires trust level 2 (current 1).","nextStep":"Ask the user to confirm they are 18+ and agree to the Terms (link: https://travel.coticsy.com/terms), then call accept_terms and retry.","requiredTrustLevel":2}}

Tools

ToolAccessWhat it does
search_tripsPublicFind travelers looking for companions. Works without an account. Filter by destination, origin, dates, needs (share_room, split_costs...), languages, sex, age range. Free text `q` matches plans and interests semantically. Results are ranked by compatibility and include masked traveler cards (first name + initial, age range, city).
search_travelersPublicBrowse masked traveler cards (not trip posts). Filter by destination of their open trips, languages, age, nationality, interests, or free text. Useful when the user asks who is going somewhere rather than for a specific date window.
get_tripPublicGet the public view of one trip by id, including the masked traveler card.
get_traveler_cardPublicGet the public, masked card of a traveler by their public id.
list_popular_destinationsPublicDestinations with the most open trips right now. Useful to suggest where companions are easiest to find.
list_needs_taxonomyPublicSuggested `needs` tags. Any snake_case tag is accepted, but these are the common ones.
get_my_statusPublicTells the agent what the current user can do: trust level, plan, whether a profile exists, and the next steps to unlock more (create profile, accept terms, verify ID).
create_or_update_profileAccountCreate the traveler profile on first call (all required fields) or update parts of it later. Birth date and postal code stay private; others see an age range and city only.
get_my_profileAccountReturn the full profile of the authenticated user.
post_tripAccountPublish a trip to find companions. kind=solo (default) for a traveler seeking companions, kind=group to organize a group with N spots, kind=meetup when already at the destination. Requires a profile.
update_tripAccountUpdate fields of one of my trips.
close_tripAccountClose or cancel one of my trips so it no longer appears in search.
list_my_tripsAccountList the authenticated user's trips, optionally filtered by status.
get_my_matchesAccountRanked compatible travelers for one of my trips, with reasons. Uses my profile preferences and the other side's preferences.
create_group_tripAccountCreate a group trip with multiple open spots. Same fields as post_trip; kind is forced to group.
meet_at_destinationAccountPost a meetup for someone already at (or about to arrive at) a destination. kind is forced to meetup.
join_group_tripTerms + 18+Request to join an open group trip. Requires terms acceptance. Owner must accept via respond_to_connection.
accept_termsAccountRecord that the user is 18+ and accepts the Terms of Service. Required before connecting with other travelers. Send them {base}/terms first.
request_connectionTerms + 18+Send a connection request to the owner of a trip. Both sides must accept before contact is shared. Requires accept_terms first.
respond_to_connectionTerms + 18+Accept or decline an incoming connection request.
list_connectionsTerms + 18+List incoming and outgoing connection requests and accepted connections.
send_messageTerms + 18+Send a relayed message on an accepted connection. Emails stay private.
get_messagesTerms + 18+List relayed messages on an accepted connection.
reveal_contactID verifiedReveal the counterpart's email (and phone if set) after both sides accept. Requires ID verification (trust level 3).
leave_reviewTerms + 18+Leave a 1-5 star review of a companion from an accepted connection, once the trip is over (from the day after its end date). One review per traveler per trip.
subscribe_match_webhookAccountRegister an HTTPS URL that receives signed POSTs when new matches or connection events fire for this user. Agents use this to proactively notify travelers. The signing secret is returned once.
report_userAccountReport a traveler for spam, scam, harassment, fake profile or safety concerns.
block_userAccountBlock a traveler. Neither side will see the other in search or be able to connect.
export_my_dataAccountReturn everything stored about the authenticated user (GDPR/CCPA export).
delete_my_accountAccountPermanently delete the account, profile, trips and messages. Irreversible. The agent must confirm with the user first.
start_id_verificationTerms + 18+Create a Stripe Identity verification session. Send the returned URL to the user. Unlocks the verified badge and contact reveal.
start_premium_checkoutAccountCreate a Stripe Checkout (Link-compatible) session for Premium. Send the returned URL to the user.
get_subscriptionAccountReturn the current plan, status and usage limits.
find_shared_stayTerms + 18+Affiliate search for hotels/villas near the destination that two matched travelers can share.
find_flights_togetherTerms + 18+Affiliate flight search for matched travelers sharing an itinerary.
find_travel_insuranceAccountAffiliate link for travel insurance suitable for companion trips.
find_esimAccountAffiliate link for destination eSIMs.

Machine-readable: /v1/tools (with input schemas) · llms-full.txt

HTTP semantics

Webhooks

subscribe_match_webhook registers an HTTPS URL for match.new, connection.requested, connection.accepted and message.received. The signing secret is returned once. Each POST carries X-TC-Signature: t=<unix>,v1=<hex> where v1 = HMAC-SHA256(secret, t + "." + body); reject timestamps older than 5 minutes.

Discovery

Support

support@travelcompanions.ai · Terms · Privacy