# VariFlight DataWorks【Flight Status Subscription Push API V3.0】API Documentation **Product Page:** [https://dataworks.variflight.com/products/flight-status-data/](PRODUCT_PAGE_URL_HERE) **Contact Us:** https://dataworks.variflight.com/about-us/contact/ **Provider:** VariFlight DataWorks **Website:** https://dataworks.variflight.com/ **Email:** dataworks@variflight.com **Address:** Building E, High-tech Innovation Valley, Wenqu Road, High-tech Zone, Hefei, P.R.China **Singapore Entity Address:** 1 Raffles Place, #02-209, Singapore 048616 PART-1 Pull API (Subscription) Introduction This document specifies the VariFlight flight status subscription and push service: how to subscribe to a flight through the pull API, and how status updates for the subscribed flight are delivered to your receiving endpoint. UTF-8 encoding is used throughout. Endpoint https://open-al.variflight.com/api/addflightpush Request method: GET Response format: JSON (UTF-8) Authentication When the partnership is established, VariFlight assigns each partner a user identification code (appid) and a registration code (appsecurity). Every request is validated by two mechanisms — a request token and an IP allowlist: • IP allowlist: requests are accepted only from allowlisted IP addresses; any other source receives error\_code = 2. • Token: computed for every request with the algorithm below and passed in the token parameter. Token generation algorithm • 1. Collect all request parameters in the URL except token, then sort them by parameter name in ascending ASCII order. • 2. Join the parameters as name=value pairs with "\&", using the raw values (before URL encoding). • 3. Append the registration code (appsecurity) to the resulting string. • 4. Apply MD5 twice: token = md5(md5(str + appsecurity)). Each digest is a 32-character lowercase hexadecimal string. Note: the token itself never takes part in the signature. Every other parameter actually present in the URL — including optional parameters such as fid and lang — must be included. Request the registration code from your VariFlight administrator. It is used for mutual authentication and must be kept strictly confidential. Example (PHP): ksort($data); foreach($data as $k=>$v){ $strtomd5\[]=$k.'='.$v; } $token= md5(md5(implode('\&',$strtomd5).$appsecurity)); Example (Java): public static String generateToken(Map data, String appsecurity) { String concatenatedString = data.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .map(entry -> entry.getKey() + "=" + entry.getValue()) .reduce((s1, s2) -> s1 + "\&" + s2) .orElse("") + appsecurity; return calculateMD5Hash(calculateMD5Hash(concatenatedString)); } public static String calculateMD5Hash(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte\[] hashBytes = md.digest(input.getBytes()); StringBuilder hexString = new StringBuilder(); for (byte b : hashBytes) { hexString.append(String.format("%02x", b)); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } Example (C#): static string GenerateToken(Dictionary data, string appsecurity) { var strtomd5 = data.OrderBy(kvp => kvp.Key) .Select(kvp => $"{kvp.Key}={kvp.Value}") .ToArray(); string concatenatedString = string.Join("\&", strtomd5) + appsecurity; return CalculateMD5Hash(CalculateMD5Hash(concatenatedString)); } static string CalculateMD5Hash(string input) { byte\[] inputBytes = Encoding.UTF8.GetBytes(input); byte\[] hashBytes = MD5.HashData(inputBytes); return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); } Note: appsecurity in the samples above denotes the registration code. Worked example Customize by Flight Number + Route + Date: Request URL: https://open-al.variflight.com/api/addflightpush?appid=${appid}\&arr=YIH\&date=2023-03-08\&dep=HAK\&fnum=GX8915\&token=${token} Step 1 — take all request parameters except token and sort them by parameter name in ascending ASCII order to obtain the signature string str: str = appid=${appid}\&arr=YIH\&date=2023-03-08\&dep=HAK\&fnum=GX8915 Step 2 — take the registration code appsecurity: appsecurity = ${appsecurity} Step 3 — concatenate the two strings and apply MD5 twice to obtain the token: token = md5(md5(str + appsecurity)) Request Parameters |Parameter|Description|Example|Required|Type|Rules| |-|-|-|-|-|-| |appid|App ID||Yes|string|| |token|Token||Yes|string|| |fnum|Flight Number|GX8915|Yes|string|| |dep|Departure Airport IATA Code|HAK|Yes|string|| |arr|Destination Airport IATA Code|YIH|Yes|string|| |fid|Flight ID String|a2014090511012|No|string|| |date|Flight Date|2023-03-08|Yes|string|| |lang|Language Type||No|string|| Parameter format rules • fnum: 3–7 alphanumeric characters; the server strips leading zeros after the airline code (e.g. CA0123 → CA123). • dep / arr: 3-letter IATA airport code. • date: YYYY-MM-DD format; must not be earlier than yesterday. • fid: up to 50 characters; digits, letters, underscores and hyphens only. It is echoed back verbatim in every push payload for correlation on your side, and is part of the subscription identity — subscribing to the same flight with a different fid creates a separate subscription. • lang: pass EN for English responses; Chinese is returned by default. Response Parameters |Parameter|Description|Example|Type|Rules| |-|-|-|-|-| |error\_code|Status Code||number|| |error|Status Name||string|| |FlightDeptimePlanDate|Scheduled Departure Time||string|| |FlightArrtimePlanDate|Scheduled Arrival Time||string|| Response examples: Successful subscription (error\_code is 8 on success): { "error\_code" : 8, "error" : "success", "FlightDeptimePlanDate" : "2023-03-08 07:50:00", "FlightArrtimePlanDate" : "2023-03-08 09:10:00" } Error response: { "error\_code": 3, "error": "Lack of parameters or parameter identification failed" } Error Codes |error\_code|Description| |-|-| |2|The requesting IP address is not on the IP allowlist| |3|Missing parameter or parameter validation failed (e.g. invalid token, date, flight number, origin/destination or fid format)| |4|No data permission (interface disabled or expired, invalid request method, or call quota exceeded)| |5|No flight matches the given criteria| |6|Duplicate subscription is not allowed| |8|Subscription succeeded| |10|No data available| |11|Unknown error (subscription failed)| |500|Unknown error (internal server error)| Note: when the call quota is exceeded, the error code and message follow the quota policy configured for your account; refer to your service agreement. Subscription Rules • A subscription is uniquely identified by the combination of appid + flight number + origin airport + destination airport + flight date + fid + language (lang). Submitting the exact same combination again returns error\_code = 6, while a different fid (or lang) creates a new, independent subscription with its own push stream. • Once a subscription succeeds, status changes of the flight are pushed to your receiving endpoint as described in PART-2 until the flight completes. • With lang=EN, both the subscription response and the push payloads are returned in English. PART-2 Push API Introduction Once a subscription is active, whenever the status data of the flight changes, the system automatically pushes the latest data to the receiving endpoint you provide. • Push payloads are UTF-8 encoded JSON; URL decoding is not required. • A push is triggered only when the data content actually changes (payloads are deduplicated); a flight is typically pushed several times over its life cycle. • Respond with an HTTP 2xx status code to acknowledge delivery; on any non-2xx response the system retries. Push Method HTTP POST. • The request body is a JSON array containing the flight object(s) for the subscribed segment (usually one). • Content-Type is application/json;charset=utf-8. Push Parameters The set of pushed fields is determined by the field permissions enabled for your account. Enabled fields that currently have no data are sent with a default value (usually "0"). |Parameter|Description|Example|Type|Rules| |-|-|-|-|-| |fcategory|||string|| |ftype||B738|string|| |fservice||J|string|| |FirstClassCheckinTable||C3|string|| |BusinessCheckinTable||C3|string|| |FlightNo||SC7621|string|| |FlightCompany||Shandong Airlines|string|| |FlightDepcode||YNT|string|| |FlightArrcode||CAN|string|| |AircraftNumber||B306R|string|| |FlightDeptimePlanDate||2023-12-22 08:20:00|string|| |FlightArrtimePlanDate||2023-12-22 11:20:00|string|| |FFlightDeptimePlanDate||2023-12-22 07:05:00|string|| |FFlightArrtimePlanDate||2023-12-22 10:35:00|string|| |FlightDeptimeReadyDate||2023-12-22 08:20:00|string|| |FlightArrtimeReadyDate||2023-12-22 11:20:00|string|| |FlightDeptimeDate||2023-12-22 08:28:00|string|| |FlightArrtimeDate||2023-12-22 11:28:00|string|| |FlightIngateTime||2023-12-22 11:57:00|string|| |FlightOutgateTime||2023-12-22 11:57:00|string|| |CheckinTable||C|string|| |CheckDoor||gate 4|string|| |BoardGate||15|string|| |ReachExit||W1|string|| |BaggageID||7|string|| |BoardState||check-in|string|| |FlightState||schedule|string|| |FlightHTerminal||T1|string|| |FlightTerminal||T1|string|| |org\_timezone||28800|string|| |dst\_timezone||28800|string|| |ShareFlightNo|||string|| |StopFlag||1|string|| |ShareFlag||1|string|| |VirtualFlag||0|string|| |BoardGateTime|||string|| |ArrStandGate||212|string|| |DepStandGate||309|string|| |DelayReason||Flow control|string|| |LegFlag||0|string|| |Food|||string|| |LastCheckinTime||2023-12-22 07:45:00|string|| |EstimateBoardingStartTime|||string|| |EstimateBoardingEndTime|||string|| |FlightDep||Yantai|string|| |FlightArr||Guangzhou|string|| |deptel||0535-5134352|string|| |arrtel||020-96158|string|| |TodayTimeRate|||string|| |airlinetel||95369|string|| |FlightWaitData||0|number|| |bridge||not utilize aerobridge|string|| |arr\_bridge||utilize aerobridge|string|| |FlightDepAirport||Yantai Penglai|string|| |FlightArrAirport||Guangzhou Baiyun|string|| |OntimeRate||80.00%|string|| |generic||Boeing 737-85N|string|| |FlightYear||7.3|number|| |ArrOntimeRate||83.33%|string|| |DepWeather||Snow shower turning to cloudy\|\|\|89\|-4/-10|string|| |ArrWeather||Cloudy\|\|\|102\|12/3|string|| |FlightDuration||171|string|| |distance||2132|string|| |FastestExitDuration||62.8|number|| |SlowestExitDuration||73.8|number|| |FastestExitTime||2023-12-22 12:45:48|string|| |SlowestExitTime||2023-12-22 12:56:48|string|| |DepOnCargodoorTime|||string|| |DepOffCargodoorTime|||string|| |ArrOnCargodoorTime|||string|| |ArrOffCargodoorTime|||string|| |ChangePlane||0|string|| |VeryZhunReadyDeptimeDate||2023-12-22 08:29:00|string|| |VeryZhunReadyArrtimeDate||2023-12-22 11:43:18|string|| |AssistFlightState||arrival|string|| |DepAirportLat||37.660556|string|| |DepAirportLon||120.979167|string|| |DepTerminalLat||37.664518|string|| |DepTerminalLon||120.99807|string|| |ArrAirportLon||113.29734|string|| |ArrTerminalLon||113.309858|string|| |ArrAirportLat||23.387861|string|| |ArrTerminalLat||23.393169|string|| |FlightCancelTime|||string|| |FlightStateNum||1|number|| |FillFlightNo|||string|| |StopAirportCode|||string|| |alternate\_info|||array|| |AlternateStatus|||string|| |AlternateDepCity|||string|| |AlternateArrCity|||string|| |AlternateDepAirport|||string|| |AlternateArrAirport|||string|| |AlternateDeptimePlan|||string|| |AlternateArrtimePlan|||string|| |AlternateDeptime|||string|| |AlternateArrtime|||string|| |AlternateDepTimezone|||string|| |AlternateArrTimezone|||string|| |StopCity|||string|| |depctry|||string|| |depprov|||string|| |arrctry|||string|| |arrprov|||string|| |depcontinent|||string|| |arrcontinent|||string|| |fid|||string|| |FillFlightInfo|||object|| |FlightNo||9C668Q|string|| |FlightDepcode||URC|string|| |FlightArrcode||AAT|string|| |FlightState||schedule|string|| |FlightDeptimePlanDate||2025-11-14 12:30:00|string|| |FlightArrtimePlanDate||2025-11-14 13:40:00|string|| |FlightDeptimeDate||2025-11-14 12:30:00|string|| |FlightArrtimeDate||2025-11-14 13:40:00|string|| Push payload example (the outermost element is a JSON array): \[ { "fcategory" : "0", "ftype" : "B738", "fservice" : "J", "FirstClassCheckinTable" : "C3", "BusinessCheckinTable" : "C3", "FlightNo" : "SC7621", "FlightCompany" : "Shandong Airlines", "FlightDepcode" : "YNT", "FlightArrcode" : "CAN", "AircraftNumber" : "B306R", "FlightDeptimePlanDate" : "2023-12-22 08:20:00", "FlightArrtimePlanDate" : "2023-12-22 11:20:00", "FFlightDeptimePlanDate" : "2023-12-22 07:05:00", "FFlightArrtimePlanDate" : "2023-12-22 10:35:00", "FlightDeptimeReadyDate" : "2023-12-22 08:20:00", "FlightArrtimeReadyDate" : "2023-12-22 11:20:00", "FlightDeptimeDate" : "2023-12-22 08:28:00", "FlightArrtimeDate" : "2023-12-22 11:28:00", "FlightIngateTime" : "2023-12-22 11:57:00", "FlightOutgateTime" : "2023-12-22 11:57:00", "CheckinTable" : "C", "CheckDoor" : "gate 4", "BoardGate" : "15", "ReachExit" : "W1", "BaggageID" : "7", "BoardState" : "check-in", "FlightState" : "schedule", "FlightHTerminal" : "T1", "FlightTerminal" : "T1", "ShareFlightNo" : "0", "StopFlag" : "1", "ShareFlag" : "1", "VirtualFlag" : "0", "BoardGateTime" : "0", "ArrStandGate" : "212", "DepStandGate" : "309", "DelayReason" : "Flow control", "LegFlag" : "0", "Food" : "0", "EstimateBoardingEndTime" : "0", "FlightDep" : "Yantai", "FlightArr" : "Guangzhou", "deptel" : "0535-5134352", "arrtel" : "020-96158", "TodayTimeRate" : "0", "airlinetel" : "95369", "FlightWaitData" : 0, "bridge" : "not utilize aerobridge", "arr\_bridge" : "utilize aerobridge", "FlightDepAirport" : "Yantai Penglai", "FlightArrAirport" : "Guangzhou Baiyun", "OntimeRate" : "80.00%", "generic" : "Boeing 737-85N", "FlightYear" : 7.3, "ArrOntimeRate" : "83.33%", "DepWeather" : "Snow shower turning to cloudy|||89|-4/-10", "ArrWeather" : "Cloudy|||102|12/3", "FlightDuration" : "171", "distance" : "2132", "FastestExitDuration" : 62.8, "SlowestExitDuration" : 73.8, "FastestExitTime" : "2023-12-22 12:45:48", "SlowestExitTime" : "2023-12-22 12:56:48", "DepOnCargodoorTime" : "0", "DepOffCargodoorTime" : "0", "ArrOnCargodoorTime" : "0", "ArrOffCargodoorTime" : "0", "ChangePlane" : "0", "VeryZhunReadyDeptimeDate" : "2023-12-22 08:29:00", "VeryZhunReadyArrtimeDate" : "2023-12-22 11:43:18", "AssistFlightState" : "arrival", "DepAirportLat" : "37.660556", "DepAirportLon" : "120.979167", "DepTerminalLat" : "37.664518", "DepTerminalLon" : "120.99807", "ArrAirportLon" : "113.29734", "ArrTerminalLon" : "113.309858", "ArrAirportLat" : "23.387861", "ArrTerminalLat" : "23.393169", "FlightCancelTime" : "0", "FlightStateNum" : 1, "FillFlightNo" : "0", "StopAirportCode" : "0", "alternate\_info" : \[ { "AlternateArrCity" : "0", "AlternateDepAirport " : "0", "AlternateArrAirport" : "0", "AlternateDeptimePlan" : "0", "AlternateArrtimePlan" : "0", "AlternateDeptime" : "0", "AlternateArrtime" : "0", "AlternateDepTimezone" : "0", "AlternateArrTimezone" : "0", "AlternateDepCity" : "0", "AlternateStatus" : "0" } ], "StopCity" : "0", "depctry" : "0", "depprov" : "0", "arrctry" : "0", "arrprov" : "0", "depcontinent" : "0", "FillFlightInfo" : { "FlightNo" : "9C668Q", "FlightDepcode" : "URC", "FlightArrcode" : "AAT", "FlightState" : "schedule", "FlightDeptimePlanDate" : "2025-11-14 12:30:00", "FlightArrtimePlanDate" : "2025-11-14 13:40:00", "FlightDeptimeDate" : "2025-11-14 12:30:00", "FlightArrtimeDate" : "2025-11-14 13:40:00" }, "LastCheckinTime" : "2023-12-22 07:45:00", "EstimateBoardingStartTime" : "0", "fid" : "0", "arrcontinent" : "0", "dst\_timezone" : "28800", "org\_timezone" : "28800" } ] Flight Status Codes In response and push payloads, the FlightStateNum field carries the numeric status code and the FlightState field carries the status text, mapped as follows: |FlightStateNum|FlightState (zh)|FlightState (lang=EN)| |-|-|-| |0|计划|schedule| |1|起飞|departure| |2|到达|arrival| |3|取消|cancel| |4|延误|delay| |5|备降|diversion| |11|返航|return| |13|可能延误|delay alert| |14|可能取消|cancellation alert| |31|备降起飞|diverted flight departure| |32|备降到达|diverted flight arrival| |33|备降取消|diverted flight cancel| |41|返航起飞|returned flight departure| |42|返航到达|returned flight arrival| |43|返航取消|returned flight cancel| |73|提前取消|cancel in advance|