Your source for free iOS 6 Passbook passes.

We will be launching a new version of the site soon which includes API updates. If you have applications that use the API, please contact us to ensure compatibility.


Note: this document is still a work in progress. We will do our best to maintain the contracts, but we reserve the right to change things up. Feel free to email us to discuss your particular needs.

9/12/2013: Because passInfo can become quite large, starting with v2 of the Pass Scanner app, passInfo will be sent along as a POST variable instead of a GET variable. Please update your code as necessary.

6/6/2013: Previous versions of the API had the pass info URL as /passinfo.php, however, for consistency, we've moved the page to apiPassInfo.php. We have left the old passinfo.php file in place with an internal re-direct to apiPassInfo.php, but please note that we will remove this file in the future, so please migrate your code if you use this feature.

Previous versions of the API had type_id and template_id with underscores. Given that all the other variables are camelcase, we have standardized these both to use camelcase (typeId and templateId). We have added code that should handle either for now, but please note that we may strip out the deprecated version in the future, so please migrate your code if you use that parameter.

We've also improved the API by standardizing our error messages a little more.

Finally, we've expanded the tracking features of our API to give you a bit more detail on the state changes of passes. We're including the URL call for each transaction update so that you can see what changes were made to the pass during updates.

If you have any questions or feedback (we're still looking for feedback on cookie-less authentication options and analytics reports), please let us know! Now on to the API…

New features

Note: new feature keys can be added manually to the JSON. For example, expirationDate and voided and userInfo can be added and will appear in the output JSON.

Simple features

On pass backfields, you may want to create a link that includes the pass's hashed serial number. Anywhere we see the string PS_HASHED_SERIAL_NUMBER we will replace it with the hashed serial number of the pass when generating the pass.


Pretty much everything is based on templates. You can use our website to create templates to customize passes to your liking. This will be your first step in designing and testing passes you will customize for your users.

Go ahead and create some templates and try out the passes on your test device to see how they look. Once they look right, you can move on to creating passes for your users.

Public passes are branded with a link back to and are shareable. Private passes are white-labeled (including personal account passes). If you create your own pass while logged in, you will get an update link to update your pass.


Most of the API calls will require that you be logged in in order to validate that you and not some third party are creating the passes. If you have suggestions for our upcoming token-based authentication, please let us know your requirements.

The structure is as follows:[URL_ENCODED_EMAIL]&password=[URL_ENCODED_PASSWORD] This page will return "SUCCESS" upon successful login. Unsuccessful attempts will return "FAILURE". For all these URLs, you can use HTTPS instead of HTTP if you need more security.

Creating Passes

There are two ways to create passes. You can either provide specially encoded links to your users and let them create their own passes (useful for coupons or other types of passes where security or data integrity is not an issue) or you can create the pass for the user and provide them a link to download the pass as you created it.

Clear-text pass links

This method is particularly useful if you already have an email program that you can insert fields from your database into. It does not require any web server or backend to manage your passes so it is the easiest solution for restaurants distributing loyalty cards or coupons. Note, however, that only user-editable fields can be overwritten in this way by your users. Anyone can use this link to create passes on your behalf like this, so use the Pre-generated passes instead if there is information a user should not be able to edit.

Before you create your pass link, you will need to fetch the template hash to enable clear-text pass modification. To do this, visit:[YOUR_TEMPLATE_ID] while you're logged in. This only works for your templates and essentially will make the template user-editable (since anyone can change the values in the links) but it will not appear in the public list unless you have also flagged the template as public (note that the public list is cached for optimization so it may take a couple hours to appear in the list).

Once you have your template hash, to create the pass link, just construct a link as follows:[YOUR_TEMPLATE_HASH]&[*FIELD_VALUE_PAIRS] The field-value pairs are simply additional get parameters where the key corresponds to the path to the value you want to modify and the value is the URL encoded value for that key. The key path are the keys separated by underscores (note that this means underscores are not allowed in PassSource pass keys). For array items like primaryFields, use the element's key value as the key. Values can be flat values or JSON encoded objects (for example if you wanted to replace the locations list, you would urlencode a JSON array of location fields and pass that as the location parameter). If you are not logged in, only fields marked as user editable will be applied and other values will be ignored. If you are logged in and own the template, you can modify any field in this way. Note that the highest order editable field will take precedence, so if you're seeing defaults appear, make sure that you haven't made one of the parents of the field you're editing editable.

You may also overwrite and specify images by setting the key to images_ plus the image name and the value to a URL encoded URL to the image. For example, you could add the following to change out the logo: & The possible keys are as follows. Note that not all pass types support all image types. For more information, check out Apple's documentation (you must have an Apple developer account to access). images_icon images_logo images_thumbnail images_strip images_background images_footer You may add "@2x" to the end of any of those to specifically target the high resolution version but if there is no @2x in the template, you can just specify the normal version and Apple will scale the image to fit the space. Note: you must be logged in for this to work.

For example, if you wished to set a barcode number and altText to "9991212", and a member name to "George P. Burdell" (using the format of a generic pass type), you could do the following:,&barcode_message=9991212&barcode_altText=9991212&generic_primaryFields_member_value=George%20P.%20Burdell Don't forget to URL encode the values. You could use this method to distribute customized passes to a mailing list with each person's email containing a link to a pass with their name and member ID pre-filled so all they have to do is tap the link and tap add to get it in their passbook. You could add additional user-editable fields if you wanted to capture additional information, or have no user editable fields to take them directly to the pass.

Pre-generated passes

This is a good method for creating store-cards and other items where you would rather the user not be able to modify the values themselves. The first step is to add the user's custom fields in the same manner as the clear-text pass links. Since this would be run via a CURL request or other automated process, we don't need to actually download the pass and we do need to fetch the unique serial number for this pass. For security, we only give you an encoded version of the serial number. To get the encoded serial number, add &generate=true to the end of the URL created above. This will return a hashed string representing the serial number for this pass. You can store this in your database as you will use this for any updates and tracking of this pass. When you want to give this pass to the user, simply direct them to the following URL:[HASHED_SERIAL_NUMBER] This link will download this user's pass with the customizations you've made.

Why hash the serial number? The serial number is not secured for the user since they can obviously open up the pass file to get that. The reason we hash the serial number is it adds an additional level of complexity. Since anyone can download any pass by just having the serial number, hashing it makes brute-force guessing of serial numbers that much more difficult. If you have a good argument for not hashing it, please tell us as we've considered doing away with the hashing for serial numbers since they are not sequential and a brute force guess would still take a while. If you have arguments for why they should stay hashed, please tell us also.

Updating Passes

If at some point you need to update a user's pass information (for example, a new offer or an updated balance), you may do so using the hashed serial number you got when creating the pass.

Simply form a URL as if you were creating a new pass (including the templateHash) with all the new user information (not just the changes) and include the following parameters: &hashedSerialNumber=[HASHED_SERIAL_NUMBER]&generate=true This will automatically update the pass as well as send a push notification to the user's device with the updates. If you have specified a change message for a field, that should appear on the user's lock screen. We handle all the registrations and updates with Apple's push servers so you don't have to.

Pass information

If you have a scanner and need to get or check basic info about a pass, you can call the following:[HASHED_SERIAL_NUMBER] If you are logged in as the template owner, this will return a JSON object with information about the pass. If the serial number is not found or not one of our passes, it will return: {"status":"invalid", "scanText":"Invalid Code"} If you are not the template owner or not logged in, it will return: {"status":"access", "scanText":"Access Denied"} Otherwise, it will return the following: { "status":"success", "scanText":"Successful Scan", "hashedSerialNumber":the same as what you passed in, "templateId":the template id, "templateHash":templateHash you can use with the API, "description":pass description, "userFields":a JSON array of field value pairs as described above, "additional":see below, "transactions":this will be an array of events (see below), "options":an array of options for PassScan (described below), "downloadLink":the link to download the pass } This will allow you to build a scanner tool (or use ours) to process scans.

The additional field will include any JSON text you have provided on your account info page. If you have left this blank, or if the additional info is not valid JSON, this value will be null.

The transactions field will allow you to get detailed information on the state and history of the pass. If you need detailed analytics on a pass, this is how to get it. The log is in reverse chronological order and contains JSON objects with three fields: time, which is a MySQL timestamp of the event, url, which is the URL that triggered the event, and accessType, which is an integer representing the following events: 1: creation — when the pass was created 2: install — the pass was installed on a new device 3: update — the device requested an update 4: user update — a user updated user editable data on our site 5: api update — API calls were used to update the pass 6: deletion — the user deleted the pass from their device 7: scan — the pass was scanned with the PassScanner tool

Deletion Callback URL

If your code needs to be notified when passes are deleted, you can include a callback URL on your account page. The URL can be any publicly accessible URL and the text HASHED_SERIAL_NUMBER will be replaced with the serial number of the deleted pass. This allows you to specify the hashed serial number either in REST format or as a GET parameter or as a hash tag.

PassScan features

Note: some of these features will only be available once Apple approves the 1.2 update to the Pass Scanner app.

You may use our Pass Scanner (in the app store) to automatically process passes if you do not have any systems you need to hook into. You can include several options when you choose PassScan as the barcode type. You can specify an action that the PassScanner app will perform upon scan or you can direct the cashier to a web page to manage values for loyalty and gift cards.

To specify options, create a JSON object with the keys and values described below and set the barcode message value to the stringified version of this JSON object (PassScan must be selected as the barcode type for these to take effect).

The action parameter specifies what should happen when the pass is scanned. This action is taken as soon as the code is scanned so use these if you want the scan itself to trigger the action, otherwise, use the additional parameters to do things later such as call your web service or display a page to let the cashier manually take action. These are the current available actions (let us know if you have other ideas):

"action":"check" This will not do anything to the pass but can be used in conjunction with a callbackURL or displayURL to do more advanced updates. The Pass Scanner will simply display the status and not make any updates to the pass.

"action":"invalidate" This will mark the pass as "used" and once scanned and invalidated, any future scans will return a status of rescan. You may also include a rateLimit parameter. If set and the last scan was longer than the value of rateLimit seconds ago, the status will be success and not rescan. The value for rateLimit is in number of seconds, so, for example, if you want it to only be valid every 24 hours, set this to 24*60*60 = 86400.

"action":"increment" This will increment the value stored in the path parameter by amount if specified (otherwise will increment by 1). You may pass in a negative number for the amount parameter to decrement the path value for things like punch cards and redemptions. If you use a negative number, the value will never be decremented beyond 0 and if a scan happens when the value is already at 0, status will be rescan.

The scanText parameter specifies the text to display when the scan has a status of success. If not provided, defaults to Successful Scan.

The zeroText parameter specifies the text to display when the path value is 0.

The autoreturn parameter specifies that the Pass Scanner app should return to the scan screen after scanning and validating the pass. This can be useful in businesses where you want to set up an automatic checkin system.

The sound parameter specifies the URL to a sound file that will be played. If you want to have different sounds for approval and rescans, or if the balance falls below a certain amount, or other conditions, use the callbackURL functionality to update the passInfo based on your own logic. Very complex logic rules can therefore be handled by your server while still being able to use the Pass Scanner app.

The callbackURL parameter specifies that a URL will be called with passInfo added as a POST parameter when the pass is scanned in case your service needs to update its database or make modifications to the default behavior after the scan is performed. This allows you to add hooks into the process to insert your own custom behaviors, like validating that a punchcard balance is not negative, automatically credit a reward after a certain number of scans have been performed, update a balance based on a POS transaction, etc.

The informationURL parameter specifies a URL that will be called with passInfo added as a POST parameter as a button at the bottom of the scan interface to do more advanced updating or get information about the pass after scanning. This would allow you to back out the loyalty scan if you just wanted to check the balance or make manual adjustments, etc.

The displayURL parameter specifies that a URL will be called with passInfo added as a POST parameter in case your service needs to update its database after the scan is performed. This will show the page at the URL instead of the default interface. You can use this to create more advanced edit controls for updating your passes or custom branded management interfaces.

The passInfo parameter in this case will be exactly the same information returned by the pass information URL above and will be passed as a POST parameter.

We have developed a couple URLs to help you perform some common tasks that you can use as the displayURL to easily manage passes: This page will display a toggle to mark the pass as scanned or not scanned. Combine this with the invalidate action to verify and optionally reverse the scan validation. This page will display a control to increment/decrement the path value by the absolute value of amount (to make sure things are clear) or to edit the value by direct input.

An example of how this could all be used: Say we wanted to create a loyalty card that automatically increments the user's balance by 5 points every time they shop with us. When they hit 50 points, we would like to give them a discount and reset their points to 0. Our template is of type storeCard has a headerField field with key points. Here's the text we would assign to the message value in the template: { "action":"increment", "path":"storeCard_headerFields_points_value", "amount":5, "scanText":"Points Added", "informationURL":"" } When the cashier scans the pass, it will automatically add 5 points to the customer's loyalty balance and immediately update the customer's card via a push notification. The cashier will be briefly presented with the "Points Added" message before being presented a webpage where they can increase or decrease the point value or set it to 0 once they choose to redeem their points. If they accidentally scan it twice, they can similarly press the down arrow to remove the additional points. When the customer reaches some reward level, they can also deduct the points and redeem the reward.

If you'd like to test this out, download our PassSource Examples from our site and login to the Pass Scanner app with the username "demo" and the password "demo".

Additional Features

You may want to provide the use with a link on the back of the pass to update the pass's locations or update a store card balance manually. To include the hashed serial number in a link, just use the placeholder PS_HASHED_SERIAL_NUMBER and we will replace this string with the hashed serial number when generating the pass. Hashed serial numbers are URL safe so there's no need to worry about URL encoding. For example: Your code can then fetch the pass for that serial and issue any necessary updates. We will automatically call this URL anytime the pass is generated as long as it is at the end of the value and the generate flag is not set and the field key is psUpdateLink (if not, the user will have to tap the link manually after installing the pass). If you have data that would be too sensitive to include on the card, you can make the field type Hidden which will prevent the data from appearing on the pass.

The Unique checkbox is a feature of the API that allows you to specify a field that must be unique. This will cause us to pull an existing pass if it's already been created instead of always creating a new one. This can be useful if you're sending 1 time use items to people via email. For example, if you are distributing a coupon to your mailing list and want to make sure each email address only gets one coupon, you can set the email as a backfield, make it editable, make it unique, and when you distribute the pass via URL, no matter how many times the user clicks that coupon, it will generate the same coupon for that email. This means that if you invalidate that email's coupon, even if they delete the pass and try to add the coupon again, when you scan the pass, it will still show as already scanned. While this can be easily subverted by the user editing the email field to use a different value, it will make it more difficult to subvert. If you wanted to account for this, you could validate the email on the pass against your database at scan time for an additional security check. Or you could specify the user's first and last name and validate that against their driver's license when you scan the coupon. Or you could capture their drivers license number along with the scan to validate the pass. So you could have various levels of security based on how secure you need it to be or you could simply just deter people from generating extra passes and cluttering your database by clicking on links multiple times.

Getting the pass file

If you need to download the pass file, add the following parameter to the create URL: &download=true This acts the same as the generate parameter with the difference that instead of returning the serial number, it will return the pass itself. If you need the hashedSerialNumber, do the generate command and then use the user's create link with the download parameter to get the pass data.

This is the default behavior for the create link, but it will instead display an HTML page if the user agent isn't an iOS device.


If there's a problem, usually we display an HTML error page that gives some indication as to the problem. If you're using the API, you may want something simpler. We have a solution for you: if you add &webservice=true to the end of a URL, instead of showing an error page, we'll return a JSON object with the following fields: { "success":boolean false, "errorMessage":error message string }

Pass Scanner: End-to-end solution

You can use our Pass Scanner app to scan and manage your Passbook passes. To have PassSource generate the code for you for simpler scanning and linking with our Pass Scanner tool, set the Barcode format type to PKBarcodeFormatPassScan. This will use the hashed serial number as the barcode message which your app or the Pass Scanner app can use to link the pass to your database.

The current features are large display of the encoded data (QR currently supported) or it can automatically invalidate a pass to update the user's pass information and flag a pass as being scanned. It can also increment a value such as points or punches and can display any URL you specify to manage the data. We also support sending the QR data to a custom URL adding the parameter "message=%" where % is the QR data string as entered in the pass. This then opens a web-view with that URL where you can create your own controls and information.

The flash in the app turns on automatically if there isn't enough light. Make sure the phone is not resting on the table when you start the app and there is enough light in the room and the flash should not engage.

To log in, tap the settings icon and then the Handle Pass Scan disclosure button to sign in. You don't need an account if you just want to display large data or call your own custom URL.

To automatically set the iBeacon parameters for the app, use a URL in the format: passscanner://?proximityUUID=68753A44-4D6F-1226-9C60-0050E4C00067&major=2&minor=1

More information

You can get a list of all your templates, their names, and hashes using the following URL (after logging in): The page returns a JSON array of objects with parameters id, name, and hash.

You can get a list of all the passes generated for one of your templates using the following URL (after logging in):[YOUR_TEMPLATE_ID] Leaving the templateId parameter off will get all the passes for all your templates. The page returns a JSON array of hashed serial numbers. If you add includePassInfo=true as a parameter, instead of an array of hashed serial numbers, you will get an array of pass info objects (see Pass information section above) without transaction information. If you add update=true as a parameter, this will update all passes based on this template that have been created before the last template update date. This will display an HTML page when done and not return any JSON. Note that there is a fixed limit of 100,000 results for normal calls and 100 results when using the includePassInfo flag. If you have more than that, you can fetch the next page of results by adding &page=2 to the URL (subsequent pages can also be fetched this way for larger datasets).

Some Examples

Here are some examples you can try yourself. You will need to modify the template hashes to your own templates, but for these examples, we are using the base public templates, so you can clone those for your own account.

First, we need to login:[YOUR_EMAIL]&password=[YOUR_PASSWORD] Returns SUCCESS. Then we need to get the hash for the template we're using:[YOUR_TEMPLATE_ID] Returns your template hash. For this example we used templateId=2 which returned eNortjIysVIycEwyDskvM85PL3DOSU4pDvUyczZKt7VVsgZcMJ5yCZk,. Next we can create a pass updating the offer to $10 off any purchase over $80 (remember the values need to be URL encoded first) adding the generate tag so that we can get the serial number of the newly generated pass:,&coupon_primaryFields_offer_value=%2410%20off&coupon_primaryFields_offer_label=any%20purchase%20over%20%2480&generate=true This returns a hashed serial number for the pass (note, re-running the command will generate a new unique serial number and pass instance in your list): eNortjIysVJyDcpONfdNDUsqL8mxMNN29NMPzPdLt7VVsgZcMJ3lCXI,. We can now send this pass to a customer or post it to our website by creating the following link:, If we want to update the pass, say with a new expiration date to 1/1/2013, we can use the serial number in conjunction with the template hash to issue the update:,&templateHash=eNortjIysVIycEwyDskvM85PL3DOSU4pDvUyczZKt7VVsgZcMJ5yCZk,&coupon_auxiliaryFields_expires_value=1%2F1%2F2013&generate=true This will push an update to all devices with that pass installed. If someone goes to download the pass using the original link, it will now reflect the updated expiration.

Say you were trying to convert paper loyalty cards. For every $10 the customer spends, they get one punch. When they get 10 punches, they can redeem for 20% off their next purchase. To create this, set up your pass as a PassScan barcode and put the following in the message field: { "action":"increment", "path":"coupon_headerFields_punches_value", "amount":1, "scanText":"one punch added", "informationURL":"" } Every time the pass is scanned, 1 punch will be added. If they already have 10, you can scan the pass and use our utility page (the loyaltyEdit page) to deduct 10 punches.

Here's an example of a widget that allows the user to enter their member number which becomes the barcode for a generic pass: <form method="get" action=""> <input type="hidden" name="templateHash" value="eNortjIysVIqLA00jIiyyC0pMXKOcPYqyrIozC4ItLVVsgZcMKPxCfk," /> <label>Enter your member number:</label> <input type="text" name="barcode_message" /> <input type="submit" value="Get Pass" /> </form>

Here's some examples of server code using cookies in JAVA that might be helpful: // your first request that does the authentication URL authUrl = new URL(""); HttpsURLConnection authCon = (HttpsURLConnection) authUrl.openConnection(); authCon.connect(); // temporary to build request cookie header StringBuilder sb = new StringBuilder(); // find the cookies in the response header from the first request List cookies = authCon.getHeaderFields().get("Set-Cookie"); if (cookies != null) { for (String cookie : cookies) { if (sb.length() > 0) { sb.append("; "); } // only want the first part of the cookie header that has the value String value = cookie.split(";")[0]; sb.append(value); } } // build request cookie header to send on all subsequent requests String cookieHeader = sb.toString(); // with the cookie header your session should be preserved URL regUrl = new URL(""); HttpsURLConnection regCon = (HttpsURLConnection) regUrl.openConnection(); regCon.setRequestProperty("Cookie", cookieHeader); regCon.connect();

Frequently Asked Questions

The strip text isn't using the foreground or label colors.

That is a "feature" of the passes with a strip section. To customize the color, you need to add a color called "stripColor" to the root of the pass. That should allow you to color it how you want. If you need help doing this, send us a link to the template and we'll add the color for you. The visual editor should allow you to change it, but if the field isn't present, it won't do anything (we're fixing that). This is an undocumented "feature" and Apple may remove it in a future update.

Do you have any example code for creating passes in iOS?

We used a helper category to do the URLencoding. Note, the login step is unnecessary if you have the template hash already and you've made the fields user-editable (which may or may not be what you want). An example project with the following code can be downloaded from #import "NSString+urlencode.h" #import <PassKit/PassKit.h> #define username @"demo" #define password @"demo" #define template_hash @"eNortjIysVIqLA00jIiyyC0pMXKOcPYqyrIozC4ItLVVsgZcMKPxCfk," // do the following in a UIViewController // Encode the username and password NSString *encoded_username = [username urlEncoded]; NSString *encoded_password = [password urlEncoded]; // in your implementation with AFHTTPRequest, you may need to flip the handle cookies value: // [request setHTTPShouldHandleCookies:YES]; // run asynchronously to not block main thread dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSError *error; // login NSString *loginResult = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"", encoded_username, encoded_password]] encoding:NSUTF8StringEncoding error:&error]; NSLog(@"Login result: %@", loginResult); if ([loginResult isEqualToString:@"SUCCESS"]) { // create pass with template NSString *passURL = [NSString stringWithFormat:@"", template_hash]; NSLog(@"Loading pass from URL: %@", passURL); NSData *passData = [NSData dataWithContentsOfURL:[NSURL URLWithString:passURL]]; PKPass *pass = [[PKPass alloc] initWithData:passData error:&error]; if (pass == nil) { NSLog(@"Error creating pass: %@", error); } else { dispatch_async( dispatch_get_main_queue(), ^{ PKAddPassesViewController *apvc = [[PKAddPassesViewController alloc] initWithPass:pass]; [self presentViewController:apvc animated:YES completion:nil]; }); } } else { NSLog(@"There was a login error: %@", error); } });

Can I remove (or add) a barcode to a template that doesn't have one at a later date?

If you're logged in as the template owner, by passing the templateHash along with the serial number, you can update any field. For example, to remove a barcode from a pass, you could add the following ({} url encoded): &barcode=%7B%7D

I'm seeing the wrong icon when I make updates to my passes.

Yup. It's a known bug in iOS 6 for passes with shared passTypeIDs. Restarting your device will reset which icon is chosen but then it's locked for that passTypeID, even if you delete the pass! If you file a bug or send Apple feedback, you can reference radar:12044637. If you need us to set up a unique passTypeID for you, let us know.

I'm having issues with passes in use where I've deleted a field.

Updating passes where you've deleted a field can cause issues with the customize page if users are expected to enter/update their own information. If you must make a change, make sure to preserve any existing fields. You can change their type to Hidden to prevent them from showing up on the pass.

I'm using the API and the field I'm passing as a parameter isn't updating/overwriting.

If the field you're updating has any parents marked as User Editable, that will mask the override of the field you're trying to update so make sure User Editable is off or only on for the specific fields you're attempting to update. If you are still having trouble, please email us the url that's failing.

Is there a Java example of how to do the session-based authentication?

// your first request that does the authentication
URL authUrl = new URL("");
HttpsURLConnection authCon = (HttpsURLConnection) authUrl.openConnection();

// temporary to build request cookie header
StringBuilder sb = new StringBuilder();

// find the cookies in the response header from the first request
List<String> cookies = authCon.getHeaderFields().get("Set-Cookie");
if (cookies != null) {
    for (String cookie : cookies) {
        if (sb.length() > 0) {
            sb.append("; ");

        // only want the first part of the cookie header that has the value
        String value = cookie.split(";")[0];

// build request cookie header to send on all subsequent requests
String cookieHeader = sb.toString();

// with the cookie header your session should be preserved
URL regUrl = new URL("");
HttpsURLConnection regCon = (HttpsURLConnection) regUrl.openConnection();
regCon.setRequestProperty("Cookie", cookieHeader);

I'm not seeing an image passed in via the URL in my pass.

Specifying images via the URL is only available when using the API after logging in. Clear text use of this is not allowed as end-users would be able to specify their own logos and images which could make you liable if they are using other brands on your pass. If you need to dynamically assign images to user's passes, generate the pass for the user and send them their customized pass link.

Why am I not seeing update notifications in PassWallet?

PassWallet only supports updates of fields on the front of the pass, so if the update you're looking for is in the backFields array, the update will not be shown.

I'm getting a blank page when using CURL to contact your server.

Make sure you're doing the following in your CURL code (this is for PHP…make sure the equivalent flag is set depending on your language): curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

I need help!

We offer professional services for integration assistance, but during the beta, we will be working with everyone to make sure this API is a success. If you have questions, please email us, but please make sure your question isn't already answered by this FAQ!