# Detroit Airport Flight Status Scraper (`automation-lab/detroit-dtw-flight-status`) Actor

Export current Detroit Metro Airport (DTW) arrivals and departures with airline, flight number, route, estimated time, status, gate, and observation timestamp.

- **URL**: https://apify.com/automation-lab/detroit-dtw-flight-status.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.48 / 1,000 flight extracteds

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/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

## Detroit Airport Flight Status Scraper

Export **detroit airport flight status** as structured arrival and departure rows from the current public Detroit Metropolitan Airport (DTW) flight board. Use the dataset to check flight identities, routes, estimated times, public statuses and gates during repeated airport operations monitoring.

The Actor reads the airport's browser-facing flight feed. It is a snapshot exporter, not a flight alerting or historical archive service. Run it again on an Apify schedule to collect later snapshots; compare them downstream when change detection matters.

### Who is this for?

- Airport operations teams assembling a current inbound or outbound board in a spreadsheet.
- Ground transportation operators checking arrivals and gates before dispatch.
- Travel automation builders refreshing specific airline or status subsets.

### Why use this Actor?

One run yields normalized rows instead of a screenshot or manually copied table. Choose arrivals, departures, or both, then narrow the current feed by airline, flight number, route city/code or public status. Output includes an observation timestamp and source URL for provenance. Missing source values stay `null`; the Actor never invents a scheduled time from an estimated time.

### What data is exported?

| Field | Meaning |
| --- | --- |
| `direction`, `airline`, `airlineCode`, `flightNumber` | Public flight identity and movement type. |
| `originAirportCode`, `originCity`, `destinationAirportCode`, `destinationCity` | The public airport route labels. |
| `scheduledTime`, `estimatedTime` | Source local date/time strings, without an implied timezone offset. Sentinel/missing times become null. |
| `status`, `gate` | Airport public status and gate, nullable. |
| `observedAt`, `sourceUrl` | UTC observation time and official board URL. `observedAt` is **not** the airport's last-update time. |

### Get started

1. Leave **Flight direction** at Both for the current board, or pick Arrivals/Departures.
2. Optionally enter an airline, flight number, city/airport code or public status filter.
3. Set a row limit and run. The default saves at most 100 matches.
4. Download the dataset as JSON or CSV, or schedule another run for a later snapshot.

### Input options

- `direction`: `both`, `arrivals` or `departures` (default `both`).
- `airline`: case-insensitive substring of airline name or code.
- `flightNumber`: case-insensitive substring of the flight identifier.
- `city`: case-insensitive substring of either route city or airport code.
- `status`: case-insensitive substring of the published public status.
- `maxItems`: 1–5000; defaults to 100. The limit is applied after filtering/deduplication.

The airport feed covers a rolling public window (normally six hours past and twelve hours ahead). There is no arbitrary date, archived history, custom URL, flight tracking map, alert delivery, or guaranteed full-day schedule mode. Filters search only the rows currently returned by the airport.

### Example input

```json
{"direction":"arrivals","maxItems":25}
```

For a focused operations feed: `{"direction":"arrivals","status":"Arrived","maxItems":100}`. Airlines and statuses can change with the source; a highly specific filter can legitimately return zero rows.

### Example output

A representative local flight-board row (sampled from the public feed; live values change):

```json
{
  "direction": "Arrival",
  "airline": "WestJet",
  "airlineCode": "WS",
  "flightNumber": "WS8354",
  "originAirportCode": "SEA",
  "originCity": "Seattle WA",
  "destinationAirportCode": "DTW",
  "destinationCity": "Detroit MI",
  "scheduledTime": null,
  "estimatedTime": "2026-09-24T12:54:00",
  "status": "Arrived",
  "gate": "A6",
  "observedAt": "2026-09-24T20:09:22.037Z",
  "sourceUrl": "https://www.metroairport.com/flights/flight-status"
}
```

### How much does it cost to export Detroit airport flight status?

Pay-per-event billing includes a one-time `start` event per run and a `flight` event per saved row. Runs with no matching flights emit no `flight` event; the `start` event can still be charged. See the Actor's live Pricing tab for the applicable current plan and exact tiered rate before scheduling a high-volume export. Platform compute charges and refunds are governed by Apify's terms.

### Integrations and monitoring

Use an Apify Task to save an arrivals-only or airline-specific input. Schedule the Task at the interval your operation needs, then send dataset rows to a sheet, webhook consumer, or warehouse using Apify integrations. For change detection, key by direction, flight number and estimated time, retaining `observedAt` for snapshot provenance; the Actor does not itself send alerts or deduplicate across separate runs.

### API with cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/automation-lab~detroit-dtw-flight-status/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"direction":"departures","maxItems":25}'
```

Keep API tokens in secrets, not in public code or shared reports.

### API with JavaScript

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/detroit-dtw-flight-status').call({ direction: 'arrivals', maxItems: 25 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API with Python

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/detroit-dtw-flight-status').call(run_input={'direction': 'arrivals', 'maxItems': 25})
print(client.dataset(run['defaultDatasetId']).list_items().items)
```

### MCP use

Expose this Actor to an MCP client such as Claude Code:

```bash
claude mcp add --transport http apify 'https://mcp.apify.com?tools=automation-lab/detroit-dtw-flight-status'
```

Claude Desktop, Cursor, and VS Code can each use an HTTP MCP server configuration (use the client's MCP settings location):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/detroit-dtw-flight-status"}}}
```

Example prompts for MCP:

- “Run the Detroit DTW flight status Actor for arrivals, up to 20 rows, and summarize the public statuses.”
- “Export current DTW departures matching WestJet, then list their destination cities and gates.”

MCP calls run the same current-board workflow, not a historical flight lookup.

### Reliability and limitations

The upstream feed can be delayed, omit fields, or temporarily fail. The Actor validates the JSON shape and retries transient network/429/server errors up to three requests per selected direction, then fails rather than returning a misleading empty success. It does not use a proxy or browser for the functioning public JSON endpoint. Gate and status are snapshots, not operational guarantees: confirm time-sensitive travel decisions with the airline and airport.

### Legality and responsible use

Only collect publicly displayed flight status records at sensible schedule intervals. Follow the airport site's applicable terms and Apify's platform policies; do not treat this output as a safety-critical source of truth, a private passenger manifest, or a substitute for airline confirmation.

### FAQ

**Why is `scheduledTime` null?** The sampled airport feed returned the year-0001 sentinel for that field. We explicitly convert this to null rather than invent a scheduled time.

**Why did my airline or status filter return no rows?** Only currently visible flights match; spelling and published status can change. Try a broad arrivals/departures run first.

**Why does an error appear instead of an empty dataset?** A failed, challenged, or structurally changed feed is treated as a source failure rather than as proof there are no flights.

### Related automation-lab Actors

[Phoenix Sky Harbor Flight Status Scraper](https://apify.com/automation-lab/phoenix-sky-harbor-flight-status) exports a different airport's flight board; [FAA NAS Status & Airport Delays Scraper](https://apify.com/automation-lab/faa-nas-status-airport-delays-scraper) tracks airport-level advisories, not individual DTW flights.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/detroit-dtw-flight-status/changelog.md

# Actor input Schema

## `direction` (type: `string`):

Read arrivals, departures, or both from the current DTW board.

## `airline` (type: `string`):

Optional case-insensitive substring of the public airline name or code.

## `flightNumber` (type: `string`):

Optional flight number or airline-prefixed flight code.

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

Optional origin or destination city or airport code, matched against the DTW board.

## `status` (type: `string`):

Optional substring of the airport's visible flight status (for example, Arrived).

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

Maximum matching flight rows to save (1–5000).

## Actor input object example

```json
{
  "direction": "both",
  "maxItems": 20
}
```

# Actor output Schema

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

Open the run's default dataset of current flight rows, including direction, route, times, status, gate and provenance.

# 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 = {
    "direction": "both",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/detroit-dtw-flight-status").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 = {
    "direction": "both",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/detroit-dtw-flight-status").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 '{
  "direction": "both",
  "maxItems": 20
}' |
apify call automation-lab/detroit-dtw-flight-status --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/detroit-dtw-flight-status"
        }
    }
}
```

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/1Qdu6f6thb8o8ezeG/builds/mrYzBb0PaopQTTilr/openapi.json
