Python SDK for the Strait hotel booking API — booking infrastructure for AI agents.
Project description
Strait Python SDK
Hotel booking for AI agents. Python client for the Strait API.
pip install getstrait
- Resolve a hotel name to a property ID
- Check availability and pricing
- Book with human-in-the-loop approval (or skip it for autonomous flows)
- Cancel confirmed bookings
- One-line tool adapters for Anthropic and OpenAI
Full API reference: getstrait.dev
Auth
Pass api_key= or set STRAIT_API_KEY:
from strait import Strait
strait = Strait(api_key="sk_live_...") # explicit
strait = Strait() # picks up STRAIT_API_KEY
Override the base URL (staging, self-host) with base_url= or STRAIT_BASE_URL.
Agent loop — Anthropic
Drop Strait into an Anthropic agent in three lines: get the tool definitions, run the model, and dispatch tool calls back through execute().
import anthropic
from strait import Strait
strait = Strait()
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Book me a night at Hotel Berlin on April 10."}]
while True:
resp = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=strait.tools.for_anthropic(),
messages=messages,
)
if resp.stop_reason != "tool_use":
break
tool_results = []
for block in resp.content:
if block.type == "tool_use":
result = strait.tools.execute(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
})
messages += [
{"role": "assistant", "content": resp.content},
{"role": "user", "content": tool_results},
]
By default, hotels_book and hotels_cancel_booking return UI-render data so a human can approve. Pass mode="auto" in the tool input to skip approval.
Agent loop — OpenAI
from openai import OpenAI
from strait import Strait
strait = Strait()
openai = OpenAI()
resp = openai.chat.completions.create(
model="gpt-4.1",
tools=strait.tools.for_openai(),
messages=[{"role": "user", "content": "Find me a hotel in Berlin for April 10-12."}],
)
Dispatch tool calls the same way: strait.tools.execute(name, json.loads(args)).
Direct API
The SDK also exposes the raw resources if you'd rather call endpoints yourself:
from strait import Strait
strait = Strait()
# 1. Resolve
match = strait.properties.resolve(name="Hotel Berlin", city="Berlin")
property_id = match.results[0].property_id
# 2. Availability
avail = strait.properties.availability(
property_id=property_id,
check_in="2026-04-10",
check_out="2026-04-12",
guests=2,
)
offer = avail.available_offers[0]
# 3. Book — auto mode (no human approval UI)
booking = strait.checkout.book(
offer_id=offer.offer_id,
guest_name="Jane Doe",
guest_email="jane@example.com",
mode="auto",
)
print(booking.confirmation_code)
Human approval vs auto
checkout.book() returns either a SessionResponse or ExecuteResponse depending on mode:
| mode | returns | side effects |
|---|---|---|
"human_approval" (default) |
SessionResponse |
Creates a checkout session; UI renders ui_render_data. |
"auto" |
ExecuteResponse |
Creates session and executes the booking immediately. |
Use the session pattern when a human needs to see the price before charging — your frontend renders session.ui_render_data and confirms via your own UI flow. Use "auto" for unattended agents.
Cancellation
# Preview (returns UI render data; does not cancel)
details = strait.bookings.cancel(confirmation_code="RKCRQJDV")
# Confirm cancellation
result = strait.bookings.cancel(
confirmation_code="RKCRQJDV",
mode="auto",
reason="plans changed",
)
Errors
All errors subclass StraitError:
from strait import (
APIError, # non-2xx response (base)
AuthenticationError, # 401
NotFoundError, # 404
RateLimitError, # 429
ServerError, # 5xx
)
try:
strait.properties.availability(property_id="bad", check_in="...", check_out="...", guests=2)
except NotFoundError as e:
print(e.status_code, e.body)
Notes
- Sync only for now. An
AsyncStraitclient is on the roadmap — raise an issue if you need it sooner. - Python 3.10+.
- Use as a context manager to close the HTTP pool deterministically:
with Strait() as strait: ...
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file getstrait-0.1.0.tar.gz.
File metadata
- Download URL: getstrait-0.1.0.tar.gz
- Upload date:
- Size: 28.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b609f83f4000bccf2d9e918cb468a7c684f4062076bfecbca50c8b91f25f0047
|
|
| MD5 |
9e4a7950b17e4fa68e2fa6dab4ade88b
|
|
| BLAKE2b-256 |
15d04ddf89d467382cf7c45eb8b9ec37ff70c43f29c00d73e887acf85d237d11
|
File details
Details for the file getstrait-0.1.0-py3-none-any.whl.
File metadata
- Download URL: getstrait-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a96c4a205ad9a5ed3f2b055c696dbcc0b04f16b3ffbdd8362ae22a38fa6b1e3
|
|
| MD5 |
f49b57fd871858dbdee2b0dd22d02fcb
|
|
| BLAKE2b-256 |
a1a857e190e75cbbebdd98192a3b7eb99178bcd96b8958b16f1872ad37d6872f
|