Metadata-Version: 2.5
Name: crewai-stayingapi
Version: 0.1.0
Summary: CrewAI tools for StayingAPI: search stays, check availability, price a stay, compare prices across booking sites and read reviews, from CrewAI agents.
Project-URL: Homepage, https://stayingapi.com
Project-URL: Documentation, https://stayingapi.com/docs
Project-URL: Pricing, https://stayingapi.com/pricing
Project-URL: Repository, https://github.com/stayingapi/crewai-stayingapi
Author-email: Zero Point Studio <hello@stayingapi.com>
License: MIT License
        
        Copyright (c) 2026 Zero Point Studio
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: accommodation,ai-agent,crewai,crewai-tools,hotels,llm,price-comparison,short-term-rental,stayingapi,travel,vacation-rental
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: crewai>=0.80.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: requests>=2.31.0
Description-Content-Type: text/markdown

# crewai-stayingapi

**StayingAPI: the accommodation data API for AI agents.** CrewAI tools edition. Also available as an [n8n community node](https://www.npmjs.com/package/n8n-nodes-stayingapi) and a [native MCP server](https://stayingapi.com/docs/mcp).

This package gives [CrewAI](https://www.crewai.com/) agents six tools over [StayingAPI](https://stayingapi.com), so a crew can work with real accommodation data instead of guessing: live search, day by day availability, real prices, cross platform price comparison and normalized reviews across Airbnb, Booking.com, Vrbo and Google Hotels, all in one unified schema.

| Tool | What it does | Credits |
|---|---|---|
| `search_stays` | Find listings across platforms by place, dates and occupancy | from 5 per platform (Airbnb 2 per result, Booking.com and Vrbo 1 per result, Google Hotels 15 per page) |
| `check_availability` | Day by day availability for a known listing | from 5 per listing, scales with the date range (Vrbo from 12) |
| `get_listing` | Full normalized detail for one listing | 3 per call (Vrbo 15) |
| `get_price` | Real price quote for one listing and one stay | 3 per call |
| `compare_prices` | Cross platform comparison for the same property | 30 in name and location mode, or 3 per listing in direct mode |
| `get_reviews` | Normalized guest reviews for a known listing | from 5 per platform (Airbnb 5 per review, Booking.com and Vrbo 1 per review) |

## Installation

```bash
pip install crewai-stayingapi
```

## Credentials

You need a StayingAPI key. Live keys start with `stay_live_`, sandbox keys start with `stay_test_`.

1. Create an account at [stayingapi.com/signup](https://stayingapi.com/signup): **300 free credits to start, no card required**. Full plan details on the [pricing page](https://stayingapi.com/pricing).
2. Create a key on the [keys page](https://stayingapi.com/dashboard/keys) of your dashboard.
3. Export it:

```bash
export STAYINGAPI_API_KEY="stay_live_..."
```

### Sandbox first

A `stay_test_` sandbox key returns deterministic sample data on the exact same schema, synchronously, and costs 0 credits. Build and test your crew against a sandbox key, then swap in a live key with no code changes.

## Usage

```python
from crewai import Agent
from crewai_stayingapi import (
    StayingAPISearchTool,
    StayingAPIAvailabilityTool,
    StayingAPIListingTool,
    StayingAPIPriceTool,
    StayingAPIPriceCompareTool,
    StayingAPIReviewsTool,
)

travel_researcher = Agent(
    role="Travel researcher",
    goal="Find good places to stay and the cheapest way to book them",
    backstory="Researches real accommodation options across booking platforms.",
    tools=[
        StayingAPISearchTool(),
        StayingAPIAvailabilityTool(),
        StayingAPIListingTool(),
        StayingAPIPriceTool(),
        StayingAPIPriceCompareTool(),
        StayingAPIReviewsTool(),
    ],
)
```

The usual flow is: `search_stays` to discover properties and collect their `platformListingId` values, then `get_listing`, `check_availability`, `get_price` or `get_reviews` on the ones that matter, and `compare_prices` when the crew has settled on a property and wants the best offer for it.

```python
# Discover: a city and a set of dates, no ids needed
StayingAPISearchTool().run(
    location="Split, HR",
    check_in="2026-09-10",
    check_out="2026-09-14",
    platforms="airbnb,booking",
    adults=2,
    limit=5,
)

# Compare: one property, every booking site that sells it
StayingAPIPriceCompareTool().run(
    name="Hotel Esplanade Zagreb",
    location="Zagreb, Croatia",
    check_in="2026-09-10",
    check_out="2026-09-14",
)
```

## Tool reference

### `search_stays` (StayingAPISearchTool)

| Argument | Type | Default | Description |
|---|---|---|---|
| `location` | str | required | City, region or address, for example `"Split, HR"` |
| `check_in` | str | none | Check in date, `YYYY-MM-DD` |
| `check_out` | str | none | Check out date, `YYYY-MM-DD` |
| `platforms` | str | all enabled | Comma separated: `airbnb`, `booking`, `vrbo`, `google` |
| `adults` | int | `2` | Number of adults, 1 to 30 |
| `children` | int | `0` | Number of children; requires `child_ages` |
| `child_ages` | str | none | One age per child, for example `"4,9"` |
| `rooms` | int | `1` | Number of rooms |
| `currency` | str | `"USD"` | ISO 4217 code |
| `limit` | int | `10` | Results per platform, 1 to 40 |
| `cursor` | str | none | Cursor from `meta.pagination.nextCursor` |
| `sort` | str | none | `recommended`, `price_asc`, `price_desc`, `rating_desc` |

`limit` applies per platform, so three platforms with `limit=5` can return 15 results and bills each platform separately.

### `check_availability` (StayingAPIAvailabilityTool)

| Argument | Type | Default | Description |
|---|---|---|---|
| `platform` | str | required | `airbnb`, `booking`, `vrbo` or `google` |
| `start_date` | str | required | First date of the window, `YYYY-MM-DD` |
| `end_date` | str | required | Last date of the window, `YYYY-MM-DD` |
| `listing_id` | str | one of three | Platform listing id |
| `listing_ids` | str | one of three | Comma separated ids on the same platform |
| `url` | str | one of three | Full listing URL |
| `only_available` | bool | none | Return only the available dates |

Pass exactly one of `listing_id`, `listing_ids` or `url`.

### `get_listing` (StayingAPIListingTool)

| Argument | Type | Default | Description |
|---|---|---|---|
| `platform` | str | required | `airbnb`, `booking` or `vrbo` |
| `listing_id` | str | required | Platform listing id, or a full listing URL |
| `country` | str | none | Two letter code, needed for a bare Booking.com slug |
| `check_in` | str | none | Add dates to get a live price with the detail |
| `check_out` | str | none | Check out date, `YYYY-MM-DD` |
| `currency` | str | `"USD"` | ISO 4217 code |

### `get_price` (StayingAPIPriceTool)

| Argument | Type | Default | Description |
|---|---|---|---|
| `platform` | str | required | `airbnb`, `booking`, `vrbo` or `google` |
| `listing_id` | str | required | Platform listing id |
| `check_in` | str | required | Check in date, `YYYY-MM-DD` |
| `check_out` | str | required | Check out date, `YYYY-MM-DD` |
| `currency` | str | `"USD"` | ISO 4217 code |

Booking.com slugs are not globally unique, so outside `get_listing` (which has its own `country` argument) pass the country qualified id, for example `"hr/esplanade-zagreb"`, or the full listing URL. A bare slug returns `needs_country` and costs nothing.

### `compare_prices` (StayingAPIPriceCompareTool)

| Argument | Type | Default | Description |
|---|---|---|---|
| `check_in` | str | required | Check in date, `YYYY-MM-DD` |
| `check_out` | str | required | Check out date, `YYYY-MM-DD` |
| `name` | str | one mode | Property name, when you have no listing ids |
| `location` | str | one mode | Location hint for that name |
| `google_hotel_id` | str | one mode | Google hotel id, instead of name and location |
| `listings` | str | one mode | 2 to 6 `platform:listingId` pairs for the same property |
| `adults` | int | `2` | Number of adults |
| `children` | int | `0` | Number of children |
| `currency` | str | `"USD"` | ISO 4217 code |

Two modes, one response shape. Pass `name` with `location` (or `google_hotel_id`) when you have no ids: the property is resolved for you and every offer it surfaces is returned, for 30 credits. Pass `listings` when you already have ids from `search_stays`: each listing is priced for real and the comparison is normalized, billed as 3 credits per listing.

Fee coverage differs per platform. Airbnb reports cleaning, service and taxes, Booking.com reports taxes, Vrbo and Google Hotels report none. Compare on `totalPrice`, which is present everywhere. A `null` fee means it could not be read, not that the platform does not charge it. `min` and `median` only summarize offers quoted in the requested `currency`.

### `get_reviews` (StayingAPIReviewsTool)

| Argument | Type | Default | Description |
|---|---|---|---|
| `platform` | str | required | `airbnb`, `booking` or `vrbo` |
| `listing_id` | str | one of two | Platform listing id |
| `url` | str | one of two | Full listing URL |
| `limit` | int | `20` | Reviews to return, 1 to 100 |
| `cursor` | str | none | Cursor from `meta.pagination.nextCursor` |
| `language` | str | none | Two letter language filter, for example `"en"` |
| `sort` | str | none | `recent`, `rating_desc`, `rating_asc` |

Ratings keep the native scale of each platform, so read `ratingScale` before comparing numbers across platforms.

## Platform coverage

| Operation | Airbnb | Booking.com | Vrbo | Google Hotels |
|---|---|---|---|---|
| `search_stays` | yes | yes | yes | yes |
| `check_availability` | yes | yes | yes | yes |
| `get_listing` | yes | yes | yes | no |
| `get_price` | yes | yes | yes | yes |
| `compare_prices` | yes | yes | yes | yes |
| `get_reviews` | yes | yes | yes | no |

Asking for a platform that does not serve an operation returns the error code `platform_not_enabled` and costs nothing.

## Response envelope

Every tool returns a stable JSON string and never raises:

```json
{
  "success": true,
  "data": [{"id": "stays_airbnb_42307961", "platform": "airbnb", "name": "..."}],
  "meta": {"creditsCharged": 5, "platforms": ["airbnb"], "cached": false, "partial": false}
}
```

```json
{
  "success": false,
  "error": {
    "code": "credit_balance_too_low",
    "message": "Not enough credits for this request.",
    "fix": "The account is out of credits. Top up or upgrade at https://stayingapi.com/pricing. Nothing was charged for this call.",
    "creditsCharged": 0
  }
}
```

`meta.creditsCharged` is the real cost of that request and `meta.platformResults[].creditsCharged` breaks it down per platform, so a crew can measure its own spend. Every error carries a `fix` field with the next step.

### Error codes

`missing_api_key`, `invalid_api_key`, `revoked_api_key`, `email_unverified`, `subscription_required`, `credit_balance_too_low`, `rate_limit_exceeded`, `missing_parameter`, `invalid_parameter`, `invalid_date_range`, `date_in_past`, `child_ages_mismatch`, `stay_too_long`, `window_too_long`, `invalid_listing_url`, `invalid_language`, `invalid_sort`, `invalid_cursor`, `limit_out_of_range`, `mutually_exclusive_params`, `platform_not_enabled`, `no_enabled_platform`, `needs_country`, `listing_not_found`, `job_not_found`, `all_actors_failed`, `actor_blocked`, `upstream_degraded`, `actor_timeout`, `internal_error`, plus the client side codes `network`, `bad_response`, `job_timeout`, `job_failed` and `http_<status>`. Each service code has a page at `https://stayingapi.com/docs/errors/<code>`.

**Failed, empty, blocked and not-found calls are never billed.**

### Long running calls

A live key answers a long running request with a job id and the tool polls that job for you, free of charge, until the result is ready. Sandbox keys answer synchronously. Set `STAYINGAPI_MAX_WAIT_SECONDS` to change how long the tool waits before returning `job_timeout` (default 180).

## Resources

- [StayingAPI documentation](https://stayingapi.com/docs)
- [Pricing](https://stayingapi.com/pricing): 300 free credits to start, no card required
- [Credits and billing](https://stayingapi.com/docs/credits)
- Family: [n8n community node](https://www.npmjs.com/package/n8n-nodes-stayingapi) and [MCP server](https://stayingapi.com/docs/mcp)

## Disclosure

StayingAPI is an independent service for accommodation data. StayingAPI is not affiliated with, endorsed by, or sponsored by Airbnb, Booking.com, Vrbo, or Google Hotels. These are trademarks of their respective owners, used here descriptively to indicate the data sources StayingAPI can query.

Use of these tools is subject to the [StayingAPI terms](https://stayingapi.com/terms).

## License

[MIT](LICENSE)
