1Stay API
Reference

1Stay gives AI agents and applications access to real hotel inventory — 300,000+ properties across 140+ countries — through a simple MCP server. Reservations use the hotel's own confirmation number. Loyalty points are eligible. You're never the merchant of record.

The MCP server name is 1stay at endpoint mcp.stayker.com. There are 7 tools covering the complete booking lifecycle.

Early Access. 1Stay is onboarding developers by application. Sandbox access is free for 30 days — production requires approval and a Stripe account. Apply for access →

MCP Server Details

MCP Configuration
// Claude Desktop / claude_desktop_config.json
{
  "mcpServers": {
    "1stay": {
      "url": "https://mcp.stayker.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
Authentication
Authorization: Bearer YOUR_API_KEY

What Makes This Different

Most hotel APIs are OTA-style: you buy inventory, mark it up, you're the merchant. 1Stay is infrastructure: your agent connects guests to hotels directly. The hotel charges the guest. You build the experience, your users pay for your product — 1Stay is the booking layer that makes it possible. No inventory risk, no float, no chargebacks.

Three things that matter to your users: Loyalty points are eligible (guest books direct-equivalent). The hotel's own confirmation number appears in the guest email. And if the guest has a problem, they call the hotel — not you.

Quick
Start

From zero to a hotel checkout link in three tool calls. The canonical flow for any AI agent.

1

Search for hotels

Call search_hotels with location (or lat/lng coordinates), dates, and guest count. Returns a list of available properties with rates.

Example
// Tool: search_hotels
{
  "location": "Austin, TX",
  "check_in": "2026-05-01",
  "check_out": "2026-05-04",
  "guests": 2
}

// Returns: list of hotels with hotel_id, rates, rate_code per rate
2

Get hotel details

Call get_hotel_details with the hotel_id. Returns room types, rates, cancellation policies, amenities, and everything your agent needs.

Example
// Tool: get_hotel_details
{
  "hotel_id": "htl_x9y8z7"
}

// Returns: rates[], room types, cancellation policies, amenities
3

Book it

Call book_hotel with the guest's info and the rate_code from the hotel details. Returns a secure checkout URL — the guest completes payment there.

Example
// Tool: book_hotel
{
  "hotel_id": "htl_x9y8z7",
  "rate_code": "RAC-STK-F8E2",
  "check_in": "2026-05-01",
  "check_out": "2026-05-04",
  "guests": 2,
  "guest_name": "Jane Smith",
  "guest_email": "jane@example.com"
}

// Returns: checkout_url, total — guest pays at checkout URL

API Keys &
Auth

All requests require a Bearer token in the Authorization header. API keys are issued per application and scoped to either sandbox or production mode.

Request Header
Authorization: Bearer 1stay_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Sandbox keys begin with sk_test_. Production keys begin with 1stay_live_. You'll receive your key after approval and Stripe onboarding.

Never expose your API key in client-side code. All 1Stay API calls should be made from your server. API keys can make real bookings that incur real charges.

Key Scopes

Production plans include 50,000 searches per month with overage billed at $0.002/search. Sandbox keys use test properties and never charge guests. Production keys access live inventory and create real reservations.

search_hotels

Search for available hotels by location and dates. Returns a ranked list of properties with rates and a search_id valid for 15 minutes. The canonical entry point for any booking flow.

🔍
search_hotels
Find available hotels with live rates for a given location and date range
▲ collapse
Parameters
ParameterTypeRequiredDescription
locationstringoptionalCity and state/country. e.g. "Austin, TX" or "London, UK". Optional if lat/lng provided.
check_instringrequiredCheck-in date. ISO 8601 format: YYYY-MM-DD
check_outstringrequiredCheck-out date. ISO 8601 format: YYYY-MM-DD. Must be after check_in.
guestsintegerrequiredNumber of adult guests. Min 1, max 8.
latnumberoptionalLatitude coordinate. Use with lng for precise neighborhood searches.
lngnumberoptionalLongitude coordinate. Use with lat.
radiusintegeroptionalSearch radius in miles. Default: 25. Max: 100.
currencystringoptionalISO 4217 currency code for rates. Default: USD.
max_resultsintegeroptionalMax results to return. Default: 10. Max: 15.
Example Request
{
  "location": "Nashville, TN",
  "check_in": "2026-06-12",
  "check_out": "2026-06-15",
  "guests": 1
}
200 OK Success Response
{
  "search_id": "srch_a1b2c3d4e5f6",
  "expires_at": "2026-06-12T14:45:00Z",
  "count": 34,
  "hotels": [
    {
      "hotel_id": "htl_x9y8z7w6",
      "name": "The Hermitage Hotel",
      "address": "231 6th Ave N, Nashville, TN",
      "stars": 5,
      "from_rate": 189.00,
      "currency": "USD",
      "loyalty_eligible": true,
      "distance_miles": 0.25
    }
    // ... more hotels
  ]
}

get_hotel_details

Get room types, live rates, amenities, and cancellation policies for a specific hotel. This is the tool your agent calls before booking — it returns rate_code values needed by book_hotel. Rate codes expire in ~15 minutes.

🏨
get_hotel_details
Room types, live rates, cancellation policies, and amenities. Returns rate_codes for booking.
▼ expand
Parameters
ParameterTypeRequiredDescription
hotel_idstringrequiredHotel ID from a search_hotels response
check_instringrequiredCheck-in date (YYYY-MM-DD)
check_outstringrequiredCheck-out date (YYYY-MM-DD)
guestsintegeroptionalNumber of guests (default 2)
roomsintegeroptionalNumber of rooms (default 1)
Example Request
{
  "hotel_id": "TP-MC-DALCC",
  "check_in": "2026-06-12",
  "check_out": "2026-06-15",
  "guests": 2
}
200 OK
{
  "hotel": {
    "hotel_id": "TP-MC-DALCC",
    "name": "Dallas Marriott City Center",
    "chain": "Marriott",
    "check_in_time": "15:00",
    "check_out_time": "12:00"
  },
  "rooms": [
    {
      "room_id": "rm_01",
      "name": "King Guest Room",
      "description": "One king bed, city view",
      "bed_type": "King",
      "max_occupancy": 2,
      "rate_plans": [
        {
          "rate_code": "RAC-STK-A1B2",
          "name": "Best Available Rate",
          "avg_nightly_rate": 189.00,
          "subtotal": 572.00,
          "taxes": 82.37,
          "total_with_taxes": 654.37,
          "currency": "USD",
          "nightly_breakdown": [
            { "date": "2026-06-12", "amount": 189.00 },
            { "date": "2026-06-13", "amount": 189.00 },
            { "date": "2026-06-14", "amount": 189.00 }
          ],
          "refundable": true,
          "cancellation_policy": "Free cancellation until 48hrs before arrival",
          "reward_points_eligible": true,
          "booking_type": "Direct hotel confirmation"
        }
      ]
    }
  ],
  "rate_quote_expires_at": "2026-06-10T14:45:00Z",
  "rate_quote_ttl_seconds": 900
}
Rate codes expire in ~15 minutes. If you need to book, call book_hotel with the rate_code before it expires. If expired, call get_hotel_details again for fresh rates.

book_hotel

Create a reservation using a rate_code from get_hotel_details. Returns a secure checkout URL where the guest completes payment. The reservation is not confirmed until the guest pays.

book_hotel
Create a reservation. Returns a secure checkout URL for payment.
▼ expand
Parameters
ParameterTypeRequiredDescription
hotel_idstringrequiredHotel ID from a search_hotels or get_hotel_details response
rate_codestringrequiredRate code from get_hotel_details response
check_instringrequiredCheck-in date. ISO 8601 format: YYYY-MM-DD
check_outstringrequiredCheck-out date. ISO 8601 format: YYYY-MM-DD
guestsintegerrequiredNumber of adult guests
guest_namestringrequiredGuest's full name as it appears on their ID
guest_emailstringrequiredGuest email — confirmation is sent here after payment
external_reference_idstringoptionalYour own reference ID for this booking. Stored for your records.
Payment happens outside the conversation. The checkout_url returned by this tool is where the guest completes payment. The reservation is not confirmed until the guest pays. Checkout sessions expire after ~30 minutes.
Example Request
{
  "hotel_id": "htl_x9y8z7w6",
  "rate_code": "RAC-STK-F8E2",
  "check_in": "2026-06-12",
  "check_out": "2026-06-15",
  "guests": 2,
  "guest_name": "Jane Smith",
  "guest_email": "jane@example.com"
}
200 OK
{
  "checkout_url": "https://booking.stayker.com/hotel?hotel_id=htl_x9y8z7w6&check_in=2026-06-12&check_out=2026-06-15",
  "hotel": "The Hermitage Hotel",
  "check_in": "2026-06-12",
  "check_out": "2026-06-15",
  "total": 567.00,
  "currency": "USD",
  "status": "pending_payment",
  "expires_at": "2026-06-12T15:15:00Z"
}

get_booking

Retrieve the details of an existing booking by booking_id. Scoped to your API key — you can only retrieve bookings created with your key.

📋
get_booking
Retrieve booking details by ID. Scoped to your API key.
▼ expand
Parameters
ParameterTypeRequiredDescription
booking_idstringrequiredBooking ID returned from a book_hotel response
200 OK
{
  "booking_id": "bk_9f8e7d6c",
  "status": "confirmed",
  "confirmation_number": "HLC-98234",
  "hotel": "The Hermitage Hotel",
  "check_in": "2026-06-12",
  "check_out": "2026-06-15",
  "guest_name": "Jane Smith",
  "total": 567.00,
  "created_at": "2026-06-10T14:52:33Z"
}

retrieve_booking

Find a reservation and resend the confirmation email. This is the guest-facing lookup tool — it requires identity verification before any information is accessed. Confirmation is sent to the email on file (not returned in the response) to protect guest privacy.

🔎
retrieve_booking
Find a reservation and resend confirmation. Requires identity verification.
▼ expand
Parameters
ParameterTypeRequiredDescription
first_namestringrequiredGuest first name on the reservation
last_namestringrequiredGuest last name on the reservation
confirmation_numberstringoptional*Hotel confirmation number — provide this, email, or last_four_card
emailstringoptional*Email address used when booking
last_four_cardstringoptional*Last 4 digits of card used to book (requires check_in_date)
check_in_datestringoptionalCheck-in date (YYYY-MM-DD) — required when using last_four_card
Identity verification required. You must provide first_name + last_name plus at least one verification factor: email, confirmation_number, or last_four_card. Booking details are not returned in the response — a confirmation email is resent to the address on file.
200 OK
{
  "status": "found",
  "message": "Found your reservation. A confirmation email has been resent to the email address on file."
}

cancel_booking

Cancel an existing reservation. Requires identity verification — the guest's name and confirmation number must match. Cancellation is subject to the hotel's cancellation policy. Always surface the policy to the guest before confirming cancellation.

cancel_booking
Cancel a reservation with identity verification. Subject to hotel's cancellation policy.
▼ expand
Parameters
ParameterTypeRequiredDescription
first_namestringrequiredGuest's first name. Must match the booking record.
last_namestringrequiredGuest's last name. Must match the booking record.
confirmation_numberstringrequiredHotel confirmation number from the booking
Always confirm with the guest first. Show them the cancellation policy and penalty (if any) before calling this tool. Cancellation cannot be undone.
200 OK
{
  "booking_id": "stk_bk_9f8e7d6c",
  "status": "cancelled",
  "cancellation_number": "CXL-4421",
  "penalty": 0,
  "refund_amount": 567.00,
  "cancelled_at": "2026-06-11T09:14:22Z"
}

search_tools

Discover available MCP tools and their capabilities at runtime. Useful for agents that want to dynamically understand what operations are supported without relying on static documentation.

🛠
search_tools
List and describe available MCP tools at runtime. No parameters required.
▼ expand

No parameters required. Returns the complete list of tools with descriptions and parameter schemas.

200 OK
{
  "server": "1stay",
  "version": "1.0.0",
  "tools": [
    {
      "name": "search_hotels",
      "description": "Search available hotels by location and dates",
      "parameters": { /* schema */ }
    }
    // ... all 7 tools
  ]
}

Error
Codes

All errors return a JSON body with an error field (machine-readable code) and a message field (human-readable). Design your agent to handle these gracefully.

HTTPError CodeWhen / What to Do
200Idempotency hit — same key, booking already created. Returns original booking.
201Booking created successfully.
400invalid_requestMissing or invalid fields. Check guest data and required params.
400cache_id_invalidrate_code doesn't exist. Did you use a code from a different search?
401unauthorizedAPI key missing, invalid, or revoked.
409rate_changedRate changed between search and booking. See Rate Change Handling.
410rate_unavailableRoom/rate no longer available. Search again.
410cache_expiredRate quote expired (~15 min). Call get_hotel_details again.
429budget_exceededDaily search or booking budget exhausted. Resets midnight UTC.
500booking_failedUpstream error. No booking was created. Safe to retry with same idempotency key.

Rate Change
Handling

Hotel rates are live inventory. Any price difference between when you called get_hotel_details and when you call book_hotel may trigger a 409 rate_changed response — even a difference of $0.01. No exceptions. No silent overrides. The guest always sees every change.

Zero tolerance policy. Rate changes up, down, or sideways all require guest confirmation. This protects your users and keeps you off the hook.
409 rate_changed Response
{
  "error": "rate_changed",
  "original_rate": { "nightly": 189.00, "total": 567.00 },
  "new_rate": { "nightly": 209.00, "total": 627.00 },
  "difference": { "nightly": 20.00, "total": 60.00, "direction": "increase" }
}

If you receive a rate_changed response, surface the new rate to the guest and let them decide. To proceed at the new rate, start a fresh book_hotel call. If the guest declines, call search_hotels again to find alternatives.

What your agent should say

ScenarioSuggested Agent Response
Rate increased"The hotel just updated this room from $189 to $209/night — that's $60 more for your stay. Want to book at the new rate or look at other options?"
Rate decreased"Good news — the rate dropped from $209 to $189/night, saving you $60. Want me to lock it in?"
Small change"The rate changed slightly from $189.00 to $189.47/night — likely a tax adjustment. That's $1.41 more total. Shall I proceed?"

Access
Tiers

API capabilities and limits vary by access tier. All tiers use the same endpoints, response formats, and error codes — only the data volume and booking behavior differ.

Capability Sandbox Production Enterprise
Key prefix sk_test_ 1stay_live_ 1stay_live_
Hotels per search 5 15 Custom
Rate plans per hotel 2 All available All available
Bookings Simulated only Live reservations Live reservations
Searches / month 100 / day 50,000 included Custom
Search overage $0.002 / search Custom
Monthly fee Free (30 days) $99 / mo Custom
Platform fee Small fee / booking Custom
Booking service fee Set your own via Stripe Connect Custom structure
Cancellations Simulated Live Live
Duration 30 days Ongoing Contract term
Same code, different key. Your integration code is identical between sandbox and production. Swap sk_test_ for 1stay_live_ and you're live. Response formats, error codes, and tool interfaces don't change.

Sandbox
Mode

Sandbox keys (sk_test_...) return realistic test data without making real reservations. Use sandbox for development, integration testing, and demos.

Sandbox keys cannot create real bookings. Any call to book_hotel with a sk_test_ key returns a simulated confirmation. No hotel is contacted, no guest is charged, no reservation is created. This is enforced server-side and cannot be bypassed.
30-day trial. Sandbox access is valid for 30 days from approval. A reminder goes out at day 25. If you need more time, a self-serve extension is available once from your dashboard. After that, the path forward is production — or a conversation.
Sandbox is production-identical. Same response format, same error codes, same rate change handling — just with test properties and no real bookings. Your integration code doesn't change between sandbox and production.

Switch from sandbox to production by swapping your key from sk_test_ to 1stay_live_. No other code changes required.

Questions? Email hello@1stay.ai.