# Measurement Lab NDT Server Scraper (`parseforge/measurement-lab-ndt-scraper`) Actor

Export M-Lab NDT broadband-speed-test server inventory. Pull hostname, machine, city, country, geo, and signed download/upload endpoints for nearby and global servers. Filter by country, city, or format.

- **URL**: https://apify.com/parseforge/measurement-lab-ndt-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Developer tools, Other, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.75 / 1,000 result items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

![ParseForge Banner](https://github.com/ParseForge/apify-assets/blob/ad35ccc13ddd068b9d6cba33f323962e39aed5b2/banner.jpg?raw=true)

## 📡 Measurement Lab (M-Lab) NDT Server Scraper

> 🚀 **Export the M-Lab NDT server inventory in seconds.** Pull **broadband-speed-test servers** with hostname, machine, country, city, geo, and signed WebSocket download and upload URLs ready to use. No registration required.

> 🕒 **Last updated:** 2026-05-21 · **📊 10 fields** per record · **🌐 200+ M-Lab servers** · **🛰️ ndt7 + ndt5 formats** · **🌍 Global coverage**

The **M-Lab NDT Scraper** exports the live server inventory from **Measurement Lab**, the open networking research platform that powers the Network Diagnostic Test (NDT) used by Google's public Internet speed test and many ISP performance measurement studies. Each record returns **10 fields**, including the M-Lab machine identifier, the public hostname, the requested protocol (`ndt7` or `ndt5`), the host country and city, and four ready-to-call WebSocket URLs (secure and insecure variants for download and upload).

The inventory covers **every active M-Lab NDT pod worldwide**, with M-Lab access tokens signed for the caller so the download/upload URLs work out of the box for a network diagnostic, speed-test client, or research probe.

| 🎯 Target Audience | 💡 Primary Use Cases |
|---|---|
| Network researchers, ISP analysts, broadband policy teams, telecom engineers, CDN ops, network journalists | Speed-test infrastructure mapping, ISP performance studies, regional throughput baselines, broadband policy research, NDT probe orchestration |

---

### 📋 What the M-Lab NDT Scraper does

Multiple filtering workflows in a single run:

- 🌍 **Nearest server.** Default mode returns the M-Lab pods closest to the caller geo.
- 🏳️ **Country filter.** Restrict to one ISO 3166-1 alpha-2 country code (`US`, `GB`, `DE`, `JP`, `BR`, and more).
- 🏙️ **City filter.** Match against the location.city hint exposed by the M-Lab inventory.
- 🛰️ **Protocol filter.** `ndt7` (modern WebSocket, default) or `ndt5` (legacy), or both.
- 🔐 **Ready-to-call URLs.** Every record includes pre-signed WebSocket URLs for both secure (WSS) and insecure (WS) variants of download and upload.

Each record includes the M-Lab machine ID, the public hostname, the format (`ndt7` or `ndt5`), the country and city, and four signed WebSocket URLs you can hand directly to an NDT client library.

> 💡 **Why it matters:** M-Lab powers a meaningful slice of the public broadband-quality dataset used in regulatory filings, academic papers, and ISP scorecards. Anyone running NDT measurements at scale needs the live server inventory to balance load, study regional capacity, or audit speed-test routing. This Actor returns that inventory in a clean dataset on every run.

---

### 🎬 Full Demo

_🚧 Coming soon: a 3-minute walkthrough showing how to go from sign-up to a downloaded dataset._

---

### ⚙️ Input

<table>
<thead>
<tr><th>Input</th><th>Type</th><th>Default</th><th>Behavior</th></tr>
</thead>
<tbody>
<tr><td><code>maxItems</code></td><td>integer</td><td><code>10</code></td><td>Records to return. Free plan caps at 10, paid plan at 1,000,000.</td></tr>
<tr><td><code>country</code></td><td>string</td><td><code>""</code></td><td>ISO 3166-1 alpha-2 code (245+ enum values). Empty = nearest worldwide.</td></tr>
<tr><td><code>city</code></td><td>string</td><td><code>""</code></td><td>Optional city name hint matched against location.city. Empty = no city filter.</td></tr>
<tr><td><code>formats</code></td><td>array</td><td><code>["ndt7"]</code></td><td>Which NDT protocol to query. <code>ndt7</code> is the modern WebSocket default. <code>ndt5</code> is the legacy variant.</td></tr>
</tbody>
</table>

**Example: 25 nearest US M-Lab ndt7 servers.**

```json
{
    "maxItems": 25,
    "country": "US",
    "formats": ["ndt7"]
}
````

**Example: full global inventory across both protocols.**

```json
{
    "maxItems": 500,
    "formats": ["ndt7", "ndt5"]
}
```

> ⚠️ **Good to Know:** the signed access tokens embedded in `downloadUrl` and `uploadUrl` are issued by the M-Lab service at run time and remain valid for a limited window. For long-running campaigns, re-run the Actor to refresh the URLs before each measurement.

***

### 📊 Output

Each NDT server record contains **10 fields**. Download the dataset as CSV, Excel, JSON, or XML.

#### 🧾 Schema

| Field | Type | Example |
|---|---|---|
| 🖥️ `machine` | string | `"ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org"` |
| 🌐 `hostname` | string | `"ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org"` |
| 🛰️ `format` | string | `"ndt7"` |
| 🏳️ `country` | string | `"US"` |
| 🏙️ `city` | string | `"Washington"` |
| 🔽 `downloadUrl` | string | `"wss://.../ndt/v7/download?access_token=..."` |
| 🔼 `uploadUrl` | string | `"wss://.../ndt/v7/upload?access_token=..."` |
| 🔽 `downloadUrlInsecure` | string | `"ws://.../ndt/v7/download?access_token=..."` |
| 🔼 `uploadUrlInsecure` | string | `"ws://.../ndt/v7/upload?access_token=..."` |
| 🕒 `scrapedAt` | ISO 8601 | `"2026-05-20T21:56:17.976Z"` |

#### 📦 Sample records

<details>
<summary><strong>🇺🇸 Washington DC (IAD) M-Lab pod, ndt7</strong></summary>

```json
{
    "machine": "ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org",
    "hostname": "ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org",
    "format": "ndt7",
    "country": "US",
    "city": "Washington",
    "downloadUrl": "wss://ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org/ndt/v7/download?access_token=...",
    "uploadUrl": "wss://ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org/ndt/v7/upload?access_token=...",
    "downloadUrlInsecure": "ws://ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org/ndt/v7/download?access_token=...",
    "uploadUrlInsecure": "ws://ndt-iad396982-220b2628.googleoim.autojoin.measurement-lab.org/ndt/v7/upload?access_token=...",
    "scrapedAt": "2026-05-20T21:56:17.976Z"
}
```

</details>

<details>
<summary><strong>🏛️ Washington DC, mlab1-iad02 legacy pod</strong></summary>

```json
{
    "machine": "mlab1-iad02.mlab-oti.measurement-lab.org",
    "hostname": "ndt-mlab1-iad02.mlab-oti.measurement-lab.org",
    "format": "ndt7",
    "country": "US",
    "city": "Washington",
    "downloadUrl": "wss://ndt-mlab1-iad02.mlab-oti.measurement-lab.org/ndt/v7/download?access_token=...",
    "uploadUrl": "wss://ndt-mlab1-iad02.mlab-oti.measurement-lab.org/ndt/v7/upload?access_token=...",
    "downloadUrlInsecure": "ws://ndt-mlab1-iad02.mlab-oti.measurement-lab.org/ndt/v7/download?access_token=...",
    "uploadUrlInsecure": "ws://ndt-mlab1-iad02.mlab-oti.measurement-lab.org/ndt/v7/upload?access_token=...",
    "scrapedAt": "2026-05-20T21:56:18.096Z"
}
```

</details>

***

### ✨ Why choose this Actor

| | Capability |
|---|---|
| 🌐 | **Live M-Lab inventory.** Active NDT pods worldwide, refreshed every run from the M-Lab service. |
| 🛰️ | **ndt7 + ndt5.** Both modern WebSocket and legacy protocols, switchable per run. |
| 🔐 | **Signed access tokens.** Download and upload URLs come back ready to call, no extra auth handshake required. |
| 🏳️ | **245+ country filter.** Restrict to a specific country or leave empty for the nearest-to-caller worldwide list. |
| ⚡ | **Fast.** 10 servers in under 10 seconds. |
| 🔁 | **Always fresh.** Server inventory and access tokens are minted live, so the dataset reflects the current M-Lab fleet. |
| 🚫 | **No account.** Works against public M-Lab infrastructure. No login or API key needed. |

> 📊 The Measurement Lab dataset powers the public Internet speed test integrated into Google search and many ISP performance studies. Accurate server-inventory snapshots underpin every NDT-based measurement workflow.

***

### 📈 How it compares to alternatives

| Approach | Cost | Coverage | Refresh | Filters | Setup |
|---|---|---|---|---|---|
| **⭐ M-Lab NDT Scraper** *(this Actor)* | $5 free credit, then pay-per-use | Worldwide pods | **Live per run** | country, city, format | ⚡ 2 min |
| Direct M-Lab integration | Free | Worldwide | Per-call | Many | 🐢 Dev work |
| Commercial speed-test SDKs | $$$/year | Vendor pods | Vendor-controlled | Vendor-controlled | ⏳ Onboarding |
| Hand-maintained server lists | Free | Stale, partial | Rarely | None | 🕒 Variable |

Pick this Actor when you want the M-Lab fleet in a clean dataset, with signed URLs, without writing a custom client.

***

### 🚀 How to use

1. 📝 **Sign up.** [Create a free account with $5 credit](https://console.apify.com/sign-up?fpr=vmoqkp) (takes 2 minutes).
2. 🌐 **Open the Actor.** Go to the M-Lab NDT Scraper page on the Apify Store.
3. 🎯 **Set input.** Optionally pick a country or city, choose `ndt7`, `ndt5`, or both, and set `maxItems`.
4. 🚀 **Run it.** Click **Start** and let the Actor collect your data.
5. 📥 **Download.** Grab your results in the **Dataset** tab as CSV, Excel, JSON, or XML.

> ⏱️ Total time from signup to downloaded dataset: **3-5 minutes.** No coding required.

***

### 💼 Business use cases

<table>
<tr>
<td width="50%" valign="top">

#### 📡 Network Research

- ISP performance benchmarking at scale
- Regional throughput baselines for studies
- Long-running NDT measurement campaigns
- Server-selection experiments

</td>
<td width="50%" valign="top">

#### 📊 Broadband Policy

- Coverage and performance data for regulators
- Universal-service-obligation reporting
- Underserved-area capacity studies
- Public-interest broadband audits

</td>
</tr>
<tr>
<td width="50%" valign="top">

#### 🏗️ Telecom Engineering

- Peering and interconnect performance baselines
- CDN and ISP route validation
- Backbone latency mapping
- Edge-server placement studies

</td>
<td width="50%" valign="top">

#### 📰 Network Journalism

- Comparative ISP scorecards by city
- Story research on rural broadband
- Visualisations of speed-test footprints
- Data-driven policy reporting

</td>
</tr>
</table>

***

### 🔌 Automating M-Lab NDT Scraper

Control the scraper programmatically for scheduled runs and pipeline integrations:

- 🟢 **Node.js.** Install the `apify-client` NPM package.
- 🐍 **Python.** Use the `apify-client` PyPI package.
- 📚 See the [Apify API documentation](https://docs.apify.com/api/v2) for full details.

The [Apify Schedules feature](https://docs.apify.com/platform/schedules) lets you trigger this Actor on any cron interval. Refresh the inventory hourly or daily, then pipe the URLs into your NDT measurement orchestrator.

***

### 🌟 Beyond business use cases

Network measurement data powers more than commercial workflows. The same structured records support research, education, civic projects, and personal initiatives.

<table>
<tr>
<td width="50%">

#### 🎓 Research and academia

- Internet-measurement coursework with live pods
- Reproducible NDT-based research papers
- Networking-class lab assignments
- Comparative-broadband theses

</td>
<td width="50%">

#### 🎨 Personal and creative

- Hobbyist speed-test dashboards
- Self-hosted NDT clients with smart server picking
- Travel-blogger broadband maps
- Indie network-tools side projects

</td>
</tr>
<tr>
<td width="50%">

#### 🤝 Non-profit and civic

- Community-network performance reports
- Public-interest broadband audits
- Indigenous and rural connectivity studies
- Digital-divide investigations

</td>
<td width="50%">

#### 🧪 Experimentation

- Test multi-pod parallel NDT measurements
- Prototype global probe orchestrators
- Train geo-routing models on real pod data
- Validate ISP performance models

</td>
</tr>
</table>

***

### 🤖 Ask an AI assistant about this scraper

Open a ready-to-send prompt about this ParseForge actor in the AI of your choice:

- 💬 [**ChatGPT**](https://chat.openai.com/?q=How%20do%20I%20use%20the%20Measurement%20Lab%20NDT%20Scraper%20by%20ParseForge%20on%20Apify%3F%20Show%20me%20input%20examples%2C%20output%20fields%2C%20common%20use%20cases%2C%20and%20how%20to%20integrate%20it%20into%20a%20workflow.)
- 🧠 [**Claude**](https://claude.ai/new?q=How%20do%20I%20use%20the%20Measurement%20Lab%20NDT%20Scraper%20by%20ParseForge%20on%20Apify%3F%20Show%20me%20input%20examples%2C%20output%20fields%2C%20common%20use%20cases%2C%20and%20how%20to%20integrate%20it%20into%20a%20workflow.)
- 🔍 [**Perplexity**](https://perplexity.ai/search?q=How%20do%20I%20use%20the%20Measurement%20Lab%20NDT%20Scraper%20by%20ParseForge%20on%20Apify%3F%20Show%20me%20input%20examples%2C%20output%20fields%2C%20common%20use%20cases%2C%20and%20how%20to%20integrate%20it%20into%20a%20workflow.)
- 🅒 [**Copilot**](https://copilot.microsoft.com/?q=How%20do%20I%20use%20the%20Measurement%20Lab%20NDT%20Scraper%20by%20ParseForge%20on%20Apify%3F%20Show%20me%20input%20examples%2C%20output%20fields%2C%20common%20use%20cases%2C%20and%20how%20to%20integrate%20it%20into%20a%20workflow.)

***

### ❓ Frequently Asked Questions

#### 🧩 How does it work?

The Actor queries the M-Lab service for the requested protocol, country, and city, then emits one structured record per returned server with signed WebSocket URLs you can use directly with an NDT client.

#### 📏 How accurate is the data?

Every record is read live from the M-Lab service. Country and city come from M-Lab's location metadata, and the signed URLs are minted at run time.

#### 🔁 How often is the dataset refreshed?

The M-Lab inventory changes constantly as pods come online, drain, or are retargeted. Every run fetches a fresh inventory with fresh tokens.

#### 🛰️ What is the difference between ndt7 and ndt5?

`ndt7` is the modern WebSocket-based NDT protocol, recommended for new integrations. `ndt5` is the legacy version, still supported for backward compatibility with older clients.

#### 🌍 Which countries are covered?

M-Lab operates pods worldwide. The `country` input enumerates 245+ ISO 3166-1 alpha-2 codes; leaving it empty returns the nearest-to-caller results from M-Lab's global fleet.

#### ⏰ Can I schedule regular runs?

Yes. Use Apify Schedules to run this Actor hourly, daily, or on any cron expression. Refresh the URL list before each NDT measurement campaign.

#### ⚖️ Is this data legal to use?

M-Lab publishes its server inventory openly, intended for public use. Review M-Lab's terms for redistribution or large-scale measurement, but standard speed-test and research use is supported.

#### 💼 Can I use this data commercially?

Yes. The M-Lab service is open and used by commercial integrators, ISPs, and SaaS speed-test vendors. Follow M-Lab's acceptable-use guidelines for production traffic.

#### 💳 Do I need a paid Apify plan to use this Actor?

No. The free Apify plan is enough for testing and small runs (10 records per run). A paid plan lifts the limit and unlocks scheduling and larger datasets.

#### 🔐 Do the URLs expire?

Yes. M-Lab-issued tokens have a short lifetime by design. Re-run the Actor before each measurement campaign to refresh the signed URLs.

#### 🆘 What if I need help?

Our support team is here to help. Contact us through the Apify platform or use the Tally form linked below.

***

### 🔌 Integrate with any app

M-Lab NDT Scraper connects to any cloud service via [Apify integrations](https://apify.com/integrations):

- [**Make**](https://docs.apify.com/platform/integrations/make) - Automate multi-step workflows
- [**Zapier**](https://docs.apify.com/platform/integrations/zapier) - Connect with 5,000+ apps
- [**Slack**](https://docs.apify.com/platform/integrations/slack) - Get run notifications in your channels
- [**Airbyte**](https://docs.apify.com/platform/integrations/airbyte) - Pipe server inventory into your warehouse
- [**GitHub**](https://docs.apify.com/platform/integrations/github) - Trigger runs from commits and releases
- [**Google Drive**](https://docs.apify.com/platform/integrations/drive) - Export datasets straight to Sheets

You can also use webhooks to trigger downstream actions when a run finishes. Push fresh M-Lab inventory into your NDT orchestrator, or alert your team in Slack when pod availability changes.

***

### 🔗 Recommended Actors

- [**🌐 OurAirports Scraper**](https://apify.com/parseforge/ourairports-scraper) - Global airport reference data with codes and geo
- [**🛡️ Shodan IP Scraper**](https://apify.com/parseforge/shodan-ip-scraper) - Internet-connected device intelligence
- [**📊 OpenSky Flights Scraper**](https://apify.com/parseforge/opensky-flights-scraper) - Live aircraft network telemetry
- [**🌍 RIPE Atlas Probes Scraper**](https://apify.com/parseforge/ripe-atlas-probes-scraper) - Global Internet measurement probes
- [**📡 PeeringDB Scraper**](https://apify.com/parseforge/peeringdb-scraper) - Network interconnection registry

> 💡 **Pro Tip:** browse the complete [ParseForge collection](https://apify.com/parseforge) for more network and infrastructure scrapers.

***

**🆘 Need Help?** [**Open our contact form**](https://tally.so/r/BzdKgA) to request a new scraper, propose a custom data project, or report an issue.

***

> **⚠️ Disclaimer:** this Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Measurement Lab (M-Lab) or its operators. All trademarks mentioned are the property of their respective owners. Only publicly available M-Lab inventory data is collected.

# Actor input Schema

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

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000

## `country` (type: `string`):

Optional ISO-3166 alpha-2 country code (e.g. 'US', 'GB', 'DE'). Empty = nearest worldwide.

## `city` (type: `string`):

Optional city name hint matched against the station location. Empty = no city filter.

## `formats` (type: `array`):

Which NDT protocol to query. Default ndt7 (modern WebSocket).

## Actor input object example

```json
{
  "maxItems": 10,
  "formats": [
    "ndt7"
  ]
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/measurement-lab-ndt-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 = { "maxItems": 10 }

# Run the Actor and wait for it to finish
run = client.actor("parseforge/measurement-lab-ndt-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "maxItems": 10
}' |
apify call parseforge/measurement-lab-ndt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=parseforge/measurement-lab-ndt-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Measurement Lab NDT Server Scraper",
        "description": "Export M-Lab NDT broadband-speed-test server inventory. Pull hostname, machine, city, country, geo, and signed download/upload endpoints for nearby and global servers. Filter by country, city, or format.",
        "version": "1.0",
        "x-build-id": "ScSWAXLfO2uhD2fn1"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/parseforge~measurement-lab-ndt-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-parseforge-measurement-lab-ndt-scraper",
                "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/parseforge~measurement-lab-ndt-scraper/runs": {
            "post": {
                "operationId": "runs-sync-parseforge-measurement-lab-ndt-scraper",
                "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/parseforge~measurement-lab-ndt-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-parseforge-measurement-lab-ndt-scraper",
                "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": {
                    "maxItems": {
                        "title": "Max Items",
                        "minimum": 1,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000"
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "",
                            "AD",
                            "AE",
                            "AF",
                            "AG",
                            "AI",
                            "AL",
                            "AM",
                            "AO",
                            "AR",
                            "AS",
                            "AT",
                            "AU",
                            "AW",
                            "AX",
                            "AZ",
                            "BA",
                            "BB",
                            "BD",
                            "BE",
                            "BF",
                            "BG",
                            "BH",
                            "BI",
                            "BJ",
                            "BL",
                            "BM",
                            "BN",
                            "BO",
                            "BQ",
                            "BR",
                            "BS",
                            "BT",
                            "BW",
                            "BY",
                            "BZ",
                            "CA",
                            "CD",
                            "CF",
                            "CG",
                            "CH",
                            "CI",
                            "CK",
                            "CL",
                            "CM",
                            "CN",
                            "CO",
                            "CR",
                            "CU",
                            "CV",
                            "CW",
                            "CX",
                            "CY",
                            "CZ",
                            "DE",
                            "DJ",
                            "DK",
                            "DM",
                            "DO",
                            "DZ",
                            "EC",
                            "EE",
                            "EG",
                            "ER",
                            "ES",
                            "ET",
                            "FI",
                            "FJ",
                            "FK",
                            "FM",
                            "FO",
                            "FR",
                            "GA",
                            "GB",
                            "GD",
                            "GE",
                            "GF",
                            "GG",
                            "GH",
                            "GI",
                            "GL",
                            "GM",
                            "GN",
                            "GP",
                            "GQ",
                            "GR",
                            "GT",
                            "GU",
                            "GW",
                            "GY",
                            "HK",
                            "HN",
                            "HR",
                            "HT",
                            "HU",
                            "ID",
                            "IE",
                            "IL",
                            "IM",
                            "IN",
                            "IO",
                            "IQ",
                            "IR",
                            "IS",
                            "IT",
                            "JE",
                            "JM",
                            "JO",
                            "JP",
                            "KE",
                            "KG",
                            "KH",
                            "KI",
                            "KM",
                            "KN",
                            "KP",
                            "KR",
                            "KW",
                            "KY",
                            "KZ",
                            "LA",
                            "LB",
                            "LC",
                            "LI",
                            "LK",
                            "LR",
                            "LS",
                            "LT",
                            "LU",
                            "LV",
                            "LY",
                            "MA",
                            "MC",
                            "MD",
                            "ME",
                            "MF",
                            "MG",
                            "MH",
                            "MK",
                            "ML",
                            "MM",
                            "MN",
                            "MO",
                            "MP",
                            "MQ",
                            "MR",
                            "MS",
                            "MT",
                            "MU",
                            "MV",
                            "MW",
                            "MX",
                            "MY",
                            "MZ",
                            "NA",
                            "NC",
                            "NE",
                            "NF",
                            "NG",
                            "NI",
                            "NL",
                            "NO",
                            "NP",
                            "NR",
                            "NU",
                            "NZ",
                            "OM",
                            "PA",
                            "PE",
                            "PF",
                            "PG",
                            "PH",
                            "PK",
                            "PL",
                            "PM",
                            "PN",
                            "PR",
                            "PS",
                            "PT",
                            "PW",
                            "PY",
                            "QA",
                            "RE",
                            "RO",
                            "RS",
                            "RU",
                            "RW",
                            "SA",
                            "SB",
                            "SC",
                            "SD",
                            "SE",
                            "SG",
                            "SH",
                            "SI",
                            "SJ",
                            "SK",
                            "SL",
                            "SM",
                            "SN",
                            "SO",
                            "SR",
                            "SS",
                            "ST",
                            "SV",
                            "SX",
                            "SY",
                            "SZ",
                            "TC",
                            "TD",
                            "TG",
                            "TH",
                            "TJ",
                            "TK",
                            "TL",
                            "TM",
                            "TN",
                            "TO",
                            "TR",
                            "TT",
                            "TV",
                            "TW",
                            "TZ",
                            "UA",
                            "UG",
                            "US",
                            "UY",
                            "UZ",
                            "VA",
                            "VC",
                            "VE",
                            "VG",
                            "VI",
                            "VN",
                            "VU",
                            "WF",
                            "WS",
                            "YE",
                            "YT",
                            "ZA",
                            "ZM",
                            "ZW"
                        ],
                        "type": "string",
                        "description": "Optional ISO-3166 alpha-2 country code (e.g. 'US', 'GB', 'DE'). Empty = nearest worldwide."
                    },
                    "city": {
                        "title": "City",
                        "enum": [
                            "",
                            "Amsterdam",
                            "Antananarivo",
                            "Athens",
                            "Auckland",
                            "Barcelona",
                            "Belgrade",
                            "Berlin",
                            "Bogota",
                            "Brussels",
                            "Buenos Aires",
                            "Calgary",
                            "Cape Town",
                            "Charleston",
                            "Chennai",
                            "Chicago",
                            "Columbus",
                            "Dallas",
                            "Denver",
                            "Doha",
                            "Dublin",
                            "Florianopolis",
                            "Frankfurt",
                            "Hamburg",
                            "Helsinki",
                            "Hong Kong",
                            "Honolulu",
                            "Jakarta",
                            "Johannesburg",
                            "Lagos",
                            "Las Vegas",
                            "Lima",
                            "Lisbon",
                            "London",
                            "Los Angeles",
                            "Madrid",
                            "Manila",
                            "Maputo",
                            "Marseille",
                            "Melbourne",
                            "Mexico City",
                            "Miami",
                            "Milan",
                            "Moncton",
                            "Monterrey",
                            "Montreal",
                            "Mumbai",
                            "Nairobi",
                            "New Delhi",
                            "New York",
                            "Omaha",
                            "Osaka",
                            "Paris",
                            "Perth",
                            "Podgorica",
                            "Portland",
                            "Prague",
                            "Salt Lake City",
                            "San Francisco Bay Area",
                            "Santiago",
                            "Sao Paulo",
                            "Seattle",
                            "Seoul",
                            "Singapore",
                            "Sofia",
                            "Spokane",
                            "Stavanger",
                            "Stockholm",
                            "Sydney",
                            "Taipei",
                            "Tel Aviv",
                            "Tokyo",
                            "Toronto",
                            "Tunis",
                            "Turin",
                            "Vancouver",
                            "Warsaw",
                            "Washington",
                            "Wellington",
                            "Winnipeg",
                            "Zurich"
                        ],
                        "type": "string",
                        "description": "Optional city name hint matched against the station location. Empty = no city filter."
                    },
                    "formats": {
                        "title": "Test Formats",
                        "type": "array",
                        "description": "Which NDT protocol to query. Default ndt7 (modern WebSocket).",
                        "items": {
                            "type": "string",
                            "enum": [
                                "ndt7",
                                "ndt5"
                            ]
                        },
                        "default": [
                            "ndt7"
                        ]
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
