# Multi-OTA Hotel Price Comparator (`dapper_rotorcraft/multi-ota-price-comparator`) Actor

Search one or more locations across multiple OTAs (Booking.com, Hotels.com, Expedia, Agoda, Vrbo, Airbnb, Google Travel...) and normalize the prices into a single, currency-comparable dataset with the best price per hotel.

- **URL**: https://apify.com/dapper\_rotorcraft/multi-ota-price-comparator.md
- **Developed by:** [ossama](https://apify.com/dapper_rotorcraft) (community)
- **Categories:** Travel, Automation, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Multi-OTA Hotel Price Comparator

Compare hotel prices for one or more locations across **7+ travel platforms at
once** — Booking.com, Hotels.com, Expedia, Agoda, Vrbo, Airbnb and Google Travel —
and get a single, **currency-normalized** dataset with the **best price per hotel**
and the cross-platform savings.

### What does Multi-OTA Hotel Price Comparator do?

For every location you enter (e.g. *London, Manchester, Birmingham*), the Actor
queries each selected platform, normalizes every offer into one schema, converts
all prices into your chosen currency, and groups the same hotel across platforms
so you can instantly see **which OTA is cheapest**. You get, per offer: hotel name,
room/property type, price (per-night and whole-stay), currency, converted price,
rating (always on /10), review count, coordinates, images (with captions), badges
and amenities. Per hotel, you get the best price, the price spread and the
percentage you can save by booking on the right platform.

> 🧠 **How it works.** The big OTAs block direct scraping with commercial anti-bot
> systems. Instead of fighting that, this Actor **subcontracts the scraping to
> maintained Apify Store actors** (e.g. `voyager/booking-scraper`, 3.8M runs) via
> `Actor.call()`, and focuses on the genuinely hard part: a correct, currency-aware
> **cross-platform comparison**.

### Which platforms are supported?

| Platform      | Key             | Status |
|---------------|-----------------|--------|
| Booking.com   | `booking`       | ✅ Verified (real prices live) |
| Hotels.com    | `hotels_com`    | ✅ Verified (real prices live) |
| Expedia       | `expedia`       | ✅ Verified (real prices live) |
| Agoda         | `agoda`         | ✅ Verified (real prices live) |
| Vrbo          | `vrbo`          | ✅ Verified (real prices live) |
| Airbnb        | `airbnb`        | ✅ Verified (rich output) |
| Google Travel | `google_travel` | ✅ Verified (real prices live) |
| Trip.com      | `trip_com`      | ⚠️ Best-effort — free Store actors don't serve hotel data |
| Trivago       | `trivago`       | ⚠️ Best-effort — very slow, no date support |

Pick any subset, or leave the platform list empty to query all of them.
Non-working platforms are skipped cleanly (a warning in the log, never a crash).

> ⚠️ **Free tier note.** The Airbnb scraper requests ~4 GB. On the free plan
> (8 GB total), run Airbnb **alone or with `concurrency=1`** to avoid the memory cap.

### How much will it cost?

You only pay Apify platform usage plus whatever the subcontracted Store actors
charge per run/result (billed to **whoever runs this Actor**). A typical
single-location, few-platform run costs only a few cents. Heavier platforms
(residential proxy, more results) cost more — tune `maxResultsPerPlatform` and the
platform list to control spend.

### Input

- **`locationQueries`** *(required)* — list of locations to search, e.g.
  `["London", "Manchester", "Birmingham"]`. Each is searched and compared separately.
- **`checkIn` / `checkOut`** *(required)* — `YYYY-MM-DD`.
- **`platforms`** — subset to query, or empty for all.
- **General search options** — `locale`, `currency`, `priceMin`, `priceMax`,
  `minBeds`, `minBedrooms`, `minBathrooms`, `adults`, `children`, `infants`, `pets`.
  (Platforms apply the options they support; e.g. beds/infants/pets are Airbnb.)
- `maxResultsPerPlatform`, `concurrency`, `debugDumpHtml`.

#### Input example

```json
{
  "locationQueries": ["Marrakech"],
  "checkIn": "2026-07-10",
  "checkOut": "2026-07-12",
  "platforms": ["booking", "agoda", "expedia", "google_travel"],
  "adults": 2,
  "currency": "EUR"
}
````

### Output

Two outputs:

1. **Default dataset** — one row per offer per platform, normalized. Each offer is
   enriched with `price_per_night`, `price_total_stay`, `price_total_converted`
   (in your currency), `latitude`/`longitude`, `images`, `badges`, `amenities`...
2. **Comparison** — written to the Key-Value Store under `COMPARISON` (grouped by
   location → list of hotels) and to a dataset named `comparison` (one row per
   hotel). Each hotel group has: the offers, `platforms_found`, the `best_price`,
   the `price_spread` and `max_savings_pct` (how much you save by picking the right
   platform).

#### Output example (one normalized offer)

```json
{
  "source_platform": "airbnb",
  "location_query": "Prague",
  "hotel_name": "Lovely Apartment Heart in Old Town",
  "room_type": "entire_home",
  "address": "Apartment in Prague",
  "latitude": 50.090172,
  "longitude": 14.417268,
  "check_in": "2026-07-10",
  "check_out": "2026-07-12",
  "adults": 2,
  "price_amount": 679,
  "price_currency": "USD",
  "price_is_total_stay": true,
  "price_qualifier": "total",
  "price_per_night": 339.5,
  "price_total_stay": 679,
  "price_total_converted": 679,
  "price_currency_converted": "USD",
  "rating": 9.9,
  "review_count": 663,
  "badges": ["Guest favorite"],
  "subtitles": ["Free cancellation"],
  "amenities": [],
  "images": [
    { "url": "https://a0.muscache.com/im/.../a.jpg", "captions": [] },
    { "url": "https://a0.muscache.com/im/.../b.jpg", "captions": ["4 beds", "3 bedrooms"] }
  ],
  "url": "https://www.airbnb.com/rooms/1686130"
}
```

#### Why the comparison is correct

- **Currencies are unified.** Every offer is converted into your `currency` before
  comparison (verified live: Booking in EUR + Agoda/Expedia in USD, all compared in
  one currency). Live FX rates with a static fallback — see `src/currency.py`.
- **Per-night vs whole-stay is harmonized.** Each offer is reduced to both a
  per-night and a whole-stay price according to its platform, so the best price is
  apples-to-apples.

Real example from a live Marrakech run: *Grand Plaza Marrakech* came back **23%
cheaper on Google Travel than on Agoda**.

### How to use the scraped data

- Monitor prices for your locations and catch the cheapest platform per hotel.
- Track price spreads and savings opportunities across OTAs.
- Feed competitive pricing/revenue tools, dashboards, or Google Sheets.
- Spot emerging destinations and price trends across cities.

### Architecture

```
.actor/                actor.json + input_schema.json
src/
  main.py              orchestration: validate input, loop locations × platforms,
                       call Store actors, enrich + compare, push
  params.py            SearchParams (one location + dates + occupancy + filters)
  normalize.py         normalized schema + fuzzy matching + best-price comparison
  currency.py          FX rates (live + static fallback) and conversion
  utils.py             price/rating parsing + platform selection
  adapters/
    base.py            StoreAdapter: build_input(params) + map_item(item, params)
    booking / hotels_com / expedia / agoda / vrbo / airbnb / google_travel  (✅)
    trip_com / trivago                                                       (⚠️)
tests/                 pytest on the pure logic (no network)
```

Adding/fixing a platform = a small adapter subclassing `StoreAdapter`
(`store_actor_id` + `build_input` \[+ `map_item`]) registered in
`src/adapters/__init__.py`. Nothing else changes.

### Tests

All the logic (parsing, conversion, fuzzy matching, platform selection, input
building and output mapping) is pure Python, so it's testable offline:

```bash
pip install -r requirements-dev.txt
python -m pytest
```

64 tests cover parsing, currency conversion, per-night/whole-stay and multi-currency
best-price selection, fuzzy matching, and verified output mappings for the 7 live
platforms.

### Run it on Apify

```bash
npm install -g apify-cli
apify login
apify push
```

### Integrations & API

Like any Apify Actor, this one connects to Make, Zapier, Slack, Google Sheets,
Airbyte and more via [Apify integrations](https://apify.com/integrations) and
[webhooks](https://docs.apify.com/integrations/webhooks), and is fully driveable
through the [Apify API](https://docs.apify.com/api/v2) (Node `apify-client`,
Python `apify-client`).

### Legal

This Actor does not scrape the sites itself — it orchestrates public Apify Store
actors and normalizes/compares their output. Stay reasonable on volume and review
the terms of service of the sites and of the subcontracted actors.

# Actor input Schema

## `locationQueries` (type: `array`):

List of locations to search. Example: London, Manchester, Birmingham. Each location is searched on every selected platform and compared separately.

## `checkIn` (type: `string`):

Check-in date, format YYYY-MM-DD.

## `checkOut` (type: `string`):

Check-out date, format YYYY-MM-DD. Must be after the check-in date.

## `platforms` (type: `array`):

Pick one or more platforms, OR leave empty to query all of them. Scraping is subcontracted to maintained Apify Store actors. Verified (real prices confirmed live): Booking, Hotels.com, Expedia, Agoda, Vrbo, Airbnb, Google Travel. Best-effort: Trip.com and Trivago. Airbnb requests ~4 GB: on the Free tier, run it alone or with concurrency=1.

## `locale` (type: `string`):

Language/region used for the searches.

## `currency` (type: `string`):

All offers are converted to this currency to compare the best price across platforms (e.g. USD, EUR, GBP, MAD).

## `priceMin` (type: `integer`):

Minimum price filter (per the platform's own price basis). Optional.

## `priceMax` (type: `integer`):

Maximum price filter (per the platform's own price basis). Optional.

## `minBeds` (type: `integer`):

Minimum number of beds (supported by Airbnb). Optional.

## `minBedrooms` (type: `integer`):

Minimum number of bedrooms (supported by Airbnb). Optional.

## `minBathrooms` (type: `integer`):

Minimum number of bathrooms (supported by Airbnb). Optional.

## `adults` (type: `integer`):

Number of adults for the availability search.

## `children` (type: `integer`):

Number of children.

## `infants` (type: `integer`):

Number of infants (supported by Airbnb).

## `pets` (type: `integer`):

Number of pets (supported by Airbnb).

## `maxResultsPerPlatform` (type: `integer`):

Cap on the number of offers fetched from each platform per location.

## `concurrency` (type: `integer`):

Number of Store actors called at the same time. Lower it to limit memory/cost, raise it to go faster.

## `debugDumpHtml` (type: `boolean`):

If enabled (or whenever a platform returns items but nothing usable), saves a RAW item from the subcontracted actor to the Key-Value Store under DEBUG\_<platform>. Useful to adjust the output mapping.

## Actor input object example

```json
{
  "locationQueries": [
    "Marrakech"
  ],
  "checkIn": "2026-07-10",
  "checkOut": "2026-07-12",
  "platforms": [
    "booking"
  ],
  "locale": "en-US",
  "currency": "USD",
  "adults": 2,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "maxResultsPerPlatform": 20,
  "concurrency": 3,
  "debugDumpHtml": false
}
```

# Actor output Schema

## `offers` (type: `string`):

One row per offer per platform, with prices converted to your chosen currency.

## `comparison` (type: `string`):

Hotels grouped per location with the best price, spread and savings across platforms.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locationQueries": [
        "Marrakech"
    ],
    "checkIn": "2026-07-10",
    "checkOut": "2026-07-12"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dapper_rotorcraft/multi-ota-price-comparator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "locationQueries": ["Marrakech"],
    "checkIn": "2026-07-10",
    "checkOut": "2026-07-12",
}

# Run the Actor and wait for it to finish
run = client.actor("dapper_rotorcraft/multi-ota-price-comparator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locationQueries": [
    "Marrakech"
  ],
  "checkIn": "2026-07-10",
  "checkOut": "2026-07-12"
}' |
apify call dapper_rotorcraft/multi-ota-price-comparator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dapper_rotorcraft/multi-ota-price-comparator",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Multi-OTA Hotel Price Comparator",
        "description": "Search one or more locations across multiple OTAs (Booking.com, Hotels.com, Expedia, Agoda, Vrbo, Airbnb, Google Travel...) and normalize the prices into a single, currency-comparable dataset with the best price per hotel.",
        "version": "0.1",
        "x-build-id": "qMQTdD4YN97Tu3jfL"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dapper_rotorcraft~multi-ota-price-comparator/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dapper_rotorcraft-multi-ota-price-comparator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/dapper_rotorcraft~multi-ota-price-comparator/runs": {
            "post": {
                "operationId": "runs-sync-dapper_rotorcraft-multi-ota-price-comparator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/dapper_rotorcraft~multi-ota-price-comparator/run-sync": {
            "post": {
                "operationId": "run-sync-dapper_rotorcraft-multi-ota-price-comparator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "locationQueries",
                    "checkIn",
                    "checkOut"
                ],
                "properties": {
                    "locationQueries": {
                        "title": "Location queries",
                        "type": "array",
                        "description": "List of locations to search. Example: London, Manchester, Birmingham. Each location is searched on every selected platform and compared separately.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "checkIn": {
                        "title": "Check-in date",
                        "type": "string",
                        "description": "Check-in date, format YYYY-MM-DD."
                    },
                    "checkOut": {
                        "title": "Check-out date",
                        "type": "string",
                        "description": "Check-out date, format YYYY-MM-DD. Must be after the check-in date."
                    },
                    "platforms": {
                        "title": "Platforms to query",
                        "type": "array",
                        "description": "Pick one or more platforms, OR leave empty to query all of them. Scraping is subcontracted to maintained Apify Store actors. Verified (real prices confirmed live): Booking, Hotels.com, Expedia, Agoda, Vrbo, Airbnb, Google Travel. Best-effort: Trip.com and Trivago. Airbnb requests ~4 GB: on the Free tier, run it alone or with concurrency=1.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "booking",
                                "hotels_com",
                                "expedia",
                                "agoda",
                                "vrbo",
                                "airbnb",
                                "trip_com",
                                "trivago",
                                "google_travel"
                            ],
                            "enumTitles": [
                                "Booking.com",
                                "Hotels.com",
                                "Expedia",
                                "Agoda",
                                "Vrbo",
                                "Airbnb",
                                "Trip.com (best-effort)",
                                "Trivago (best-effort, slow)",
                                "Google Travel"
                            ]
                        },
                        "default": [
                            "booking"
                        ]
                    },
                    "locale": {
                        "title": "Locale",
                        "enum": [
                            "en-US",
                            "en-GB",
                            "fr-FR"
                        ],
                        "type": "string",
                        "description": "Language/region used for the searches.",
                        "default": "en-US"
                    },
                    "currency": {
                        "title": "Currency",
                        "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "MAD",
                            "CAD",
                            "AUD",
                            "CHF",
                            "AED"
                        ],
                        "type": "string",
                        "description": "All offers are converted to this currency to compare the best price across platforms (e.g. USD, EUR, GBP, MAD).",
                        "default": "USD"
                    },
                    "priceMin": {
                        "title": "Minimum price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum price filter (per the platform's own price basis). Optional."
                    },
                    "priceMax": {
                        "title": "Maximum price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum price filter (per the platform's own price basis). Optional."
                    },
                    "minBeds": {
                        "title": "Minimum beds",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum number of beds (supported by Airbnb). Optional."
                    },
                    "minBedrooms": {
                        "title": "Minimum bedrooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum number of bedrooms (supported by Airbnb). Optional."
                    },
                    "minBathrooms": {
                        "title": "Minimum bathrooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum number of bathrooms (supported by Airbnb). Optional."
                    },
                    "adults": {
                        "title": "Adults",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Number of adults for the availability search.",
                        "default": 2
                    },
                    "children": {
                        "title": "Children",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Number of children.",
                        "default": 0
                    },
                    "infants": {
                        "title": "Infants",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Number of infants (supported by Airbnb).",
                        "default": 0
                    },
                    "pets": {
                        "title": "Pets",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Number of pets (supported by Airbnb).",
                        "default": 0
                    },
                    "maxResultsPerPlatform": {
                        "title": "Max results per platform",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Cap on the number of offers fetched from each platform per location.",
                        "default": 20
                    },
                    "concurrency": {
                        "title": "Parallel platform calls",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Number of Store actors called at the same time. Lower it to limit memory/cost, raise it to go faster.",
                        "default": 3
                    },
                    "debugDumpHtml": {
                        "title": "Debug: save a raw item",
                        "type": "boolean",
                        "description": "If enabled (or whenever a platform returns items but nothing usable), saves a RAW item from the subcontracted actor to the Key-Value Store under DEBUG_<platform>. Useful to adjust the output mapping.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
