Profile service endpoints¶
- For general information see How to work with the profile service.
- Technical definitions of each API, sample code, test UI and Open API definitions to download you can find in the developer portal.
-> developer.discover.swiss/apis
General headers¶
Header Name | Type | Description |
---|---|---|
Ocp-Apim-Subscription-Key | string | Appropriate subscription key you can get in the developer portal |
Accept-Timezone | string | Supply a TimeZone id property acquired from Infocenter /timezones route in order to get data with desired time offset. The default is *UTC. |
Token and helpers¶
creates tokens and main profile objects
url | verb | request parameters | response |
---|---|---|---|
/token | POST | grant_type max_refresh_lifetime refresh_token |
ProfileToken Response If susccessful this endpoint always retuns a new token to access the resulting profile. |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQcm9maWxlSWQiOiIyZDk5ZThlOS03ODJhLTQ4ZWEtODRiNi0zYzdhYTRkMjEyYzQiLCJJc0d1ZXN0IjoiVHJ1ZSIsIm5iZiI6MTU5MjIxNzEwNiwiZXhwIjoxNTkyMjIwNzA2LCJpYXQiOjE1OTIyMTcxMDZ9.4qFf7YYkovASjeiqgtFQTMa-HqmAf_Snnu97sVx3l3Y",
"tokenType": "Bearer",
"expiresIn": 1592220706,
"expiresInDate": "2020-06-15T11:31:46+00:00",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJSZWZyZXNoSWQiOiIyZDk5ZThlOS03ODJhLTQ4ZWEtODRiNi0zYzdhYTRkMjEyYzQiLCJuYmYiOjE1OTIyMTcxMDYsImV4cCI6MTU5MjMwMzUwNiwiaWF0IjoxNTkyMjE3MTA2fQ.z16y-IlVsIgkhMwk1BkOo_5FupBJT8axIPIhBX3NuE8"
}
Info
There can be several different valid tokens for the same profile with different expiration date.
Request parameters
Name | value |
---|---|
grant_type | see below |
max_refresh_lifetime | wished refresh token lifetime in days. |
refresh_token | the refresh token which was delivered within a past token reference |
grant_type¶
grant_type | description | remarks |
---|---|---|
guest | creates a new guest- Person object in the profile. | If there is a profile-ID present in the request header it will return a BadRequest-Error |
authorization_header | returns a new profile token to an existing profile based on the Authorization header or creates a new Person object in the profile, copies azure B2C data into it and returns a token for the profile. |
|
authorization_header + valid ProfileToken-header |
Adds the Azure B2C data to the existing profile. | If there is already a profile with the provided B2C ID, the 2 profiles are merged as described below (the old B2C profile survives) |
refresh_token | returns a new token response if the refresh token is valid |
max_refresh_lifetime¶
wished refresh token lifetime in days. This value should be set as low as possible.
There is an upper limit set by discover.swiss: 450 days
Tip
Not in all scenarios the same lifetime of the refresh token makes sense. For client apps a longer lifetime is better so the user is still logged in even after several month of not using the App. But on web application this is a more serious security issue and the refresh token should only be valid for the duration of an expected user "session".
refresh_token¶
The refreshToken from one of tha past token request-responses.
Warning
If you are using guest profiles without authentication: Once the refresh token has expired you can not get a new one nor a new profile token.
Merge profiles A → B¶
A gets merged into B → B survives
- orders and tickets: move all from A to B (all objects from A get the profileID of B)
- parties: move all from A to B (all objects from A get the profileID of B)
- PartnerData: move all from A to B (all objects from A get the profileID of B)
But if there is partnerdata existing with the same name-property the object of B survives and the one from A gets deleted - delete person A
Person / me¶
url | verb | request | response | description |
---|---|---|---|---|
/me | GET | - | Person | returns the person-data of the current profile |
update me | /me | PATCH | Person or some properties of it |
Person |
Info
There is no POST nor PUT to replace or create the compete object. The logic always gets the existing object and applies changes to it.
Party / group of fellow travelers¶
Data is selected based on the profile token. If the profile is linked to a B2C account a valid, suitable authorization token must be present as well.
url | verb | request | response | description |
---|---|---|---|---|
/parties | GET | - | Party[] | Gets all parties (groups) of the current user |
/parties/{identifier} | GET | identifier | Party | Gets one single party (group) |
/parties | POST | Party | Party | Creates party or returns BadRequest and validation messages |
/parties/{identifier} | PUT | Party | Party | Updates party or returns BadRequest and validation messages |
/parties/{identifier} | DELETE | - | - | remove party from data base |
Partner data / destination specific profile¶
Data is selected based on the profile token and the subscription key. If the profile is linked to a B2C account a valid, suitable authorization token must be present as well.
Partner data is linked to the partner's acronym. Access is checked by subscription key
Instead of an ID which is different for every profile a name (made of letters and numbers) is used to store different named-profiledata for each user. This allows for example to organize the data for each user /partnerdata/memberdata /partnerdata/preferences
url | verb | request | response | description |
---|---|---|---|---|
/partnerdata | GET | - | PartnerData[] | gets all groups of the current user |
/partnerdata/{name} | GET | name | PartnerData | gets one single group |
/partnerdata | POST | PartnerData | PartnerData | or returns BadRequest and validation messages |
/partnerdata/{name} | PUT | PartnerData | PartnerData | or returns BadRequest and validation messages |
/partnerdata/{name} | DELETE | - | - |
Order¶
Data is selected based on the profile token and the subscription key. If the profile is linked to a B2C account a valid, suitable authorization token must be present as well.
Orders are always read only for the client.
url | verb | request | response | description |
---|---|---|---|---|
Get all orders of a profile | /orders | GET | - | Order[] |
Get a single order | /orders/{orderNumber} | GET | orderNumber | Order |
Orderinfo download¶
Data is selected only by the orderToken which is passed to the e-mail flow. There is no authentication on this endpoint.
url | verb | request | response | description |
---|---|---|---|---|
/orderinfos/{orderToken} | GET | orderToken | OrderDownload |
orderDownload sample:
{
"orderNumber": "20-107699",
"orderDate": "2020-12-10T20:13:51.9800292+00:00",
"partnerAcronym": "discover.swiss",
"@id": "https://api.discover.swiss/test/profile/orders/20-107699",
"customer": {
"email": "ordetest@gmail.com",
"familyName": "Eggenberger",
"givenName": "Christian",
"gender": "Male",
"birthDate": "1967-12-07T00:00:00"
},
"orderStatus": "Fulfilled",
"priceCurrency": "CHF",
"totalAmount": 27.0,
"totalAmountCHF": 27.0,
"mailBodyToken": "https://discoverswistestbusiness.blob.core.windows.net/mailbodies/07dcc9fc-403b-42ca-8b59-6d15e5aa8844_20-107699.html",
"language": "de",
"ticket": [
{
"name": "SBB - ZVV Zürich Card 24 Stunden",
"product": {
"@id": "https://api.discover.swiss/test/info/products/SBB_zurichcard24",
"identifier": "SBB_zurichcard24"
},
"additionalType": "e-ticket",
"ticketNumber": "640374080",
"ticketTokenId": "256754788543",
"bookingNumber": "640374080",
"ticketToken": "https://discoverswistestbusiness.blob.core.windows.net/tickets/7c36341a-855a-4119-95b7-4b3ecff8eaa6_nr_256754788543.pdf",
"qrCodeToken": "https://discoverswistestbusiness.blob.core.windows.net/qrcodes/f26dd17b-ca36-454e-b65a-62adbaa9a743_nr_256754788543.png",
"htmlToken": "https://discoverswistestbusiness.blob.core.windows.net/htmls/f41ed5b1-034e-4db2-97c7-18fef39356e3_nr_256754788543.html",
"dateIssued": "2020-12-10T20:14:32.4031913+00:00",
"priceCurrency": "CHF",
"totalPrice": 27.0,
"underName": {
"givenName": "SBB",
"familyName": "Tester",
"birthDate": "1967-12-07T00:00:00"
},
"validFrom": "2020-12-29T09:00:00+00:00",
"validUntil": "2020-12-29T09:00:00+00:00"
}
],
"errorTicket": [
{
"name": "ZVV Zürich Card 24h",
"underName": {
"givenName": "## failure ##",
"familyName": "Problem",
"birthDate": "2001-02-18T00:00:00"
},
"validFrom": "2020-02-22T05:15:00+00:00",
"orderItemNumber": "20-100145-2"
}
]
}
Tickets¶
Data is selected based on the profile token and the subscription key. If the profile is linked to a B2C account a valid, suitable authorization token must be present as well.
They are always read only for the client.
url | verb | request | response | description |
---|---|---|---|---|
/tickets | GET | scope= - all - current - past |
Ticket[] | "current" is the default scope and delivers all active tickets. |
/tickets/{identifier} | GET | identifier | Ticket | |
/tickets/{identifier}/download | GET | identifier | Binary[] / File response | downloads the ticket as a file in the correct content type (PDF, jpg, ...) public transportation: QR code only - not full PDF |
/tickets/{identifier}/base64 | GET | identifier | string / base64 | Gets the content of the ticket as base64 encoded string. which is sometimes helpful to display in a client application. |
Info
public transportation: the download contains the QR code only - not the full PDF.
The full PDF is accessible through the url in the ticketToken property of the ticket object.
Business trail¶
url | verb | request | response | description |
---|---|---|---|---|
/businesstrail | POST | BusinessTrail | empty | Creates a new Business-trail entry or returns BadRequest and validation messages |
Terms¶
url | verb | request | response | description |
---|---|---|---|---|
/terms/{termCode} | GET | the code of the Term (s and conditions) | TermVersionCheck | Get term consent state. returns the current version of the term and information if it was accepted/rejected already |
/terms | POST | AcceptTermVersionRequest | TermVersionCheck | Accept/reject a termversion. Adds the term version to the Business Trail or returns BadRequest and validation messages. |
/anonymous/terms | POST | query-string: max_refresh_lifetime={ n } body: AcceptTermVersionRequest NO ACCESS TOKENS NEEDED |
ProfileToken Response | Accept/reject a termversion and create a guest account. This request combines the creation of a guest profile and a BusinessTrail entry and is intended to use to store cookie consents/dissent of a website without any kind of profile and authentication messages. |
Info
If the posts are executed several times there will be several entries, but that doesn't hurt.
The existence of the terms get's checked.