NAV
cURL Node.js

Introduction

The following document describes the usage of YourPass REST API. You will find useful references and examples for all the available endpoints.

Enviroment URLs

URL Production Sandbox
API_URL https://api.yourpass.eu https://pass.ysplay.cz/api
DISTRIBUTION_URL https://get.yourpass.eu https://pass.ysplay.cz/pass
ISSUE_URL https://issue.yourpass.eu https://pass.ysplay.cz/issue
CONSOLE_URL https://console.yourpass.eu https://pass-console.ysplay.cz

Headers

All endpoints expect the following headers unless otherwise noted

Name Value
Accept application/json
Content-Type application/json

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

Authentication

Yourpass web services are secured with JSON web tokens (JWT). All requests which require authorization must contain JWT in an Authorization header. JWT can be used to authenticate several request until the token expires.

OAuth2 - Resource Owner Password Credentials

This service allows obtaining the access token for reliable applications, which stores user’s credentials. For more details see RFC6794.

Request

Request:

curl --request POST \
  --url https://api.yourpass.eu/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

Name Note Required
Authorization Basic base64, where base64 is clientID:clientSecret encoded in to base 64. Yes
Content-type application/x-www-form-urlencoded Yes

Body

Name Note Required
grant_type Contains constant password for this oauth2 grand type Yes
username The user’s email Yes
password The user’s pasword Yes

Response

Response:

{
  "access_token": "supersecret2token.....",
  "expires_in": 21600,
  "token_type": "Bearer"
}
Name Note
access_token
expires_in seconds to expire
token_type

OAuth2 - Authorization Code Grant

This service allows delegate access rights to the third-party application. For more detail see RFC6749.

Process description

Get authorization code

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

Get access token with authorization code

POST /oauth2/token HTTP/1.1
Host:  <API_URL>
Authorization: Basic base64(clien_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 the refresh token

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

refresh_token={refresh_token}&
grant_type=refresh_token

Scopes:

Scope Description
pass.c pass create
pass.r pass read
pass.u pass update / pass patch
pass.d template delete
template.c template create
template.r template read
template.u template update / template patch
template.d template delete
image.c image create
image.r image read
image.u image update / image patch
image.d image delete

Authorize your API request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass",
  headers: {
    authorization: "Bearer <JWT_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 endpoints accept the token in the Authorization header.

Example:

Authorization: Bearer <JWT_TOKEN>

Project

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

Projects are used to organize templates, passes, images and other assets into groups. These entities can be filtered based on the project they belong to. User may be granted access to multiple projects or its subprojects.

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:

Name Note Type
id string
name string
type type of image [logo/icon/strip/footer/background/thumbnail] string
width computed width number
height computed height number
fileSize computed file size number
url string
projectId Project ID string
createdAt datetime
updatedAt datetime
deletedAt datetime

Sizes

Pass styles and relevant image types:

Pass style Supported images Note
Boarding pass logo, icon, footer
Coupon logo, icon, strip
Event ticket logo, icon, strip, background, thumbnail If you specify a strip image, do not specify a background image or a thumbnail.
Generic logo, icon, thumbnail
Store card logo, 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 the file encoding normalization.

Request

curl -X POST <API_URL>/v1/image \
     -H 'authorization: Bearer <JWT_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 <JWT_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

Name Note Required Type
url public url or data URL Yes string
name image name Yes string
type image type Yes string
projectId ID of project Yes string

Response

Returns Image.

Read image

Read an image.

Request

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

var options = {
  method: "POST",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/image/:id",
  headers: {
    authorization: "Bearer <JWT_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.end();

GET <API_URL>/v1/image/:id

Path parameters

Name Note Required Type
id Yes string

Response

Returns Image.

List image

Return a list of images. List does not contain all properties of an image (to retrieve all the image data use read image service). The list can be filtered and ordered using HTTP request query parameters.

Request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/image?page=1&limit=100",
  headers: {
    authorization: "Bearer <JWT_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.end();

GET <API_URL>/v1/image

Query parameters

Name Note Default Required
limit paging limit (max 1000) 100 No
page page number 1 No
where url 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": null,
      "deletedAt": null
    }
  ],
  "totalCount": 1,
  "page": 1,
  "limit": 1000
}

Response body

Name Note Type
data array of Images array
totalCount total count of records number
page retuned page number
limit page size number

Template

Represents template data model used for generating passes (PKPASS file).

{
  "id": "ID OF TEMPLATE",
  "name": "NAME OF TEMPLATE",
  "jsonTemplate": {
    "barcodes": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "format": {
              "type": "string",
              "value": "PKBarcodeFormatQR"
            },
            "altText": {
              "type": "string",
              "value": "BAR CODE ALT TEXT"
            },
            "message": {
              "type": "string",
              "value": "BAR CODE VALUE"
            },
            "messageEncoding": {
              "type": "string",
              "value": "UTF-8"
            }
          }
        }
      ]
    },
    "logoText": {
      "type": "string",
      "value": "LOGO TEXT MESSAGE"
    },
    "storeCard": {
      "type": "object",
      "properties": {
        "backFields": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "value": "FIELD_KEY"
                },
                "label": {
                  "type": "string",
                  "value": "LABEL OF BACKFIELD"
                },
                "value": {
                  "type": "string",
                  "value": "VALUE TEXT OF BACKFIELD"
                },
                "changeMessage": {
                  "type": "string",
                  "value": "CHANGE MESSAGE %@"
                },
                "attributedValue": {
                  "type": "string",
                  "value": "ATTRIBUTED VALUE OF BACKFIELD"
                }
              }
            }
          ]
        },
        "auxiliaryFields": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "value": "BJIqg3Vh-"
                },
                "label": {
                  "type": "string",
                  "value": "NAME"
                },
                "value": {
                  "type": "string",
                  "value": "#{firstName} #{lastName}"
                },
                "textAlignment": {
                  "type": "string",
                  "value": "PKTextAlignmentLeft"
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "value": "S1Dsg3Vnb"
                },
                "label": {
                  "type": "string",
                  "value": "MORE INFO"
                },
                "value": {
                  "type": "string",
                  "value": "CLICK 👇 ⓘ"
                },
                "changeMessage": {
                  "type": "string",
                  "value": ""
                },
                "textAlignment": {
                  "type": "string",
                  "value": "PKTextAlignmentRight"
                }
              }
            }
          ]
        }
      }
    },
    "labelColor": {
      "type": "string",
      "value": "rgb(255,205,123)"
    },
    "description": {
      "type": "string",
      "value": "DESCRIPTION"
    },
    "backgroundColor": {
      "type": "string",
      "value": "rgb(0,0,0)"
    },
    "foregroundColor": {
      "type": "string",
      "value": "rgb(255,255,255)"
    },
    "organizationName": {
      "type": "string",
      "value": "ORGANIZATION NAME"
    }
  },
  "dynamicDataJsonSchema": {
    "type": ["object", "null"],
    "title": "DynamicData",
    "description": "Dynamic data are data....",
    "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:

Name Note Type
id string
name string
jsonTemplate appearance definition, layout, fields, barcodes and other pass properties object
dynamicDataJsonSchema JSON Schema definition for validating dynamic data used on the pass object
projectId id of projects belongs to template string
certificateId id of certificate which is used for signing passes created with this template string
images object mapping image type to image id object
languages at least one language in ISO 639-1 format array
distributable allow distribution via issue link boolean
createdAt datetime
updatedAt datetime
deletedAt datetime

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 a specific start and end points.

BoardingPass

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 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 a generic key.

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

Generic

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

Fields

Relevances

Pass style Relevant date Relevant locations Relevance
Boarding pass Recommended. 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.
Coupon Not supported. Required if relevance information is provided. Interpreted with a small radius. Relevant if any location matches.
Event ticket Recommended. 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.
Generic Optional. 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 card Not supported. Required if relevance information is provided. Interpreted with a small radius. Relevant if any location matches.

Create template

Request

curl -X POST '<API_URL>/v1/template' \
     -H 'authorization: Bearer <JWT_TOKEN>' \
     -d '{"dynamicDataJsonSchema":{"type":["object","null"],"title":"DynamicData","properties":{}},"languages":["cs"],"jsonTemplate":{"description":{"type":"string","value":"Descripton"},"backgroundColor":{"type":"string","value":"rgb(0,0,0)"},"foregroundColor":{"type":"string","value":"rgb(255,255,255)"},"labelColor":{"type":"string","value":"rgb(255,255,255)"},"organizationName":{"type":"string","value":"Organization name"},"storeCard":{"type":"object","properties":{"headerFields":{"items":[{"properties":{"key":{"value":"aaa","type":"string"},"label":{"value":"Label","type":"string"},"value":{"value":"Value","type":"string"}},"type":"object"}],"type":"array"}}}},"projectId":"b7654e80-0b87-4c4c-a351-2fc55c86e9b9","certificateId":"fa5ee1fe-8693-4a5f-9b4d-31ddeb593f28","images":null,"name":"Example template 2"}'
var http = require("https");

var options = {
  method: "POST",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template",
  headers: {
    authorization: "Bearer <JWT_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.write(
  '{"dynamicDataJsonSchema":{"type":["object","null"],"title":"DynamicData","properties":{}},"languages":["cs"],"jsonTemplate":{"description":{"type":"string","value":"Descripton"},"backgroundColor":{"type":"string","value":"rgb(0,0,0)"},"foregroundColor":{"type":"string","value":"rgb(255,255,255)"},"labelColor":{"type":"string","value":"rgb(255,255,255)"},"organizationName":{"type":"string","value":"Organization name"},"storeCard":{"type":"object","properties":{"headerFields":{"items":[{"properties":{"key":{"value":"aaa","type":"string"},"label":{"value":"Label","type":"string"},"value":{"value":"Value","type":"string"}},"type":"object"}],"type":"array"}}}},"projectId":"b7654e80-0b87-4c4c-a351-2fc55c86e9b9","certificateId":"fa5ee1fe-8693-4a5f-9b4d-31ddeb593f28","images":null,"name":"Example template 2"}'
);

req.end();

POST <API_URL>/v1/template

Body

Name Note Required Type
dynamicDataJsonSchema JSON schema definiton of your dynamic data Yes object
languages Array of languages Yes array
jsonTemplate JSON with definition template Yes object
projectId id of project Yes string
certificateId id of certifcate Yes string
images object with images definition No object
name Example template Yes string

Response

Returns Template.

Read template

Request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template/:id",
  headers: {
    authorization: "Bearer <JWT_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());
  });
});

GET <API_URL>/v1/template/:id

Path parameter

Name Note
id ID of template

Response

Returns Template.

Update template

Request

curl -X PUT '<API_URL>/v1/template/:id' \
     -H 'authorization: Bearer <JWT_TOKEN>' \
     -d '{"dynamicDataJsonSchema":{"type":["object","null"],"title":"DynamicData","properties":{}},"languages":["cs"],"jsonTemplate":{"description":{"type":"string","value":"Descripton"},"backgroundColor":{"type":"string","value":"rgb(0,0,0)"},"foregroundColor":{"type":"string","value":"rgb(255,255,255)"},"labelColor":{"type":"string","value":"rgb(255,255,255)"},"organizationName":{"type":"string","value":"Organization name"},"storeCard":{"type":"object","properties":{"headerFields":{"items":[{"properties":{"key":{"value":"aaa","type":"string"},"label":{"value":"Label","type":"string"},"value":{"value":"Value","type":"string"}},"type":"object"}],"type":"array"}}}},"projectId":"b7654e80-0b87-4c4c-a351-2fc55c86e9b9","certificateId":"fa5ee1fe-8693-4a5f-9b4d-31ddeb593f28","images":null,"name":"Example template 2"}'
var http = require("https");

var options = {
  method: "PUT",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template/:id",
  headers: {
    authorization: "Bearer <JWT_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.write(
  '{"dynamicDataJsonSchema":{"type":["object","null"],"title":"DynamicData","properties":{}},"languages":["cs"],"jsonTemplate":{"description":{"type":"string","value":"Descripton"},"backgroundColor":{"type":"string","value":"rgb(0,0,0)"},"foregroundColor":{"type":"string","value":"rgb(255,255,255)"},"labelColor":{"type":"string","value":"rgb(255,255,255)"},"organizationName":{"type":"string","value":"Organization name"},"storeCard":{"type":"object","properties":{"headerFields":{"items":[{"properties":{"key":{"value":"aaa","type":"string"},"label":{"value":"Label","type":"string"},"value":{"value":"Value","type":"string"}},"type":"object"}],"type":"array"}}}},"projectId":"b7654e80-0b87-4c4c-a351-2fc55c86e9b9","certificateId":"fa5ee1fe-8693-4a5f-9b4d-31ddeb593f28","images":null,"name":"Example template 2"}'
);

req.end();

PUT <API_URL>/v1/template

Path parameter

Name Note
id ID of template

Body

Name Note Required Type
dynamicDataJsonSchema JSON schema definiton of your dynamic data Yes object
languages Array of languages Yes array
jsonTemplate JSON with definition template Yes object
projectId id of project Yes string
certificateId id of certifcate Yes string
images object with images definition No object
name Example template Yes string

Response

Returns Template.

List template

Request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template?page=1&limit=100",
  headers: {
    authorization: "Bearer <JWT_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.end();

GET <API_URL>/v1/template

Url parameters

Name Note Required
limit maximum returned records default 100 and maximum 1000 No
page returned page default 1 No
where Jurl 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": {}
    }
  ]
}
Name Note Type
data array of templates array
totalCount total count of records Number
page retuned page Number
limit page size Number

Push template

Send a push notification to all devices that have pass issued with this template. Device that receives push notification then checks for changes and fetches updated pass(es) if available.

Request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/template/:id/push",
  headers: {
    authorization: "Bearer <JWT_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());
  });
});

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

Path parameter

Name Note
id ID of template

Response

Returns empty json object or error.

Pass

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

{
  "id": "id-of-pass",
  "templateId": "id-of-template",
  "projectId": "id-of-project",
  "dynamicData": {
    "lastName": "Jedno",
    "fistName": "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:

Name Note Type
id string
templateId string
projectId string
dynamicData validated against template’s dynamicDataJsonSchema object
dynamicImages object mapping image type to image id object
expirationDate end of the pass validity datetime
voided enable to deactivate the pass (default false) boolean
devices number of active installations on devices (grouped by platform) object
lastRegisterAt timestamp of last registration (added) into wallet datetime
firstRegisterAt timestamp of first registration (added) into wallet datetime
lastUnregisterAt timestamp of last deregistration (removed) from wallet datetime
firstUnregisterAt timestamp of irst deregistration (removed) from wallet datetime
createdAt datetime
updatedAt datetime
deletedAt datetime

Dynamic data

Dynamic data object example:

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

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

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 within a pass overrides the images object stored within 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 <JWT_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 <JWT_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

Name Note Required Type
dynamicData validated against template’s dynamicDataJsonSchema (default null) No object
dynamicImages Object with image IDs (default null) No object
expirationDate end of the pass validity No datetime
templateId Yes string

Response

Returns Pass.

Read pass

Pass detail

Request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id",
  headers: {
    authorization: "Bearer <JWT_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.end();

GET <API_URL>/v1/pass/:id

Path parameter

Name Note
id pass ID

Response

Returns Pass.

Update pass

Update existing pass. 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 <JWT_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 <JWT_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

Name Note Required
id Yes

Body

Name Note Required Type
dynamicData validated against template’s dynamicDataJsonSchema (default null) No object
dynamicImages object with image IDs (default null) No object
templateId Yes string
expirationDate end of the pass validity No datetime
voided No boolean

Response

Returns Pass.

Delete pass

Mark pass as deleted and set voided property to true.

Request

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

var options = {
  method: "DELETE",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass/:id",
  headers: {
    authorization: "Bearer <JWT_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.end();

DELETE <API_URL>/v1/pass/:id

Path parameter

Name Note
id ID of template

Response

Returns Pass.

List pass

Request

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?page=1&limit=100",
  headers: {
    authorization: "Bearer <JWT_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.end();

GET <API_URL>/v1/pass

Url parameters

Name Note Default Required
limit paging limit (max 1000) 100 No
page page number 1 No
where url 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",
      "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

Name Note Type
limit page size number
page retuned page number
totalCount total count of records number
data array of passes array

Batch pass

The batch size is limited to 25 unique passes. Batch is processed asynchronously, each id can be used only once per batch. The service always returns an HTTP STATUS of 200, status for individual operations is provided via status property in the returned data.

Request

curl -X POST '<API_URL>/v1/pass/batch' \
     -H 'authorization: Bearer <JWT_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 <JWT_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 following structure:

Name Note Required Type
method GET/POST/PUT/DELETE Yes string
id only for GET, PUT and DELETE string
data request data only for POST and PUT object

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 JSON encoded array of responses

Property Note
status object with message and code properties
data

Patch pass

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
}

Patch an existing pass overriding only specified properties. To delete a property set its value to null.

Request

Patch pass

curl -X PATCH '<API_URL>/v1/pass/:id' \
     -H 'authorization: Bearer <JWT_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 <JWT_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

Name Note Required Type
dynamicData validated against template’s dynamicDataJsonSchema No object
dynamicImages object with image IDs No object
templateId No string
expirationDate end of the pass validity No datetime
voided No boolean

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-english"
    },
    "background": "id-of-image",
    "footer": "id-of-image",
    "thumbnail": "id-of-image"
  },
  "voided": false
}

Returns JSON object described in Pass section

Anonymize pass

Pass before update

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

Pass anonymization can be achieved by updating/patching the pass resource with anonymized data or deleting the data alltogether. 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' \
     -H 'authorization: Bearer <JWT_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",
  headers: {
    authorization: "Bearer <JWT_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 specified properties.

Patch response

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

Update pass

Update request

curl -X PUT '<API_URL>/v1/pass/:id' \
     -H 'authorization: Bearer <JWT_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",
  headers: {
    authorization: "Bearer <JWT_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();

Or you can update the pass, replacing all data with the provided. Setting dynamicData to empty object deletes all keys within.

Update response

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

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

General

Paging

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?page=1&limit=100",
  headers: {
    authorization: "Bearer <JWT_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.end();

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

Query parameters

Name Note Default Required
page page number 1 No
limit page size (max 1000) 100 No

Response

Paged list response

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

Ordering

List pass ordered by updatedAt

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

var options = {
  method: "GET",
  hostname: "<API_URL>",
  port: null,
  path: "/v1/pass?order=asc&orderBy=updatedAt",
  headers: {
    authorization: "Bearer <JWT_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.end();

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

Query parameters

Name Note Required
order asc/desc No
orderBy queried object scalar property No

Querying

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 <JWT_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 <JWT_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.end();
Operator Description
{"$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]

Status codes

Code Message Description
200 OK Your request was processed successfully
201 Created Instance has been created successfully
400 Bad Request Your request sucks
401 Unauthorized Your API key is wrong
403 Forbidden The request is for administrators only
404 Not Found The specified request or data could not be found
413 Request Entity Too Large The request is larger than the server is willing or able to process. Previously called “Request Entity Too Large”
500 Internal Server Error There was a problem with our servers. Try again later
503 Service Unavailable The service is temporarially offline for maintanance. Please try again later

Pass distribution

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

Get pass

Request

Link to distribute pass

<a href="&lt;DISTRIBUTION_URL&gt;/:id?tag=someTag">Get pass</a>

GET <DISTRIBUTION_URL>/:id

Path parameters

Name Note Required
id pass id Yes

Query parameters

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

Note:

Formats

Name Note
pkpass pass in the pkpass format for wallet applications suporting it
pdf printable alternative of pkpass
barcode returns svg of the barcode in the pass
qrcode returns svg encoded qrcode with link to the preview of pass (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.

The service can be used only on 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="&lt;ISSUE_URL&gt;/:id"> Get pass </a>

Example usage in html as image:

<img src="&lt;ISSUE_URL&gt;/:id?format=qrcode" />

Request

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

Path parameters

Name Note Required
id template id Yes

Query parameters

Name Note Required
format if you set format to qrcode, svg encoded qrcode is generated with a link to issue a new pass No

Response

Without format parameter

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 will be downloaded or the user will be presented with an HTML preview

With qrcode format

No pass is created, only an SVG qrcode is generated. The qrcode contains an address back to this endpoint without the format parameter; When a user scans the qrcode they will visit the <ISSUE_URL>/:id which will generate a new pass and redirect them to Get pass as stated above.