Menu
Back to Documentation Index

Release Documentation

Release notes, deployment guide, and configuration reference

VATSWIM API — Release Documentation

System Wide Information Management for VATSIM

Version: 1.1.0

Release Date: January 2026 (Updated 2026-01-27)

Status: Production Ready

Maintained by: vATCSCC Development Team


> ⚠️ FIXM Migration Notice (v1.1.0 - 2026-01-27)

>

> VATSWIM is transitioning from legacy OOOI column names (out_utc, off_utc, on_utc, in_utc)

> to FIXM-aligned naming (actual_off_block_time, actual_time_of_departure, actual_landing_time,

> actual_in_block_time). During the 30-day transition period, both column sets are populated.

>

> API responses prefer FIXM columns with legacy fallback. Use ?format=fixm for FIXM camelCase output.

> See VATSWIM_FIXM_Field_Mapping.md for complete mapping.


Table of Contents

1. Introduction

2. Architecture Overview

3. Getting Started

4. REST API Reference

5. WebSocket Real-Time API

6. Data Models

7. Client SDKs

8. Use Cases by Role

9. Data Authority & CDM Compliance

10. Database Reference

11. Configuration Reference

12. Troubleshooting

13. Appendices


1. Introduction

1.1 What is VATSWIM?

VATSWIM (System Wide Information Management) is a comprehensive data exchange platform that provides programmatic access to real-time and historical flight data from the VATSIM virtual air traffic control network. The API follows FAA SWIM standards and FIXM (Flight Information Exchange Model) conventions to deliver standardized flight information to external consumers.

SWIM serves as the authoritative data hub for the VATSIM ecosystem, enabling consistent Traffic Management Initiative (TMI) implementation, synchronized arrival/departure times, and seamless data exchange between all VATSIM systems.

1.2 Key Capabilities

CapabilityDescription
REST APIQuery flight data, positions, TMI programs, and controlled flights
WebSocket APIReal-time event streaming for departures, arrivals, position updates, and TMI changes
Data IngestionPush flight data, track positions, and telemetry from authorized sources
Multiple Output FormatsJSON, FIXM, XML, GeoJSON, CSV, KML, NDJSON
FIXM ComplianceOptional FIXM 4.3.0 field naming via ?format=fixm parameter
Tiered AccessFour access tiers with appropriate rate limits and permissions
Client SDKsOfficial SDKs for Python, JavaScript/TypeScript, Java, and C#

1.3 API Endpoints

Base URLPurpose
https://perti.vatcscc.org/api/swim/v1REST API
wss://perti.vatcscc.org/api/swim/v1/wsWebSocket

1.4 Data Refresh Cycle

SWIM data is refreshed every 15 seconds from the VATSIM network. The system processes approximately 2,000–6,000 active flights per cycle with sub-second query response times.


2. Architecture Overview

2.1 System Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                              VATSIM NETWORK                                 │
│                        (Flight plans, Positions)                            │
└────────────────────────────────┬────────────────────────────────────────────┘
                                 │
                                 ▼ (every 15 seconds)
┌─────────────────────────────────────────────────────────────────────────────┐
│                           INTERNAL SYSTEMS                                  │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                   VATSIM_ADL Database (Azure SQL)                   │   │
│  │                                                                     │   │
│  │  Normalized Tables:                                                 │   │
│  │  • dbo.adl_flight_core      - Identity, phase, timestamps          │   │
│  │  • dbo.adl_flight_position  - Lat/lon, altitude, speed             │   │
│  │  • dbo.adl_flight_plan      - Route, airports, procedures          │   │
│  │  • dbo.adl_flight_times     - ETAs, OOOI, controlled times         │   │
│  │  • dbo.adl_flight_tmi       - Ground stops, GDP, delays            │   │
│  │  • dbo.adl_flight_aircraft  - Equipment, weight class, airline     │   │
│  └──────────────────────────────┬──────────────────────────────────────┘   │
│                                 │                                           │
│                                 │ (sync via sp_Swim_BulkUpsert)            │
│                                 ▼                                           │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │               SWIM_API Database (Azure SQL Basic - $5/mo)           │   │
│  │                                                                     │   │
│  │  Denormalized Tables:                                               │   │
│  │  • dbo.swim_flights         - Complete flight records (75 columns) │   │
│  │  • dbo.swim_api_keys        - API key credentials and tiers        │   │
│  │  • dbo.swim_audit_log       - Request logging                      │   │
│  │  • dbo.swim_ground_stops    - Cached TMI programs                  │   │
│  └──────────────────────────────┬──────────────────────────────────────┘   │
└─────────────────────────────────┼───────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           PUBLIC SWIM API                                   │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │   REST API              │    WebSocket Server                       │   │
│  │   /api/swim/v1/         │    /api/swim/v1/ws                        │   │
│  │   • flights             │    • flight.departed                      │   │
│  │   • flight              │    • flight.arrived                       │   │
│  │   • positions           │    • flight.created                       │   │
│  │   • metering/{airport}  │    • flight.positions                     │   │
│  │   • tmi/programs        │    • tmi.issued                           │   │
│  │   • tmi/controlled      │    • tmi.released                         │   │
│  │   • tmi/reroutes        │    • system.heartbeat                     │   │
│  │   • jatoc/incidents     │                                           │   │
│  │   • splits/presets      │                                           │   │
│  │   • ingest/adl          │                                           │   │
│  │   • ingest/track        │                                           │   │
│  │   • ingest/metering     │                                           │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                  │                                          │
└──────────────────────────────────┼──────────────────────────────────────────┘
                                   │
                    ┌──────────────┴──────────────┐
                    ▼                              ▼
┌─────────────────────────────┐  ┌─────────────────────────────────────────┐
│       ATC SYSTEMS           │  │         THIRD-PARTY CONSUMERS           │
│  • vNAS                     │  │  • Virtual Airlines (AOC systems)       │
│  • CRC                      │  │  • Flight Trackers (SimAware, etc.)     │
│  • EuroScope                │  │  • Analytics Platforms                  │
│  • SimTraffic               │  │  • Discord Bots                         │
└─────────────────────────────┘  └─────────────────────────────────────────┘

2.2 Database Isolation Strategy

SWIM uses a dedicated Azure SQL Basic database (SWIM_API) to serve public API queries. This isolates external traffic from the internal VATSIM_ADL Serverless database, providing:

BenefitDescription
Fixed Cost$5/month regardless of query volume (vs. variable Serverless costs)
Performance IsolationAPI load cannot impact internal ADL processing
Optimized SchemaDenormalized swim_flights table eliminates JOINs for reads

2.3 Data Flow

1. VATSIM API → VATSIM_ADL: Every 15 seconds via sp_Adl_RefreshFromVatsim_Normalized

2. VATSIM_ADL → SWIM_API: Every 2 minutes via PHP batch sync calling sp_Swim_BulkUpsert

3. MySQL (PERTI) → SWIM_API: Ground stops synced every 15 seconds

4. SWIM_API → Consumers: REST/WebSocket queries served from dedicated database


3. Getting Started

3.1 Obtaining an API Key

API keys are required for all SWIM API access. Use the self-service API Key Management Portal to request and manage your keys:

API Key Portal: https://perti.vatcscc.org/swim-keys.php

The portal allows you to:

  • Request new API keys (requires VATSIM authentication)
  • View your existing keys and usage statistics
  • Regenerate or revoke keys
  • Update key descriptions and contact information
  • For questions or to request elevated access tiers (partner/system), contact:

  • Email: dev@vatcscc.org
  • Discord: vATCSCC Server
  • 3.2 API Key Tiers

    TierPrefixRate LimitWebSocket ConnectionsWrite AccessUse Case
    systemswim_sys_30,000/min10,000YesTrusted systems (vNAS, CRC, SimTraffic)
    partnerswim_par_3,000/min500LimitedIntegration partners (Virtual Airlines)
    developerswim_dev_300/min50NoDevelopment and testing
    publicswim_pub_100/min5NoPublic consumers

    3.3 Authentication

    HTTP Header (Recommended)

    Authorization: Bearer swim_dev_your_key_here
    

    Query Parameter (WebSocket)

    wss://perti.vatcscc.org/api/swim/v1/ws?api_key=swim_dev_your_key_here
    

    3.4 Quick Start Examples

    cURL: Get Active Flights to JFK

    curl -H "Authorization: Bearer swim_dev_your_key" \
      "https://perti.vatcscc.org/api/swim/v1/flights?dest_icao=KJFK&status=active"
    

    Python: Monitor Airport Departures

    from swim_client import SWIMClient
    
    client = SWIMClient('swim_dev_your_key')
    
    @client.on('flight.departed')
    def on_departure(event, timestamp):
        print(f"{event.callsign} departed {event.dep} → {event.arr}")
    
    client.subscribe(['flight.departed'], airports=['KJFK', 'KLGA', 'KEWR'])
    client.run()
    

    JavaScript: Fetch GeoJSON Positions

    const response = await fetch(
      'https://perti.vatcscc.org/api/swim/v1/positions?artcc=ZNY',
      { headers: { 'Authorization': 'Bearer swim_dev_your_key' } }
    );
    const geojson = await response.json();
    // Ready for MapLibre/Leaflet/Mapbox
    


    4. REST API Reference

    4.1 Common Parameters

    ParameterTypeDescription
    formatstringfixm (default) for FIXM 4.3.0 field names, or legacy for original field names
    pageintPage number (default: 1)
    per_pageintResults per page (default: 100, max: 1000)

    4.2 Response Format

    All responses follow this structure:

    {
      "success": true,
      "data": [ ... ],
      "pagination": {
        "total": 156,
        "page": 1,
        "per_page": 100,
        "total_pages": 2,
        "has_more": true
      },
      "timestamp": "2026-01-16T18:30:00Z"
    }
    

    Error responses:

    {
      "success": false,
      "error": {
        "code": "AUTH_FAILED",
        "message": "Invalid or expired API key"
      },
      "timestamp": "2026-01-16T18:30:00Z"
    }
    


    4.3 GET /api/swim/v1

    Returns API information and available endpoints.

    Response:

    {
      "success": true,
      "data": {
        "name": "VATSWIM API",
        "version": "1.0.0",
        "description": "System Wide Information Management for VATSIM",
        "documentation": "https://perti.vatcscc.org/docs/swim/",
        "endpoints": {
          "flights": {
            "GET /api/swim/v1/flights": "List flights with filters",
            "GET /api/swim/v1/flight": "Get single flight by GUFI or flight_key"
          },
          "positions": {
            "GET /api/swim/v1/positions": "Bulk flight positions (GeoJSON)"
          },
          "tmi": {
            "GET /api/swim/v1/tmi/programs": "Active TMI programs (GS/GDP)",
            "GET /api/swim/v1/tmi/controlled": "Flights under TMI control"
          }
        }
      }
    }
    


    4.4 GET /api/swim/v1/flights

    Returns paginated list of flights with optional filtering.

    Query Parameters:

    ParameterTypeDescription
    statusstringactive (default), completed, or all
    dept_icaostringComma-separated departure airports (e.g., KJFK,KLGA)
    dest_icaostringComma-separated destination airports
    artccstringComma-separated ARTCCs (e.g., ZNY,ZBW)
    callsignstringCallsign pattern with wildcards (e.g., UAL)
    tmi_controlledbooleantrue to filter TMI-controlled flights
    phasestringComma-separated flight phases (e.g., ENROUTE,DESCENDING)
    formatstringResponse format: fixm (default), json, xml, geojson, csv, kml, ndjson
    Supported Formats:

    FormatContent-TypeDescription
    fixmapplication/jsonJSON with FIXM 4.3.0 camelCase field names (default)
    jsonapplication/jsonStandard JSON with snake_case fields
    xmlapplication/xmlXML format for enterprise/SOAP integrations
    geojsonapplication/geo+jsonGeoJSON FeatureCollection for mapping
    csvtext/csvCSV for spreadsheet/analytics export
    kmlapplication/vnd.google-earth.kml+xmlKML for Google Earth visualization
    ndjsonapplication/x-ndjsonNewline-delimited JSON for streaming
    Example Request:

    curl -H "Authorization: Bearer swim_dev_test" \
      "https://perti.vatcscc.org/api/swim/v1/flights?dest_icao=KJFK&status=active&per_page=50"
    

    Response (Legacy Format):

    {
      "success": true,
      "data": [
        {
          "gufi": "VAT-20260116-UAL123-KLAX-KJFK",
          "flight_uid": 12345,
          "flight_key": "UAL123_KLAX_KJFK_20260116",
          "identity": {
            "callsign": "UAL123",
            "cid": 1234567,
            "aircraft_type": "B738",
            "aircraft_icao": "B738",
            "aircraft_faa": "B738/L",
            "weight_class": "L",
            "wake_category": "M",
            "airline_icao": "UAL",
            "airline_name": "United Airlines"
          },
          "flight_plan": {
            "departure": "KLAX",
            "destination": "KJFK",
            "alternate": "KEWR",
            "cruise_altitude": 35000,
            "cruise_speed": 450,
            "route": "DOTSS5 KAYOH J146 ABQ J80 HVE J100 STL J24 JHW LENDY5",
            "remarks": "/v/",
            "flight_rules": "I",
            "departure_artcc": "ZLA",
            "destination_artcc": "ZNY",
            "departure_tracon": "SCT",
            "destination_tracon": "N90",
            "departure_fix": "DOTSS",
            "departure_procedure": "DOTSS5",
            "arrival_fix": "LENDY",
            "arrival_procedure": "LENDY5",
            "departure_runway": "25R",
            "arrival_runway": "22L"
          },
          "position": {
            "latitude": 40.1234,
            "longitude": -74.5678,
            "altitude_ft": 35000,
            "heading": 85,
            "ground_speed_kts": 480,
            "true_airspeed_kts": 465,
            "vertical_rate_fpm": 0,
            "current_artcc": "ZNY",
            "current_tracon": null,
            "current_zone": null
          },
          "progress": {
            "phase": "ENROUTE",
            "is_active": true,
            "distance_remaining_nm": 125.4,
            "distance_flown_nm": 2156.8,
            "gcd_nm": 2145.2,
            "route_total_nm": 2282.2,
            "pct_complete": 94.5,
            "time_to_dest_min": 15.7
          },
          "times": {
            "etd": null,
            "etd_runway": null,
            "eta": "2026-01-16T18:45:00Z",
            "eta_runway": "2026-01-16T18:52:00Z",
            "eta_source": "calculated",
            "eta_method": "route_gcd_blend",
            "ete_minutes": 285,
            "out": "2026-01-16T14:05:00Z",
            "off": "2026-01-16T14:18:00Z",
            "on": null,
            "in": null,
            "ctd": null,
            "cta": null,
            "edct": null
          },
          "tmi": {
            "is_controlled": false,
            "ground_stop_held": false,
            "gs_release": null,
            "control_type": null,
            "control_program": null,
            "control_element": null,
            "is_exempt": false,
            "exempt_reason": null,
            "delay_minutes": null,
            "delay_status": null,
            "slot_time": null,
            "program_id": null,
            "slot_id": null
          },
          "_source": "vatcscc",
          "_first_seen": "2026-01-16T14:03:22Z",
          "_last_seen": "2026-01-16T18:30:15Z",
          "_logon_time": "2026-01-16T14:00:00Z",
          "_last_sync": "2026-01-16T18:30:00Z"
        }
      ],
      "pagination": {
        "total": 156,
        "page": 1,
        "per_page": 50,
        "total_pages": 4,
        "has_more": true
      },
      "timestamp": "2026-01-16T18:30:00Z"
    }
    


    4.5 GET /api/swim/v1/flight

    Returns a single flight by GUFI or flight_key.

    Query Parameters:

    ParameterTypeDescription
    gufistringGlobally Unique Flight Identifier
    flight_keystringADL flight key
    formatstringlegacy or fixm
    Example:

    curl -H "Authorization: Bearer swim_dev_test" \
      "https://perti.vatcscc.org/api/swim/v1/flight?gufi=VAT-20260116-UAL123-KLAX-KJFK"
    


    4.6 GET /api/swim/v1/positions

    Returns bulk flight positions in GeoJSON FeatureCollection format, suitable for direct rendering on web maps.

    Query Parameters:

    ParameterTypeDescription
    dept_icaostringDeparture airport filter
    dest_icaostringDestination airport filter
    artccstringARTCC filter
    boundsstringBounding box: minLon,minLat,maxLon,maxLat
    tmi_controlledbooleanTMI-controlled flights only
    phasestringFlight phase filter
    include_routebooleanInclude route string in properties
    Example Request:

    curl -H "Authorization: Bearer swim_dev_test" \
      "https://perti.vatcscc.org/api/swim/v1/positions?artcc=ZNY&bounds=-76,39,-72,42"
    

    Response:

    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "id": 12345,
          "geometry": {
            "type": "Point",
            "coordinates": [-74.5678, 40.1234, 35000]
          },
          "properties": {
            "flight_uid": 12345,
            "callsign": "UAL123",
            "aircraft": "B738",
            "departure": "KLAX",
            "destination": "KJFK",
            "phase": "ENROUTE",
            "altitude": 35000,
            "heading": 85,
            "groundspeed": 480,
            "vertical_rate": 0,
            "distance_remaining_nm": 125.4,
            "tmi_status": "none"
          }
        }
      ],
      "metadata": {
        "count": 247,
        "timestamp": "2026-01-16T18:30:00Z",
        "source": "vatcscc",
        "bounds": {
          "min_lon": -76,
          "min_lat": 39,
          "max_lon": -72,
          "max_lat": 42
        }
      }
    }
    


    4.7 GET /api/swim/v1/tmi/programs

    Returns active Traffic Management Initiatives (Ground Stops, Ground Delay Programs).

    Query Parameters:

    ParameterTypeDescription
    typestringall (default), gs, or gdp
    airportstringAirport ICAO filter
    artccstringARTCC filter
    include_historybooleanInclude recently ended programs
    Response:

    {
      "success": true,
      "data": {
        "ground_stops": [
          {
            "type": "ground_stop",
            "airport": "KJFK",
            "airport_name": "John F Kennedy Intl",
            "artcc": "ZNY",
            "reason": "Thunderstorms",
            "probability_of_extension": 60,
            "times": {
              "start": "2026-01-16T17:00:00Z",
              "end": "2026-01-16T19:00:00Z"
            },
            "scope": {
              "origin_centers": ["ZDC", "ZBW", "ZOB"],
              "origin_airports": null
            },
            "advisory_number": "GS-JFK-001",
            "is_active": true
          }
        ],
        "gdp_programs": [
          {
            "type": "gdp",
            "program_id": "GDP_KEWR_20260116",
            "airport": "KEWR",
            "airport_name": "Newark Liberty Intl",
            "artcc": "ZNY",
            "reason": "Volume",
            "rates": {
              "program_rate": 40,
              "default_rate": 52
            },
            "delays": {
              "limit_minutes": 90,
              "average_minutes": 45,
              "maximum_minutes": 87
            },
            "flights": {
              "total": 156,
              "affected": 89,
              "exempt": 12
            },
            "times": {
              "start": "2026-01-16T15:00:00Z",
              "end": "2026-01-16T21:00:00Z"
            },
            "is_active": true
          }
        ],
        "summary": {
          "active_ground_stops": 1,
          "active_gdp_programs": 1,
          "total_controlled_airports": 2
        }
      },
      "timestamp": "2026-01-16T18:30:00Z"
    }
    


    4.8 GET /api/swim/v1/tmi/controlled

    Returns flights currently under TMI control.

    Query Parameters:

    ParameterTypeDescription
    airportstringFilter by affected airport
    typestringgs, gdp, or all
    include_exemptbooleanInclude exempt flights

    4.9 POST /api/swim/v1/ingest/adl

    Requires: system or partner tier with write access

    Receives flight data from authoritative sources. Maximum batch size: 500 flights.

    Request Body:

    {
      "flights": [
        {
          "callsign": "VPA123",
          "dept_icao": "KJFK",
          "dest_icao": "KLAX",
          "cid": 1234567,
          "aircraft_type": "B738",
          "route": "DCT JFK J584 ORD J64 LAX",
          "phase": "ENROUTE",
          "is_active": true,
          "latitude": 40.1234,
          "longitude": -98.5678,
          "altitude_ft": 35000,
          "heading_deg": 270,
          "groundspeed_kts": 450,
          "vertical_rate_fpm": 0,
          "out_utc": "2026-01-16T14:05:00Z",
          "off_utc": "2026-01-16T14:18:00Z",
          "eta_utc": "2026-01-16T18:45:00Z",
          "tmi": {
            "ctl_type": "GDP",
            "slot_time_utc": "2026-01-16T18:30:00Z",
            "delay_minutes": 45
          }
        }
      ]
    }
    

    Response:

    {
      "success": true,
      "data": {
        "processed": 1,
        "created": 0,
        "updated": 1,
        "errors": 0,
        "error_details": []
      },
      "timestamp": "2026-01-16T18:30:00Z",
      "meta": {
        "source": "virtual_airline",
        "batch_size": 1
      }
    }
    


    4.10 POST /api/swim/v1/ingest/track

    Requires: system or partner tier with write access

    Receives real-time track/position updates from ATC automation systems. Maximum batch size: 1000 tracks.

    Request Body:

    {
      "tracks": [
        {
          "callsign": "UAL123",
          "latitude": 40.6413,
          "longitude": -73.7781,
          "altitude_ft": 35000,
          "ground_speed_kts": 450,
          "heading_deg": 270,
          "vertical_rate_fpm": -500,
          "squawk": "1200",
          "track_source": "radar"
        }
      ]
    }
    

    Track Source Values:

    ValueDescription
    radarPrimary/secondary radar
    ads-bADS-B surveillance
    mlatMultilateration
    mode-sMode S transponder
    acarsACARS position report

    5. WebSocket Real-Time API

    5.1 Connecting

    const ws = new WebSocket('wss://perti.vatcscc.org/api/swim/v1/ws?api_key=YOUR_KEY');
    

    Connection Response:

    {
      "type": "connected",
      "data": {
        "client_id": "c_abc123def456",
        "server_time": "2026-01-16T18:30:00Z",
        "version": "1.0.0"
      }
    }
    

    5.2 Subscribing to Channels

    Send a subscribe message to receive specific event types:

    {
      "action": "subscribe",
      "channels": ["flight.departed", "flight.arrived", "tmi.issued"],
      "filters": {
        "airports": ["KJFK", "KLGA", "KEWR"],
        "artccs": ["ZNY"]
      }
    }
    

    Available Channels:

    ChannelDescription
    flight.createdNew pilot connected to network
    flight.departedAircraft wheels-up (OFF time detected)
    flight.arrivedAircraft wheels-down (IN time detected)
    flight.deletedPilot disconnected
    flight.positionsBatched position updates (every 15 sec)
    flight.All flight events
    tmi.issuedNew Ground Stop/GDP created
    tmi.releasedTMI ended/released
    tmi.All TMI events
    system.heartbeatServer keepalive (30 sec interval)
    Subscription Filters:

    FilterTypeDescription
    airportsarrayICAO codes for departure/destination
    artccsarrayARTCC identifiers
    callsign_prefixarrayCallsign prefixes (e.g., ["UAL", "DAL"])
    bboxobjectGeographic bounding box {north, south, east, west}

    5.3 Event Formats

    flight.departed:

    {
      "type": "flight.departed",
      "timestamp": "2026-01-16T18:30:15.123Z",
      "data": {
        "callsign": "UAL123",
        "flight_uid": 12345,
        "dep": "KLAX",
        "arr": "KJFK",
        "off_utc": "2026-01-16T18:30:00Z",
        "aircraft": "B738"
      }
    }
    

    flight.arrived:

    {
      "type": "flight.arrived",
      "timestamp": "2026-01-16T22:45:30.456Z",
      "data": {
        "callsign": "UAL123",
        "flight_uid": 12345,
        "dep": "KLAX",
        "arr": "KJFK",
        "in_utc": "2026-01-16T22:45:00Z"
      }
    }
    

    flight.positions (batched):

    {
      "type": "flight.positions",
      "timestamp": "2026-01-16T18:30:15.123Z",
      "data": {
        "count": 2847,
        "positions": [
          {
            "callsign": "UAL123",
            "flight_uid": 12345,
            "latitude": 40.1234,
            "longitude": -74.5678,
            "altitude_ft": 35000,
            "groundspeed_kts": 480,
            "heading_deg": 85,
            "vertical_rate_fpm": 0,
            "current_artcc": "ZNY",
            "dep": "KLAX",
            "arr": "KJFK",
            "phase": "ENROUTE"
          }
        ]
      }
    }
    

    tmi.issued:

    {
      "type": "tmi.issued",
      "timestamp": "2026-01-16T17:00:00.000Z",
      "data": {
        "program_id": "GS_KJFK_20260116",
        "program_type": "GROUND_STOP",
        "airport": "KJFK",
        "start_time": "2026-01-16T17:00:00Z",
        "end_time": "2026-01-16T19:00:00Z",
        "reason": "Thunderstorms"
      }
    }
    

    5.4 Client Actions

    ActionRequestDescription
    Ping{"action": "ping"}Server responds with {"type": "pong"}
    Status{"action": "status"}Returns current subscriptions and stats
    Unsubscribe{"action": "unsubscribe", "channels": [...]}Remove channel subscriptions

    5.5 Error Codes

    CodeDescription
    AUTH_FAILEDInvalid or expired API key
    CONNECTION_LIMITTier connection limit reached
    RATE_LIMITEDToo many messages per second
    INVALID_JSONMalformed JSON message
    INVALID_CHANNELUnknown channel name
    INVALID_FILTERInvalid filter specification
    MESSAGE_TOO_LARGEMessage exceeds 64KB limit

    6. Data Models

    6.1 GUFI (Globally Unique Flight Identifier)

    Format: VAT-YYYYMMDD-CALLSIGN-DEPT-DEST

    Example: VAT-20260116-UAL123-KLAX-KJFK

    The GUFI is computed in the SWIM_API database as a persisted computed column on dbo.swim_flights:

    gufi AS ('VAT-' + FORMAT(COALESCE(first_seen_utc, GETUTCDATE()), 'yyyyMMdd') 
            + '-' + callsign + '-' + ISNULL(fp_dept_icao, 'XXXX') 
            + '-' + ISNULL(fp_dest_icao, 'XXXX')) PERSISTED
    

    6.2 Flight Phases

    PhaseDescription
    PREFLIGHTConnected, not yet departed
    DEPARTINGTaxiing for departure
    CLIMBINGAirborne, climbing
    ENROUTECruise altitude
    DESCENDINGDescending to destination
    APPROACHOn approach
    LANDEDWheels down, taxiing in
    ARRIVEDAt gate/parked

    6.3 TMI Control Types

    TypeDescription
    GSGround Stop
    GDPGround Delay Program
    MITMiles-in-Trail
    MINITMinutes-in-Trail
    AFPAirspace Flow Program

    6.4 OOOI Times (Out/Off/On/In)

    SWIM tracks four critical flight milestone times aligned with FAA CDM specifications:

    FieldCDM ReferenceDescriptionDatabase Column
    OUTT13Actual Off-Block (pushback)out_utc
    OFFT11Actual Takeoff (wheels-up)off_utc
    ONT12Actual Landing (wheels-down)on_utc
    INT14Actual In-Block (gate arrival)in_utc

    6.5 FIXM Field Mapping

    The ?format=fixm parameter returns FIXM 4.3.0 aligned field names:

    Legacy NameFIXM Name
    callsignaircraft_identification
    departuredeparture_aerodrome
    destinationarrival_aerodrome
    cruise_altitudecruising_level
    headingtrack
    ground_speed_ktsground_speed
    altitude_ftaltitude
    phaseflight_status
    wake_categorywake_turbulence
    airline_icaooperator_icao
    outactual_off_block_time
    offactual_time_of_departure
    onactual_landing_time
    inactual_in_block_time

    7. Client SDKs

    7.1 Python SDK

    Location: PERTI/sdk/python/

    Installation:

    cd sdk/python
    pip install -e .
    

    Or: pip install websockets

    Basic Usage:

    from swim_client import SWIMClient
    
    client = SWIMClient('swim_dev_your_key', debug=True)
    
    @client.on('connected')
    def on_connected(info, timestamp):
        print(f"Connected! Client ID: {info.client_id}")
    
    @client.on('flight.departed')
    def on_departure(event, timestamp):
        print(f"{event.callsign} departed {event.dep}")
    
    @client.on('flight.arrived')  
    def on_arrival(event, timestamp):
        print(f"{event.callsign} arrived at {event.arr}")
    
    client.subscribe(['flight.departed', 'flight.arrived'])
    client.run()
    

    Async Usage:

    import asyncio
    from swim_client import SWIMClient
    
    async def main():
        client = SWIMClient('swim_dev_your_key')
        
        @client.on('flight.departed')
        def on_departure(event, timestamp):
            print(f"{event.callsign} departed")
        
        client.subscribe(['flight.departed'])
        await client.connect()
        await client.run_async()
    
    asyncio.run(main())
    

    SDK Configuration:

    ParameterDefaultDescription
    api_keyrequiredAPI key for authentication
    urlwss://perti.vatcscc.org/...WebSocket URL
    reconnectTrueAuto-reconnect on disconnect
    reconnect_interval5.0Initial reconnect delay (seconds)
    max_reconnect_interval60.0Maximum reconnect delay
    ping_interval30.0Ping interval (seconds)
    debugFalseEnable debug logging
    Example Scripts:

    ScriptDescription
    examples/basic_example.pySimple connection and event handling
    examples/airport_monitor.pyMonitor specific airport traffic
    examples/tmi_monitor.pyTrack TMI issuances and releases
    examples/discord_bot.pyDiscord integration example
    examples/data_export_pipeline.pyExport flight data to CSV/JSON

    7.2 JavaScript/TypeScript SDK

    Location: PERTI/sdk/javascript/

    Installation:

    npm install
    

    Usage:

    import { SwimClient } from './src';
    
    const client = new SwimClient('swim_dev_your_key');
    
    client.on('flight.departed', (event) => {
      console.log(${event.callsign} departed ${event.dep});
    });
    
    client.subscribe(['flight.departed', 'flight.arrived']);
    client.connect();
    


    7.3 Java SDK

    Location: PERTI/sdk/java/swim-client/

    Maven:

    <dependency>
      <groupId>org.vatsim.swim</groupId>
      <artifactId>swim-client</artifactId>
      <version>1.0.0</version>
    </dependency>
    

    Usage:

    import org.vatsim.swim.SwimWebSocketClient;
    
    SwimWebSocketClient client = new SwimWebSocketClient("swim_dev_your_key");
    
    client.onDeparture(event -> {
        System.out.println(event.getCallsign() + " departed " + event.getDeparture());
    });
    
    client.subscribe(Arrays.asList("flight.departed", "flight.arrived"));
    client.connect();
    


    7.4 C# SDK

    Location: PERTI/sdk/csharp/SwimClient/

    NuGet:

    dotnet add package VatsimSwim.Client
    

    Usage:

    using VatsimSwim;
    
    var client = new SwimWebSocketClient("swim_dev_your_key");
    
    client.OnDeparture += (sender, e) => {
        Console.WriteLine($"{e.Callsign} departed {e.Departure}");
    };
    
    await client.SubscribeAsync(new[] { "flight.departed", "flight.arrived" });
    await client.ConnectAsync();
    


    8. Use Cases by Role

    8.1 Virtual Airlines

    Virtual Airlines can integrate SWIM to enhance their operations:

    Read Access (developer tier):

  • Real-time fleet tracking via WebSocket flight.positions
  • Departure/arrival notifications for pilot PIREPs
  • TMI awareness for operational planning
  • Flight progress monitoring for dispatch
  • Write Access (partner tier):

  • Push OOOI times from ACARS/AOC systems via /ingest/adl
  • Update ETAs from dispatch systems
  • Provide schedule data (STD/STA) per CDM T1-T4 specifications
  • Example: Fleet Tracker

    from swim_client import SWIMClient
    
    AIRLINE_PREFIX = 'VPA'  # Your airline's callsign prefix
    
    client = SWIMClient('swim_par_your_airline_key')
    
    @client.on('flight.departed')
    def track_departure(event, ts):
        if event.callsign.startswith(AIRLINE_PREFIX):
            # Log to your airline's dispatch system
            log_pirep_departure(event.callsign, event.dep, event.off_utc)
    
    @client.on('flight.arrived')
    def track_arrival(event, ts):
        if event.callsign.startswith(AIRLINE_PREFIX):
            log_pirep_arrival(event.callsign, event.arr, event.in_utc)
    
    client.subscribe(
        ['flight.departed', 'flight.arrived'],
        callsign_prefix=[AIRLINE_PREFIX]
    )
    client.run()
    


    8.2 ATC Client Developers

    ATC client developers (CRC, EuroScope plugins, vNAS) can use SWIM for:

    Read Access:

  • Flight data for display rendering
  • TMI status for tag annotations
  • Position data for traffic displays
  • Write Access (system tier):

  • Push track data from radar simulation
  • Update handoff times and clearances
  • Provide metering data from TBFM-style systems
  • Example: CRC Plugin Data Feed

    // Push track positions every second
    var tracks = GetAllTrackedFlights().Select(f => new {
        callsign = f.Callsign,
        latitude = f.Position.Latitude,
        longitude = f.Position.Longitude,
        altitude_ft = f.Altitude,
        ground_speed_kts = f.GroundSpeed,
        heading_deg = f.Heading,
        track_source = "radar"
    }).ToList();
    
    await swimClient.PostAsync("/api/swim/v1/ingest/track", new { tracks });
    


    8.3 Third-Party Application Developers

    Build flight trackers, analytics tools, or integration services:

    Flight Tracking Application:

    // Fetch positions for map display
    async function updateMap() {
      const response = await fetch(
        'https://perti.vatcscc.org/api/swim/v1/positions',
        { headers: { 'Authorization': Bearer ${API_KEY} } }
      );
      const geojson = await response.json();
      
      // Update MapLibre source
      map.getSource('flights').setData(geojson);
    }
    
    // Update every 15 seconds
    setInterval(updateMap, 15000);
    

    Discord Bot:

    import discord
    from swim_client import SWIMClient
    
    bot = discord.Bot()
    swim = SWIMClient('swim_dev_your_key')
    
    @swim.on('tmi.issued')
    async def announce_tmi(event, ts):
        channel = bot.get_channel(TMI_CHANNEL_ID)
        await channel.send(
            f"⚠️ {event.program_type} issued for {event.airport}\n"
            f"Reason: {event.reason}\n"
            f"Until: {event.end_time}"
        )
    
    swim.subscribe(['tmi.issued', 'tmi.released'])
    


    8.4 TMU/ATCSCC Staff

    Traffic Management personnel can programmatically access TMI data:

    Monitor Controlled Flights:

    import requests
    
    def get_controlled_flights(airport):
        response = requests.get(
            f'https://perti.vatcscc.org/api/swim/v1/tmi/controlled',
            headers={'Authorization': f'Bearer {API_KEY}'},
            params={'airport': airport}
        )
        return response.json()['data']
    
    

    Get all flights affected by JFK ground stop

    jfk_held = get_controlled_flights('KJFK') for flight in jfk_held: print(f"{flight['callsign']}: delay {flight['delay_minutes']}min")


    9. Data Authority & CDM Compliance

    9.1 Data Source Hierarchy

    SWIM implements FAA CDM (Collaborative Decision Making) specifications for data authority:

    Data TypePrimary SourceCan Override
    Identity (callsign, cid)VATSIMNo
    Flight PlanVATSIMNo
    TMI (gs_held, edct_utc, slot_time_utc)vATCSCCNo
    Track PositionvNAS → CRC → EuroScope → simulatorYes
    OOOI TimesACARS → Virtual Airline → simulatorYes
    Schedule (STD/STA)Virtual Airline → SimBriefYes
    MeteringSimTraffic → vATCSCC → vNASYes

    9.2 Source Priority Rankings

    When multiple sources provide the same data, priority determines which value is accepted:

    OOOI Times (T11-T14):

    1. acars / hoppie (priority 1)

    2. virtual_airline (priority 2)

    3. simulator (priority 3)

    4. vatcscc (priority 4)

    Track Positions:

    1. vnas (priority 1)

    2. crc (priority 2)

    3. euroscope (priority 3)

    4. simulator (priority 4)

    5. acars (priority 5)

    9.3 Field Merge Behaviors

    BehaviorDescriptionExample Fields
    monotonicReject older timestampslat, lon, altitude_ft
    variableAccept newer timestampseta_utc, delay_minutes
    priority_basedHigher priority source winsout_utc, off_utc, on_utc, in_utc
    immutableOnly authoritative source can writegs_held, ctl_type, edct_utc
    latestLast write winsfp_route, aircraft_type

    9.4 CDM Time Field Reference

    FieldCDM RefDescriptionAuthority
    lrtd_utcT1Airline Runway Time of DepartureVirtual Airline
    lrta_utcT2Airline Runway Time of ArrivalVirtual Airline
    lgtd_utcT3Airline Gate Time of DepartureVirtual Airline
    lgta_utcT4Airline Gate Time of ArrivalVirtual Airline
    ertd_utcT7Earliest Runway Time of DepartureVirtual Airline
    erta_utcT8Earliest Runway Time of ArrivalVirtual Airline
    out_utcT13Actual Off-Block (AOBT)ACARS/VA/sim
    off_utcT11Actual Takeoff (ATOT)ACARS/VA/sim
    on_utcT12Actual Landing (ALDT)ACARS/VA/sim
    in_utcT14Actual In-Block (AIBT)ACARS/VA/sim

    10. Database Reference

    10.1 Connection Configuration

    Database connections are established in PERTI/load/connect.php:

    // Primary Website Database (MySQL)
    $conn_pdo    // PDO connection to MySQL (PERTI app data)
    $conn_sqli   // MySQLi connection to MySQL
    
    // ADL Database (Azure SQL Serverless) - Internal
    $conn_adl    // sqlsrv connection to VATSIM_ADL
    
    // SWIM API Database (Azure SQL Basic) - Public API
    $conn_swim   // sqlsrv connection to SWIM_API
    

    Connection credentials are defined in PERTI/load/config.php:

    // MySQL (PERTI)
    define("SQL_HOST", "...");
    define("SQL_DATABASE", "...");
    define("SQL_USERNAME", "...");
    define("SQL_PASSWORD", "...");
    
    // Azure SQL - ADL (Internal)
    define("ADL_SQL_HOST", "...");
    define("ADL_SQL_DATABASE", "VATSIM_ADL");
    define("ADL_SQL_USERNAME", "...");
    define("ADL_SQL_PASSWORD", "...");
    
    // Azure SQL - SWIM API (Public)
    define("SWIM_SQL_HOST", "...");
    define("SWIM_SQL_DATABASE", "SWIM_API");
    define("SWIM_SQL_USERNAME", "...");
    define("SWIM_SQL_PASSWORD", "...");
    

    10.2 SWIM_API Database Schema

    dbo.swim_flights

    The primary denormalized flight table (75 columns):

    CREATE TABLE dbo.swim_flights (
        -- Primary Key
        flight_uid BIGINT NOT NULL PRIMARY KEY,
        flight_key NVARCHAR(64) NULL,
        
        -- GUFI (Computed)
        gufi AS ('VAT-' + FORMAT(COALESCE(first_seen_utc, GETUTCDATE()), 'yyyyMMdd') 
                + '-' + callsign + '-' + ISNULL(fp_dept_icao, 'XXXX') 
                + '-' + ISNULL(fp_dest_icao, 'XXXX')) PERSISTED,
        
        -- Identity
        callsign NVARCHAR(16) NOT NULL,
        cid INT NULL,
        flight_id NVARCHAR(32) NULL,
        
        -- Position
        lat DECIMAL(9,6) NULL,
        lon DECIMAL(10,6) NULL,
        altitude_ft INT NULL,
        heading_deg SMALLINT NULL,
        groundspeed_kts INT NULL,
        vertical_rate_fpm INT NULL,
        
        -- Flight Plan
        fp_dept_icao CHAR(4) NULL,
        fp_dest_icao CHAR(4) NULL,
        fp_alt_icao CHAR(4) NULL,
        fp_altitude_ft INT NULL,
        fp_tas_kts INT NULL,
        fp_route NVARCHAR(MAX) NULL,
        fp_remarks NVARCHAR(MAX) NULL,
        fp_rule NCHAR(1) NULL,
        fp_dept_artcc NVARCHAR(8) NULL,
        fp_dest_artcc NVARCHAR(8) NULL,
        fp_dept_tracon NVARCHAR(64) NULL,
        fp_dest_tracon NVARCHAR(64) NULL,
        
        -- Procedures
        dfix NVARCHAR(8) NULL,              -- Departure fix
        dp_name NVARCHAR(16) NULL,          -- SID name
        afix NVARCHAR(8) NULL,              -- Arrival fix
        star_name NVARCHAR(16) NULL,        -- STAR name
        dep_runway NVARCHAR(4) NULL,
        arr_runway NVARCHAR(4) NULL,
        
        -- Progress
        phase NVARCHAR(16) NULL,
        is_active BIT NOT NULL DEFAULT 1,
        dist_to_dest_nm DECIMAL(10,2) NULL,
        dist_flown_nm DECIMAL(10,2) NULL,
        pct_complete DECIMAL(5,2) NULL,
        gcd_nm DECIMAL(10,2) NULL,
        route_total_nm DECIMAL(10,2) NULL,
        
        -- Airspace
        current_artcc NVARCHAR(16) NULL,
        current_tracon NVARCHAR(32) NULL,
        current_zone NVARCHAR(16) NULL,
        
        -- Times
        first_seen_utc DATETIME2 NULL,
        last_seen_utc DATETIME2 NULL,
        logon_time_utc DATETIME2 NULL,
        eta_utc DATETIME2 NULL,
        eta_runway_utc DATETIME2 NULL,
        eta_source NVARCHAR(16) NULL,
        eta_method NVARCHAR(16) NULL,
        etd_utc DATETIME2 NULL,
        out_utc DATETIME2 NULL,
        off_utc DATETIME2 NULL,
        on_utc DATETIME2 NULL,
        in_utc DATETIME2 NULL,
        ete_minutes INT NULL,
        
        -- Controlled Times
        ctd_utc DATETIME2 NULL,
        cta_utc DATETIME2 NULL,
        edct_utc DATETIME2 NULL,
        
        -- TMI
        gs_held BIT NULL DEFAULT 0,
        gs_release_utc DATETIME2 NULL,
        ctl_type NVARCHAR(8) NULL,
        ctl_prgm NVARCHAR(32) NULL,
        ctl_element NVARCHAR(8) NULL,
        is_exempt BIT NULL DEFAULT 0,
        exempt_reason NVARCHAR(64) NULL,
        slot_time_utc DATETIME2 NULL,
        slot_status NVARCHAR(16) NULL,
        program_id INT NULL,
        slot_id BIGINT NULL,
        delay_minutes INT NULL,
        delay_status NVARCHAR(16) NULL,
        
        -- Aircraft
        aircraft_type NVARCHAR(8) NULL,
        aircraft_icao NVARCHAR(8) NULL,
        aircraft_faa NVARCHAR(16) NULL,
        weight_class NCHAR(1) NULL,
        wake_category NVARCHAR(8) NULL,
        engine_type NVARCHAR(8) NULL,
        airline_icao NVARCHAR(4) NULL,
        airline_name NVARCHAR(64) NULL,
        
        -- Sync Metadata
        last_sync_utc DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
        sync_source NVARCHAR(16) NOT NULL DEFAULT 'ADL'
    );
    

    Indexes:

    CREATE INDEX IX_swim_flights_active ON dbo.swim_flights (is_active, callsign);
    CREATE INDEX IX_swim_flights_dept ON dbo.swim_flights (fp_dept_icao) WHERE is_active = 1;
    CREATE INDEX IX_swim_flights_dest ON dbo.swim_flights (fp_dest_icao) WHERE is_active = 1;
    CREATE INDEX IX_swim_flights_dest_artcc ON dbo.swim_flights (fp_dest_artcc) WHERE is_active = 1;
    CREATE INDEX IX_swim_flights_phase ON dbo.swim_flights (phase) WHERE is_active = 1;
    CREATE INDEX IX_swim_flights_tmi ON dbo.swim_flights (gs_held, ctl_type) WHERE is_active = 1;
    CREATE INDEX IX_swim_flights_position ON dbo.swim_flights (lat, lon) WHERE is_active = 1 AND lat IS NOT NULL;
    

    dbo.swim_api_keys

    CREATE TABLE dbo.swim_api_keys (
        id INT IDENTITY(1,1) PRIMARY KEY,
        api_key NVARCHAR(128) NOT NULL UNIQUE,
        tier NVARCHAR(16) NOT NULL DEFAULT 'public',  -- system, partner, developer, public
        owner_name NVARCHAR(128) NULL,
        owner_email NVARCHAR(256) NULL,
        source_id NVARCHAR(32) NULL,                  -- Data source identifier
        can_write BIT NOT NULL DEFAULT 0,
        allowed_sources NVARCHAR(MAX) NULL,           -- JSON array
        ip_whitelist NVARCHAR(MAX) NULL,              -- JSON array
        expires_at DATETIME2 NULL,
        created_at DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
        last_used_at DATETIME2 NULL,
        is_active BIT NOT NULL DEFAULT 1,
        
        CONSTRAINT CHK_swim_api_keys_tier CHECK (tier IN ('system', 'partner', 'developer', 'public'))
    );
    

    dbo.swim_audit_log

    CREATE TABLE dbo.swim_audit_log (
        id BIGINT IDENTITY(1,1) PRIMARY KEY,
        api_key_id INT NULL,
        endpoint NVARCHAR(256) NOT NULL,
        method NVARCHAR(8) NOT NULL,
        ip_address NVARCHAR(64) NULL,
        user_agent NVARCHAR(512) NULL,
        request_time DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
        response_code INT NULL,
        response_time_ms INT NULL,
        request_params NVARCHAR(MAX) NULL
    );
    

    10.3 VATSIM_ADL Normalized Tables

    The internal VATSIM_ADL database uses normalized tables:

    TablePurposeKey Columns
    dbo.adl_flight_coreIdentity, phase, timestampsflight_uid, callsign, cid, phase, is_active
    dbo.adl_flight_positionCurrent positionlat, lon, altitude_ft, heading_deg, groundspeed_kts
    dbo.adl_flight_planFlight plan datafp_dept_icao, fp_dest_icao, fp_route, fp_altitude_ft
    dbo.adl_flight_timesETAs and OOOIeta_utc, out_utc, off_utc, on_utc, in_utc
    dbo.adl_flight_tmiTMI statusgs_held, ctl_type, slot_time_utc, delay_minutes
    dbo.adl_flight_aircraftEquipment infoaircraft_icao, weight_class, airline_icao

    11. Configuration Reference

    11.1 swim_config.php

    Located at PERTI/load/swim_config.php:

    // API Version
    define('SWIM_API_VERSION', '1.0.0');
    define('SWIM_API_PREFIX', '/api/swim/v1');
    
    // Rate Limits (requests per minute)
    $SWIM_RATE_LIMITS = [
        'system'    => 30000,
        'partner'   => 3000,
        'developer' => 300,
        'public'    => 100
    ];
    
    // API Key Prefixes
    $SWIM_KEY_PREFIXES = [
        'system'    => 'swim_sys_',
        'partner'   => 'swim_par_',
        'developer' => 'swim_dev_',
        'public'    => 'swim_pub_'
    ];
    
    // Cache TTL (seconds)
    $SWIM_CACHE_TTL = [
        'flights_list'   => 5,
        'flight_single'  => 3,
        'positions'      => 2,
        'tmi_programs'   => 10,
        'stats'          => 60
    ];
    
    // Pagination
    define('SWIM_DEFAULT_PAGE_SIZE', 100);
    define('SWIM_MAX_PAGE_SIZE', 1000);
    define('SWIM_GEOJSON_PRECISION', 5);
    
    // GUFI
    define('SWIM_GUFI_PREFIX', 'VAT');
    define('SWIM_GUFI_SEPARATOR', '-');
    
    // Timestamp tolerance for merge decisions
    define('SWIM_TIMESTAMP_TOLERANCE', 5);  // seconds
    

    11.2 Data Sources

    $SWIM_DATA_SOURCES = [
        // Core sources
        'VATSIM'          => 'vatsim',
        'vATCSCC'         => 'vatcscc',
        
        // Track/position sources
        'VNAS'            => 'vnas',
        'CRC'             => 'crc',
        'EUROSCOPE'       => 'euroscope',
        
        // Pilot sources
        'SIMULATOR'       => 'simulator',
        
        // ACARS sources
        'ACARS'           => 'acars',
        'HOPPIE'          => 'hoppie',
        
        // Metering sources
        'SIMTRAFFIC'      => 'simtraffic',
        'TOPSKY'          => 'topsky',
        
        // External sources
        'SIMBRIEF'        => 'simbrief',
        'VIRTUAL_AIRLINE' => 'virtual_airline',
    ];
    

    11.3 WebSocket Server Configuration

    $config = [
        'auth_enabled'          => true,
        'rate_limit_msg_per_sec' => 10,
        'heartbeat_interval'    => 30,
        'max_message_size'      => 65536,
        'allowed_origins'       => [''],
        'debug'                 => false
    ];
    
    // Tier connection limits
    $tierLimits = [
        'public'    => 5,
        'developer' => 50,
        'partner'   => 500,
        'system'    => 10000  // WebSocket connection limits (unchanged)
    ];
    


    12. Troubleshooting

    12.1 Common Error Codes

    HTTP CodeError CodeDescriptionResolution
    401AUTH_FAILEDInvalid or missing API keyVerify key is correct and active
    403WRITE_FORBIDDENWrite access not permittedRequest partner/system tier
    429RATE_LIMITEDRate limit exceededReduce request frequency
    500DB_ERRORDatabase errorContact support
    503SERVICE_UNAVAILABLEDatabase connection failedRetry after delay

    12.2 WebSocket Disconnections

    Symptoms: Connection drops frequently

    Solutions:

    1. Implement ping/pong every 30 seconds

    2. Handle reconnection with exponential backoff

    3. Check tier connection limits

    # Python reconnection example
    client = SWIMClient(
        api_key,
        reconnect=True,
        reconnect_interval=5.0,
        max_reconnect_interval=60.0
    )
    

    12.3 Stale Data

    Symptoms: Data appears outdated

    Explanation: SWIM_API syncs from VATSIM_ADL every 2 minutes. Maximum data staleness is ~2.5 minutes.

    Verification:

  • Check _last_sync field in response
  • Compare timestamp in response metadata

12.4 Debug Endpoints

Check API status:

curl -H "Authorization: Bearer swim_sys_internal" \
  "https://perti.vatcscc.org/api/swim/v1"

WebSocket server stats (system tier):

curl -H "Authorization: Bearer swim_sys_internal" \
  "https://perti.vatcscc.org/api/swim/v1/ws/stats"


13. Appendices

13.1 File Structure

PERTI/
├── api/swim/v1/
│   ├── index.php              # API index
│   ├── auth.php               # Authentication middleware
│   ├── flights.php            # Flights list endpoint
│   ├── flight.php             # Single flight endpoint
│   ├── positions.php          # GeoJSON positions
│   ├── ingest/
│   │   ├── adl.php            # ADL data ingestion
│   │   └── track.php          # Track position ingestion
│   ├── tmi/
│   │   ├── programs.php       # TMI programs endpoint
│   │   └── controlled.php     # Controlled flights endpoint
│   └── ws/
│       ├── WebSocketServer.php
│       ├── ClientConnection.php
│       └── SubscriptionManager.php
├── sdk/
│   ├── python/
│   │   ├── swim_client/
│   │   └── examples/
│   ├── javascript/
│   ├── java/
│   └── csharp/
├── scripts/
│   ├── swim_ws_server.php     # WebSocket daemon
│   ├── swim_ws_events.php     # Event detection
│   └── swim_sync.php          # Database sync
├── load/
│   ├── config.php             # Database credentials
│   ├── connect.php            # Connection management
│   └── swim_config.php        # SWIM configuration
├── database/migrations/swim/
│   ├── 001_swim_tables.sql
│   ├── 002_swim_api_database.sql
│   ├── 003_swim_api_database_fixed.sql
│   ├── 004_swim_bulk_upsert_sp.sql
│   └── 005_swim_add_telemetry_columns.sql
└── docs/swim/
    ├── VATSIM_SWIM_API_Documentation.md
    ├── VATSIM_SWIM_Design_Document_v1.md
    └── VATSIM_SWIM_FIXM_Field_Mapping.md

13.2 Glossary

TermDefinition
ADLAggregate Demand List - normalized flight data tables
ARTCCAir Route Traffic Control Center
CDMCollaborative Decision Making - FAA data sharing framework
EDCTExpected Departure Clearance Time
ETAEstimated Time of Arrival
FIXMFlight Information Exchange Model - international standard
GDPGround Delay Program
GSGround Stop
GUFIGlobally Unique Flight Identifier
OOOIOut-Off-On-In times (gate departure, takeoff, landing, gate arrival)
SWIMSystem Wide Information Management
TBFMTime Based Flow Management
TMITraffic Management Initiative
TRACONTerminal Radar Approach Control

13.3 Contact & Support

ResourceContact
API Key Portalhttps://perti.vatcscc.org/swim-keys.php
Documentationhttps://perti.vatcscc.org/docs/swim/
Emaildev@vatcscc.org
DiscordvATCSCC Server
Issue TrackerGitHub (internal)

Document Version: 1.0.0

Last Updated: January 2026

Maintained by: vATCSCC Development Team*