# Airbnb API for agents

> API for Agents · https://apiforagents.dev/platforms/airbnb · HTML twin: https://apiforagents.dev/platforms/airbnb

Listings, prices for a stay and reviews from Airbnb.

Endpoint: `POST https://apiforagents.dev/v1/airbnb`. One op per call. Quote first with `"estimateOnly": true`.

## Prices (USD per record, pay as you go)

| Record | Per record |
|---|---|
| listings | $0.0018 |
| reviews | $0.0018 |

## Operations

### listings

Full cards for up to ten listings by URL or room id, priced for a stay. Nightly and total price, availability, ratings by category, amenities, house rules, cancellation policy, host.

| Field | Required | Type | Meaning |
|---|---|---|---|
| subjects | yes | list of string (1-10 items) | Listing URLs or room ids. |
| stay | no | object |  |
| stay.checkIn | no | string (YYYY-MM-DD) | First night, YYYY-MM-DD. Only read together with checkOut. |
| stay.checkOut | no | string (YYYY-MM-DD) | Departure day, YYYY-MM-DD, after checkIn. |
| stay.adults | no | integer (1-16) | Guests aged 13+; the nightly price depends on the party. |
| stay.children | no | integer (0-10) | Guests aged 2-12. |
| stay.infants | no | integer (0-5) | Guests under 2; usually not counted toward the listing's capacity. |
| stay.pets | no | integer (0-5) | Pets, where the listing allows them; adds the pet fee to the total. |
| stay.currency | no | string (ISO 4217) | ISO 4217 code the prices come back in ("USD", "INR", "EUR"). |
| stay.locale | no | string (≤10 chars) | Language tag for titles and descriptions ("en-US", "fr-FR"). |

Response fields (each row of data; every field present, null when the source had nothing):

| Field | Type |
|---|---|
| listingId | string |
| listingUrl | string |
| title | string |
| propertyType | string |
| roomType | string |
| capacity | integer |
| summaryDetails | list of string |
| description | string |
| location | string |
| locationSubtitle | string |
| locationPath | string |
| latitude | number |
| longitude | number |
| neighborhoodNotes | any |
| ratings | any |
| ratingOverall | number |
| reviewsCount | integer |
| highlights | any |
| amenities | any |
| houseRules | any |
| cancellationPolicy | string |
| available | boolean |
| stay | string |
| currency | string |
| totalPriceText | string |
| pricePerNightText | string |
| baseSubtotalText | string |
| priceQualifier | string |
| totalPrice | number |
| pricePerNight | number |
| host | any |
| hostName | string |
| hostIsSuperhost | boolean |
| coHosts | any |
| images | any |
| thumbnail | string |
| details | object |

`details` is always the last field: everything else the source sent for that row, under our own field names. Its keys depend on the source that answered, so read them defensively; it is `{}` when there is nothing more.

Example request:

```bash
curl -X POST https://apiforagents.dev/v1/airbnb \
  -H "Authorization: Bearer $AFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"op":"listings","subjects":["https://www.airbnb.com/rooms/<room-id>"],"stay":{"checkIn":"2027-03-12","checkOut":"2027-03-15","adults":2,"currency":"USD"}}'
```

Example response rows (made-up names, real field names; a live row carries every field above):

```json
[
  {
    "title": "Sunny loft near the old town",
    "propertyType": "Entire loft",
    "roomType": "Entire home",
    "capacity": 3,
    "location": "Lisbon, Portugal",
    "ratingOverall": 4.92,
    "reviewsCount": 214,
    "pricePerNight": 118,
    "currency": "USD",
    "hostName": "Inês",
    "hostIsSuperhost": true,
    "amenities": [
      "Wifi",
      "Kitchen",
      "Washer"
    ],
    "listingId": "4266698829",
    "listingUrl": "https://www.airbnb.com/sunny-loft-near-the-old-town-1000",
    "details": {}
  },
  {
    "title": "Quiet garden studio",
    "propertyType": "Entire guest suite",
    "roomType": "Entire home",
    "capacity": 2,
    "location": "Bengaluru, India",
    "ratingOverall": 4.85,
    "reviewsCount": 96,
    "pricePerNight": 42,
    "currency": "USD",
    "hostName": "Meera",
    "hostIsSuperhost": false,
    "amenities": [
      "Wifi",
      "Air conditioning"
    ],
    "listingId": "4179722422",
    "listingUrl": "https://www.airbnb.com/quiet-garden-studio-1001",
    "details": {}
  }
]
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=airbnb&op=listings (sign in first).

### reviews

Reviews for up to ten listings. Text, rating, date, host response.

| Field | Required | Type | Meaning |
|---|---|---|---|
| subjects | yes | list of string (1-10 items) | Listing URLs or room ids. |
| locale | no | string (≤10 chars) | Language tag the review text is returned in ("en-US"); reviews in other languages come translated. |
| limit | no | integer (1-100) |  |

Response fields (each row of data; every field present, null when the source had nothing):

| Field | Type |
|---|---|
| reviewId | string |
| reviewText | string |
| translatedText | string |
| originalLanguage | string |
| rating | number |
| postedDate | string |
| highlight | string |
| highlightType | string |
| hostResponse | string |
| hostId | string |
| hostName | string |
| hostProfileUrl | string |
| reviewerUserId | string |
| reviewerName | string |
| reviewerProfile | string |
| reviewerAvatar | string |
| reviewerLocation | string |
| reviewerTenure | string |
| details | object |

`details` is always the last field: everything else the source sent for that row, under our own field names. Its keys depend on the source that answered, so read them defensively; it is `{}` when there is nothing more.

Example request:

```bash
curl -X POST https://apiforagents.dev/v1/airbnb \
  -H "Authorization: Bearer $AFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"op":"reviews","subjects":["https://www.airbnb.com/rooms/<room-id>"],"locale":"en-US","limit":25}'
```

Example response rows (made-up names, real field names; a live row carries every field above):

```json
[
  {
    "reviewerName": "Hannah",
    "reviewerLocation": "Berlin, Germany",
    "rating": 5,
    "reviewText": "Spotless, bright and a 2-minute walk to everything.",
    "postedDate": "2026-10-08",
    "hostName": "Inês",
    "hostResponse": null,
    "reviewId": "3422556718",
    "hostId": "84440075",
    "hostProfileUrl": "https://www.airbnb.com/hannah-1000",
    "reviewerUserId": "1660453336",
    "details": {}
  },
  {
    "reviewerName": "Arjun",
    "reviewerLocation": "Pune, India",
    "rating": 5,
    "reviewText": "Host replied in minutes. Would stay again.",
    "postedDate": "2026-09-30",
    "hostName": "Inês",
    "hostResponse": null,
    "reviewId": "3672073992",
    "hostId": "558151567",
    "hostProfileUrl": "https://www.airbnb.com/arjun-1001",
    "reviewerUserId": "598161622",
    "details": {}
  }
]
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=airbnb&op=reviews (sign in first).

### history (free)

Stored price/rating series of listings already held. Free.

| Field | Required | Type | Meaning |
|---|---|---|---|
| subjects | yes | list of string (1-10 items) |  |
| metric | no | enum |  Values: price_per_night, total_price, rating_overall, reviews_count. |
| days | no | integer (1-730) |  |

Request shape:

```json
{
  "op": "history",
  "subjects": [
    "example"
  ]
}
```

Try it in the playground: https://apiforagents.dev/dashboard/run?platform=airbnb&op=history (sign in first).

## Notes for the agent

Measured Airbnb data, one operation per call. Listings are named by URL or room id. A `stay` (checkIn, checkOut, adults, children, infants, pets, currency) is part of every price. Without dates a card comes back unpriced. And every priced fetch adds a point to the listing's history tagged with that stay. ops: listings (full cards for up to ten listings. Nightly and total price, availability, overall and per-category ratings, review count, amenities, house rules, cancellation policy, host with superhost flag), reviews (reviews for up to ten listings. Text, rating, date, host response), history (stored price/rating series for listings already held, free). Ops are independent. Issue several as PARALLEL tool calls. Fresh fetches are charged per record; your own answer is free while fresh.
