{
  "data": {
    "id": "Xmh8dSBFSS8Tyl2NY",
    "actId": "gHitVmx9P5320qnK1",
    "userId": "NL4ThgItAwaoBlffQ",
    "startedAt": "2026-11-07T08:53:44.924Z",
    "finishedAt": "2026-11-07T08:54:24.272Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 39275,
      "runTimeSecs": 39.275,
      "computeUnits": 0.04363888888888889,
      "imageSizeBytes": 3112493056
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "zifX0mkAFMHe8CatY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Google Maps Business Hours Scraper\",\n  \"description\": \"Extract structured weekly opening hours, live open/closed status, and holiday or special hours from Google Maps places. Look places up directly by URL or Place ID, or discover them with a keyword search.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"What to scrape\",\n      \"type\": \"string\",\n      \"description\": \"Choose 'Places' to read specific place URLs or Place IDs, or 'Search' to find places by keyword and read their hours.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"places\",\n        \"search\"\n      ],\n      \"enumTitles\": [\n        \"Places (URLs or Place IDs)\",\n        \"Search by keyword\"\n      ],\n      \"default\": \"places\",\n      \"prefill\": \"places\",\n      \"sectionCaption\": \"What to scrape\",\n      \"sectionDescription\": \"Read a known list of places, or discover places with a search query.\"\n    },\n    \"placeUrls\": {\n      \"title\": \"Place URLs\",\n      \"type\": \"array\",\n      \"description\": \"Google Maps place URLs to read. Paste one URL or a batch; short maps.app.goo.gl links are resolved too.\",\n      \"editor\": \"stringList\",\n      \"prefill\": [\n        \"https://www.google.com/maps/place/Starbucks+Reserve+Roastery+New+York/@40.7416,-74.0053,17z/data=!3m1!4b1!4m6!3m5!1s0x89c259bf6dd90021:0x645ce21be1b31735!8m2!3d40.7416!4d-74.0053!16s%2Fg%2F11j7w8j09h?hl=en\"\n      ],\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"sectionCaption\": \"Places mode\",\n      \"sectionDescription\": \"Used when 'What to scrape' is Places. Provide URLs, Place IDs, or both.\"\n    },\n    \"placeIds\": {\n      \"title\": \"Google Place IDs\",\n      \"type\": \"array\",\n      \"description\": \"Canonical Google Place IDs beginning with ChIJ. Each ID always points to the same place, which is ideal for monitoring a fixed list.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"searchQuery\": {\n      \"title\": \"Search query\",\n      \"type\": \"string\",\n      \"description\": \"What to search for, for example 'coffee shops in New York' or 'dentists near me'. Required in Search mode.\",\n      \"editor\": \"textfield\",\n      \"sectionCaption\": \"Search mode\",\n      \"sectionDescription\": \"Used when 'What to scrape' is Search. Google Maps ranks the places and the actor reads each place's hours.\"\n    },\n    \"location\": {\n      \"title\": \"Location (optional)\",\n      \"type\": \"string\",\n      \"description\": \"Add a town, city, or region to the search query, for example 'Austin, TX'. Leave blank when the query already names the area.\",\n      \"editor\": \"textfield\"\n    },\n    \"maxResults\": {\n      \"title\": \"Maximum places in Search mode\",\n      \"type\": \"integer\",\n      \"description\": \"How many ranked places to read in Search mode. Smaller runs finish faster and cost less.\",\n      \"default\": 20,\n      \"prefill\": 5,\n      \"minimum\": 1,\n      \"maximum\": 500\n    },\n    \"language\": {\n      \"title\": \"Google Maps language\",\n      \"type\": \"string\",\n      \"description\": \"Language of the Google Maps labels and status line. Times are normalized to a stable 12-hour clock in the output.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"en\",\n        \"es\",\n        \"fr\",\n        \"de\",\n        \"it\",\n        \"pt\",\n        \"ja\",\n        \"ko\",\n        \"zh\",\n        \"ar\",\n        \"ru\"\n      ],\n      \"enumTitles\": [\n        \"English\",\n        \"Spanish\",\n        \"French\",\n        \"German\",\n        \"Italian\",\n        \"Portuguese\",\n        \"Japanese\",\n        \"Korean\",\n        \"Chinese\",\n        \"Arabic\",\n        \"Russian\"\n      ],\n      \"default\": \"en\",\n      \"prefill\": \"en\",\n      \"sectionCaption\": \"Output and speed\",\n      \"sectionDescription\": \"Control the language of the status text, how many places run in parallel, and whether closed places are returned.\"\n    },\n    \"openNowOnly\": {\n      \"title\": \"Only return places open right now\",\n      \"type\": \"boolean\",\n      \"description\": \"When on, places that Google reports as closed, or whose live state is unknown, are excluded from the dataset.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"maxConcurrency\": {\n      \"title\": \"Places processed in parallel\",\n      \"type\": \"integer\",\n      \"description\": \"How many place pages are requested at the same time in Places mode. Higher values finish large batches faster.\",\n      \"default\": 3,\n      \"prefill\": 2,\n      \"minimum\": 1,\n      \"maximum\": 8\n    }\n  }\n}",
    "readme": "# Google Maps Hours, Open-Now Status & Holiday Schedule\n\nRead a business's full week of opening hours, its live open/closed state, and the holiday or special hours Google publishes for a date — from a URL, a Place ID, a batch of either, or a keyword search. Every row is structured, timezone-aware, and ready for a database, dashboard, or alerting job.\n\n## Two ways to use it\n\n- **Places mode** — paste Google Maps place URLs, canonical `ChIJ…` Place IDs, or a mixture of both. Short `maps.app.goo.gl` links are resolved automatically.\n- **Search mode** — describe what you want (\"coffee shops in New York\") and the actor ranks the places Google Maps returns, then reads the opening hours for each one.\n\nBoth modes are cookieless. No Google account, API key, or proxy setup is needed.\n\n## What a record contains\n\n```json\n{\n  \"recordType\": \"businessHours\",\n  \"businessName\": \"Starbucks Reserve Roastery New York\",\n  \"placeId\": \"ChIJIQDZbb9ZwokRNRez4RviXGQ\",\n  \"featureId\": \"0x89c259bf6dd90021:0x645ce21be1b31735\",\n  \"cid\": \"995473537737540317\",\n  \"kgmid\": \"/g/11j7w8j09h\",\n  \"placeUrl\": \"https://www.google.com/maps/place/?q=place_id:ChIJIQDZbb9ZwokRNRez4RviXGQ\",\n  \"sourceUrl\": \"https://www.google.com/maps/place/Starbucks+Reserve+Roastery+New+York/...\",\n  \"address\": \"61 9th Ave, New York, NY 10011, United States\",\n  \"categories\": [\"Coffee shop\", \"Bakery\", \"Cafe\", \"Cocktail bar\", \"Coffee roastery\", \"Tourist attraction\"],\n  \"categoryName\": \"Coffee shop\",\n  \"phone\": \"+1 212-691-0531\",\n  \"website\": \"https://www.starbucksreserve.com/locations/new-york-roastery\",\n  \"rating\": 4.4,\n  \"reviewCount\": 7956,\n  \"location\": { \"lat\": 40.7416, \"lng\": -74.0053 },\n  \"isOpenNow\": false,\n  \"is24Hours\": false,\n  \"openingHoursText\": \"Closed · Opens 7:30 AM\",\n  \"hoursStatus\": \"Closed - Opens 7:30 AM\",\n  \"hours\": {\n    \"monday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"tuesday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"wednesday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"thursday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"friday\": { \"open\": \"7:30 AM\", \"close\": \"11 PM\" },\n    \"saturday\": { \"open\": \"7:30 AM\", \"close\": \"11 PM\" },\n    \"sunday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" }\n  },\n  \"weeklyPattern\": \"Mon-Thu 7:30 AM - 10 PM, Fri-Sat 7:30 AM - 11 PM, Sun 7:30 AM - 10 PM\",\n  \"totalHoursPerWeek\": 103.5,\n  \"holidayHours\": [\n    {\n      \"day\": \"wednesday\",\n      \"date\": \"2026-11-11\",\n      \"label\": \"Veterans Day\",\n      \"note\": \"Veterans Day might affect these hours\",\n      \"hoursMayDiffer\": true\n    }\n  ],\n  \"specialHours\": [\n    {\n      \"day\": \"wednesday\",\n      \"date\": \"2026-11-11\",\n      \"label\": \"Veterans Day\",\n      \"note\": \"Veterans Day might affect these hours\",\n      \"hoursMayDiffer\": true\n    }\n  ],\n  \"timezone\": \"America/New_York\",\n  \"currentLocalTime\": \"2026-11-07T03:21:45-05:00\",\n  \"nextOpenTime\": \"2026-11-07T07:30:00-05:00\",\n  \"timeUntilNextChange\": \"Opens in 4 hours\",\n  \"hoursSurfaceRendered\": true,\n  \"scrapedAt\": \"2026-11-07T08:21:45+00:00\"\n}\n```\n\nFields are omitted when the source does not publish them — there are no `null` placeholders.\n\n## Field reference\n\n- `businessName` — the place name Google Maps displays.\n- `placeId` — canonical Google Place ID (`ChIJ…`), when exposed.\n- `featureId` — legacy Maps feature token (`0x…:0x…`), kept separate from `placeId`.\n- `cid` — Google's decimal CID for the place, when exposed.\n- `kgmid` — Google Knowledge Graph MID, when exposed.\n- `placeUrl` — canonical Maps URL derived from the place identity.\n- `sourceUrl` — the URL or Place ID that produced this row.\n- `searchQuery` — the search query, in Search mode only.\n- `address` — street address as Google formats it.\n- `categories` — all category labels, with `categoryName` as the primary one.\n- `phone` — public phone number.\n- `website` — public website URL.\n- `rating` — average star rating (0–5).\n- `reviewCount` — number of Google reviews.\n- `location` — place centroid as `lat`/`lng`; never the map viewport.\n- `isOpenNow` — Google's live open/closed state at scrape time.\n- `temporarilyClosed` — `true` only when Google shows that exact badge.\n- `permanentlyClosed` — `true` only when Google shows that exact badge.\n- `is24Hours` — whether the complete weekly schedule is open 24 hours.\n- `openingHoursText` — the status line as Google renders it.\n- `hoursStatus` — the same line cleaned for display.\n- `hours` — structured schedule by weekday; formats below.\n- `weeklyPattern` — compact summary of the week.\n- `totalHoursPerWeek` — scheduled hours for a complete week.\n- `holidayHours` — holiday and special-date entries; see below.\n- `specialHours` — the same entries under the alternate field name kept for existing integrations.\n- `timezone` — IANA timezone reported by Google for the place.\n- `currentLocalTime` — observation timestamp in the place's timezone.\n- `nextOpenTime` — next opening as a local-time ISO timestamp.\n- `nextCloseTime` — next closing as a local-time ISO timestamp.\n- `timeUntilNextChange` — readable countdown such as \"Closes in 2 hours\".\n- `hoursSurfaceRendered` — positive evidence that Google returned a schedule for the place.\n- `recordType` — constant row label (`businessHours`).\n- `scrapedAt` — UTC timestamp when the row was collected.\n\nEach `hours` day uses one of these shapes:\n\n| Shape | Meaning |\n|---|---|\n| `{\"open\": \"9:00 AM\", \"close\": \"5:00 PM\"}` | Regular opening window |\n| `{\"open\": \"...\", \"close\": \"...\", \"intervals\": [...]}` | Split shift; every window is listed |\n| `{\"closed\": true}` | Closed that day |\n| `{\"open\": \"12:00 AM\", \"close\": \"11:59 PM\", \"is24Hours\": true}` | Open 24 hours |\n| `{\"raw\": \"...\"}` | Source format was not a clock range; the text is preserved |\n\nHoliday entries describe the date Google attaches them to:\n\n- `date` — the calendar date, `YYYY-MM-DD`.\n- `day` — the weekday of that date.\n- `label` — Google's holiday name (\"Veterans Day\", \"Thanksgiving\").\n- `note` — Google's own wording.\n- `specialHours: true` plus `status`, `open`, and `close` — Google publishes different hours for that date.\n- `hoursMayDiffer: true` — Google warns that the regular hours may change but has not published the replacement yet.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `mode` | select | `places` | `places` reads URLs/Place IDs; `search` discovers places by keyword |\n| `placeUrls` | array | – | Google Maps place URLs (batch supported; the prefill shows one example) |\n| `placeIds` | array | – | Canonical Place IDs beginning with `ChIJ` |\n| `searchQuery` | string | – | Keyword query for Search mode |\n| `location` | string | – | Optional area appended to the search query |\n| `maxResults` | integer | `20` | Maximum places to read in Search mode (1–500) |\n| `language` | select | `en` | Maps UI language for the status line and labels |\n| `openNowOnly` | boolean | `false` | Keep only places that are open at scrape time |\n| `maxConcurrency` | integer | `3` | Places requested in parallel in Places mode (1–8) |\n\n### Example: one URL\n\n```json\n{\n  \"mode\": \"places\",\n  \"placeUrls\": [\"https://www.google.com/maps/place/Starbucks/@40.7127281,-74.0060152,17z/\"]\n}\n```\n\n### Example: a mixed batch\n\n```json\n{\n  \"mode\": \"places\",\n  \"placeUrls\": [\n    \"https://www.google.com/maps/place/Starbucks/@40.7127281,-74.0060152,17z/\",\n    \"https://maps.app.goo.gl/exampleShortLink\"\n  ],\n  \"placeIds\": [\"ChIJabtoT7hlwokRLECK0SW3_8I\", \"ChIJd3dF_VBZwokRAAFm3WMspbk\"],\n  \"openNowOnly\": false\n}\n```\n\n### Example: keyword search\n\n```json\n{\n  \"mode\": \"search\",\n  \"searchQuery\": \"coffee shops\",\n  \"location\": \"New York, NY\",\n  \"maxResults\": 25,\n  \"openNowOnly\": true\n}\n```\n\n### Example: localized labels\n\n```json\n{\n  \"mode\": \"places\",\n  \"placeUrl\": \"https://www.google.com/maps/place/McDonald%27s/@40.7580,-73.9855,17z/\",\n  \"language\": \"es\"\n}\n```\n\n## Legacy input keys\n\nSaved tasks from earlier versions keep working without edits. The actor maps\n`placeUrl`, `placeurls`, `placeids`, `query`, `keyword`, `maxItems`, `limit`,\nand `openNow` onto the fields above inside the code. `proxyConfiguration` is\naccepted but no longer needed: requests start direct and move to datacenter or\nresidential connections only after a real block.\n\n## How it works\n\nGoogle Maps serves its place data through the same public XHR endpoints the\nwebsite uses. The actor asks those endpoints for the place record, reads the\nweekly schedule, holiday rows, live status, and timezone directly from the\nstructured payload, and normalizes clock values itself. That avoids cookie\nwalls, browser rendering, and fragile DOM selectors. A browser-based reader is\nkept only as a fallback for unusual URLs that carry no resolvable place token.\n\n## FAQ and honest limits\n\n**Do I need an API key or cookies?** No. The endpoints are public and the actor\nnever signs in.\n\n**Why is `nextCloseTime` missing?** When the place is closed, there is no\ncurrent closing to report. When a holiday replaces the weekly schedule, the\ncountdown fields are omitted rather than computed from the wrong schedule.\n\n**How far ahead does holiday data go?** Google attaches holiday rows to the\nseven dates it currently displays (today plus six days). Dates outside that\nwindow are not published by the source and are not invented.\n\n**A place has no hours row. Why?** Some listings genuinely publish no hours,\nand some categories (for example a pure service area) have no schedule. Those\nplaces are reported in the run status and skipped instead of emitting an empty\nplaceholder row.\n\n**Is this affiliated with Google?** No. It is an independent reader of public\nGoogle Maps data.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "google-maps-hours-open-now-status-and-holiday",
      "title": "Google Maps Hours, Open-Now Status & Holiday Schedule",
      "description": "Get structured opening hours for all 7 days, live open/closed status, holiday and special hours, and a next open/close countdown from Google Maps. Read a batch of place URLs or Place IDs, or discover places with a keyword search.",
      "version": "1.0",
      "buildTag": "latest",
      "dockerfile": "./Dockerfile",
      "readme": "# Google Maps Hours, Open-Now Status & Holiday Schedule\n\nRead a business's full week of opening hours, its live open/closed state, and the holiday or special hours Google publishes for a date — from a URL, a Place ID, a batch of either, or a keyword search. Every row is structured, timezone-aware, and ready for a database, dashboard, or alerting job.\n\n## Two ways to use it\n\n- **Places mode** — paste Google Maps place URLs, canonical `ChIJ…` Place IDs, or a mixture of both. Short `maps.app.goo.gl` links are resolved automatically.\n- **Search mode** — describe what you want (\"coffee shops in New York\") and the actor ranks the places Google Maps returns, then reads the opening hours for each one.\n\nBoth modes are cookieless. No Google account, API key, or proxy setup is needed.\n\n## What a record contains\n\n```json\n{\n  \"recordType\": \"businessHours\",\n  \"businessName\": \"Starbucks Reserve Roastery New York\",\n  \"placeId\": \"ChIJIQDZbb9ZwokRNRez4RviXGQ\",\n  \"featureId\": \"0x89c259bf6dd90021:0x645ce21be1b31735\",\n  \"cid\": \"995473537737540317\",\n  \"kgmid\": \"/g/11j7w8j09h\",\n  \"placeUrl\": \"https://www.google.com/maps/place/?q=place_id:ChIJIQDZbb9ZwokRNRez4RviXGQ\",\n  \"sourceUrl\": \"https://www.google.com/maps/place/Starbucks+Reserve+Roastery+New+York/...\",\n  \"address\": \"61 9th Ave, New York, NY 10011, United States\",\n  \"categories\": [\"Coffee shop\", \"Bakery\", \"Cafe\", \"Cocktail bar\", \"Coffee roastery\", \"Tourist attraction\"],\n  \"categoryName\": \"Coffee shop\",\n  \"phone\": \"+1 212-691-0531\",\n  \"website\": \"https://www.starbucksreserve.com/locations/new-york-roastery\",\n  \"rating\": 4.4,\n  \"reviewCount\": 7956,\n  \"location\": { \"lat\": 40.7416, \"lng\": -74.0053 },\n  \"isOpenNow\": false,\n  \"is24Hours\": false,\n  \"openingHoursText\": \"Closed · Opens 7:30 AM\",\n  \"hoursStatus\": \"Closed - Opens 7:30 AM\",\n  \"hours\": {\n    \"monday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"tuesday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"wednesday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"thursday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" },\n    \"friday\": { \"open\": \"7:30 AM\", \"close\": \"11 PM\" },\n    \"saturday\": { \"open\": \"7:30 AM\", \"close\": \"11 PM\" },\n    \"sunday\": { \"open\": \"7:30 AM\", \"close\": \"10 PM\" }\n  },\n  \"weeklyPattern\": \"Mon-Thu 7:30 AM - 10 PM, Fri-Sat 7:30 AM - 11 PM, Sun 7:30 AM - 10 PM\",\n  \"totalHoursPerWeek\": 103.5,\n  \"holidayHours\": [\n    {\n      \"day\": \"wednesday\",\n      \"date\": \"2026-11-11\",\n      \"label\": \"Veterans Day\",\n      \"note\": \"Veterans Day might affect these hours\",\n      \"hoursMayDiffer\": true\n    }\n  ],\n  \"specialHours\": [\n    {\n      \"day\": \"wednesday\",\n      \"date\": \"2026-11-11\",\n      \"label\": \"Veterans Day\",\n      \"note\": \"Veterans Day might affect these hours\",\n      \"hoursMayDiffer\": true\n    }\n  ],\n  \"timezone\": \"America/New_York\",\n  \"currentLocalTime\": \"2026-11-07T03:21:45-05:00\",\n  \"nextOpenTime\": \"2026-11-07T07:30:00-05:00\",\n  \"timeUntilNextChange\": \"Opens in 4 hours\",\n  \"hoursSurfaceRendered\": true,\n  \"scrapedAt\": \"2026-11-07T08:21:45+00:00\"\n}\n```\n\nFields are omitted when the source does not publish them — there are no `null` placeholders.\n\n## Field reference\n\n- `businessName` — the place name Google Maps displays.\n- `placeId` — canonical Google Place ID (`ChIJ…`), when exposed.\n- `featureId` — legacy Maps feature token (`0x…:0x…`), kept separate from `placeId`.\n- `cid` — Google's decimal CID for the place, when exposed.\n- `kgmid` — Google Knowledge Graph MID, when exposed.\n- `placeUrl` — canonical Maps URL derived from the place identity.\n- `sourceUrl` — the URL or Place ID that produced this row.\n- `searchQuery` — the search query, in Search mode only.\n- `address` — street address as Google formats it.\n- `categories` — all category labels, with `categoryName` as the primary one.\n- `phone` — public phone number.\n- `website` — public website URL.\n- `rating` — average star rating (0–5).\n- `reviewCount` — number of Google reviews.\n- `location` — place centroid as `lat`/`lng`; never the map viewport.\n- `isOpenNow` — Google's live open/closed state at scrape time.\n- `temporarilyClosed` — `true` only when Google shows that exact badge.\n- `permanentlyClosed` — `true` only when Google shows that exact badge.\n- `is24Hours` — whether the complete weekly schedule is open 24 hours.\n- `openingHoursText` — the status line as Google renders it.\n- `hoursStatus` — the same line cleaned for display.\n- `hours` — structured schedule by weekday; formats below.\n- `weeklyPattern` — compact summary of the week.\n- `totalHoursPerWeek` — scheduled hours for a complete week.\n- `holidayHours` — holiday and special-date entries; see below.\n- `specialHours` — the same entries under the alternate field name kept for existing integrations.\n- `timezone` — IANA timezone reported by Google for the place.\n- `currentLocalTime` — observation timestamp in the place's timezone.\n- `nextOpenTime` — next opening as a local-time ISO timestamp.\n- `nextCloseTime` — next closing as a local-time ISO timestamp.\n- `timeUntilNextChange` — readable countdown such as \"Closes in 2 hours\".\n- `hoursSurfaceRendered` — positive evidence that Google returned a schedule for the place.\n- `recordType` — constant row label (`businessHours`).\n- `scrapedAt` — UTC timestamp when the row was collected.\n\nEach `hours` day uses one of these shapes:\n\n| Shape | Meaning |\n|---|---|\n| `{\"open\": \"9:00 AM\", \"close\": \"5:00 PM\"}` | Regular opening window |\n| `{\"open\": \"...\", \"close\": \"...\", \"intervals\": [...]}` | Split shift; every window is listed |\n| `{\"closed\": true}` | Closed that day |\n| `{\"open\": \"12:00 AM\", \"close\": \"11:59 PM\", \"is24Hours\": true}` | Open 24 hours |\n| `{\"raw\": \"...\"}` | Source format was not a clock range; the text is preserved |\n\nHoliday entries describe the date Google attaches them to:\n\n- `date` — the calendar date, `YYYY-MM-DD`.\n- `day` — the weekday of that date.\n- `label` — Google's holiday name (\"Veterans Day\", \"Thanksgiving\").\n- `note` — Google's own wording.\n- `specialHours: true` plus `status`, `open`, and `close` — Google publishes different hours for that date.\n- `hoursMayDiffer: true` — Google warns that the regular hours may change but has not published the replacement yet.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `mode` | select | `places` | `places` reads URLs/Place IDs; `search` discovers places by keyword |\n| `placeUrls` | array | – | Google Maps place URLs (batch supported; the prefill shows one example) |\n| `placeIds` | array | – | Canonical Place IDs beginning with `ChIJ` |\n| `searchQuery` | string | – | Keyword query for Search mode |\n| `location` | string | – | Optional area appended to the search query |\n| `maxResults` | integer | `20` | Maximum places to read in Search mode (1–500) |\n| `language` | select | `en` | Maps UI language for the status line and labels |\n| `openNowOnly` | boolean | `false` | Keep only places that are open at scrape time |\n| `maxConcurrency` | integer | `3` | Places requested in parallel in Places mode (1–8) |\n\n### Example: one URL\n\n```json\n{\n  \"mode\": \"places\",\n  \"placeUrls\": [\"https://www.google.com/maps/place/Starbucks/@40.7127281,-74.0060152,17z/\"]\n}\n```\n\n### Example: a mixed batch\n\n```json\n{\n  \"mode\": \"places\",\n  \"placeUrls\": [\n    \"https://www.google.com/maps/place/Starbucks/@40.7127281,-74.0060152,17z/\",\n    \"https://maps.app.goo.gl/exampleShortLink\"\n  ],\n  \"placeIds\": [\"ChIJabtoT7hlwokRLECK0SW3_8I\", \"ChIJd3dF_VBZwokRAAFm3WMspbk\"],\n  \"openNowOnly\": false\n}\n```\n\n### Example: keyword search\n\n```json\n{\n  \"mode\": \"search\",\n  \"searchQuery\": \"coffee shops\",\n  \"location\": \"New York, NY\",\n  \"maxResults\": 25,\n  \"openNowOnly\": true\n}\n```\n\n### Example: localized labels\n\n```json\n{\n  \"mode\": \"places\",\n  \"placeUrl\": \"https://www.google.com/maps/place/McDonald%27s/@40.7580,-73.9855,17z/\",\n  \"language\": \"es\"\n}\n```\n\n## Legacy input keys\n\nSaved tasks from earlier versions keep working without edits. The actor maps\n`placeUrl`, `placeurls`, `placeids`, `query`, `keyword`, `maxItems`, `limit`,\nand `openNow` onto the fields above inside the code. `proxyConfiguration` is\naccepted but no longer needed: requests start direct and move to datacenter or\nresidential connections only after a real block.\n\n## How it works\n\nGoogle Maps serves its place data through the same public XHR endpoints the\nwebsite uses. The actor asks those endpoints for the place record, reads the\nweekly schedule, holiday rows, live status, and timezone directly from the\nstructured payload, and normalizes clock values itself. That avoids cookie\nwalls, browser rendering, and fragile DOM selectors. A browser-based reader is\nkept only as a fallback for unusual URLs that carry no resolvable place token.\n\n## FAQ and honest limits\n\n**Do I need an API key or cookies?** No. The endpoints are public and the actor\nnever signs in.\n\n**Why is `nextCloseTime` missing?** When the place is closed, there is no\ncurrent closing to report. When a holiday replaces the weekly schedule, the\ncountdown fields are omitted rather than computed from the wrong schedule.\n\n**How far ahead does holiday data go?** Google attaches holiday rows to the\nseven dates it currently displays (today plus six days). Dates outside that\nwindow are not published by the source and are not invented.\n\n**A place has no hours row. Why?** Some listings genuinely publish no hours,\nand some categories (for example a pure service area) have no schedule. Those\nplaces are reported in the run status and skipped instead of emitting an empty\nplaceholder row.\n\n**Is this affiliated with Google?** No. It is an independent reader of public\nGoogle Maps data.\n",
      "input": {
        "title": "Google Maps Business Hours Scraper",
        "description": "Extract structured weekly opening hours, live open/closed status, and holiday or special hours from Google Maps places. Look places up directly by URL or Place ID, or discover them with a keyword search.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "What to scrape",
            "type": "string",
            "description": "Choose 'Places' to read specific place URLs or Place IDs, or 'Search' to find places by keyword and read their hours.",
            "editor": "select",
            "enum": [
              "places",
              "search"
            ],
            "enumTitles": [
              "Places (URLs or Place IDs)",
              "Search by keyword"
            ],
            "default": "places",
            "prefill": "places",
            "sectionCaption": "What to scrape",
            "sectionDescription": "Read a known list of places, or discover places with a search query."
          },
          "placeUrls": {
            "title": "Place URLs",
            "type": "array",
            "description": "Google Maps place URLs to read. Paste one URL or a batch; short maps.app.goo.gl links are resolved too.",
            "editor": "stringList",
            "prefill": [
              "https://www.google.com/maps/place/Starbucks+Reserve+Roastery+New+York/@40.7416,-74.0053,17z/data=!3m1!4b1!4m6!3m5!1s0x89c259bf6dd90021:0x645ce21be1b31735!8m2!3d40.7416!4d-74.0053!16s%2Fg%2F11j7w8j09h?hl=en"
            ],
            "items": {
              "type": "string"
            },
            "sectionCaption": "Places mode",
            "sectionDescription": "Used when 'What to scrape' is Places. Provide URLs, Place IDs, or both."
          },
          "placeIds": {
            "title": "Google Place IDs",
            "type": "array",
            "description": "Canonical Google Place IDs beginning with ChIJ. Each ID always points to the same place, which is ideal for monitoring a fixed list.",
            "editor": "stringList",
            "items": {
              "type": "string"
            }
          },
          "searchQuery": {
            "title": "Search query",
            "type": "string",
            "description": "What to search for, for example 'coffee shops in New York' or 'dentists near me'. Required in Search mode.",
            "editor": "textfield",
            "sectionCaption": "Search mode",
            "sectionDescription": "Used when 'What to scrape' is Search. Google Maps ranks the places and the actor reads each place's hours."
          },
          "location": {
            "title": "Location (optional)",
            "type": "string",
            "description": "Add a town, city, or region to the search query, for example 'Austin, TX'. Leave blank when the query already names the area.",
            "editor": "textfield"
          },
          "maxResults": {
            "title": "Maximum places in Search mode",
            "type": "integer",
            "description": "How many ranked places to read in Search mode. Smaller runs finish faster and cost less.",
            "default": 20,
            "prefill": 5,
            "minimum": 1,
            "maximum": 500
          },
          "language": {
            "title": "Google Maps language",
            "type": "string",
            "description": "Language of the Google Maps labels and status line. Times are normalized to a stable 12-hour clock in the output.",
            "editor": "select",
            "enum": [
              "en",
              "es",
              "fr",
              "de",
              "it",
              "pt",
              "ja",
              "ko",
              "zh",
              "ar",
              "ru"
            ],
            "enumTitles": [
              "English",
              "Spanish",
              "French",
              "German",
              "Italian",
              "Portuguese",
              "Japanese",
              "Korean",
              "Chinese",
              "Arabic",
              "Russian"
            ],
            "default": "en",
            "prefill": "en",
            "sectionCaption": "Output and speed",
            "sectionDescription": "Control the language of the status text, how many places run in parallel, and whether closed places are returned."
          },
          "openNowOnly": {
            "title": "Only return places open right now",
            "type": "boolean",
            "description": "When on, places that Google reports as closed, or whose live state is unknown, are excluded from the dataset.",
            "default": false,
            "prefill": false
          },
          "maxConcurrency": {
            "title": "Places processed in parallel",
            "type": "integer",
            "description": "How many place pages are requested at the same time in Places mode. Higher values finish large batches faster.",
            "default": 3,
            "prefill": 2,
            "minimum": 1,
            "maximum": 8
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Google Maps Hours, Open-Now Status & Holiday Schedule Output",
        "description": "Business hours records from Google Maps — place identity and contact details, structured 7-day opening hours, live open/closed status, holiday and special hours, local-time countdown fields, and scrape timestamp.",
        "properties": {
          "businessHours": {
            "type": "string",
            "title": "Business hours records",
            "description": "Dataset containing all scraped Google Maps business hours records.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "minMemoryMbytes": 2048,
      "maxMemoryMbytes": 2048,
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "views": {
            "overview": {
              "title": "Business Hours",
              "transformation": {
                "fields": [
                  "recordType",
                  "businessName",
                  "placeId",
                  "featureId",
                  "cid",
                  "kgmid",
                  "placeUrl",
                  "sourceUrl",
                  "searchQuery",
                  "address",
                  "categories",
                  "categoryName",
                  "phone",
                  "website",
                  "rating",
                  "reviewCount",
                  "location",
                  "isOpenNow",
                  "temporarilyClosed",
                  "permanentlyClosed",
                  "is24Hours",
                  "openingHoursText",
                  "hoursStatus",
                  "hoursSurfaceRendered",
                  "hours",
                  "weeklyPattern",
                  "totalHoursPerWeek",
                  "holidayHours",
                  "specialHours",
                  "timezone",
                  "currentLocalTime",
                  "nextOpenTime",
                  "nextCloseTime",
                  "timeUntilNextChange",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            }
          }
        }
      },
      "environmentVariables": {}
    },
    "buildNumber": "1.0.2",
    "imageDigest": "679735afe7c5d954c95af6f26ef71f6689500e6f94a645b68b4137034cbf9a59",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.04363888888888889
    }
  }
}