{
  "openapi": "3.0.1",
  "info": {
    "title": "Booking Hotel Finder & Scraper: AI best-value shortlist",
    "description": "First 10 hotels free. Booking hotel finder: runs the Booking Scraper, drops sold-out and over-budget hotels free, ranks a hotel shortlist by value per night with AI brief match and hotel price drop alerts. Pay per result, per qualified hotel. Free demo on any plan; live search on your Apify account.",
    "version": "0.1",
    "x-build-id": "k5xMBY5HovSerw8Zs"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/rich_minds~booking-hotel-finder-ai/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-rich_minds-booking-hotel-finder-ai",
        "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/rich_minds~booking-hotel-finder-ai/runs": {
      "post": {
        "operationId": "runs-sync-rich_minds-booking-hotel-finder-ai",
        "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/rich_minds~booking-hotel-finder-ai/run-sync": {
      "post": {
        "operationId": "run-sync-rich_minds-booking-hotel-finder-ai",
        "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",
        "properties": {
          "destination": {
            "title": "Destination",
            "type": "string",
            "description": "City, district or hotel name as on Booking.com, e.g. <code>Lisbon</code>. Typed next to the prefilled demo, it starts the live search for you (capped by <b>Max source spend</b>) — no source switch needed. The live search runs a Store Actor on your Apify plan (any plan that runs Store Actors) — if your plan cannot, paste hotel rows you already have in the <i>list</i> mode, or rank a Booking dataset you already have in the <i>dataset</i> mode."
          },
          "preset": {
            "title": "Start from a ready niche search (one click)",
            "enum": [
              "custom",
              "event-planner",
              "price-drop-alert",
              "travel-agent"
            ],
            "type": "string",
            "description": "Pick a ready search and press Start: it fills the fields you left empty and runs the live search (spend-capped by <b>Max source spend</b>). Your own values always win. <b>Custom</b> = fill the fields yourself.",
            "default": "custom"
          },
          "checkIn": {
            "title": "Check-in date",
            "type": "string",
            "description": "<code>YYYY-MM-DD</code> or relative, e.g. <code>30 days</code> from today. Without dates Booking shows no prices and hotels are ranked on rating only. With relative dates a schedule tracks each hotel by hotel + nights + adults, so price drops still show; fixed dates track one exact stay.",
            "default": "30 days"
          },
          "checkOut": {
            "title": "Check-out date",
            "type": "string",
            "description": "<code>YYYY-MM-DD</code> or relative, e.g. <code>32 days</code> (= 2 nights after a <code>30 days</code> check-in). Price per night = Booking's stay price ÷ nights.",
            "default": "32 days"
          },
          "maxQualified": {
            "title": "Max hotels on the shortlist",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "The best-value hotels are delivered first, up to this many — and the ceiling of what <b>this Actor</b> charges: at most this many × $0.01 with AI on (× $0.004 with AI off), e.g. 25 × $0.01 = $0.25. The source's own spend has its cap right below.",
            "default": 25
          },
          "maxDiscoveryChargeUsd": {
            "title": "Max source spend (USD)",
            "minimum": 0.01,
            "maximum": 1000,
            "type": "number",
            "description": "Hard cap on what the Booking scraper run may charge your account in live mode — $0.50 (≈ 100 properties with the default scraper, ≈ 166 with the $0.003 one) in the form and for an API or agent call that leaves it out. Raise it for bigger searches.",
            "default": 0.5
          },
          "notifyEmail": {
            "title": "E-mail me the shortlist (optional)",
            "type": "string",
            "description": "After every run with at least one new hotel or price drop, the digest (top 10 with price per night, rating and links) is e-mailed here through Apify's send-mail Actor. Schedule the run daily or weekly (Actions → Schedule) for price-drop alerts. Never sent for the free demo."
          },
          "discoveryActorId": {
            "title": "Booking scraper for the live search",
            "enum": [
              "voyager/booking-scraper",
              "santamaria-automations/booking-com-scraper",
              "voyager/fast-booking-scraper"
            ],
            "type": "string",
            "description": "Which Store Actor searches Booking.com on your account — most of what a run costs. The default brings the full listing (facilities, fine print, review summary); the $0.003 and $0.002 scrapers bring the search-page row — price, rating, free cancellation, meal plan — at 40–60 % less.",
            "default": "voyager/booking-scraper"
          },
          "travellerBrief": {
            "title": "Traveller brief (AI)",
            "type": "string",
            "description": "Who is travelling and what matters, in plain words. The AI scores every hotel against it with verbatim evidence from the listing and writes a why-this-hotel line. Without AI, the amenities it names are matched against Booking's facility list."
          },
          "minScore": {
            "title": "Minimum value score (0–100)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "The field that decides what you pay: hotels whose value score (price per night vs rating, reviews, location, cancellation — AI-adjusted with your brief) is below this are dropped and <b>not charged</b>.",
            "default": 40
          },
          "enableAi": {
            "title": "AI brief match, pros/cons & fine print",
            "type": "boolean",
            "description": "Scores each hotel against your brief with evidence quotes, writes a why-this-hotel line and pros/cons, and flags fine-print risks (city tax, deposit, cash only). <b>On = $0.01 per qualified hotel + AI tokens; off = $0.004</b> (rule-based value score, Booking's pros/cons, regex fine-print flags). Your first 5 hotels get live AI verdicts on any plan; every one with Apify model access or a paid own key.",
            "default": true
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Guests per search. Part of the price and of the stay the price-drop memory tracks.",
            "default": 2
          },
          "minRating": {
            "title": "Minimum guest rating (0–10)",
            "minimum": 0,
            "maximum": 10,
            "type": "number",
            "description": "Booking guest rating. Passed to the scraper as its <code>minScore</code> and checked again here. Hotels without a rating yet are dropped while this is above 0.",
            "default": 7.5
          },
          "maxPricePerNight": {
            "title": "Max price per night",
            "minimum": 1,
            "type": "number",
            "description": "In the currency below. Passed to Booking's price filter and checked again on the computed price per night. Empty = no budget cap."
          },
          "mustHaveAmenities": {
            "title": "Must-have amenities",
            "type": "array",
            "description": "Matched against Booking's structured facility list with synonyms (wifi, parking, pool, air conditioning, pets allowed, gym, kitchen, airport shuttle, spa, elevator …). A hotel missing one is dropped free; one at extra charge stays and is named in <code>amenitiesExtraCharge</code>.",
            "items": {
              "type": "string"
            }
          },
          "freeCancellationOnly": {
            "title": "Free cancellation only",
            "type": "boolean",
            "description": "Keep only hotels with at least one room option that can be cancelled for free.",
            "default": false
          },
          "breakfastIncludedOnly": {
            "title": "Breakfast included only",
            "type": "boolean",
            "description": "Keep only hotels with a room option whose conditions say breakfast is included.",
            "default": false
          },
          "children": {
            "title": "Children",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Number of children.",
            "default": 0
          },
          "nearPoint": {
            "title": "Near this point (latitude,longitude)",
            "type": "string",
            "description": "Your venue, beach or old town, e.g. <code>38.7139,-9.1394</code> (right-click a place in Google Maps to copy it). Every hotel gets <code>distanceKm</code> and closer ones score higher."
          },
          "maxDistanceKm": {
            "title": "Max distance (km)",
            "minimum": 0.1,
            "type": "number",
            "description": "Drops hotels farther than this from <b>Near this point</b> (free). Needs that point."
          },
          "propertyTypes": {
            "title": "Property types",
            "type": "array",
            "description": "Empty = any. One type is passed to Booking's own filter; several are filtered here on each property's type.",
            "items": {
              "type": "string",
              "enum": [
                "Hotels",
                "Apartments",
                "Guest houses",
                "Hostels",
                "Bed and breakfasts",
                "Villas",
                "Holiday homes",
                "Resorts",
                "Motels",
                "Homestays",
                "Country houses",
                "Campsites"
              ],
              "enumTitles": [
                "Hotels",
                "Apartments",
                "Guest houses",
                "Hostels",
                "Bed and breakfasts",
                "Villas",
                "Holiday homes",
                "Resorts",
                "Motels",
                "Homestays",
                "Country houses",
                "Campsites"
              ]
            }
          },
          "currency": {
            "title": "Currency",
            "enum": [
              "USD",
              "EUR",
              "GBP",
              "CHF",
              "CAD",
              "AUD",
              "NZD",
              "JPY",
              "CNY",
              "HKD",
              "SGD",
              "INR",
              "AED",
              "SAR",
              "BRL",
              "MXN",
              "ARS",
              "ZAR",
              "SEK",
              "NOK",
              "DKK",
              "PLN",
              "CZK",
              "HUF",
              "RON",
              "TRY",
              "ILS",
              "THB",
              "KRW",
              "IDR",
              "MYR",
              "PHP"
            ],
            "type": "string",
            "description": "Currency Booking shows prices in (and of <code>maxPricePerNight</code>).",
            "default": "USD"
          },
          "startUrls": {
            "title": "Booking.com URLs (instead of a destination)",
            "type": "array",
            "description": "Booking search result, hotel or shared-list URLs, passed to the scraper as <code>startUrls</code>; typed next to the demo, they start the live search. The live search runs a Store Actor on your Apify plan — if your plan cannot run Store Actors, use the <i>dataset</i> mode.",
            "items": {
              "type": "string"
            }
          },
          "shortlistMemo": {
            "title": "Client-ready shortlist memo",
            "type": "boolean",
            "description": "Writes a memo comparing the top 5 into the <code>SHORTLIST_MEMO</code> record and <code>OUTPUT</code> — one AI call per run with AI on, a markdown table otherwise.",
            "default": false
          },
          "onlyNewOrPriceDrop": {
            "title": "Only new hotels or price drops",
            "type": "boolean",
            "description": "Price-drop monitoring: a hotel already delivered for the same stay comes back only when its price fell by at least the percentage below — with <code>previousPrice</code> and <code>priceChangePct</code>. The stay is dates + adults, or hotel + nights + adults when the dates are relative. Off = every run delivers the full shortlist, still marked new / price_drop / unchanged.",
            "default": true
          },
          "minPriceDropPct": {
            "title": "Minimum price drop (%)",
            "minimum": 0,
            "maximum": 90,
            "type": "number",
            "description": "A remembered hotel counts as a price drop when its stay price fell by at least this much.",
            "default": 5
          },
          "sendAlertsTo": {
            "title": "Send alerts to (Slack, Discord, Teams, Google Chat, Telegram or webhook)",
            "type": "string",
            "description": "Paste one or more URLs, one per line — the service is detected from the address: a Slack or Discord channel webhook, a Teams Workflows or Google Chat space webhook, your Telegram bot's send link (<code>https://api.telegram.org/bot&lt;token&gt;/sendMessage?chat_id=@yourchannel</code>) or any other https URL (Zapier, Make, n8n, your CRM), which gets the hotels as JSON. After every run with at least one new hotel or price drop, the digest (top 10 with price per night, rating and links) is posted there. Never sent for the free demo. Webhook headers, batching and signing: the API-only <code>webhookHeaders</code>, <code>webhookBatchSize</code> and <code>webhookSecret</code>."
          },
          "dedupeAcrossRuns": {
            "title": "Remember delivered hotels and prices",
            "type": "boolean",
            "description": "Keeps every delivered hotel stay and its price in a named key-value store on your account — needed for price-drop alerts. Off = every run starts fresh.",
            "default": true
          },
          "dedupeTtlDays": {
            "title": "Deliver a hotel again after (days)",
            "minimum": 0,
            "maximum": 3650,
            "type": "integer",
            "description": "How long a delivered hotel stay stays remembered. 0 = never deliver or charge it again unless its price drops. A number of days lets a hotel come back after that many days — charged again as a new hotel.",
            "default": 0
          },
          "llmProvider": {
            "title": "AI model access",
            "enum": [
              "apify",
              "byok"
            ],
            "type": "string",
            "description": "<b>Apify (no keys)</b> — the AI runs through Apify's built-in OpenRouter proxy; tokens are billed to your Apify account at OpenRouter's rates. <b>My own key</b> — use your OpenAI / Anthropic / Gemini / Groq key instead; a free-tier key assesses only a few hotels per run — expect 1–3 AI checks (2 calls at a time, one after a rate limit, then the 3 borderline hotels retried one by one) — and the rest keep their rule score; a paid Groq / Gemini key (billing on) assesses every hotel.",
            "default": "apify"
          },
          "llmApiKey": {
            "title": "Your API key (own-key mode only)",
            "type": "string",
            "description": "Required when <b>AI model access</b> is <i>My own API key</i>. Stored encrypted by Apify, never logged."
          },
          "sourceMode": {
            "title": "Where do the hotels come from?",
            "enum": [
              "actor",
              "dataset",
              "list"
            ],
            "type": "string",
            "description": "<b>Live search</b> runs the Booking scraper picked above on your account (≈ $0.002–0.005 per property, capped by <b>Max source spend</b>). <b>Dataset</b> ranks an existing Booking scraper run. <b>List</b> ranks records you paste. <b>Bring your own data:</b> rows or a dataset ID, and you pay only for the analysis — the source Actor is never run. The mode you choose always runs as chosen; only the untouched sample records next to a search you typed switch to the live search (spend-capped). <code>{}</code> over the API runs the free demo — nothing charged.",
            "default": "actor"
          },
          "datasetId": {
            "title": "Dataset",
            "type": "string",
            "description": "Only for <b>dataset</b> mode: a dataset of <code>voyager/booking-scraper</code> (or another Booking scraper with name, url and price / rating). Pick it so the Actor is granted read access."
          },
          "itemsList": {
            "title": "Hotels to rank",
            "type": "array",
            "description": "Only for <b>list</b> mode. JSON array of Booking records (voyager/booking-scraper fields: <code>name</code>, <code>url</code>, <code>price</code>, <code>checkInDate</code>, <code>checkOutDate</code>, <code>rating</code>, <code>reviews</code>, <code>rooms</code>, <code>facilities</code> …). The prefill is the free demo's sample."
          },
          "targetFlags": {
            "title": "Target flags (any of)",
            "type": "array",
            "description": "Only deliver hotels with at least one of these flags, and rank those with more of them higher. Leave empty to keep everything. An API call passes the flag names from the README's flag table, e.g. <code>free_cancellation</code> (<code>freeCancellation</code> works too); an unknown name stops the run at once with the list of valid ones.",
            "items": {
              "type": "string",
              "enum": [
                "free_cancellation",
                "breakfast_included",
                "genius_discount",
                "few_rooms_left",
                "top_rated",
                "great_value_for_money",
                "budget_friendly",
                "all_amenities",
                "near_point",
                "price_drop",
                "extra_fees",
                "deposit_required"
              ],
              "enumTitles": [
                "Free cancellation",
                "Breakfast included",
                "Genius discount",
                "3 rooms or fewer left",
                "Rated 9.0 or higher",
                "Value for money rated 8.5+",
                "Cheapest third of the search",
                "Has every must-have amenity",
                "Within 1 km of your point",
                "Cheaper than last delivered",
                "Fine print names extra fees",
                "Fine print asks for a deposit"
              ]
            }
          },
          "historyDatasetName": {
            "title": "Keep a running log (dataset name) (API only)",
            "type": "string",
            "description": "API only — hidden on the form. Optional. Type a name (e.g. <code>booking-hotel-finder-ai-seen-log</code>) and every run appends its new hotels with the date to that named dataset on your account — one list across months to connect to Google Sheets or your BI tool once. Empty = off. Costs nothing extra.",
            "default": ""
          },
          "webhookUrl": {
            "title": "Webhook URL (optional) (API only)",
            "type": "string",
            "description": "API only — hidden on the form. Qualified hotels are POSTed here as JSON with a Slack-ready <code>text</code> line (Zapier, Make, n8n, your app). Stored encrypted, like a key."
          },
          "webhookHeaders": {
            "title": "Webhook headers (optional) (API only)",
            "type": "object",
            "description": "API only — hidden on the form. Extra HTTP headers for the webhook, e.g. <code>{\"Authorization\": \"Bearer …\"}</code>. Stored encrypted — never shown in the run input."
          },
          "webhookBatchSize": {
            "title": "Webhook batch size (API only)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "API only — hidden on the form. 1 = one POST per hotel the moment it is ready. Higher = one POST per N hotels.",
            "default": 1
          },
          "webhookSecret": {
            "title": "Webhook signing secret (optional) (API only)",
            "type": "string",
            "description": "API only — hidden on the form. Any random string. Every webhook POST then carries <code>X-Signature: sha256=&lt;HMAC-SHA256 of the raw body with this secret&gt;</code>, so your endpoint can verify it came from this Actor. Stored encrypted by Apify, never logged."
          },
          "dedupeStoreName": {
            "title": "Memory store name (API only)",
            "type": "string",
            "description": "API only — hidden on the form. Key-value store for the cross-run memory. Left at the default, the memory is kept per search (destination or start URLs, guests, currency, source) — rewording the traveller brief keeps it, so a scheduled run never re-delivers what you already have, and another search starts its own list. Running it for several clients on one account, type one name per client.",
            "default": "booking-hotel-finder-ai-seen"
          },
          "llmModel": {
            "title": "AI model (API only)",
            "type": "string",
            "description": "API only — hidden on the form. Leave empty for the default (<code>anthropic/claude-haiku-4.5</code>). Apify mode takes an OpenRouter slug such as <code>openai/gpt-4.1-mini</code>; own-key mode takes <code>provider:model</code>, e.g. <code>anthropic:claude-haiku-4-5-20251001</code>; left empty, your key picks it (a Google key → <code>google:gemini-3.5-flash-lite</code>, an Anthropic key → Claude Haiku 4.5)."
          },
          "aiCandidateMultiplier": {
            "title": "AI candidate pool (× max hotels) (API only)",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "API only — hidden on the form. How many of the best rule-scored hotels get the AI pass, as a multiple of <b>Max hotels on the shortlist</b> — best first, every one at or above the minimum value score − 15. Higher = more thorough, more tokens.",
            "default": 2
          },
          "autoSwitchToLive": {
            "title": "Typed search next to the sample starts the live search (API only)",
            "type": "boolean",
            "description": "API only — hidden on the form. On (default): search terms typed next to the untouched sample records start the live search (spend-capped; <code>OUTPUT.switchedToLive</code> names them). Off: the mode you send is the mode that runs — the sample stays the free demo and the status names the terms it did not search. API pipelines that must never start a paid read on their own: send <code>false</code>.",
            "default": true
          },
          "discoveryInput": {
            "title": "Extra source input (advanced) (API only)",
            "type": "object",
            "description": "API only — hidden on the form. Merged over the scraper input this Actor builds (e.g. <code>{\"flexWindow\": \"1\"}</code>). The live search runs a Store Actor on your Apify plan — if your plan cannot run Store Actors, paste your own records in <b>list</b> mode (any plan); <b>dataset</b> only for a Booking dataset you already have from another account or tool."
          },
          "maxToProcess": {
            "title": "Max properties to scrape (API only)",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "API only — hidden on the form. The scraper's row limit — also cut by <b>Max source spend</b> ÷ the scraper's price per property.",
            "default": 100
          },
          "language": {
            "title": "Listing language (API only)",
            "type": "string",
            "description": "API only — hidden on the form. Language of descriptions, facilities and policies. One of: en-gb, en-us, de, fr, es, it, pt-pt, pt-br, nl, pl, cs, sv, da, no, fi, el, tr, ru, ja, zh-cn, ko, ar, he, hu, ro.",
            "default": "en-gb"
          },
          "rooms": {
            "title": "Rooms (API only)",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "API only — hidden on the form. Number of rooms.",
            "default": 1
          },
          "minStars": {
            "title": "Minimum stars (API only)",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "API only — hidden on the form. 0 = any. Checked on each property (Booking's own star filter takes one exact value only).",
            "default": 0
          },
          "minReviews": {
            "title": "Minimum number of reviews (API only)",
            "minimum": 0,
            "type": "integer",
            "description": "API only — hidden on the form. Drops properties with too few reviews to trust their rating.",
            "default": 20
          },
          "discoveryTimeoutSecs": {
            "title": "Source run timeout, seconds (API only)",
            "minimum": 60,
            "maximum": 86400,
            "type": "integer",
            "description": "API only — hidden on the form. How long the source Store Actor may run before its partial results are used. Raise it when the status says the source stopped early.",
            "default": 600
          },
          "slackWebhookUrl": {
            "title": "Slack webhook URL (API only)",
            "type": "string",
            "description": "API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Slack incoming-webhook URL for the digest."
          },
          "discordWebhookUrl": {
            "title": "Discord webhook URL (API only)",
            "type": "string",
            "description": "API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Discord channel webhook URL for the digest."
          },
          "teamsWebhookUrl": {
            "title": "Microsoft Teams webhook URL (API only)",
            "type": "string",
            "description": "API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Teams Workflows webhook URL for the digest."
          },
          "googleChatWebhookUrl": {
            "title": "Google Chat webhook URL (API only)",
            "type": "string",
            "description": "API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Google Chat space webhook URL for the digest."
          },
          "telegramUrl": {
            "title": "Telegram sendMessage link (API only)",
            "type": "string",
            "description": "API only — hidden on the form, where <code>sendAlertsTo</code> takes it. The bot's sendMessage link with its chat_id."
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}