# Healthgrades Scraper — Doctors & Practice Leads (`b2b_leads/healthgrades-real-time-data-scraper`) Actor

Export clean, deduplicated Healthgrades provider leads in minutes: name, specialty, ratings and practice locations, plus the practice website, emails and social profiles when listed. Add specialty + city, stream results to your dataset or CRM as they are found. Free plan: limited sample.

- **URL**: https://apify.com/b2b\_leads/healthgrades-real-time-data-scraper.md
- **Developed by:** [Emmanuel](https://apify.com/b2b_leads) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Healthgrades Real-Time Data Scraper

[Apify Actor](https://apify.com) — collect Healthgrades provider data at scale: specialty + location search, full provider profiles, and lead-generation contact details, streamed to your dataset in real time.

> ### ⚠️ Paid only — free accounts are limited
>
> This Actor is intended for paying Apify users. **Free Apify accounts are limited to a small sample of results per run** (2 results by default) and are asked to upgrade for full, unlimited data. This restriction is stated here, in the input schema, and in the run logs — it is a policy limit, not a bug. See the [FAQ](#-faq) for details.

***

### What it does

- 🔎 **Search** Healthgrades by specialty + location — run many pairs in one go (e.g. *dermatologist in Miami, FL* and *cardiologist in Dallas, TX*). Each row includes the provider's name, specialty, rating, review count, and practice location when listed.
- 📍 **Provider details** — extract full structured profiles from provider profile URLs: ratings, office locations, board certifications, hospital affiliations, insurance plans, languages, and more.
- 🎯 **Lead details** — an *enable, not filter* enrichment pass. Where publicly listed, each provider is enriched with a practice website, email addresses, and social profiles. **Every provider is exported even when nothing extra is found** — output stays complete and per-1,000-provider runtime stays predictable (lead details add a little extra time per provider).
- ⚡ **Real-time streaming** — records are pushed to your dataset as soon as each provider is processed, so you can watch results arrive and integrate them live. Memory stays flat on long runs.
- 🔔 **Webhooks** — push every record to your CRM, Slack, Zapier, Make, or Google Sheets as it is scraped.
- 🧾 **Transparent run summary** — every run writes an `OUTPUT` object summarizing what was exported, why the run stopped, and (for transparency) the paywall status of the account that ran it.

#### Outcome

A clean, deduplicated list of healthcare providers — with contactable details where they exist — ready for outreach, market mapping, and healthcare-sales prospecting.

***

### Who it is for

- **Medical device & pharma sales teams** — build territory lists of specialists by city and specialty.
- **Healthcare recruiters** — find physicians by specialty and location for placement outreach.
- **Private-practice growth agencies** — prospect practices that have a website and email but weak online presence.
- **Health-tech BD teams** — map provider density by metro area for launch planning.
- **Insurance brokers** — build lists of practices to approach with group plans.
- **Lead-generation agencies** — enrich CRM pipelines with verified practice contact points.
- **Market researchers & consultants** — analyze provider supply, ratings, and coverage by region.

***

### Use cases

- Build a **territory list** of dermatologists in the 10 biggest US metros, with practice websites and phones.
- **Recruit** cardiologists within a state: filter by rating and review count, then contact via practice site.
- **Enrich a CRM** of known providers: pass profile URLs to Provider Details and get full structured profiles back.
- **Map the competitive landscape**: how many family-medicine practices exist in a county, and which have a website?
- **Power an outreach campaign**: export providers with `leadDetailsComplete = true` (website/email/social found) for high-deliverability prospecting.
- **Stream into your stack**: use the webhook to push each provider into HubSpot/Make/Zapier the moment it is scraped.
- **Insurance prospecting**: list practices with multiple office locations (larger groups = larger group plans).
- **Academic/health-services research**: collect structured snapshots of provider listings by region and specialty.

***

### Input schema (every field)

| Field | Type | Default | Description |
|---|---|---|---|
| `enableSearch` | boolean | `true` | Enable specialty + location search. |
| `searchTasks` | array of objects | *(1 prefill row)* | One row per search: `query` (specialty or doctor name, required), `location` (e.g. `Miami, FL`), and optional per-task `maxResults`. Add as many rows as you like. |
| `maxResultsPerQuery` | integer | `10` | Default maximum providers per search task. A row's own `maxResults` overrides it; this value applies when a row leaves it empty. |
| `enableProviderDetails` | boolean | `false` | Enable full-profile extraction for `providerUrls`. |
| `providerUrls` | string list | `[]` | Healthgrades provider profile URLs to scrape in full. |
| `npiNumbers` | string list | `[]` | Reserved for future identifier-based lookups. Currently a no-op. |
| `enableLeadDetails` | boolean | `true` | **Enable lead details**: enrich each provider with practice website, emails, and social profiles where publicly listed. Providers without findable details are **not** filtered out. |
| `maxItems` | integer | `10` | Global cap on dataset rows for the run — raise it (e.g. `10000`) for large jobs. |
| `language` | string | `en` | Language for names and addresses (`en`, `es`, …). |
| `webhookUrl` | string | `""` | Optional. Each record is POSTed to this URL as it is scraped (in addition to the dataset). |
| `webhookFormat` | `json` | `slack` | `json` | Payload format for the webhook. `json` = the full record object; `slack` = a Slack-message payload. |
| `proxyConfiguration` | object | Apify residential, US | Proxy for reliable collection. US residential is on by default; you can change country or provide custom proxy URLs. |

> **Starter input:** the Actor opens pre-filled with one small search (one specialty, one city, 10 providers) so you can hit **Start** and see live results immediately. Raise the per-task and **Max total items** values for larger jobs.

#### Example input

```json
{
    "enableSearch": true,
    "searchTasks": [
        { "query": "dermatologist", "location": "Miami, FL", "maxResults": 200 },
        { "query": "cardiologist", "location": "Dallas, TX" }
    ],
    "maxResultsPerQuery": 100,
    "enableLeadDetails": true,
    "maxItems": 5000,
    "webhookUrl": "https://hooks.zapier.com/hooks/catch/12345/abcdef/",
    "webhookFormat": "json"
}
```

#### Provider-details-only input

```json
{
    "enableSearch": false,
    "enableProviderDetails": true,
    "providerUrls": [
        "https://www.healthgrades.com/physician/dr-jane-smith-ym34x"
    ],
    "enableLeadDetails": true
}
```

***

### Output schema (field by field)

Each dataset row is one provider. All fields are always present (`null`/empty when unknown) so exports are stable for spreadsheets and ETL.

#### Identification

| Field | Type | Description |
|---|---|---|
| `featureType` | string | `search` (search result), `provider` (full profile), or `lookup`. |
| `providerId` | string | null | Stable identifier from the profile. |
| `providerUrl` | string | null | Provider profile URL. |
| `name` | string | null | Provider name (e.g. `Dr. Jane Smith, MD`). |
| `nameSlug` | string | null | URL slug for the profile. |
| `prefix` / `suffix` | string | null | Name prefix/suffix when exposed. |
| `scrapedAt` | string | ISO-8601 timestamp of collection. |

#### Professional details

| Field | Type | Description |
|---|---|---|
| `specialty` | string | null | Primary specialty (e.g. `Dermatology`). |
| `subspecialties` | string\[] | Sub-specialties when listed. |
| `gender` | string | null | When listed. |
| `npiNumber` | string | null | National Provider Identifier when exposed. |
| `yearsExperience` | number | null | When listed. |
| `languages` | string\[] | Languages spoken, when listed. |
| `boardCertifications` | array | `{ board, specialty, year? }` entries. |
| `hospitalAffiliations` | string\[] | Hospital names. |
| `insurancePlans` | string\[] | Insurance plans accepted, when listed. |
| `conditionsTreated` / `proceduresPerformed` | string\[] | When listed on the profile. |
| `telehealthAvailable` | boolean | null | Telehealth flag when exposed. |
| `acceptingNewPatients` | boolean | null | When exposed. |
| `awards` | string\[] | Awards and recognitions. |

#### Ratings & location

| Field | Type | Description |
|---|---|---|
| `overallRating` | number | null | Rating (0–5 scale). |
| `reviewCount` | integer | null | Number of patient reviews. |
| `location` | string | null | Primary location string (e.g. `Miami, FL` or full address). |
| `locations` | array | Office locations: `{ name?, address?, city?, state?, zipCode?, fullAddress?, phone?, fax?, isPrimary?, latitude?, longitude? }`. |

#### Lead details (with `enableLeadDetails`)

| Field | Type | Description |
|---|---|---|
| `phone` / `phones` | string | null / string\[] | Primary phone (formatted) plus up to 3 unique numbers. |
| `fax` | string | null | Fax number when listed. |
| `website` | string | null | Practice website when found. |
| `email` / `emails` | string | null / string\[] | Contact email(s) when publicly listed on the practice site. |
| `socials` | string\[] | Social profile URLs (LinkedIn, Facebook, Instagram, X/Twitter, YouTube, …). |
| `linkedinUrl`, `facebookUrl`, `instagramUrl`, `twitterUrl` | string | null | Flattened social fields for spreadsheet columns. |
| `leadDetailsComplete` | boolean | null | `true` when at least one extra detail (website/email/social) was found; `false` when none was; `null` when lead details are disabled. **Providers are never filtered out based on this flag.** |

#### Search context

| Field | Type | Description |
|---|---|---|
| `searchQuery` | string | null | The specialty/search term that produced this row. |
| `searchLocation` | string | null | The location used for this row. |
| `searchTaskIndex` | integer | null | 0-based index of the producing task. |
| `searchTaskLabel` | string | null | Human label, e.g. `dermatologist | Miami, FL`. |
| `position` | integer | null | Position within the task when available. |

#### Run OUTPUT (key-value store, key `OUTPUT`)

```json
{
    "totalPushed": 6,
    "requestsMade": 9,
    "spendingLimitReached": false,
    "stoppedReason": "completed",
    "paywall": {
        "detected": true,
        "isPaying": true,
        "pricingTier": "GOLD",
        "blocked": false,
        "limited": false,
        "freeTierMaxItems": null
    },
    "errors": []
}
```

`stoppedReason` is one of `completed`, `max_items`, `spending_limit`, `free_tier_limit`, `free_tier_blocked`. The `paywall` object is included for transparency: `detected` (platform run), `isPaying`, `pricingTier`, `blocked`, `limited`, and `freeTierMaxItems` (the cap in force for free accounts).

***

### Webhook setup

1. Put a URL (CRM endpoint, Slack incoming webhook, Zapier, Make, n8n, Google Sheets app script) into the **Webhook URL** input.
2. Pick a **format**:
   - `json` — the full provider record (same object as the dataset row), POSTed once per record as it is scraped.
   - `slack` — a compact Slack message: provider name, specialty, rating, phone, location, and a profile link.
3. Run the Actor. Records arrive one by one, in near real time, while the run continues.

Notes:

- The dataset is always written first — the webhook is an additional push, so a webhook failure never loses data.
- Delivery failures are logged as a fixed sentence and counted in the run log; they never stop the run.
- Webhook payloads contain only the documented record fields — no internal or debug data.

#### Slack payload example

```json
{
    "text": ":stethoscope: *Dr. Jane Smith, MD*\n*Specialty:* Dermatology  •  *Rating:* 4.8\n*Phone:* (305) 555-0142\nMiami, FL\n<https://www.healthgrades.com/physician/...|View profile>"
}
```

***

### MCP usage

This Actor works with [Apify MCP Server](https://docs.apify.com/platform/integrations/mcp), so MCP clients (Claude, Cursor, and other tool-enabled agents) can call it directly.

Typical MCP tool call:

```json
{
    "tool": "apify/actor-run",
    "arguments": {
        "actorId": "your-actor-id/healthgrades-real-time-data-scraper",
        "input": {
            "enableSearch": true,
            "searchTasks": [{ "query": "dermatologist", "location": "Miami, FL" }],
            "maxResultsPerQuery": 50,
            "enableLeadDetails": true
        }
    }
}
```

Tips for agent workflows:

- Prefer small `maxResultsPerQuery` (10–50) so the agent can iterate city-by-city.
- Keep `enableLeadDetails` on when the agent plans outreach — it gets `website`, `emails`, and `socials` directly in the rows.
- Read `OUTPUT.paywall` before planning large jobs: on free accounts the run stops at the free-tier sample.
- The flat, all-fields-present row shape makes the dataset directly loadable into LLM-friendly CSV/JSONL.

***

### Performance & limits

- **Streaming**: rows are pushed page-sized-chunk at a time; memory stays flat regardless of job size.
- **Runtime**: search is fast; `enableLeadDetails` adds a little extra time per provider (it looks up the practice site and checks its contact pages). A 1,000-provider run with lead details typically takes a few hours depending on concurrency and source responsiveness.
- **Visible progress**: the run logs what it is doing throughout (`Processing 120 provider(s) with lead details…`, `Lead details: 40/120 provider(s) done.`, `Progress: 40 provider(s) exported.`), so a long job is never a black box.
- **Predictable lead details**: a provider that cannot be enriched in time is still exported, and the whole lead-details phase is capped by a time budget (15 minutes by default, `LEAD_DETAILS_BUDGET_SECONDS` to change it). Once the budget is spent the remaining providers are exported with the details already collected, so a run's length stays predictable and it always finishes.
- **Timeout**: the Actor is configured for a 10,000-second run timeout — large jobs fit in one run.
- **Memory**: 512 MB default; 256–2048 MB supported. Memory does not need to scale with result count.
- **Recommended concurrency**: keep `maxItems` at or below ~10,000 per run; split bigger jobs by city or specialty.

***

### Paid only / free tier (policy)

Apify injects the account's pay status into every platform run, and this Actor reads it at run start:

- **Paying users** — normal runs, full output, no caps. One confirmation line is logged: `Paying user — full output.`
- **Free (non-paying) users** — by default the run exports a **maximum sample (2 results)**, logs a clear warning to upgrade, and finishes gracefully. This cap keeps the free experience useful while keeping paid output worth paying for.
- The free-tier behavior is **not** an error: the run ends cleanly with a status message and the `paywall` object in `OUTPUT`.
- The owner can tune the free-tier behavior and the lead-details time budget with environment variables on the Actor (documented in `.env.example`).

If you need full, unlimited exports, **upgrade your Apify plan** — the Actor detects paid plans automatically on the next run.

***

### ❓ FAQ

**Is this really limited on free accounts?**
Yes. Free Apify accounts get a small sample per run (2 results by default). Paying accounts get full, unlimited output. This is stated up front in the README and input schema, logged at run start, and surfaced in `OUTPUT.paywall`.

**Why did my run stop after 2 results with a message about upgrading?**
You ran it from a free Apify account. The Actor capped the run to the free sample and exited gracefully. Upgrade to a paid Apify plan and run it again — no other change needed.

**Do lead filters remove providers without contact info?**
No — this Actor intentionally has **no lead filters**. The **Enable lead details** option *adds* website/email/social fields where they can be found, and **every provider is exported** even when nothing is found. Filtering would make runtime unpredictable and pricing impossible; enabling keeps output complete and per-1,000-provider runtime consistent (lead details add a little extra time per provider).

**How current is the data?**
Everything is collected in real time during your run — there is no cached database behind it.

**Can I scrape by URL or NPI number?**
URLs: yes — enable *Provider Details* and paste profile URLs. NPI lookups: the field is reserved; use profile URLs for now.

**How many providers can I get in one run?**
Set `maxItems` high (e.g. 10000). The run timeout is 10,000 seconds; for very large jobs, split by city or specialty.

**Does it work outside the US?**
Healthgrades lists US providers, so a US connection is used by default for reliable collection.

**Can I get emails for every provider?**
No. Emails are included **only when publicly listed** on a practice's own site. Many practices publish a phone but no email; those rows still export (with `leadDetailsComplete: false`).

**Is any raw or debug data attached to records?**
No. Records contain only the documented fields — the same fields land in the dataset, in exports, and in webhook payloads.

**How do I get Slack notifications per provider?**
Set `webhookUrl` to a Slack incoming webhook and `webhookFormat` to `slack`.

**Can I use this with Zapier / Make / n8n?**
Yes — point the webhook at a Zapier/Make/n8n catch hook, or fetch the dataset at the end of the run via the API link in the output.

**Is the number of reviews a quality signal?**
It reflects patient feedback volume on the platform. Combine `overallRating` + `reviewCount` to prioritize outreach targets.

***

### Support

Open an issue on the Actor's page or contact the maintainer through Apify. Please include the run ID (never edit or redact the run's own logs — they never contain sensitive connection data).

# Actor input Schema

## `enableSearch` (type: `boolean`):

Search Healthgrades by specialty and location. Enabled by default.

## `searchTasks` (type: `array`):

Add one row per search. Pair a specialty with a city or area. Add more rows to run several searches (and several cities) in one go.

## `maxResultsPerQuery` (type: `integer`):

Default maximum providers per search task. A row's own Max providers value overrides it. Raise this to collect more per task.

## `enableProviderDetails` (type: `boolean`):

Collect full structured profiles for specific provider profile URLs.

## `providerUrls` (type: `array`):

Healthgrades provider profile URLs.

## `npiNumbers` (type: `array`):

Reserved for identifier-based lookups. Currently a no-op; use profile URLs instead.

## `enableLeadDetails` (type: `boolean`):

Enrich every provider with extra lead details (practice website, emails, social profiles) where they can be found. Adds a little extra time per provider. Every provider is still exported even when no extra details are found — output stays complete and predictable.

## `maxItems` (type: `integer`):

Global cap on total rows for the whole run, across all tasks and features. Raise it for large jobs (e.g. 10000). Free Apify accounts are capped to a small sample per run regardless of this value.

## `language` (type: `string`):

Language for provider names and addresses (e.g. en, es).

## `webhookUrl` (type: `string`):

Optional. Every record is always saved to the run's dataset — this webhook is an ADDITIONAL real-time push. When set, each new record is also POSTed to this URL (CRM, Slack incoming webhook, Zapier, Make, Google Sheets).

## `webhookFormat` (type: `string`):

json = full record object; slack = Slack-friendly message payload.

## `proxyConfiguration` (type: `object`):

A US residential connection is enabled by default for reliable collection.

## Actor input object example

```json
{
  "enableSearch": true,
  "searchTasks": [
    {
      "query": "dermatologist",
      "location": "Miami, FL",
      "maxResults": 10
    }
  ],
  "maxResultsPerQuery": 10,
  "enableProviderDetails": false,
  "providerUrls": [],
  "npiNumbers": [],
  "enableLeadDetails": true,
  "maxItems": 10,
  "language": "en",
  "webhookUrl": "",
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `allResults` (type: `string`):

Complete dataset with every field from all enabled features in this run.

## `search` (type: `string`):

Providers from specialty + location search.

## `providers` (type: `string`):

Full profile rows from provider URLs.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "enableSearch": true,
    "searchTasks": [
        {
            "query": "dermatologist",
            "location": "Miami, FL",
            "maxResults": 10
        }
    ],
    "maxResultsPerQuery": 10,
    "enableProviderDetails": false,
    "providerUrls": [],
    "npiNumbers": [],
    "enableLeadDetails": true,
    "maxItems": 10,
    "language": "en",
    "webhookUrl": "",
    "webhookFormat": "json",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_leads/healthgrades-real-time-data-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "enableSearch": True,
    "searchTasks": [{
            "query": "dermatologist",
            "location": "Miami, FL",
            "maxResults": 10,
        }],
    "maxResultsPerQuery": 10,
    "enableProviderDetails": False,
    "providerUrls": [],
    "npiNumbers": [],
    "enableLeadDetails": True,
    "maxItems": 10,
    "language": "en",
    "webhookUrl": "",
    "webhookFormat": "json",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_leads/healthgrades-real-time-data-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "enableSearch": true,
  "searchTasks": [
    {
      "query": "dermatologist",
      "location": "Miami, FL",
      "maxResults": 10
    }
  ],
  "maxResultsPerQuery": 10,
  "enableProviderDetails": false,
  "providerUrls": [],
  "npiNumbers": [],
  "enableLeadDetails": true,
  "maxItems": 10,
  "language": "en",
  "webhookUrl": "",
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call b2b_leads/healthgrades-real-time-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,b2b_leads/healthgrades-real-time-data-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/G3hLHhE1oK1YWSqd9/builds/z9j8Hdb2fedBBhdq0/openapi.json
