NAV

Introduction

This document describes how to use the Yourpass REST API. It provides useful references and examples for all available endpoints.

Console

Yourpass provides a web-based tool for interacting with the API.

For the sandbox environment, which is intended for integration testing, you can access the Console at https://console.yourpass.space.

For production environments, contact Yourpass support to receive the URL.

Environment URLs

URLProductionSandbox (integration testing only)
API_URLSee belowhttps://api.yourpass.space
DISTRIBUTION_URLSee belowhttps://get.yourpass.space
ISSUE_URLSee belowhttps://issue.yourpass.space

This documentation uses placeholders for these URLs. Whenever you see <...>, you should replace it with one of the above URLs based on the selected environment. For example <API_URL>/v1/pass translates to https://api.yourpass.space/v1/pass for the sandbox environment.

Headers

All endpoints expect the following headers, unless otherwise noted:

NameValue
Acceptapplication/json
Content-Typeapplication/json

Optionally, an Authorization header can be specified. See Authentication for more information.

Authentication

Yourpass web services are secured via token-based authentication. All requests that require authorization must contain a token in an Authorization header.

OAuth2 - Resource Owner Password Credentials

This service lets trusted applications that store user credentials obtain an access token. For more details, see RFC6749.

Debugging authentication errors

This authentication flow is not available for federated identities.

Try your credentials at <CONSOLE_URL>. If you cannot log in using the Console, try resetting your password first or contact support.

If you can authenticate using the Console, debug your issue with the curl commands provided in the right panel of this documentation.

If you use the curl command or create the authentication URL manually in your application, make sure all URL parameters, including the password, are URL-encoded.

Request

Request:

curl --request POST <API_URL>/oauth2/token \
  --header "Authorization: Basic YzM2YjY3MjEtMDRkNS00ZGNlLWIxZjItNDc5NmQ4ZmNjODQ5Og==" \
  --header "Cache-Control: no-cache" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data "grant_type=password&username=your@email.com&password=yourPassword"
var qs = require("querystring");
var http = require("https");

var options = {
  method: "POST",
  hostname: ["api", "yourpass", "eu"],
  path: ["oauth2", "token"],
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
    Authorization: "Basic YzM2YjY3MjEtMDRkNS00ZGNlLWIxZjItNDc5NmQ4ZmNjODQ5Og==",
    "Cache-Control": "no-cache",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(
  qs.stringify({
    grant_type: "password",
    username: "your@email.com",
    password: "yourPassword",
  }),
);
req.end();

POST <API_URL>/oauth2/token

Header parameters

NameNoteRequired
AuthorizationBasic xxx, where xxx is the base64-encoded clientID:clientSecretYes
Content-Typeapplication/x-www-form-urlencodedYes

Body

NameNoteRequired
grant_typeContains the constant password for this OAuth2 grant typeYes
usernameThe user’s emailYes
passwordThe user’s passwordYes

Response

Response:

{
  "access_token": "supersecret2token.....",
  "expires_in": 21600,
  "token_type": "Bearer"
}
NameNote
access_token
expires_inseconds until expiry
token_type

OAuth2 - Authorization Code Grant

This service lets users delegate access rights to a third-party application. For more details, see RFC6749.

Process description

Get authorization code

GET /oauth2/auth?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope={scope}&state={state} HTTP/1.1
Host: <API_URL>

Get an access token with an authorization code

POST /oauth2/token HTTP/1.1
Host: <API_URL>
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

code={your_received_code}&
redirect_uri={redirect_uri}&
grant_type=authorization_code

Renew the access token with a refresh token

POST /oauth2/token HTTP/1.1
Host: <API_URL>
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

refresh_token={refresh_token}&
grant_type=refresh_token

Scopes:

ScopeDescription
pass.cpass create
pass.rpass read
pass.upass update / pass patch
pass.dpass delete
template.ctemplate create
template.rtemplate read
template.utemplate update / template patch
template.dtemplate delete
image.cimage create
image.rimage read
image.uimage update / image patch
image.dimage delete

Authorize your API request

curl -X GET '<API_URL>/v1/pass' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

All following endpoints accept the token in the Authorization header.

Example:

Authorization: Bearer <ACCESS_TOKEN>

Permissions

The given authorization token is always issued on behalf of an existing Yourpass user. The user’s permissions to perform API calls are managed on a per-project basis.

If you believe you lack a permission, please contact an administrator in your organization or Yourpass support directly.

Project

Projects organize templates, passes, images and other assets into groups. These entities can be filtered by the project they belong to. A user may be granted access to multiple projects or their subprojects.

{
  "id": "id-of-project",
  "name": "project name",
  "description": "project description",
  "parentId": null,
  "createdAt": "2017-02-09T10:23:55.787232Z",
  "updatedAt": "2017-02-17T08:52:01.971545Z",
  "deletedAt": null
}

Properties

NameNotefilter&sortType
idstring
namestring
descriptionstring
parentIdstring
createdAtdatetime
updatedAtdatetime
deletedAtdatetime

Read project

Request

curl -X GET '<API_URL>/v1/project/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/project/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/project/:id

Path parameter

NameNote
idProject ID

Response

Returns Project.

Image

{
  "id": "image-id",
  "name": "image-name",
  "type": "strip",
  "width": 640,
  "height": 246,
  "fileSize": 164414,
  "url": "data:image/png;base64,iVBOR...gg==",
  "projectId": "b7654e80-0b87-4c4c-a351-2fc55c86e9b9",
  "createdAt": "2017-11-03T10:32:37.756841Z",
  "updatedAt": "2017-11-03T10:32:37.756841Z",
  "deletedAt": null
}

Properties

NameNotefilter&sortType
idstring
namestring
typeimage type [logo/icon/strip/footer/background/thumbnail]string
widthcomputed widthnumber
heightcomputed heightnumber
fileSizecomputed file sizenumber
urlstring
projectIdProject IDstring
createdAtdatetime
updatedAtdatetime
deletedAtdatetime

Sizes

Pass styles and relevant image types:

Pass styleSupported imagesNote
Boarding passlogo, icon, footer
Couponlogo, icon, strip
Event ticketlogo, icon, strip, background, thumbnailIf you specify a strip image, do not specify a background image or a thumbnail.
Genericlogo, icon, thumbnail
Store cardlogo, icon, strip

Create image

Create an image. This service requires an image URL.

There are two ways to provide an image URL:

The image dimensions must conform to the sizes specified above. The size of the resulting image can differ from the original because of file encoding normalization.

Request

curl -X POST <API_URL>/v1/image \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '{"url": "public URL or data URL","type":"logo","name":"image name","projectId":"id-of-project"}'
var http = require("https");

var options = {
  method: "POST",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/image",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(
  '{"url": "public URL or data URL","type":"logo","name":"image name","projectId":"id-of-project"}',
);

req.end();

POST <API_URL>/v1/image

Body

NameNoteRequiredType
urlpublic URL or data URLYesstring
nameimage nameYesstring
typeimage typeYesstring
projectIdID of the projectYesstring

Response

Returns Image.

Read image

Read an image.

Request

curl -X GET <API_URL>/v1/image/:id \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/image/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/image/:id

Path parameters

NameNoteRequiredType
idYesstring

Response

Returns Image.

Delete image

Mark an image as deleted.

Request

curl -X DELETE '<API_URL>/v1/image/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "DELETE",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/image/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

DELETE <API_URL>/v1/image/:id

Path parameter

NameNote
idID of image

Response

Returns Image.

List image

Return a list of images. The list does not include all image properties. To retrieve all image data, use the Read image service. The list can be filtered and sorted using HTTP request query parameters.

Request

curl -X GET '<API_URL>/v1/image?page=1&limit=100' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/image?page=1&limit=100",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/image

Query parameters

NameNoteDefaultRequired
limitpaging limit (max 1000)100No
pagepage number1No
whereURL-encoded JSON query (see Querying)No
order(see Ordering)No
orderBy(see Ordering)No

Response

Response

{
  "data": [
    {
      "id": "id-of-image",
      "name": "name",
      "type": "logo",
      "width": 640,
      "height": 246,
      "fileSize": 164414,
      "url": "http://.....",
      "projectId": "b7654e80-0b87-4c4c-a351-2fc55c86e9b9",
      "createdAt": "2017-11-03T10:32:37.756841Z",
      "updatedAt": "2017-11-03T10:32:37.756841Z",
      "deletedAt": null
    }
  ],
  "totalCount": 1,
  "page": 1,
  "limit": 1000
}

Response body

NameNoteType
dataarray of Imagesarray
totalCounttotal count of recordsnumber
pagereturned pagenumber
limitpage sizenumber

Template

Represents the template data model used to generate passes.

{
  "id": "ID OF TEMPLATE",
  "name": "NAME OF TEMPLATE",
  "jsonTemplate": {
    // unstable, do not use
  },
  "dynamicDataJsonSchema": {
    "type": ["object", "null"],
    "title": "DynamicData",
    "description": "Dynamic data values....",
    "properties": {
      "firstName": {
        "title": "First name",
        "type": "string"
      },
      "lastName": {
        "title": "last name",
        "type": "string"
      }
    },
    "required": ["firstName", "lastName"]
  },
  "projectId": "8e99b56f-6599-42a5-b19b-31f9d0bb39c0",
  "certificateId": "1529a6a1-ddca-497b-aa44-74c19433c440",
  "images": {
    "icon": {
      "cs": "a5021600-9f29-4a05-91e4-5bbce2a4a21a",
      "en": "a5021600-9f29-4a05-91e4-5bbce2a4a21a"
    },
    "logo": "9db7c521-9c23-463e-8ce6-67c5bc11e764",
    "strip": "ff6b8d14-6e08-40c5-a480-1344cd0797c1"
  },
  "languages": ["cs"],
  "distributable": true,
  "createdAt": "2017-10-17T11:27:04.113254Z",
  "updatedAt": "2017-11-03T14:40:25.293086Z",
  "deletedAt": null
}

Properties

NameNotefilter&sortType
idstring
namestring
jsonTemplateappearance definition, layout, fields, barcodes and other pass propertiesobject
dynamicDataJsonSchemaJSON Schema definition for validating dynamic data used on the passobject
projectIdID of the project the template belongs tostring
certificateIdID of the certificate used for signing passes created with this templatestring
imagesobject mapping an image type to an image IDobject
languagesat least one language in ISO 639-1 formatarray
distributableallows distribution via issue linkboolean
createdAtdatetime
updatedAtdatetime
deletedAtdatetime

Template layout

Boarding passes are specified by a boardingPass key.

Appropriate for: passes used with transit systems, such as train tickets, airline boarding passes and other types of transit.

Each pass typically corresponds to a single trip with specific start and end points.

Boarding Pass

Coupons are specified by a coupon key.

Appropriate for: coupons, special offers and other discounts.

Coupon

Event tickets are specified by an eventTicket key.

Appropriate for: passes used to gain entry to an event, such as concerts, movies, plays or sporting events.

Each pass typically corresponds to a specific event, but you can also use a single pass for several events, such as a season ticket.

Event ticket

Store cards are specified by a storeCard key.

Appropriate for: store loyalty cards, discount cards, points cards and gift cards.

A store card typically identifies the user’s account within your company, which can then be used to make payments or receive discounts. If the account carries a balance, it shows the current balance on the pass.

Store card

Generic passes are specified by the generic key.

Appropriate for: any pass that does not fit into one of the more specific categories above, e.g. gym membership cards, coat-check claim tickets and metro passes that carry a balance.

Generic

PKPass documentation is available in the Wallet Developer Guide. Individual fields are described in the PassKit Package Format Reference.

Fields

Relevance

Pass styleRelevant dateRelevant locationsRelevance
Boarding passRecommended.Include the relevant date unless the pass is relevant for an extended period of time, such as for a month-long bus pass.Optional. Interpreted with a large radius.Relevant if the date and any location matches. Prior to iOS 6.1, relevant if the date or any location matches. Without a relevant date, pass is relevant if the location matches.
CouponNot supported.Required if relevance information is provided.Interpreted with a small radius.Relevant if any location matches.
Event ticketRecommended. Include the relevant date unless the pass is relevant for an extended period of time, such as for a multi-day event. Prior to iOS 7.1, required if relevance information is provided.Optional. Interpreted with a large radius.Relevant if the date and any location matches. Without a relevant location, relevant if the date matches.
GenericOptional.Required if relevance information is provided. Interpreted with a small radius.Relevant if the date and any location matches. Without a relevant date, relevant if any location matches.
Store cardNot supported.Required if relevance information is provided. Interpreted with a small radius.Relevant if any location matches.

Read template

Request

curl -X GET '<API_URL>/v1/template/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/template/:id

Path parameter

NameNote
idID of template

Response

Returns Template.

List template

Request

curl -X GET '<API_URL>/v1/template?page=1&limit=100' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template?page=1&limit=100",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/template

Query parameters

NameNoteRequired
limitmaximum number of returned records; default 100, maximum 1000No
pagereturned page; default 1No
whereURL-encoded JSON query (see Querying)No
order(see Ordering)No
orderBy(see Ordering)No

Response

Response:

{
  "limit": 10,
  "page": 1,
  "totalCount": 1,
  "data": [
    {
      "id": "0a088428-40ec-4166-8271-05658e87ad8f",
      "name": "TemplateName",
      "certificationId": "b7654e80-0b87-4c4c-a351-2fc55c86e9b9",
      "projectId": "b7654e80-0b87-4c4c-a351-2fc55c86e9b9",
      "createdAt": "2016-11-04T15:07:21.703676+01:00",
      "deletedAt": null,
      "updatedAt": "2016-12-13T11:55:59.813897+01:00",
      "jsonSchema": {}
    }
  ]
}
NameNoteType
dataarray of templatesarray
totalCounttotal count of recordsNumber
pagereturned pageNumber
limitpage sizeNumber

Push template

Send a push notification to all devices with a pass issued from this template. A device that receives a push notification then checks for changes and fetches updated passes, if available.

Request

curl -X GET '<API_URL>/v1/template/:id/push' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template/:id/push",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/template/:id/push

Path parameter

NameNote
idID of template

Response

Returns an empty JSON object or an error.

Pass

Represents an individual pass composed of a template and dynamic data.

{
  "id": "id-of-pass",
  "url": "https://...",
  "templateId": "id-of-template",
  "projectId": "id-of-project",
  "dynamicData": {
    "lastName": "Jedno",
    "firstName": "Tomáš"
  },
  "dynamicImages": {
    "logo": "id-of-logo-image",
    "icon": "id-of-image",
    "strip": {
      "cs": "id-of-czech-image",
      "en": "id-of-english-image"
    },
    "background": "id-of-image",
    "footer": "id-of-image",
    "thumbnail": "id-of-image"
  },
  "expirationDate": null,
  "voided": false,
  "devices": null,
  "lastRegisterAt": null,
  "firstRegisterAt": null,
  "lastUnregisterAt": null,
  "firstUnregisterAt": null,
  "updatedAt": null,
  "createdAt": "2016-10-10T21:48:01.565Z",
  "deletedAt": null
}

Properties

NameNotefilter&sortType
idstring
urlURL for pass distributionstring
templateIdstring
projectIdstring
dynamicDatavalidated against template’s dynamicDataJsonSchemaobject
dynamicImagesobject mapping an image type to an image IDobject
expirationDateend of the pass validitydatetime
voidedset to true to deactivate the pass (default false)boolean
devicesnumber of active installations on devices (grouped by platform)object
lastRegisterAttimestamp of last registration (addition) to a walletdatetime
firstRegisterAttimestamp of first registration (addition) to a walletdatetime
lastUnregisterAttimestamp of last deregistration (removal) from a walletdatetime
firstUnregisterAttimestamp of first deregistration (removal) from a walletdatetime
createdAtdatetime
updatedAtdatetime
deletedAtdatetime

Dynamic data

Dynamic data object example:

{
  "firstName": "Tomáš",
  "lastName": "Jedno"
}

Dynamic data consists of variable values that, together with the template and images, make up the content of the pass.

Dynamic images

Dynamic images object example:

{
  "images": {
    "logo": "id-of-logo-image",
    "icon": "id-of-image",
    "strip": {
      "cs": "id-of-image-for-czech",
      "sk": "id-of-image-for-slovak",
      "en": "id-of-image-for-english"
    },
    "background": "id-of-image",
    "footer": "id-of-image",
    "thumbnail": "id-of-image"
  }
}

The images object stored in a pass overrides the images object stored in a template.

Do not specify an images object if you want to use the one from the template.

Create pass

Create a single pass.

Request

curl -X POST '<API_URL>/v1/pass' \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '{"dynamicData":{"qrcode":"12345678","fullName":"Mr. Tomáš Dvě","cardNumber":"12345678"},"dynamicImages":{"logo":"id-of-logo-image","icon":"id-of-image","strip":{"cs":"id-of-image-for-czech","sk":"id-of-image-for-slovak","en":"id-of-image-for-english"},"background":"id-of-image","footer":"id-of-image","thumbnail":"id-of-image"},"templateId":"id-of-template"}'
var http = require("https");

var options = {
  method: "POST",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(
  '{"dynamicData":{"qrcode":"12345678","fullName":"Mr. Tomáš Dvě","cardNumber":"12345678"},"dynamicImages":{"logo":"id-of-logo-image","icon":"id-of-image","strip":{"cs":"id-of-image-for-czech","sk":"id-of-image-for-slovak","en":"id-of-image-for-english"},"background":"id-of-image","footer":"id-of-image","thumbnail":"id-of-image"},"templateId":"id-of-template"}',
);

req.end();

POST <API_URL>/v1/pass

Body

NameNoteRequiredType
dynamicDatavalidated against template’s dynamicDataJsonSchema (default null)Noobject
dynamicImagesobject with image IDs (default null)Noobject
expirationDateend of the pass validityNodatetime
templateIdYesstring

Response

Returns Pass.

Read pass

Pass details.

Request

curl -X GET '<API_URL>/v1/pass/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/pass/:id

Path parameter

NameNote
idpass ID

Response

Returns Pass.

Patch pass

Patch an existing pass by updating only the specified properties.

PATCH is the recommended way to update a pass in most cases. It preserves all unspecified data, which makes it safer when multiple systems or integrations update different parts of the same pass. For example, one integration can update customer data while another updates loyalty points or images without overwriting each other’s fields.

Use PUT only when you want to replace the pass data with a complete representation.

Pass before patching

{
  "id": "id-of-pass",
  "templateId": "id-of-template",
  "dynamicData": {
    "qrcode": "12345678",
    "fullName": "Mr. Tomáš Jedno",
    "cardNumber": "12345678"
  },
  "dynamicImages": {
    "logo": "id-of-logo-image",
    "icon": "id-of-icon-image",
    "strip": "id-of-strip-image",
    "background": "id-of-image",
    "footer": "id-of-image",
    "thumbnail": "id-of-image"
  },
  "voided": false
}

To delete a property, set its value to null.

Request

Patch pass

curl -X PATCH '<API_URL>/v1/pass/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '{"dynamicData":{"fullName":"Mr. Tomáš Tři"},"dynamicImages":{"strip":{"cs":"id-of-image-for-czech","en":"id-of-image-for-english"}},"templateId":"id-of-another-template"}'
var http = require("https");

var options = {
  method: "PATCH",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(
  '{"dynamicData":{"fullName":"Mr. Tomáš Tři"},"dynamicImages":{"strip":{"cs":"id-of-image-for-czech","en":"id-of-image-for-english"}},"templateId":"id-of-another-template"}',
);

req.end();

PATCH <API_URL>/v1/pass/:id

Body

NameNoteRequiredType
dynamicDatavalidated against template’s dynamicDataJsonSchemaNoobject
dynamicImagesobject with image IDsNoobject
templateIdNostring
expirationDateend of the pass validityNodatetime
voidedNoboolean

Response

Patched pass

{
  "id": "id-of-pass",
  "templateId": "id-of-another-template",
  "dynamicData": {
    "qrcode": "12345678",
    "fullName": "Mr. Tomáš Tři",
    "cardNumber": "12345678"
  },
  "dynamicImages": {
    "logo": "id-of-logo-image",
    "icon": "id-of-icon-image",
    "strip": {
      "cs": "id-of-czech-image",
      "en": "id-of-english-image"
    },
    "background": "id-of-image",
    "footer": "id-of-image",
    "thumbnail": "id-of-image"
  },
  "voided": false
}

Returns the JSON object described in the Pass section.

Replace pass

PUT replaces the pass data with the provided request body. Use it when you intentionally want to send the complete desired state of the pass. For most partial updates, prefer Patch pass, because PATCH preserves unspecified properties and is safer when multiple integrations update different data.

If templateId is changed, the dynamic data must validate against the JSON schema stored with the new template.

Request

curl -X PUT '<API_URL>/v1/pass/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '{"dynamicData":{"qrcode":"12345678","fullName":"Mr. Tomáš Dvě","cardNumber":"12345678"},"dynamicImages":{"logo":"id-of-logo-image","icon":"id-of-image","strip":{"cs":"id-of-image-for-czech","sk":"id-of-image-for-slovak","en":"id-of-image-for-english"},"background":"id-of-image","footer":"id-of-image","thumbnail":"id-of-image"},"templateId":"id-of-template"}'
var http = require("https");

var options = {
  method: "PUT",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(
  '{"dynamicData":{"qrcode":"12345678","fullName":"Mr. Tomáš Dvě","cardNumber":"12345678"},"dynamicImages":{"logo":"id-of-logo-image","icon":"id-of-image","strip":{"cs":"id-of-image-for-czech","sk":"id-of-image-for-slovak","en":"id-of-image-for-english"},"background":"id-of-image","footer":"id-of-image","thumbnail":"id-of-image"},"templateId":"id-of-template"}',
);

req.end();

PUT <API_URL>/v1/pass/:id

Path parameter

NameNoteRequired
idYes

Body

NameNoteRequiredType
dynamicDatavalidated against template’s dynamicDataJsonSchema (default null)Noobject
dynamicImagesobject with image IDs (default null)Noobject
templateIdYesstring
expirationDateend of the pass validityNodatetime
voidedNoboolean

Response

Returns Pass.

Delete pass

Mark a pass as deleted and set the voided property to true. All pass data (dynamicData) is removed from the pass.

Request

curl -X DELETE '<API_URL>/v1/pass/:id' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "DELETE",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

DELETE <API_URL>/v1/pass/:id

Path parameter

NameNote
idID of pass

Response

Returns Pass.

List pass

Request

curl -X GET '<API_URL>/v1/pass?page=1&limit=100' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?page=1&limit=100",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/pass

Query parameters

NameNoteDefaultRequired
limitpaging limit (max 1000)100No
pagepage number1No
whereURL-encoded JSON query (see Querying)No
order(see Ordering)No
orderBy(see Ordering)No

Response

Response:

{
  "limit": 1000,
  "page": 1,
  "totalCount": 1,
  "data": [
    {
      "id": "id-of-pass",
      "url": "https://...",
      "templateId": "id-of-template",
      "dynamicData": {
        "qrcode": "12345678",
        "fullName": "Mr. Tomáš Dvě",
        "cardNumber": "12345678"
      },
      "dynamicImages": {
        "logo": "id-of-logo-image",
        "icon": "id-of-image",
        "strip": {
          "cs": "id-of-image-for-czech",
          "sk": "id-of-image-for-slovak",
          "en": "id-of-image-for-english"
        },
        "background": "id-of-image",
        "footer": "id-of-image",
        "thumbnail": "id-of-image"
      },
      "voided": false,
      "devices": null,
      "lastRegisterAt": null,
      "firstRegisterAt": null,
      "lastUnregisterAt": null,
      "firstUnregisterAt": null,
      "updatedAt": "2017-11-06T13:21:31.815Z",
      "createdAt": "2016-10-10T21:48:01.565Z",
      "deletedAt": null
    }
  ]
}

Response body

NameNoteType
limitpage sizenumber
pagereturned pagenumber
totalCounttotal count of recordsnumber
dataarray of passesarray

Batch pass

The batch size is limited to 1000 unique passes. The batch may be processed asynchronously. Each ID can be used only once per batch. The service always returns an HTTP 200 status code. The status of each individual operation is provided through the status property in the returned data, preserving order.

Request

curl -X POST '<API_URL>/v1/pass/batch' \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '[{"method":"POST","data":{"templateId":"YourtemplateId","dynamicData":{"property":"..."},"dynamicImages":{"logo":"..."}}},{"method":"GET","id":"id-of-pass"},{"method":"PUT","id":"id-of-pass","data":{"id":"id-of-pass","templateId":"YourtemplateId","dynamicData":{"property":"..."},"dynamicImages":{"logo":"..."}}},{"method":"DELETE","id":"id-of-pass"}]'
var http = require("https");

var options = {
  method: "POST",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/batch",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(
  '[{"method":"POST","data":{"templateId":"YourtemplateId","dynamicData":{"property":"..."},"dynamicImages":{"logo":"..."}}},{"method":"GET","id":"id-of-pass"},{"method":"PUT","id":"id-of-pass","data":{"id":"id-of-pass","templateId":"YourtemplateId","dynamicData":{"property":"..."},"dynamicImages":{"logo":"..."}}},{"method":"DELETE","id":"id-of-pass"}]',
);
req.end();

POST <API_URL>/v1/pass/batch

Body

JSON-encoded array of objects with the following structure:

NameNoteRequiredType
methodGET/POST/PUT/DELETEYesstring
idonly for GET, PUT and DELETEstring
datarequest dataonly for POST and PUTobject

Response

Response:

[
  {
    "status": {
      "code": 201,
      "message": "created"
    },
    "data": {
      "id": "id-of-pass",
      "templateId": "YourtemplateId",
      "dynamicData": {
        "property": "..."
      },
      "dynamicImages": {
        "logo": "..."
      }
    }
  },
  {
    "status": {
      "code": 200,
      "message": "ok"
    },
    "data": {
      "templateId": "YourtemplateId",
      "id": "id-of-pass",
      "dynamicData": {
        "property": "..."
      },
      "dynamicImages": {
        "logo": "..."
      }
    }
  },
  {
    "status": {
      "code": 200,
      "message": "ok"
    },
    "data": {
      "id": "id-of-pass",
      "templateId": "YourtemplateId",
      "dynamicData": {
        "property": "..."
      },
      "dynamicImages": {
        "logo": "..."
      }
    }
  },
  {
    "status": {
      "code": 200,
      "message": "ok"
    },
    "data": {
      "id": "id-of-pass",
      "templateId": "YourtemplateId",
      "dynamicData": {
        "property": "..."
      },
      "dynamicImages": {
        "logo": "..."
      }
    }
  }
]

Returns a JSON-encoded array of responses.

PropertyNote
statusobject with message and code properties
data

Anonymize pass

Pass before updating

{
  "id": "id-of-pass",
  "templateId": "id-of-template",
  "dynamicData": {
    "name": "Batman",
    "realName": "Bruce Wayne"
  },
  "voided": false
}

You can anonymize a pass by replacing or patching the pass resource with anonymized data or by deleting the data altogether. In both cases, the data is no longer stored in Yourpass. Therefore, the process is irreversible.

Patch pass

Patch request

curl -X PATCH '<API_URL>/v1/pass/:id?anonymize=true' \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '{"dynamicData":{"realName":"unknown"}}'
var http = require("https");

var options = {
  method: "PATCH",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id?anonymize=true",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write('{"dynamicData":{"realName":"unknown"}}');

req.end();

You can patch an existing pass, overriding only the specified properties.

Patch response

{
  "id": "id-of-pass",
  "templateId": "id-of-template",
  "dynamicData": {
    "name": "Batman",
    "realName": "unknown"
  },
  "voided": false
}

Replace pass

Update request

curl -X PUT '<API_URL>/v1/pass/:id?anonymize=true' \
     -H 'authorization: Bearer <ACCESS_TOKEN>' \
     -H 'content-type: application/json' \
     -d '{"dynamicData":{},"templateId":"id-of-template"}'
var http = require("https");

var options = {
  method: "PUT",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id?anonymize=true",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
    "content-type": "application/json",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write('{"dynamicData":{},"templateId":"id-of-template"}');

req.end();

You can also update the pass, replacing all data with the provided data. Setting dynamicData to an empty object deletes all keys within it.

Update response

{
  "id": "id-of-pass",
  "templateId": "id-of-template",
  "dynamicData": {},
  "voided": false
}

If there is no dynamicData, a fallback will be used when rendering the pass.

General

Paging

curl -X GET '<API_URL>/v1/pass?page=1&limit=100' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?page=1&limit=100",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/pass?page=1&limit=100

Query parameters

NameNoteDefaultRequired
pagepage number1No
limitpage size (max 1000)100No

Response

Paged list response

{
  "data": [],
  "limit": 100,
  "page": 1,
  "totalCount": 0
}

Ordering

Ordering/sorting of resources.

List pass ordered by updatedAt

curl -X GET '<API_URL>/v1/pass?order=asc&orderBy=updatedAt' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?order=asc&orderBy=updatedAt",
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();

GET <API_URL>/v1/pass?order=asc&orderBy=updatedAt

Query parameters

NameNoteRequired
orderasc/descNo
orderByqueried object scalar propertyNo

Querying

Querying/filtering of resources.

GET <API_URL>/v1/pass?where={"voided":{"$eq":true}}

List of voided passes created in July 2017

curl -X GET '<API_URL>/v1/pass?where={"voided":{"$eq":true},"createdAt":{"$gte":"2017-07-01","$lt":"2017-08-01"}}' \
     -H 'authorization: Bearer <ACCESS_TOKEN>'
var http = require("https");

var where = {
  voided: { $eq: true },
  createdAt: { $gte: "2017-07-01", $lt: "2017-08-01" },
};

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?where=" + encodeURIComponent(JSON.stringify(where)),
  headers: {
    authorization: "Bearer <ACCESS_TOKEN>",
  },
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();
OperatorDescription
{"$gt": 6}> 6
{"$gte": 6}>= 6
{"$lt": 10}< 10
{"$lte": 10}<= 10
{"$ne": null}!= null
{"$eq": null}= null
{"$in": [1, 2]}IN [1, 2]
{"$notIn": [1, 2]}NOT IN [1, 2]
{"$like": "%hat%"}LIKE ‘%hat%’
{"$notLike": "%hat"}NOT LIKE ‘%hat’
{"$all": [5, 3]}@> [5, 3]

If the $like or $notLike operator is provided without a % symbol, it behaves like $eq or $ne, respectively.

Type definitions

datetime

Datetime fields are of type string and their format is defined by RFC3339.

All fields that expect a date as input must adhere to this specification, including dynamic data values that will be used in these fields.

Pass distribution

A pass can be distributed directly (e.g. as an email attachment) in pkpass format or through a link to our servers.

Get pass

Request

Link to distribute pass

<a href="<DISTRIBUTION_URL>/:id?tag=someTag">Get pass</a>

GET <DISTRIBUTION_URL>/:id

Path parameters

NameNoteRequired
idpass IDYes

Query parameters

NameNoteRequired
tagtag your distribution channels; can be used multiple times (<DISTRIBUTION_URL>/:id?tag=rollup&tag=entrance)No
formatdistribution format [pkpass/pdf/barcode/qrcode]No

Note:

Formats

NameNote
pkpasspass in the pkpass format for wallet applications supporting it
pdfprintable alternative of pkpass
barcodereturns SVG of the barcode in the pass
qrcodereturns an SVG-encoded QR code with a link to the pass preview (no format)

Response

Returns a pass to the end-user in the specified format. If no format is supplied and the device supports pkpass, it is returned in this format. Otherwise, an HTML preview is shown, which includes action buttons to download the pass. This service also collects statistical information about pass downloads and previews.

This service can be used only with distributable templates (i.e. the distributable flag is set to true).

The endpoint can be used in two ways:

Example usage in HTML as link:

<a href="<ISSUE_URL>/:id"> Get pass </a>

Example usage in HTML as image:

<img src="<ISSUE_URL>/:id?format=qrcode" />

Request

GET <ISSUE_URL>/:id or GET <ISSUE_URL>/:id?format=qrcode

Path parameters

NameNoteRequired
idtemplate IDYes

Query parameters

NameNoteRequired
formatif you set format to qrcode, an SVG-encoded QR code is generated with a link that issues a new passNo

Response

Without format parameter

A new pass is created and the end-user is redirected to Get pass. The redirect URL does not contain the format parameter, which means that either pkpass is downloaded or the user is presented with an HTML preview.

With qrcode format

No pass is created, only an SVG QR code is generated. The QR code contains an address back to this endpoint without the format parameter. When a user scans the QR code, they visit <ISSUE_URL>/:id, which generates a new pass and redirects them to Get pass, as described above.

Webhooks

Four kinds of webhooks are currently supported:

  1. device registration (pkpass)
  2. device unregistration (pkpass)
  3. user add (Google Wallet)
  4. user delete (Google Wallet)

PKPass (Apple Wallet) and Google Wallet are different technologies that provide different mechanisms for engagement tracking. For PKPass, we communicate with end-user devices directly and each device registers with us directly. With Google Wallet, we can determine whether the pass is currently added to Google Wallet, but we cannot verify how many devices are affected. A user with no Android devices can still add their passes to Google Wallet via the web interface.

The webhook service expects a successful response (HTTP status code 2xx) within 10 seconds. If your service does not respond in time or does not return one of the status codes mentioned above, the event is marked as “undelivered”. An undelivered event is retried with exponential backoff (this backoff is configurable). All subsequent messages are postponed until the failed one succeeds. If the number of retries reaches the limit, the event is discarded.

By default, the limit is 15 retries with exponential backoff using the formula 10 × 1.5^n in seconds, where n is the retry number.

The only currently supported authentication method is an API key (using the X-API-Key header) with the value of your choice.

Webhooks need to be configured manually. Please contact Yourpass support and provide the following information:

Example:

Project ID: 00000000-0000-0000-0000-000000000000
Webhook URL for device registration: https://example.com/webhook/yourpass?event=register
Webhook URL for device unregistration: https://example.com/webhook/yourpass?event=unregister
Webhook URL for user add: https://example.com/webhook/yourpass?event=gw_add
Webhook URL for user delete: https://example.com/webhook/yourpass?event=gw_delete

Device registration

Sent whenever the device registers to receive push notifications for the wallet pass.

{
  "passId": "00000000-0000-0000-0000-000000000000",
  "timestamp": "2006-01-02T15:04:05.999Z",
  "deviceCount": 2,
  "wallet": "ios_wallet"
}

Properties

NameNoteType
passIdstring
timestampdatetime
deviceCountnumber of devices registered with this pass, including the event that resulted in this webhook payloadnumber
wallettype of wallet [ios_wallet/android_yourwallet/android_pass2u/android_attido/android_walletpasses/unknown]string

Device unregistration

{
  "passId": "00000000-0000-0000-0000-000000000000",
  "timestamp": "2006-01-02T15:04:05.999Z",
  "deviceCount": 0,
  "wallet": "ios_wallet"
}

Properties

NameNoteType
passIdstring
timestampdatetime
deviceCountnumber of devices registered with this pass, including the event that resulted in this webhook payloadnumber
wallettype of wallet [ios_wallet/android_yourwallet/android_pass2u/android_attido/android_walletpasses/unknown]string

User add

{
  "passId": "00000000-0000-0000-0000-000000000000",
  "timestamp": "2006-01-02T15:04:05.999Z",
  "userCount": 1
}

Properties

NameNoteType
passIdstring
timestampdatetime
userCountnumber of user accounts that have added this pass to Google Walletnumber

User delete

{
  "passId": "00000000-0000-0000-0000-000000000000",
  "timestamp": "2006-01-02T15:04:05.999Z",
  "userCount": 0
}

Properties

NameNoteType
passIdstring
timestampdatetime
userCountnumber of user accounts that have added this pass to Google Walletnumber