# Phoenix Sky Harbor Flight Status Scraper (`automation-lab/phoenix-sky-harbor-flight-status`) Actor

Export current Phoenix Sky Harbor arrivals and departures with airline, flight number, city, times, terminal, gate, status, and bag claim for operations.

- **URL**: https://apify.com/automation-lab/phoenix-sky-harbor-flight-status.md
- **Developed by:** [Stas Persiianenko](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.52 / 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Phoenix Sky Harbor Flight Status Scraper

Export **Phoenix Sky Harbor flight status** records from the airport's public flight board.
Get current arrivals and departures with airline, flight number, city, scheduled and estimated times, terminal, gate, status, and bag claim.
The Actor turns the changing PHX board into typed dataset rows for traveler tools, recurring checks, spreadsheets, and airport-operations feeds.

### What can this Actor do?

- Export current Phoenix Sky Harbor arrivals, departures, or both.
- Filter by airline, city or airport code, flight number, status, and scheduled date.
- Capture scheduled, estimated, actual, and chock times when the source provides them.
- Capture terminal, gate, flight status, and arrival bag claim.
- Limit output for focused checks or save a larger board snapshot.
- Feed scheduled Apify Tasks, webhooks, spreadsheets, databases, and alerting workflows.

This Actor reads the same public structured data used by the Sky Harbor flight page.
It does not require an airline account, browser, or proxy.

### Who is it for?

**Travel application developers** can add a current PHX status feed without parsing a visual table.

**Airport and ground-operations teams** can schedule snapshots and track gate, terminal, arrival, or departure changes.

**Traveler-service teams** can filter one airline, flight, or city and connect the dataset to notifications.

**Data analysts** can export repeatable board snapshots to JSON, CSV, Excel, Google Sheets, or a warehouse.

**Automation builders** can combine scheduled runs with Apify webhooks to trigger downstream processing.

### Why use this flight status scraper?

The public board is designed for interactive lookup.
This Actor provides integration-ready records with stable field names and explicit null values.

It validates the upstream response before saving data.
Transient network, rate-limit, and server errors receive bounded retries.
An invalid response fails the run instead of silently returning a misleading empty dataset.

Filters are applied before charging and saving, so you only pay per qualifying flight record.

### What Phoenix flight data is extracted?

| Field | Meaning |
| --- | --- |
| `flightId` | Source flight-record identifier |
| `direction` | `arrival` or `departure` |
| `airline` | Airline name shown by PHX |
| `airlineCode` | Airline code when available |
| `flightNumber` | Combined airline code and number |
| `city` | Origin for arrivals or destination for departures |
| `airportCode` | Parsed origin or destination airport code |
| `scheduledTime` | ISO 8601 scheduled timestamp |
| `scheduledDisplay` | Schedule text shown by the airport |
| `estimatedTime` | Current estimate when available |
| `actualTime` | Actual time when available |
| `chockTime` | Aircraft chock time when available |
| `terminal` | PHX terminal number when assigned |
| `gate` | Gate when assigned |
| `status` | Current human-readable status |
| `statusCode` | Compact source status code |
| `bagClaim` | Arrival bag-claim carousel when assigned |
| `codeShares` | Code-share entries from the source |
| `fetchedAt` | Time the board snapshot was fetched |
| `sourceUrl` | Public Sky Harbor flight-page URL |

### How to scrape Phoenix Sky Harbor flights

1. Open the Actor in Apify Console.
2. Choose `arrivals`, `departures`, or `both`.
3. Add optional airline, city, flight-number, status, or date filters.
4. Set the maximum number of qualifying flights.
5. Click **Start**.
6. Open the **Dataset** tab to inspect or export the records.
7. Optionally create a schedule and webhook for recurring monitoring.

For a broad first run, use:

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

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `direction` | string | `both` | `arrivals`, `departures`, or `both` |
| `airline` | string | — | Case-insensitive airline-name filter |
| `city` | string | — | Case-insensitive city or airport-code filter |
| `flightNumber` | string | — | Number with or without airline code |
| `status` | string | — | Status text such as `arrived` or `delayed` |
| `scheduledDate` | string | — | Date in `YYYY-MM-DD` format |
| `maxItems` | integer | `100` | Save 1–2,000 qualifying records |

All text filters use case-insensitive partial comparisons.
For example, `Southwest` matches `Southwest Airlines`, and `DEN` matches a city label ending in `(DEN)`.

### Useful input examples

#### Current PHX arrivals

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

#### Southwest departures

```json
{
  "direction": "departures",
  "airline": "Southwest",
  "maxItems": 25
}
```

#### Arrived-flight monitoring feed

```json
{
  "direction": "arrivals",
  "status": "arrived",
  "maxItems": 100
}
```

#### One route or airport

```json
{
  "direction": "both",
  "city": "DEN",
  "maxItems": 100
}
```

#### One flight number

```json
{
  "direction": "both",
  "flightNumber": "4077",
  "maxItems": 10
}
```

### Output example

A real run produces records shaped like this:

```json
{
  "sourceUrl": "https://www.skyharbor.com/flights/",
  "flightId": "3374717",
  "direction": "departure",
  "airline": "Southwest Airlines",
  "airlineCode": "WN",
  "flightNumber": "WN4077",
  "city": "HOUSTON",
  "airportCode": "HOU",
  "scheduledTime": "2026-08-29T05:00:00Z",
  "scheduledDisplay": "5:00 AM",
  "estimatedTime": "5:06 AM",
  "actualTime": "5:23 AM",
  "chockTime": "5:08 AM",
  "terminal": "4",
  "gate": "D17",
  "status": "Departed",
  "statusCode": "DP",
  "bagClaim": null,
  "codeShares": [],
  "fetchedAt": "2026-08-29T14:08:07.568Z"
}
```

Times such as `estimatedTime` are display values from the airport board.
Fields not yet assigned by the airport are returned as `null`.

### How much does it cost to export Phoenix Sky Harbor flight status?

The Actor uses pay-per-event pricing:

- a **$0.005** start fee per run;
- a tiered **flight record** fee for each qualifying row saved.

At the BRONZE tier, a flight record is **$0.000872**.
That makes 25 records about **$0.0268** including the start fee, 100 records about **$0.0922**, and 1,000 records about **$0.877**.
Higher-volume subscription tiers receive lower per-record prices.
Apify platform usage is included in pay-per-event pricing; no proxy is required by the current implementation.

Only accepted flight records are charged.
A valid zero-result filter incurs the one-time start event but no flight-record events.

### Recurring monitoring and alerts

The Actor returns a snapshot; it does not keep running after completion or send alerts by itself.
Use an Apify schedule to run it at your chosen interval.

A common workflow is:

1. Schedule a filtered arrival or departure input.
2. Send the completed-run webhook to Make, Zapier, n8n, or your API.
3. Compare `flightId`, `status`, `gate`, `terminal`, and time fields with the previous snapshot.
4. Notify users only when a relevant value changes.

Store prior snapshots in your own database or automation destination when change history matters.

### Export and integrations

The default dataset supports JSON, CSV, XML, RSS, and Excel-compatible downloads through Apify.
You can also:

- send results to Google Sheets;
- stream dataset items into a warehouse;
- trigger an Apify webhook when a run finishes;
- call the Actor from JavaScript or Python;
- expose it to AI agents through Apify MCP.

Keep `flightId` together with `scheduledTime` when deduplicating recurring snapshots.

### Run with the Apify API

Replace `YOUR_TOKEN` with an Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~phoenix-sky-harbor-flight-status/runs?token=YOUR_TOKEN&waitForFinish=120" \
  -H "Content-Type: application/json" \
  -d '{"direction":"arrivals","maxItems":25}'
```

Fetch dataset items using the `defaultDatasetId` returned by the run.

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/phoenix-sky-harbor-flight-status').call({
  direction: 'departures',
  airline: 'Southwest',
  maxItems: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/phoenix-sky-harbor-flight-status").call(
    run_input={"direction": "both", "city": "DEN", "maxItems": 100}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/phoenix-sky-harbor-flight-status"
```

Use the same JSON block for **Claude Desktop**, **Cursor**, and **VS Code**:

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

Example prompts:

- “Export the 25 latest Phoenix Sky Harbor arrivals.”
- “Find current Southwest departures from PHX and show gate changes.”
- “Return arrived flights from Denver for my operations report.”

### Reliability and retries

Each run makes one request to the public structured flight feed.
Network failures, HTTP 429 responses, and temporary server errors are retried with bounded exponential backoff, up to three attempts total.

The Actor validates JSON content type and required source fields.
A blocked, malformed, or changed endpoint causes a failed run rather than incomplete output presented as success.
No unmeasured residential fallback is enabled.

### Limits and freshness

- The airport controls board coverage, update timing, and field assignments.
- The public feed exposes its current schedule window, not arbitrary flight history.
- `scheduledDate` only filters dates already present in that current window.
- Gate, terminal, estimate, status, bag claim, and code shares can be missing or change after a run.
- The Actor does not include aircraft position, fares, parking, terminal maps, or airport-delay advisories.
- A scheduled Task creates snapshots; it does not guarantee instant change notification.

Always check `fetchedAt` when freshness matters.

### Empty results

A run can correctly return zero rows when no current board record matches every filter.
Try these checks:

1. Remove `scheduledDate`; it may be outside the source's current window.
2. Use a partial airline name such as `Southwest`.
3. Use an airport code or part of a city name.
4. Remove the status filter because statuses change throughout the day.
5. Switch `direction` to `both`.

A zero-result run is different from an upstream failure: invalid upstream data fails with an error in the run log.

### Troubleshooting

**The run says the date is invalid.**
Use an actual calendar date formatted exactly as `YYYY-MM-DD`.

**A gate or bag claim is null.**
The airport has not assigned or published that field for the flight.

**The flight number does not match.**
Try the numeric part only, or the combined source form such as `WN4077`.

**A known flight is absent.**
It may fall outside the public board's current schedule window, or the airline may be showing a code-share number not present as the primary record.

**The Actor failed after retries.**
Inspect the run log. A temporary source outage can be retried later; a response-schema error may indicate that Sky Harbor changed its feed.

### Legality and responsible use

This Actor extracts public operational flight information.
Use it in accordance with applicable laws, Sky Harbor's terms, Apify's terms, and your downstream providers' rules.

Do not represent a snapshot as an official safety, boarding, or emergency instruction.
Travelers should confirm time-sensitive details with Phoenix Sky Harbor and the operating airline.
Avoid excessive scheduling and collect only the fields needed for your workflow.

### Related Actors

- [FAA NAS Status & Airport Delays Scraper](https://apify.com/automation-lab/faa-nas-status-airport-delays-scraper) — pair PHX flight rows with broader FAA airport advisory and delay context.
- [Ryanair Flight Fares and Cheapest Routes](https://apify.com/automation-lab/ryanair-flight-fares-cheapest-routes) — use when the job is Ryanair fare and route monitoring rather than Phoenix airport status.

These Actors provide different records and are not substitutes for the current Sky Harbor flight board.

### FAQ

#### Does this Actor provide live aircraft positions?

No. It exports the status and schedule fields published on the Phoenix Sky Harbor flight board.

#### Can it export historical flights?

No. It filters the source's current schedule window and does not claim a historical archive.

#### Can I monitor one airline or route?

Yes. Combine `direction` with `airline`, `city`, or `flightNumber` and schedule the input.

#### Does it need a proxy?

No. The current implementation uses a public JSON feed directly without a proxy or browser.

#### Are all fields always available?

No. Estimates, actual times, gates, terminals, bag claims, and code shares depend on what the airport has assigned and published.

#### How do I avoid duplicate notifications?

Persist the previous snapshot and compare stable identifiers plus status, gate, terminal, and time fields before sending an alert.

#### Is this an official Phoenix airport product?

No. It is an independent Apify Actor that structures public data from the Phoenix Sky Harbor flight board.

# Actor input Schema

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

Return arrivals, departures, or both.

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

Optional case-insensitive airline name filter, for example American Airlines or Southwest.

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

Optional case-insensitive city or airport-code filter, for example Denver or DEN.

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

Optional flight number filter with or without airline code, for example WN4077 or 4077.

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

Optional case-insensitive status filter, such as delayed, arrived, departed, or on time.

## `scheduledDate` (type: `string`):

Optional date filter in YYYY-MM-DD format. The public board only exposes its current schedule window.

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

Maximum number of matching flight records to save.

## Actor input object example

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

# Actor output Schema

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

Open the default dataset using the flight-status table view.

# 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/phoenix-sky-harbor-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/phoenix-sky-harbor-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/phoenix-sky-harbor-flight-status --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/phoenix-sky-harbor-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/4ewp3MQdSTwqYpo8n/builds/jaNYS5BsFoqqdF9jN/openapi.json
