{
  "openapi": "3.0.1",
  "info": {
    "title": "Bulk PageSpeed Insights & Core Web Vitals Checker",
    "description": "Bulk-test URLs with Google's official PageSpeed Insights API: Lighthouse scores (performance, accessibility, best practices, SEO), lab metrics, real-user CrUX Core Web Vitals (LCP, INP, CLS) and top fixes, mobile and desktop.",
    "version": "0.1",
    "x-build-id": "Jc7SoeRLE7NhCeqoG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/halos_ai_main~bulk-pagespeed-core-web-vitals-checker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-halos_ai_main-bulk-pagespeed-core-web-vitals-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/halos_ai_main~bulk-pagespeed-core-web-vitals-checker/runs": {
      "post": {
        "operationId": "runs-sync-halos_ai_main-bulk-pagespeed-core-web-vitals-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/halos_ai_main~bulk-pagespeed-core-web-vitals-checker/run-sync": {
      "post": {
        "operationId": "run-sync-halos_ai_main-bulk-pagespeed-core-web-vitals-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",
        "required": [
          "urls"
        ],
        "properties": {
          "urls": {
            "title": "URLs",
            "type": "array",
            "description": "Pages to test, one per line. A missing scheme gets https:// added (example.com becomes https://example.com/). Fragments are dropped and duplicates removed. Test full page URLs (e.g. a product page), not just homepages, for page-level results.",
            "items": {
              "type": "string"
            }
          },
          "strategy": {
            "title": "Device",
            "enum": [
              "mobile",
              "desktop",
              "both"
            ],
            "type": "string",
            "description": "Lighthouse emulation profile. Mobile uses a throttled mid-range phone, which is what Google's mobile-first indexing and most Core Web Vitals reports focus on. 'Both' tests every URL twice and bills 2 page checks.",
            "default": "mobile"
          },
          "categories": {
            "title": "Lighthouse categories",
            "type": "array",
            "description": "Which Lighthouse category scores (0-100) to compute. Lab metrics and fixes come from Performance, so keep it on for speed audits. Fewer categories make each check slightly faster; the price is the same.",
            "items": {
              "type": "string",
              "enum": [
                "performance",
                "accessibility",
                "best-practices",
                "seo"
              ],
              "enumTitles": [
                "Performance",
                "Accessibility",
                "Best practices",
                "SEO"
              ]
            },
            "default": [
              "performance",
              "accessibility",
              "best-practices",
              "seo"
            ]
          },
          "googleApiKey": {
            "title": "Google API key (bring your own, free)",
            "type": "string",
            "description": "Your own free Google Cloud API key. Google's shared keyless quota is 0, so without a key every check returns a free quota-error row. Setup (2 min): Google Cloud Console → create a project → APIs & Services → Library → enable 'PageSpeed Insights API' and 'Chrome UX Report API' → Credentials → Create credentials → API key (restrict it to those two APIs). Google's default quota is 25,000 checks/day and about 400 per 100 seconds per project, free. The key is stored encrypted, sent only to Google in a request header, never logged or written to the output, and usage counts against your own Google project."
          },
          "includeCruxApi": {
            "title": "Fill gaps with the Chrome UX Report API",
            "type": "boolean",
            "description": "When PageSpeed returns no real-user data for a URL or origin, query Google's Chrome UX Report API directly. This needs 'Chrome UX Report API' enabled on the same Google project as your key; it's free and doesn't change the price. If it isn't enabled, the run still works and the log tells you. Google has announced it will phase field data out of the PageSpeed API, so this keeps CrUX results working.",
            "default": true
          },
          "maxOpportunities": {
            "title": "Fixes per page",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "How many of the top Lighthouse opportunities and insights to return per page, ranked by estimated time saved (then bytes). Set 0 to skip them.",
            "default": 5
          },
          "concurrency": {
            "title": "Concurrency",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many pages are tested in parallel. Each PageSpeed test takes about 10-40 seconds on Google's side. Google's per-key limit is about 400 requests per 100 seconds, so 4-8 is safe; lower it if you share the key with other tools.",
            "default": 4
          },
          "maxRetries": {
            "title": "Retries per page",
            "minimum": 0,
            "maximum": 6,
            "type": "integer",
            "description": "Retries for rate limits (HTTP 429), Google server errors (5xx) and network errors, with exponential backoff (honors Retry-After). A daily-quota error stops the run instead of retrying, because retries can't fix it.",
            "default": 3
          },
          "requestTimeoutSecs": {
            "title": "Timeout per check (seconds)",
            "minimum": 30,
            "maximum": 180,
            "type": "integer",
            "description": "How long to wait for Google to finish one Lighthouse test before retrying. Very heavy pages can take over a minute.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}