{"openapi":"3.1.0","info":{"title":"cwsi.net API","version":"1.0.0","description":"Airline fare classes, mileage calculators, great circle distance and airport lounges from cwsi.net. Secret keys are sent as \"Authorization: Bearer <key>\" from servers. Public keys may be sent as ?key= or as a Bearer token from an allowed website."},"servers":[{"url":"https://api.cwsi.net"}],"security":[{"bearerAuth":[]},{"apiKey":[]}],"paths":{"/v1/airlines":{"get":{"operationId":"listAirlines","summary":"Airlines with a fare chart, and their calculator when there is one","responses":{"200":{"description":"Airlines","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"airlines":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"fares_url":{"type":"string","format":"uri","description":"The matching cwsi.net page."},"calculator":{"type":"string","format":"uri","description":"The matching cwsi.net page."}},"additionalProperties":true}}},"additionalProperties":true}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Key verification or metering is temporarily unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/fares/{airline}":{"get":{"operationId":"getFares","summary":"An airline's fare classes","parameters":[{"name":"airline","in":"path","required":true,"description":"Airline code, name or common alias, for example DL or \"delta\".","schema":{"type":"string"}}],"responses":{"200":{"description":"Fare chart","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FareChart"}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown airline (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Fare data unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/fares/{airline}/{class}":{"get":{"operationId":"getFare","summary":"One fare class (a letter or fare name)","parameters":[{"name":"airline","in":"path","required":true,"description":"Airline code, name or common alias, for example DL or \"delta\".","schema":{"type":"string"}},{"name":"class","in":"path","required":true,"description":"The fare class to look up: a fare letter such as K, a Southwest fare name, or the name of a named row (the budget carriers, Iberia, Finnair and JetBlue publish fare names or bundles, not letters).","schema":{"type":"string"}}],"responses":{"200":{"description":"Matching fares","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FareChart"}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown airline or fare class (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Fare data unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/fares/compare":{"get":{"operationId":"compareFares","summary":"Compare a fare class on one airline with the same fare, or its own, on another","description":"Only American (AA), Alaska (AS), Delta (DL), Southwest (WN) and United (UA) can be compared; any other airline gives invalid_input.","parameters":[{"name":"a","in":"query","required":true,"description":"AIRLINE:FARE, for example AA:Y.","schema":{"type":"string"}},{"name":"b","in":"query","required":true,"description":"An airline, for example DL. Add :FARE to compare a different fare.","schema":{"type":"string"}}],"responses":{"200":{"description":"Two sides","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"a":{"$ref":"#/components/schemas/FareSide"},"b":{"$ref":"#/components/schemas/FareSide"},"source":{"type":"string","format":"uri","description":"The matching cwsi.net page."}},"additionalProperties":true}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Fare class not found (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Missing or bad parameter (invalid_input).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Fare data unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/calculators":{"get":{"operationId":"listCalculators","summary":"Every mileage calculator and its inputs","responses":{"200":{"description":"Calculators","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"calculators":{"type":"array","items":{"$ref":"#/components/schemas/Calculator"}}},"additionalProperties":true}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Key verification or metering is temporarily unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/calc/{airline}":{"post":{"operationId":"calculate","summary":"Estimate what a ticket earns","parameters":[{"name":"airline","in":"path","required":true,"description":"Airline code, name or common alias, for example DL or \"delta\".","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"segs":{"type":"array","minItems":1,"maxItems":8,"description":"Up to 8 flights; some calculators allow fewer (Etihad Airways takes up to 4), so check the max of the segs input for the airline in /v1/calculators. Lufthansa (LH), Air France-KLM (AF, KL), Korean Air (KE), Japan Airlines (JL), Singapore Airlines (SQ), ANA (NH), Qantas (QF), Qatar Airways (QR), Turkish Airlines (TK), Virgin Atlantic (VS), EVA Air (BR), Iberia (IB), Copa Airlines (CM), TAP Air Portugal (TP), SAS (SK), LOT Polish Airlines (LO), Air New Zealand (NZ), Air China (CA), China Airlines (CI), Thai Airways (TG), ITA Airways (AZ), Royal Air Maroc (AT), Malaysia Airlines (MH), Vietnam Airlines (VN), Aegean Airlines (A3), Aerolineas Argentinas (AR), Royal Jordanian (RJ), SriLankan Airlines (UL), Croatia Airlines (OU), Shenzhen Airlines (ZH) and Etihad Airways (EY) only: the one-way flights in order, one object per flight. Required by all of them except Lufthansa. fromCountry and toCountry are required on every flight except on Air New Zealand, Aegean Airlines and Etihad Airways, which need from and to instead (their earn tables are keyed by the airport pair) and take the country codes as optional; the schema allows either pair and the API checks the right one for each calculator.","items":{"type":"object","properties":{"fromCountry":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"ISO 3166 two-letter country code of the departure airport. Required on every flight, except on Air New Zealand (NZ), Aegean Airlines (A3) and Etihad Airways (EY), where it is optional and from and to are required instead."},"toCountry":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"ISO 3166 two-letter country code of the arrival airport (as fromCountry)."},"miles":{"type":"integer","minimum":1,"maximum":12500},"kind":{"type":"string","enum":["C","I"]},"cabin":{"type":"string","enum":["E","P","B","F","Y","W","C","S"],"description":"The cabin of this flight when it differs from the ticket cabin: E, P, B or F on Air France-KLM; Y, W or C on Iberia; Y, C or S (Business Suite) on Malaysia Airlines."},"table":{"type":"string","pattern":"^[A-Z]{3}$","description":"Qantas only: the route table for this flight (the keys and names are in the segs input of /v1/calculators), for example EWC or EEC for the West or East Coast USA/Canada."},"from":{"type":"string","pattern":"^[A-Za-z0-9]{3,4}$","description":"IATA code of the departure airport. Labels the breakdown; JAL and ANA use it to spot Vladivostok (VVO), Qantas to pick its route tables, Iberia to spot the Madrid-Barcelona Air Shuttle (MAD, BCN), SAS to pick its long-haul tables (named by city), Air New Zealand and Aegean Airlines (required there) to find the flight in their earn tables, Royal Jordanian to spot Amman to Aqaba or Tel Aviv (half a segment), and Malaysia Airlines to see whether the flight touches Kuala Lumpur (KUL), the only flights it works out Elite Points for."},"to":{"type":"string","pattern":"^[A-Za-z0-9]{3,4}$","description":"IATA code of the arrival airport (as from)."}},"anyOf":[{"required":["fromCountry","toCountry"]},{"required":["from","to"]}],"additionalProperties":false}},"creditTo":{"type":"string","description":"Credit the flights to a partner program instead of the airline's own (\"Credit this flight to\"): one of the creditTo options /v1/calculators lists for this airline (american, alaska, delta, united, aeroplan, flying-club, flying-blue, ba-club where partners.json has a distance pair; the airline's own program is never listed). Earns by each flight's distance and the booking class at the program's published partner rates; no price is needed."},"creditStatus":{"type":"string","description":"With creditTo: your status in that program, by name (the values are listed under creditStatus in /v1/calculators). Defaults to the base level."},"creditClass":{"type":"string","pattern":"^[A-Za-z]$","description":"With creditTo: the booking class letter. Required on calculators without a booking-class input of their own (the price-based ones, Lufthansa, Air France-KLM, Iberia, Copa, TAP, Qantas, Cathay Pacific); elsewhere it overrides cls."},"creditFlights":{"type":"array","minItems":1,"maxItems":8,"description":"With creditTo: the flights, one object per one-way flight with its great-circle miles (from /v1/distance) and optional from and to airport codes. Defaults to segs when the calculator's segs carry miles (and to miles on Cathay Pacific). A calculator for several airlines (Lufthansa op, Air France-KLM airline, Air India carrier) uses the pair of the airline that input names.","items":{"type":"object","properties":{"miles":{"type":"integer","minimum":1,"maximum":12500},"from":{"type":"string","pattern":"^[A-Za-z0-9]{3,4}$"},"to":{"type":"string","pattern":"^[A-Za-z0-9]{3,4}$"}},"required":["miles"],"additionalProperties":false}}},"additionalProperties":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"The inputs listed by /v1/calculators for this airline: price (required by every calculator except Cathay Pacific, which takes miles, cls and fare instead, and the distance-based ones below; in US dollars except British Airways (GBP), Air Canada (CAD), Lufthansa, Air France-KLM, Iberia, Finnair and Air Europa (EUR), Air India (INR), China Eastern and Xiamen Airlines (CNY), Malaysia Airlines (MYR) and South African Airways (ZAR), as the currency of the price input says) plus its choice and number inputs. Korean Air, Japan Airlines, Singapore Airlines, ANA and Qantas take no price either: they earn by distance and booking class (Qantas: earn category), so send segs with the great-circle miles of each flight and the country codes of its two airports, plus from and to airport codes (JAL and ANA need them for Vladivostok; Qantas picks its route tables from them) and, for Qantas, an optional table. Qatar Airways, Turkish Airlines, Virgin Atlantic and EVA Air take no price and need segs the same way. Iberia takes the price in EUR plus segs with miles, the two country codes and from and to airport codes (they mark the Madrid-Barcelona Air Shuttle, MAD-BCN), and an optional per-flight cabin; Finnair takes only the price in EUR (no segs). Aeromexico and Avianca take only the price in US dollars (no segs). Copa Airlines, TAP Air Portugal and LOT Polish Airlines take no price and need segs with miles and the two country codes (TAP and LOT read the zone from the countries). SAS takes no price and needs segs with the two country codes and, for long-haul flights, from and to airport codes (SAS names those tables by city), but no miles. Air India takes only the price in INR and China Eastern only the price in CNY (no segs). Air China, China Airlines and Thai Airways take no price and need segs with miles and the two country codes (Air China reads Mainland China from them). Air New Zealand takes no price and needs segs with from and to airport codes (no miles; the country codes are optional). ITA Airways, Royal Air Maroc and Vietnam Airlines take no price and need segs with miles and the two country codes (ITA reads its European zones and Vietnam Airlines its domestic rate from them). Malaysia Airlines takes the price in MYR plus segs with miles, the two country codes, from and to airport codes (Elite Points are worked out only for flights to or from Kuala Lumpur, KUL) and an optional per-flight cabin; Air Europa takes only the price in EUR (no segs). Aerolineas Argentinas, Royal Jordanian and SriLankan Airlines take no price and need segs with miles and the two country codes (Aerolineas Argentinas prices only flights to or from Argentina, by zone). Aegean Airlines takes no price and needs segs with from and to airport codes (no miles; its own route table; the country codes are optional). South African Airways takes only the price in ZAR (no segs). Croatia Airlines and Shenzhen Airlines take no price and need segs with miles and the two country codes (Croatia Airlines prices only flights within Croatia or between European countries; Shenzhen Airlines reads Mainland China from them). Xiamen Airlines takes only the price in CNY, the base fare plus fuel surcharge for one flight (no segs). Etihad Airways takes no price and needs segs with from and to airport codes on its network (no miles; the Etihad base number per route from Abu Dhabi, a journey between two other cities priced via Abu Dhabi). Lufthansa and Air France-KLM also take segs, one object per flight with the country codes of its two airports (Air France-KLM: plus its great-circle miles; Lufthansa: or cont and icf counts instead). /v1/calc/KL is the Air France-KLM calculator with airline KL."},"example":{"price":450,"fare":"CR","status":"GM"}}}},"responses":{"200":{"description":"Estimate","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalcResult"}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No calculator for that airline (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid input; the message names each bad field (invalid_input).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Key verification or metering is temporarily unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/distance":{"get":{"operationId":"distance","summary":"Great circle distance for a route","parameters":[{"name":"route","in":"query","required":true,"description":"Airport codes joined by \"-\"; separate trips with \"~\". Up to 5 trips and 20 airports, for example ATL-SFO~SJC-ATL.","schema":{"type":"string"}}],"responses":{"200":{"description":"Route distances in miles, nautical miles and kilometres","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"unknown":{"type":"array","items":{"type":"string"}},"mi":{"type":"number"},"nm":{"type":"number"},"km":{"type":"number"},"trips":{"type":"array","items":{"type":"object","additionalProperties":true}},"source":{"type":"string","format":"uri","description":"The matching cwsi.net page."}},"additionalProperties":true}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Route does not parse (invalid_input).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Distance service unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/lounges/{airport}":{"get":{"operationId":"lounges","summary":"Lounges at an airport","parameters":[{"name":"airport","in":"path","required":true,"description":"3 letter IATA code, for example ATL.","schema":{"type":"string","pattern":"^[A-Za-z]{3}$"}}],"responses":{"200":{"description":"Airport lounges","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}},"content":{"application/json":{"schema":{"type":"object","properties":{"airport":{"type":"string"},"name":{"type":"string"},"city":{"type":"string"},"country":{"type":"string"},"lounges":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"brand":{"type":"string"},"group":{"type":"string"},"terminal":{"type":"string"},"concourse":{"type":"string"},"gate":{"type":"string"},"airside":{"type":["boolean","null"]},"hours":{"type":"string"},"access":{"type":"string"},"url":{"type":"string"}},"additionalProperties":true}},"source":{"type":"string","format":"uri","description":"The matching cwsi.net page."}},"additionalProperties":true}}}},"401":{"description":"Missing or unknown key (missing_key, invalid_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Revoked key or origin not allowed (revoked_key, origin_not_allowed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Airport not covered (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Not a 3 letter code (invalid_input).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-minute or monthly limit reached (rate_limited, monthly_limit), or the per-IP guard (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Monthly allowance for this key (not sent by the per-IP guard)."},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left this month."},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"},"description":"When the allowance resets (first of next month, UTC)."}}},"500":{"description":"Unexpected server error (internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Lounge data unavailable (upstream_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/openapi.json":{"get":{"operationId":"openapi","summary":"This document","security":[],"responses":{"200":{"description":"OpenAPI 3.1 JSON","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Secret (cwsi_sk_...) or public (cwsi_pk_...) key."},"apiKey":{"type":"apiKey","in":"query","name":"key","description":"Public keys only (cwsi_pk_...), from an allowed website."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["missing_key","invalid_key","revoked_key","origin_not_allowed","not_found","invalid_input","rate_limited","monthly_limit","upstream_unavailable","internal_error"]},"message":{"type":"string"},"reset":{"type":"string","format":"date-time","description":"Rate and monthly limit errors: when the allowance resets."},"fields":{"type":"array","items":{"type":"string"},"description":"invalid_input on /v1/calc only: every bad field."}},"additionalProperties":true}}},"Fare":{"type":"object","properties":{"fare":{"type":"string"},"group":{"type":"string"},"description":{"type":"string"},"attributes":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"additionalProperties":true}}},"additionalProperties":true},"FareChart":{"type":"object","properties":{"airline":{"type":"string"},"name":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"fares":{"type":"array","items":{"$ref":"#/components/schemas/Fare"}},"source":{"type":"string","format":"uri","description":"The matching cwsi.net page."}},"additionalProperties":true},"FareSide":{"type":"object","properties":{"airline":{"type":"string"},"airline_name":{"type":"string"},"fares":{"type":"array","items":{"$ref":"#/components/schemas/Fare"}}},"additionalProperties":true},"Calculator":{"type":"object","properties":{"airline":{"type":"string"},"name":{"type":"string"},"path":{"type":"string","format":"uri","description":"The matching cwsi.net page."},"inputs":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"type":{"type":"string","enum":["number","choice","segments","text"]},"min":{"type":"number"},"max":{"type":"number"},"currency":{"type":"string","description":"On the price input: the currency the price is in, such as USD, GBP or EUR."},"required":{"type":"boolean","description":"On a segments input: true when the calculator needs it."},"default":{"oneOf":[{"type":"string"},{"type":"number"}]},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}},"additionalProperties":true}},"fields":{"type":"array","items":{"type":"string"}},"tables":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true},"CalcResult":{"type":"object","properties":{"airline":{"type":"string"},"calculator":{"type":"string"},"inputs":{"type":"object","additionalProperties":true},"headline":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"detail":{"type":"string"},"value":{"type":"string"}},"additionalProperties":true}},"breakdown":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"detail":{"type":"string"},"value":{"type":"string"}},"additionalProperties":true}},"progress":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"string"}},"source":{"type":"string","format":"uri","description":"The matching cwsi.net page."}},"additionalProperties":true}}}}