{
  "openapi": "3.0.1",
  "info": {
    "title": "Skyscanner Flight Scraper",
    "description": "Scrapes Skyscanner flights via the internal web-unified-search JSON API — no browser needed (pure HTTP over residential proxy). Mirrors the jupri/skyscanner-flight technique.",
    "version": "0.1",
    "x-build-id": "9ApqnUoz6SLHggjGl"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/exotic_harmonium~skyscanner-flight/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-exotic_harmonium-skyscanner-flight",
        "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/exotic_harmonium~skyscanner-flight/runs": {
      "post": {
        "operationId": "runs-sync-exotic_harmonium-skyscanner-flight",
        "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/exotic_harmonium~skyscanner-flight/run-sync": {
      "post": {
        "operationId": "run-sync-exotic_harmonium-skyscanner-flight",
        "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": [
          "origin.0",
          "target.0",
          "depart.0"
        ],
        "properties": {
          "origin.0": {
            "title": "Origin #0",
            "type": "string",
            "description": "Origin city or airport (IATA code, e.g. LHR, or a city name)."
          },
          "target.0": {
            "title": "Target #0",
            "type": "string",
            "description": "Destination city or airport (IATA code, e.g. JFK, or a city name)."
          },
          "depart.0": {
            "title": "Depart #0",
            "type": "string",
            "description": "Departure date (YYYY-MM-DD). NOTE: the prefill below is what Apify's automated quality test runs the Actor with, so it must stay in the FUTURE — a past date makes the test fail and the Actor gets flagged 'Under maintenance'. Refresh it well before 2026-12-08."
          },
          "origin.1": {
            "title": "Origin #1",
            "type": "string",
            "description": "Second leg origin (for round trip, set = target.0)."
          },
          "target.1": {
            "title": "Target #1",
            "type": "string",
            "description": "Second leg destination (for round trip, set = origin.0)."
          },
          "depart.1": {
            "title": "Depart #1",
            "type": "string",
            "description": "Second leg / return date (YYYY-MM-DD). Kept in the future for the same reason as Depart #0."
          },
          "origin.2": {
            "title": "Origin #2",
            "type": "string",
            "description": "Leg 2 origin."
          },
          "target.2": {
            "title": "Target #2",
            "type": "string",
            "description": "Leg 2 destination."
          },
          "depart.2": {
            "title": "Depart #2",
            "type": "string",
            "description": "Leg 2 date (YYYY-MM-DD)."
          },
          "origin.3": {
            "title": "Origin #3",
            "type": "string",
            "description": "Leg 3 origin."
          },
          "target.3": {
            "title": "Target #3",
            "type": "string",
            "description": "Leg 3 destination."
          },
          "depart.3": {
            "title": "Depart #3",
            "type": "string",
            "description": "Leg 3 date (YYYY-MM-DD)."
          },
          "origin.4": {
            "title": "Origin #4",
            "type": "string",
            "description": "Leg 4 origin."
          },
          "target.4": {
            "title": "Target #4",
            "type": "string",
            "description": "Leg 4 destination."
          },
          "depart.4": {
            "title": "Depart #4",
            "type": "string",
            "description": "Leg 4 date (YYYY-MM-DD)."
          },
          "origin.5": {
            "title": "Origin #5",
            "type": "string",
            "description": "Leg 5 origin."
          },
          "target.5": {
            "title": "Target #5",
            "type": "string",
            "description": "Leg 5 destination."
          },
          "depart.5": {
            "title": "Depart #5",
            "type": "string",
            "description": "Leg 5 date (YYYY-MM-DD)."
          },
          "market": {
            "title": "Market",
            "type": "string",
            "description": "Country you're searching from — gives local deals. ISO country code.",
            "default": "US"
          },
          "currency": {
            "title": "Currency",
            "type": "string",
            "description": "Pricing currency (ISO code, e.g. USD, ILS, EUR).",
            "default": "USD"
          },
          "sort": {
            "title": "Sort",
            "enum": [
              "score",
              "cheapest",
              "fastest",
              "departure"
            ],
            "type": "string",
            "description": "How to sort results.",
            "default": "score"
          },
          "limit": {
            "title": "Limit",
            "minimum": 1,
            "type": "integer",
            "description": "Max number of results to push per search (slice, after sort). Leave empty for all."
          },
          "trips": {
            "title": "Multi-search (price calendar)",
            "type": "array",
            "description": "Run MANY searches in ONE browser session — PerimeterX is passed once and amortized across all of them. Each item: {\"depart\":\"YYYY-MM-DD\",\"return\":\"YYYY-MM-DD\"} (return optional; origin/target default to origin.0/target.0, or override per item with \"origin\"/\"target\"). When set, the single origin.0/depart.0 search is ignored. Records are tagged with search_depart/search_return."
          },
          "poll_budget_s": {
            "title": "Poll budget (seconds)",
            "minimum": 15,
            "type": "integer",
            "description": "Max seconds to poll each search toward status:complete. Higher = more agents populate per itinerary; lower = faster but fewer agents on some itineraries. Default 120.",
            "default": 120
          },
          "poll_stall_s": {
            "title": "Stop after N seconds with no new results",
            "minimum": 0,
            "type": "integer",
            "description": "Stop polling a search once its result count has not grown for this many seconds. Skyscanner currently freezes these searches (never reports 'complete'), so without this every search runs the full poll budget for nothing. 0 = disabled (poll the whole budget).",
            "default": 45
          },
          "freeze_stall_s": {
            "title": "Stall timeout for a never-growing search (seconds)",
            "minimum": 0,
            "type": "integer",
            "description": "Shorter stall window applied only when the result count never grew past the first snapshot — the frozen shape. A search that grew at least once keeps the full poll_stall_s window. 0 = use poll_stall_s for both.",
            "default": 20
          },
          "poll_interval_s": {
            "title": "Poll interval (seconds)",
            "minimum": 1,
            "maximum": 15,
            "type": "integer",
            "description": "Seconds between polls of a running search. Each poll replays the CREATE request, which starts a NEW search server-side, so polling fast can keep killing a search before it matures. Raise this if searches freeze at 10 results. Default 2.",
            "default": 2
          },
          "passive_poll": {
            "title": "Passive poll (let the site drive)",
            "type": "boolean",
            "description": "Send no poll requests of our own — only capture the web-unified-search responses the site's own JS fires. Avoids the 'every poll starts a new search' problem entirely. Falls back to active polling if the site fires only once in 20s.",
            "default": false
          },
          "renav_on_freeze": {
            "title": "Re-navigate on a frozen search",
            "type": "boolean",
            "description": "When a search shows the freeze signature (count stuck at the first snapshot, no poll continuing the same session), reload the results page once instead of waiting out the stall timeout. Costs ~10s and lets the site create a fresh search, versus ~45s of waiting that ends with 10 records.",
            "default": false
          },
          "block_third_party": {
            "title": "Block ad/analytics hosts",
            "type": "boolean",
            "description": "Abort requests to third-party ad and analytics domains (doubleclick, GTM, hotjar, ...). Nothing on a skyscanner domain and nothing PerimeterX-related is blocked. Cuts page load work; measure the 403 rate before leaving it on.",
            "default": false
          },
          "search_concurrency": {
            "title": "Parallel dates (multi-search)",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "How many of the trips dates may run at once. MEASURED: leave this at 1. Skyscanner degrades concurrent searches from the same session — same 2 dates took 76s sequentially (1 snapshot each, 15 records each) versus 165s in parallel tabs, where every poll took 20-35s and searches stall-stopped at 10 results. 3 was worse still and lost a whole date. Raise only with fresh measurements.",
            "default": 1
          },
          "early_stop": {
            "title": "Early stop (faster)",
            "type": "boolean",
            "description": "Stop polling once the cheapest `limit` itineraries have stopped changing for a few consecutive snapshots, instead of waiting for the full result set to complete. Much faster; small risk of missing a cheaper flight that surfaces late. Best combined with a set `limit`.",
            "default": false
          },
          "race_ips": {
            "title": "Race N residential IPs",
            "minimum": 1,
            "maximum": 4,
            "type": "integer",
            "description": "Launch a browser on this many residential IPs in parallel and take the first that passes PerimeterX; the rest are closed. 2 hides the ~20s otherwise wasted when the first IP hits an interstitial. 1 disables the race. Higher = more RAM (use 4GB if >2).",
            "default": 2
          },
          "cabin_class": {
            "title": "Cabin class",
            "enum": [
              "economy",
              "premiumeconomy",
              "business",
              "first"
            ],
            "type": "string",
            "description": "Cabin class.",
            "default": "economy"
          },
          "alternate_origin": {
            "title": "Alternate origin airports",
            "type": "boolean",
            "description": "Include nearby origin airports.",
            "default": false
          },
          "alternate_target": {
            "title": "Alternate target airports",
            "type": "boolean",
            "description": "Include nearby destination airports.",
            "default": false
          },
          "non_stop": {
            "title": "Direct only",
            "type": "boolean",
            "description": "Keep only direct (non-stop) flights.",
            "default": false
          },
          "one_stop": {
            "title": "1 stop",
            "type": "boolean",
            "description": "Keep 1-stop flights.",
            "default": false
          },
          "two_stop": {
            "title": "2+ stops",
            "type": "boolean",
            "description": "Keep 2+ stop flights.",
            "default": false
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "Number of adults (max 8).",
            "default": 1
          },
          "children": {
            "title": "Children",
            "minimum": 0,
            "maximum": 8,
            "type": "integer",
            "description": "Number of children (max 8).",
            "default": 0
          },
          "infants": {
            "title": "Infants",
            "minimum": 0,
            "maximum": 8,
            "type": "integer",
            "description": "Number of infants (max 8).",
            "default": 0
          },
          "dev_proxy_config": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Override the proxy networking entirely. LEAVE EMPTY unless you know you need it: when set, it takes precedence over `proxy_groups`, which pins one proxy group and disables the automatic failover away from a group PerimeterX has flagged. This field used to carry a DEFAULT of BUYPROXIES94952, which silently pinned every run to that group — including after PerimeterX flagged it. Sticky sessions are used internally either way, so the cookie mint and every fire exit the same IP."
          },
          "dev_custom_headers": {
            "title": "Custom HTTP headers",
            "type": "array",
            "description": "Additional HTTP headers as {name, value} objects, merged into every request."
          },
          "dev_custom_cookies": {
            "title": "Custom HTTP cookies",
            "type": "array",
            "description": "Additional cookies as {name, value} objects, merged into the cookie jar. Use to inject a pre-minted _px3 if you have one (see reuse_session_id)."
          },
          "reuse_session_id": {
            "title": "Reuse PX session id",
            "type": "string",
            "description": "Reuse a previously-minted PerimeterX session to SKIP the browser. Set this to the session_id from a prior run's KV 'px_session', and pass that run's cookies in dev_custom_cookies. Phase 1 (pure HTTP) then exits the same residential IP the _px3 is bound to. Works only while the _px3 + sticky IP are still alive (minutes). On failure it falls back to the browser."
          },
          "dev_transform_fields": {
            "title": "Output fields",
            "type": "array",
            "description": "Restrict pushed output to these field names (in order). Empty = full record."
          },
          "dev_dataset_name": {
            "title": "Dataset name",
            "type": "string",
            "description": "Named dataset to push to. Supports {ACTOR}, {DATE}, {TIME} tokens. Empty = default dataset."
          },
          "dev_dataset_clear": {
            "title": "Clear dataset first",
            "type": "boolean",
            "description": "Wipe the target dataset before pushing.",
            "default": false
          },
          "dev_no_strip": {
            "title": "Keep empty values",
            "type": "boolean",
            "description": "Keep null/empty fields in output instead of stripping them.",
            "default": false
          },
          "dev_discover_config": {
            "title": "Discover config endpoint (debug)",
            "type": "boolean",
            "description": "One-off: navigate the /config/<id> page for the first itinerary and log every XHR that carries pricing_options, so the details endpoint can be captured. Saves the raw hit to KV key 'config_capture'.",
            "default": false
          },
          "fetch_details": {
            "title": "Fetch per-agent pricing options (optional)",
            "type": "boolean",
            "description": "LEGACY / optional. Every run now already returns the full agent list inline in each record's `agents` (via poll-to-complete + snapshot merge), so this is only needed for the extra jupri-shaped `pricing_options` with agent names/ratings from the /config details endpoint. Costs one browser session + one page visit per itinerary — leave OFF unless you need the richer per-agent metadata.",
            "default": false
          },
          "details_limit": {
            "title": "Details limit",
            "minimum": 1,
            "type": "integer",
            "description": "How many top itineraries (after sort) to enrich with pricing_options when 'Fetch per-agent pricing options' is on.",
            "default": 10
          },
          "details_only": {
            "title": "Only enriched results",
            "type": "boolean",
            "description": "With 'Fetch per-agent pricing options' on: output ONLY the top-N enriched itineraries and finish immediately, skipping all other itineraries. Fastest/cheapest when you just want the top results in full.",
            "default": false
          },
          "replay_dates": {
            "title": "Replay later dates instead of navigating",
            "type": "boolean",
            "description": "For multi-date (trips) runs, derive each later date's search by swapping the dates in the CREATE request captured on the first date, issued from the same PerimeterX-warm tab. Measured: the navigation itself is 1-2s but waiting for the site's own JS to fire its search costs 16-26s per extra date. Falls back to a normal navigation whenever the route differs or the replay does not return results. Only affects trips runs.",
            "default": true
          },
          "px_block_fire_s": {
            "title": "Extra fire wait after a PerimeterX challenge is detected (seconds)",
            "minimum": 0,
            "maximum": 30,
            "type": "integer",
            "description": "MEASURED CORRECTION: a PerimeterX block does NOT return 403 on the results document. The document loads normally and the site JS simply never fires a search, so both raced IPs sit out the full 30s deadline (~36s per failed attempt, up to 3 attempts per run). The actor therefore probes the PAGE for the PX challenge (captcha element / challenge copy) while waiting, and always LOGS when it sees one and whether that page went on to fire anyway. Set this to how many extra seconds to allow after the signature has been seen twice. 0 = off (keep the full wait) and is the default, because a page mid-challenge can still self-solve. Set it from the \"after PX signature: fired=... at Xs\" log lines rather than by guessing. The probe runs on every search path — multi-date, single-date, and the Standby session mint (where it is read from the PX_BLOCK_FIRE_S env var, since a standby container has no run input).",
            "default": 0
          },
          "rolling_ips": {
            "title": "Replace blocked IPs continuously instead of in rounds",
            "type": "boolean",
            "description": "PerimeterX blocks are only knowable by the search never firing — neither the document status nor the page DOM shows one (both measured and refuted), so the only lever left is making a blocked attempt cheaper. Off, the actor retries in rounds: every IP of a round must die before the next round launches, so the round costs its slowest member and then pays a cold browser launch with nothing else in flight. On, a dead IP is replaced the instant it dies and the replacement's launch overlaps its siblings' waits. Same total IP budget either way (race_ips x 3). Default off pending an A/B in a blocking window.",
            "default": false
          },
          "fire_wait_s": {
            "title": "Seconds an IP gets to fire the search before it is written off",
            "minimum": 5,
            "maximum": 90,
            "type": "integer",
            "description": "A PerimeterX block is only knowable by the search never firing, so this value alone decides when an IP is declared dead — the largest lever measured on this actor, and it used to be set far too low. Three paired A/Bs, 8 runs per arm launched together in one blocking window (2026-08-05): 15s failed SEVEN of eight runs while 25s failed two, and all six of the 25s arm's wins fired at 16.5-25.2s (i.e. from IPs a 15s cutoff discarded); 25s vs 40s both reached zero failures, but 40s won on its first pair of IPs in all eight runs, median mint 56.1s to 23.9s; 40s vs 60s was indistinguishable. Most of what this actor recorded as PerimeterX blocks was in fact this timeout. Raising the cap is nearly free — the wait ends the instant the search fires, so a healthy IP never reaches it. Applies to the single-search, multi-date and Standby-mint paths alike.",
            "default": 40
          },
          "ip_budget": {
            "title": "Total IPs a rolling pool may try",
            "minimum": 0,
            "maximum": 24,
            "type": "integer",
            "description": "How many browsers the rolling pool may launch in total before giving up. Only used when rolling_ips is on. 0 (default) keeps the historical coupling, race_ips x 3. Set it explicitly to vary pool DEPTH (race_ips) without also varying the budget — raising race_ips alone would change both at once.",
            "default": 0
          },
          "parallel_replays": {
            "title": "Fire every date's search in one round-trip",
            "type": "boolean",
            "description": "For multi-date (trips) runs, ask for every remaining date's search concurrently from the first date's PerimeterX-warm tab in a single in-page call, instead of one tab + navigation + blocking replay per date. VALIDATED on 4 dates, 5 runs per arm on a healthy window: identical data in every run (451 records, same per-date counts) with wall median 174s -> 114s and p90 256s -> 141s. Unlike search_concurrency (measured worse) it opens no extra tabs and runs no competing site JS. Any date whose replay does not come back usable falls back to a normal navigation. Turn off to restore the strictly sequential behaviour.",
            "default": true
          },
          "partial_enrich_top": {
            "title": "Recover the agent list on partial searches (top N)",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "When a search does not reach \"complete\", its flights and prices are correct but each itinerary carries only ONE agent, because the inline agent list fills in over poll snapshots that never arrive. /itinerary/details does not depend on the search completing — measured on a frozen date it returned 18-19 priced agents with names, ratings and booking links for itineraries that had 1. This enriches the cheapest N of any PARTIAL date so the rows people actually read keep a full seller list. Costs a few seconds, and only on dates that came back partial. 0 = off. Dates that complete normally are unaffected; fetch_details still overrides for all dates. Sizing note: the enrichment replays fire 4 per round, so 4 costs the same as 3 (one round) and 5-8 all cost one extra round. 4 is the free maximum.",
            "default": 4
          },
          "proxy_groups": {
            "title": "Proxy groups to try, in order",
            "type": "array",
            "description": "PerimeterX flags whole Apify proxy GROUPS, not individual IPs, and which group is clean has already flipped once: BUYPROXIES94952 used to pass and RESIDENTIAL was flagged, then on 2026-08-13 18 of 18 BUYPROXIES94952 IPs were blocked while RESIDENTIAL passed 4 of 4. The Actor therefore tries these in order and moves to the next one whenever every IP in the current group comes back blocked — rotating IPs inside a flagged group is pointless. Leave empty for the default order.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}