Southwest Sniping

Welcome to Southwest Sniping, the place for getting the lowest "A"-group position number on a Southwest Airlines flight you can find! Here is the main article about Southwest Sniping: /2008/12/how-southwest-airlines-online-boarding.html

Thursday, January 7, 2010

Southwest Website Changed, Southwest Sniping Defunct

Welcome to Southwest Sniping!

Sometime in the last year or so, Southwest Airlines revamped their Website, including changing the Webpages for the boarding pass check-in process. Before this happened, there was an intermediate stage when the error pages were changed to give the error numbers a different numbering scheme including adding a hyphen to them, but the process was still the same. In the site's current state, all the pages, URLs, and the procedure are different, and in ways to make it more difficult to run automatic check-in snipers. For example, cookies, redirects, and more state are used; there are redundant form fields; and the ordering of some form fields is verified. If a Web client fails to get these nuances right, then it is redirected back to the beginning. However, these appear to simply be "traps". Southwest still does not use a CAPTHCA, JavaScript is not required for the process to function, and it is possible to snipe boarding passes; it's just more sophisticated now. There are now also multiple Web interfaces that are used to support mobile clients and the interface displayed depends on the "User-Agent" header. The "normal" site for ordinary Web browsers is the most functional but now displays error messages inline in the page (though in an organized and parseable fashion). The mobile interfaces (see http://m.southwest.com), by virtue of being simpler, are easier to parse, but only one passenger at a time can be selected when there are multiple passengers.

So from this point, all of the previously-posted information is history. I hope the details on the functionality of the new Web interfaces will become available someday soon.

See ya!

Sunday, December 14, 2008

Southwest Sniper result

Hello,
I recently got a pretty good result from using my Perl sniper Cronjob script -- position 18 on the first flight, and position 32 on a connecting flight.

I have pondered how Southwest Airlines decides the position number for a flight connection when they have connecting passengers check-in for both flights at the same time -- 24 hours before the first flight -- because all of the "normal" passengers for the second flight, who didn't have it as a connecting flight, check-in online 24 hours before that flight, and their positions have to be assigned on a first-come first-serve basis as well. It is apparent that position numbers for connecting flights, which are assigned before the 24-hour mark for that flight, probably aren't simply the first ones available before all the "normal" passengers for that flight get to check-in. I have tried to call Southwest Airlines to ask them how position numbers are decided for connecting flights, and although they gave me some basic information, unfortunately the customer-service operators didn't have the information to answer this and cannot find out. (One was interested in finding this out themself and said they would ask during their next meeting.)

I suspect the position number might be calculated by a prediction based on some kind of statistical interpolation of how long it took the user to check-in after their window (for the first flight) opened, against some distribution (i.e. normal/Gaussian distribution) of past sample sets of what position people "usually" get vs. the difference in time between their check-in and their window opening. But I suppose there isn't any conclusive way to tell. I recall that in the past (before I was using a sniper), sometimes I would get a better position on the second flight than on the first.
Of course, don't forget that all positions up to A15 may be reserved on any given flight for Southwest's "Business Select" customers, and there is some policy they told me regarding "Rapid Rewards A-Class" members -- people who are Rapid Rewards customers who fly more than some number of times within a 12-month period -- specifically, that they are guaranteed an "A"-group boarding pass. However, I don't know how being a "Rapid-Rewards A-Class" member affects placement within the "A" group.

Sunday, December 7, 2008

How Southwest Airlines Online Boarding Pass Check-In Works (with technical info)

How Southwest Airlines Online Boarding Pass Check-In Works (with technical info)

In this article I would like share how the Southwest Airlines online boarding pass check-in process works -- but first, a little history:

Over the years, Southwest Airlines has implemented different procedures of how customers check-in for their flights and how they reserve their positions in line for boarding the plane. Most people flying Southwest nowadays know that the line-up order is now determined individually for all boarding passes on a first-come, first-serve basis based on the order that customers checked in starting exactly 24 hours prior to the scheduled flight time. It used to be that the chronological order of users' check-ins was only stratified to the extent of determining which boarding group they would earn -- A, B, or C -- and then, within that boarding group, passengers could line up arbitrarily as they arrived at the gate, thus having to stake out their place in line at that time. The great thing about Southwest's new procedure is that the entire line-up order, down to the individual person (although at first done by groups of 5), is fully determined at the time of check-in (when the position number is assigned), thus freeing us passengers from the obligation of staking out our place in line (or of requiring people in one's party to take turns of staying in line), and giving us time to do other things like get something to eat, shop in the airport, etc. Of course, many naive people still don't understand or haven't adapted to this system and waste their time staying in line long before the attendant calls group A to line up anyway. (They learn the hard way when people like me finally get up and ask people's position numbers to pinpoint and claim our place in line.)

However, this new system has made the competition and timing of checking in online more critical than ever, because from the exact moment that the check-in window opens (24 hours before the departure time) and everybody scrambles to register, every second counts for one's place in line.


People have long wanted ways to be able to automatically "snipe" their check-in window so that they didn't have to manually check-in exactly 24 hours before their flight time, and so they could get the best group (and now, to a greater extent, position number) possible. Within the last few years, several automatic check-in services (many for pay) have been introduced by various independent vendors who found out how the technicalities of the check-in process worked, and put up Websites allowing users to schedule automatic "snipes" in which, at the right time, the vendor's Website would Web-scrape Southest.com to check the user in. Once Southwest Airlines found out about these services that were offered to the public, they took action by sending the Website owners cease-and-desist letters and/or pursued legal action, because in its terms and conditions Southwest prohibits unauthorized commercial use of its Website, and prohibits Web-scraping and automatic generation of clicks and form submission, and prohibits one person from logging onto the site with another person's credentials, etc. A couple of examples of check-in services unaffiliated with Southwest upon whom Southwest acted to stop, were BoardFirst.com (which they did successfully sue) and FreeCheckin.com (which acquiesced to the cease-and-desist letter which they posted online). For more information about what has transpired, look at Southwest's Wikipedia article at http://en.wikipedia.org/wiki/Southwest%20Airlines, look up the case of "Southwest Airlines Co. v. Boardfirst LLC", and look up more Southwest automatic check-in Websites that ceased their services.

However, how do these automatic check-in services work? Well, the people who coded them probably viewed the HTML pages and forms, and/or got a packet-capture, of one or more normal, live Web check-ins for an actual flight(s), analyzed how the Web requests are made and what the responses are, and, using these observations, wrote a program to emulate the same client Web requests to be used for the check-in process for future flights. Web services that one has to subscribe to may or may not be the most reliable ways to run a snipe; hopefully one can expect it is run on a Web server that should be well-maintained and have a fast connection, and the sniping program should be tried and ture. However, it is also possible for a user to have a program running on their own computer, on a scheduler, to snipe the Southwest.com site. There is at least one code sample out there I was able to find that somebody made in Python, at http://code.activestate.com/recipes/496790/. However, I have not been able to get this particular one to work. (I had similar problems to what people posted in the comments.) There are also sites like http://tyrellperera.blogspot.com/2008/10/how-to-run-soutwest-auto-cheking-mashup.html that have users download a bunch of programs that run as a local server and use those. There is also at least one Windows program that is designed to be downloaded and installed, which costs $5 and has a 7-day trial version (to play Devil's Advocate, another contravention of Southwest's terms and conditions).

But until now, something has been missing. No one has yet posted the information on how the actual check-in protocol itself works (something that can only be seen and analyzed during the time of a live check-in window). Some of the scripts out there could be analyzed, but it is tedious (and may not be possible) to figure out what the Web pages, forms, and fields are, and it can't give a very good idea of the boundary conditions and constraints of input and output.

Well, during my past flight check-ins I have packet-captured the process, interpreted the code for the Web forms, heuristically analyzed how the Web requests, form submissions, and responses work, and have even successfully written a Perl script using the WWW::Mechanize module that can retrieve boarding passes at the right moment and runs as a Cronjob.

I would like to publicly document and share my knowledge of how the Southwest Airlines online boarding pass check-in process works, i.e. for people who want to make their own scripts/programs but don't want to have to wait to have a flight before that to analyze the process during a live check-in, or don't want to bother doing the analysis to begin with. In my opinion people can keep their Web sniper/scraper code private, but everyone should have access to the information to start making their own scripts that they could otherwise get if they had a real flight and active check-in window. As long as you run your own script that enters your own credentials into the site, you shouldn't be in violation of terms that say not to enter other users' credentials (such as the aformentioned Web services), but you may still be in violation of the terms that say not to use Web-scraping or automatic submission of forms.

Note that I can make absolutely no guarantee whatsoever that you will find any of this information to suit your needs, or that you will necessarily be able to get an "A" boarding pass with a low position number, or even that Southwest won't one day change their Web pages or forms or do something crazy like make a CAPTCHA so everyone will be forced to check-in manually. This information is provided to you as-is, with no guarantee of accuracy or anything else. Also, you agree that YOU are responsible for what you do with these instructions and whether or not you violate Southwest's terms and conditions. Also, it is impossible for me to find out what all the boundary conditions are of the check-in process, but I will share what I was able to figure out, and using a standard Web-client program/script should work just fine with Southwest's current setup. Also, group/position numbers are also determined by Business Class customers (who get guaranteed A 1-15) and by people having a connecting flight whose window for the first flight opens before the window for the connecting flight (when everyone else for that flight will check in). Also, if enough people make automatic sniper scripts to retrieve their boarding passes, then this whole process will be self-defeating as the competition for earlier spots will just increase.


Instructions:

Check-In Step 1: Information that anyone can find out without having a current active flight check-in:

The first Web form that the user fills out is at http://www.southwest.com/content/travel_center/retrieveCheckinDoc.html?ref=ckin_hp_wl_tt. The main page of Southwest.com has a convenient tab for filling out the same Web form, but if for some reason the JavaScript fails to work, it redirects to that page. The page does not require using any JavaScript whatsoever, so it is perfect for a Web-scraper. There is exactly one form on that page, which uses a POST method, whose action page is "/cgi-bin/selectBoardingPass", and has the following fields (inputs):

"recordLocator": a text field, the Confirmation Number of the flight. This has a validation maximum of 13 characters, but the confirmation number is always 6 characters. It says to use the characters "O" and "I" instead of the numbers "0" and "1".

"firstName": a text field, the registered passenger's first name. Maximum validation length of 30.

"lastName": a text field, the registered passenger's last name. Maximum validation length of 30.

"retrievePaxList": the Submit button, with a value of "Retrieve Reservation".


Check-In Step 2:

This is the page the first form submits to, "http://www.southwest.com/cgi-bin/selectBoardingPass". This page can receive form data by POST or GET. It does not matter whether you Web-scrape the first page and submit it, or submit form data directly to this page -- the referrer is not checked. The submit-button value is not checked. The fields it must receive (so as not to get some of the below errors) are the same ones as listed above (except for the submit value); here they are with their known boundary conditions:

"recordLocator": the 6-length alphanumeric confirmation number. Constraints: Not case-sensitive. "O" and "0" are interpreted the same, and "I" and "1" are interpreted the same.
"firstName": the first name in the reservation. Constraints: In actuality, only the first initial is necessary at the beginning of the string and is verified, and it does not matter whether text comes after that initial or what text that is. Not case-sensitive.
"lastName": the last name in the reservation. Constraints: In actuality, the only requirements are that the first initial appear at the beginning of the string and that all consonants must be present (not sure if the last letter is needed if not a consonant). Any other characters, including vowels, numbers, and invalid characters, may appear anywhere within the last name or after it, but not at the beginning. "Y" counts as a vowel. Also, every consonant in the last name may be repeated an arbitrary number of times (with ignored characters allowed in-between repeats), and the first consonant (or perhaps the first consonant that is not the first letter) may be repeated arbitrarily throughout the string without any effect. Not case-sensitive.

It can return a variety of errors pages, which are not exhaustively listed here (because I can't possibly find all of them). All error pages have the title "Error" and the string "<!-- error.htx -->" is always in the HTML. Every error page has the string "Reference Number: " followed by a 6-digit number string. In-between the error-comment and the reference number are two sections of text, "What happened?" and "What you need to do:". The "what happened" response text is in a SPAN tag: "<span class="bodyText" id="whatHappened">". The "what you need to do" response text is in a SPAN tag: "<span class="bodyText" id="whatToDo">". You can use these fields to generate error messages for your script if you like.

Here are common errors, errors I have experienced, and errors you may wish to handle:

Type: No confirmation number
Boundary conditions: This error will *always* be returned if there is no confirmation number regardless of other fields.
What-happened text: "No confirmation number was entered."
What-to-do text: "Go back and enter a valid confirmation number."
Reference number: 200403

Type: Confirmation number wrong length
Boundary conditions: This error will *always* be returned if the confirmation number is not the correct length of 6 alphanumeric characters, regardless of other fields.
What-happened text: "Southwest Airlines confirmation numbers contain six alpha-numeric characters. The confirmation number entered is not valid."
What-to-do text: "Please use your browser's back button to return to the previous screen and enter a valid confirmation number that contains six alpha-numeric characters."
Reference number: 200402

Type: Confirmation number has invalid (non-alphanumeric) characters
Boundary conditions: Confirmation number entered was the correct length.
What-happened text: "The confirmation number entered contains invalid characters."
What-to-do text: "Go back to the previous page and enter the correct Confirmation Number."
Reference number: 200404

Type: No first name entered
Boundary conditions: The confirmation number is valid, but may or may not be a correct one. Does not matter if a last name was entered.
What-happened text: "No first name was entered."
What-to-do text: "Go back and enter a first name."
Reference number: 400100

Type: No last name entered
Boundary conditions: The confirmation number is valid, but may or may not be a correct one, and a first name was entered, regardless of correctness.
What-happened text: "No last name was entered."
What-to-do text: "Go back and enter a last name."
Reference number: 400101

Type: Confirmation number wrong
Boundary conditions: A first name and a last name were entered, regardless of correctness, and the confirmation number was entered, is the correct length, and doesn't have invalid (non-alphanumeric) characters.
What-happened text: "The confirmation number entered is not valid."
What-to-do text: "Please use your browser's back button to return to the previous screen and re-enter a valid confirmation number and Passenger name."
Reference number: 200075

Type: First/last name wrong
Boundary conditions: A correct confirmation number was entered, and a first and last name were entered.
What-happened text: "The confirmation number and the Passenger name on the Boarding Pass must match those in the reservation."
What-to-do text: "Please use your browser's back button to return to the previous screen and verify the Passenger name and the Confirmation number that was entered."
Reference number: 200074

Type: Checking in too early (more than 24 hours before flight time) (or too late -- less than an hour before flight time). (Important -- You need to test for this error when sniping to know when to keep making more requests if you are too early.)
What-happened text: "The request to check in and print your Boarding Pass is before 24 hours prior to your scheduled departure or within 1 hour prior to departure flight time."
What-to-do-text: "Please try again during the allotted time frame or proceed to the airport to check in for your flight. Customers may check in for their flight and obtain their Boarding Pass 24 hours prior to the scheduled departure until 1 hour prior to flight departure time."
Reference Number: 200077

Type: Something temporarily wrong with the system. (I got this error when Southwest was having site errors and I couldn't retrieve my boarding pass; they said it was only on my account and I'd have to check-in at the airport, but it cleared up after an hour or so. It recurred another time.)
Boundary conditions: Not entirely sure, but I recall it only happened when the confirmation number, first name, and last name were all correct.
What-happened text: "A system error occurred while trying to process your request to check in for your flight."
What-to-do text: "Please use your browser's back button to return to the previous page and submit your request again. You may also check in at the departure airport at a Southwest Airlines Skycap Podium, Ticket Counter, or RAPID CHECKIN kiosk to obtain Boarding Pass or Security Document before proceeding to the security checkpoint."
Reference number: 200430



You can test for whether the window has opened yet with the following regular expression (Perl format):
/\<\!\-\- error\.htx \-\-\>.*Reference Number: 200077/s

You can then test whether any other error was encountered if the previous regular expression was not matched and the string "<!-- error.htx -->" is matched.



If there are no errors and you login successfully, the Webpage will not contain the string "<!-- error.htx -->", but will rather contain the string "<!-- selectBoardingPass.htx -->", and will have one form named "viewBoardingPass" with an action page "/cgi-bin/viewBoardingPass" and using the "post" method. It will contain the following fields:

"rrStatus": a hidden type, usually empty.

"CCOUNT": a hidden type, with a generated ID string that is 20 characters long consisting of only upper-case letters (non-numeric). A different string is generated each time you access this page.

"passenger": either a set of radio buttons or checkboxes, depending on the HTTP-User-Agent header given by the client. Each selection represents one of the passengers registered under this confirmation number. If you use a HTTP-User-Agent field of one of the "standard" modern-day Internet browsers (i.e. Internet Explorer or Firefox), you will get a set of checkboxes all with the name "passenger" and can select all of them at once, which is the most efficient way to check everyone in. Otherwise, you will get radio buttons, in which case the form has to be re-submitted for every passenger selected. An example of how to get checkboxes is using the User-Agent string "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3", which comes from Firefox 3 for Windows and is the one I tested to work. I do not know if it is possible to get radio buttons and still submit multiple passenger values to the next page using the same "CCOUNT" or "disc" fields; to be safe, use a User-Agent string that will procure checkboxes, and select all the checkboxes. Note: If there are multiple passengers and you want to identify who each one is, more HTML parsing will be necessary. This may be useful, for instance, if you want to have a certain position order of people in your confirmation-number party. (The items appear in a table with each passenger's information in one row. I will consider researching and posting more details about this format in the future.)

"disc": a hidden type, with a generated ID string consisting of: 1 numerical digit, then a colon ":", then a numerical digit, then ":", then 10 numerical digits, then a dot ".", then 6 digits, then ":", then 2 or 3 digits, then an at-sign "@", then 40 upper-case alpha-numeric characters. A different string is generated each time the page is accessed.


Step 3: Boarding pass page: "http://www.southwest.com/cgi-bin/viewBoardingPass"

You should generally only access this page by submitting (i.e. Web-scrape-submitting) the form on the previous page. The generated fields ("CCOUNT" and "disc") should stay valid for some time, but it is unknown how much time. Once this page has been accessed, the group and position number will be reserved for all passenger(s) selected. The format of the page returned depends on the HTTP-User-Agent. Normally the POST method is used, but I have successfully used the GET method as well.

Update 7/25/09: Possible errors (same format as for submission of the previous form):

Type: Re-submission of expired data
Boundary conditions: You submit form values obtained from selectBoardingPass, after these have expired. (Time of expiry unknown.) (Not sure how the different field values can be combined between different visits to selectBoardingPass and still be valid for viewBoardingPass.)

What-happened text: "The system's time allocated to complete your request has expired."
What-to-do text: "
Please use your browser's back button to return to the previous page to re-enter your information and submit your request."
Reference number: 200086-5086

I do not quite understand how to parse the response body to identify each boarding pass separately when there are multiple boarding passes, but for a single boarding pass you can see the group (A, B, or C) based on an image tag. For group "A", the image tag:
<img src="/images/boarding/boardingA.gif" width="50" height="50" alt="" />
will be present.

The position number can be found inside the "DIV" tag with class "bpPassNum". If the boarding pass was accessed more than once (in which case the position was already reserved), there will be a lower-case "r" after the position number. For example:
<div class="bpPassNum" style="padding-left:8px;">30r</div>


That's it! I hope you found this information helpful. Also, if you can fill in any of the missing details in this documentation, or have any other feedback you would like to share, please feel free to post in the comments!

Happy Sniping!

Followers