{
  "openapi": "3.0.1",
  "info": {
    "title": "Bulk PageSpeed and Core Web Vitals Checker",
    "description": "Audits a list of URLs with Google's official PageSpeed Insights API v5 and returns performance, accessibility, SEO and best-practices scores alongside lab and CrUX field Core Web Vitals.",
    "version": "0.1",
    "x-build-id": "RCU8ooIDTUeFgFBe4"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/opendatalabs~bulk-pagespeed-cwv-checker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-opendatalabs-bulk-pagespeed-cwv-checker",
        "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/opendatalabs~bulk-pagespeed-cwv-checker/runs": {
      "post": {
        "operationId": "runs-sync-opendatalabs-bulk-pagespeed-cwv-checker",
        "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/opendatalabs~bulk-pagespeed-cwv-checker/run-sync": {
      "post": {
        "operationId": "run-sync-opendatalabs-bulk-pagespeed-cwv-checker",
        "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": {
          "urls": {
            "title": "URLs to audit",
            "maxItems": 100000,
            "type": "array",
            "description": "Public page URLs. Each URL is audited once per selected strategy, and each audit is one row in the dataset. Bare domains are accepted and upgraded to https://. Leave this and the source dataset empty to audit the demo URL https://example.com.",
            "items": {
              "type": "string"
            }
          },
          "strategy": {
            "title": "Strategy",
            "enum": [
              "mobile",
              "desktop",
              "both"
            ],
            "type": "string",
            "description": "Which form factor to emulate. 'Both' doubles the number of API calls, and therefore the quota used.",
            "default": "mobile"
          },
          "apiKey": {
            "title": "PageSpeed Insights API key",
            "type": "string",
            "description": "Required, and free. Enable both the \"PageSpeed Insights API\" and the \"Chrome UX Report API\" for the key's project. Without a key the run makes no PageSpeed Insights calls and returns one guidance row explaining how to get one (Google's shared anonymous quota is almost always exhausted). A free key from Google Cloud (enable the PageSpeed Insights API, then create an API key) gives you a private quota (commonly cited limits: 25,000 queries/day and 240/minute; check your Quotas page in Google Cloud Console). The key is only ever sent to googleapis.com and is redacted from logs."
          },
          "categories": {
            "title": "Lighthouse categories",
            "type": "array",
            "description": "Which Lighthouse categories to run. Fewer categories means a faster audit. Quota is charged per API call, not per category, so there is no quota saving in trimming this.",
            "items": {
              "type": "string",
              "enum": [
                "performance",
                "accessibility",
                "best-practices",
                "seo",
                "pwa"
              ],
              "enumTitles": [
                "Performance",
                "Accessibility",
                "Best practices",
                "SEO",
                "PWA"
              ]
            },
            "default": [
              "performance",
              "accessibility",
              "best-practices",
              "seo"
            ]
          },
          "includeFieldData": {
            "title": "Include CrUX field data",
            "type": "boolean",
            "description": "Adds real-user Chrome UX Report metrics (75th percentile LCP, INP, CLS, FCP and TTFB) when Google has enough traffic for the URL. Falls back to origin-level data when URL-level data is missing; fieldDataScope and fieldDataSource record which one you got. Low-traffic pages have no field data at all, and hasFieldData will be false. Included in the audit price.",
            "default": true
          },
          "includeCrux": {
            "title": "Use the Chrome UX Report (CrUX) API for field data",
            "type": "boolean",
            "description": "Looks up real-user data in Google's CrUX API with the same key (page first, then the whole site, matching the mobile/desktop strategy). Requires the free \"Chrome UX Report API\" to be enabled in the same Google Cloud project as your key. If it is not enabled or the lookup fails, the audit still succeeds and keeps the PageSpeed Insights field data; the row's cruxError says why. No extra charge. Turn off to use only the field data embedded in PageSpeed Insights responses.",
            "default": true
          },
          "includeAudits": {
            "title": "Include opportunity audits",
            "type": "boolean",
            "description": "Adds an 'audits' object with the main Lighthouse opportunities: render-blocking resources, unused JS and CSS, image formats, text compression, the LCP element and third-party weight. Makes rows noticeably larger.",
            "default": false
          },
          "locale": {
            "title": "Locale",
            "type": "string",
            "description": "BCP-47 locale for Lighthouse's human-readable strings, for example en, de or pt-BR. Does not change the numbers.",
            "default": "en"
          },
          "sourceDatasetId": {
            "title": "Read URLs from a dataset",
            "type": "string",
            "description": "Dataset id or name to pull URLs from, instead of (or in addition to) the list above. Point this at a Sitemap URL Extractor run to audit a whole site without copying URLs by hand."
          },
          "sourceDatasetField": {
            "title": "URL field in that dataset",
            "type": "string",
            "description": "Which property of each dataset item holds the URL.",
            "default": "url"
          },
          "sourceDatasetChangeTypes": {
            "title": "Only these change types",
            "type": "array",
            "description": "When the source dataset came from the Sitemap Change Tracker in change mode, restrict the audit to URLs with these changeType values. Leave empty to audit every URL. Selecting added and changed is the cheap way to run a nightly audit of only what moved.",
            "items": {
              "type": "string",
              "enum": [
                "added",
                "changed",
                "removed",
                "unchanged"
              ],
              "enumTitles": [
                "Added",
                "Changed",
                "Removed",
                "Unchanged"
              ]
            },
            "default": []
          },
          "maxUrlsFromSourceDataset": {
            "title": "Max URLs to take from the dataset",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Safety cap. A sitemap run can easily return more URLs than your PSI quota allows in a day.",
            "default": 1000
          },
          "concurrency": {
            "title": "Concurrent audits",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "A single PSI call takes roughly 10 to 30 seconds, so concurrency is what makes a large batch finish. Capped at 1 when no API key is supplied. Defaults to 4 with a key.",
            "default": 4
          },
          "maxRequestsPerMinute": {
            "title": "Max requests per minute",
            "minimum": 1,
            "maximum": 240,
            "type": "integer",
            "description": "Hard rate ceiling, enforced by a token bucket. 240/minute is the commonly cited limit for a keyed project (check your Quotas page in Google Cloud Console); the default of 60 leaves headroom for anything else using the same key.",
            "default": 60
          },
          "stopOnDailyQuotaExhausted": {
            "title": "Stop calling the API once the daily quota is gone",
            "type": "boolean",
            "description": "A daily quota does not reset inside a run, so once it is hit, every remaining URL is written as a skipped row immediately instead of spending the run's time on retries that cannot succeed. Turn this off only if you share a key with another workload that might free up quota mid-run.",
            "default": true
          },
          "maxRetries": {
            "title": "Attempts per audit",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "Total attempts, including the first. Retries back off exponentially with jitter and honour Retry-After. Per-minute rate limits are retried; a daily quota error is not.",
            "default": 3
          },
          "requestTimeoutSecs": {
            "title": "Timeout per audit (seconds)",
            "minimum": 20,
            "maximum": 600,
            "type": "integer",
            "description": "PSI commonly takes 10 to 30 seconds and occasionally much longer on heavy pages. Below about 60 seconds you will start timing out audits that would have succeeded.",
            "default": 120
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}