Using the Profiles on Demand API allows third-party applications to query profile information from Umbrella Faces after being authorized with OAuth2 authentication.
The interface is part of our standard web service offering and can be found in our swagger.yml documentation.
Preamble / General Notes
The Profiles on Demand API relies fully on the OAuth2 protocol to perform authentication and authorization to profiles. It is strongly suggested to get a general grasp of the OAuth 2.0 flows, specifically the Authorization Code and Client Credentials flows, before running any API related inquiries.
While the Profiles on Demand API does not currently support all data fields and entity types available in Umbrella Faces, the API is continuously being developed and extended. As a result, new data structures may be added to existing responses at any time without prior notice. It is therefore required to design a client application to only request information needed by the application as well as configure the application to not fail should there be additional (newly added) properties in the response.
Authentication
Application registration and certification
Third parties wishing to access data from Faces must provide the following details, which will be evaluated before any Oauth API can be accessed:
Field | Description |
---|---|
Application Name | Application name, which will be shown to the user |
Application Purpose | Short description of what the application wants to achieve using the Oauth2 enabled APIs |
Desired OAuth Scopes | OAuth Scopes requested by the application see Available OAuth Data-Scopes |
Desired OAuth Flow(s) | One or more OAuth flows, see Supported OAuth2 Flows By default you will be granted access to the Authorization Code flow, which requires user interaction to authorize your application, however depending on your applications purpose it may be possible to setup a different flow (For example to allow unlimited access to all profiles belonging to your own travel agency in case you’re implementing an in-house application) |
Umbrella will provide the application with a clientId and clientSecret to be used for development on our integration environment at https://hurricane.umbrellanet.ch/uf-test
Certification will be achieved by demonstrating the product accessing Faces using Oauth
Available OAuth Data-Scopes
Your application will be granted some or all of the following OAuth scopes for data access:
Scope | Description |
---|---|
api.profilesondemand.read | Access to the Profiles API (read only) |
api.profilesondemand.write | Access to the Profiles API (write) |
openid | Required scope when requesting an ID-Token for “Login using Faces” functionality |
agencyid | Optional scope to be included in and ID-Token. Please see the section Usage of an ID token within this document. |
Optional scope to be included in and ID-Token. Please see the section Usage of an ID token within this document. | |
profile | Optional scope to be included in and ID-Token. Please see the section Usage of an ID token within this document. |
Please let our friendly support-staff know which scopes you’ll be requiring in order to provide which desired functionality.
Supported OAuth2 Flows
Faces supports multiple Oauth2 grant flows, depending on the individual requirements of the client application. The following table lists possible flows:
Type | Description | Restrictions |
---|---|---|
Authorization Code | Allows an application to act on behalf of a (or multiple) specific user within Faces. The Authorization Code Flow requires the client application to open a popup-window where an user signs into Faces and explicitly allows access. Once Access has been granted, a refresh-token is issued which allows further access without additional human interaction. | Not all API operations may be available, depending on the authorization level of the user. (e.g. company data can not be queried or updated by a traveller) |
Implicit | Similar to the Authorization Code flow, with the difference that no refresh-token will be issued and thus only temporary access of maximum one hour is possible before re-confirmation is needed. | Same as for Authorization Code. |
Client Credentials | Currently allows a specific OAuth2 Client to be linked to a specific travel agency in Faces. No end-user interaction is required | ID-Tokens cannot be requested since the access is not tied to a specific user. |
Please let us know which OAuth flow you plan on supporting for your use case when requesting API credentials. If not otherwise specified, we’ll be supplying you with access to the Authorization Code flow.
Oauth2 Authorization Code Flow by example
Step 1: Request authorization code grant
The user is given a link to start the authorization process, including mandatory parameters
Parameter | Description |
---|---|
response_type=code | Specifies the application is requesting an authorization code grant (value = always “code”) |
client_id=CLIENT_ID | The clientId which has been setup for the application |
redirect_uri=CALLBACK_URL | Where Faces redirects the user after an authorization code is granted (full URI, including http:// https:// or other prefix) |
https://hurricane.umbrellanet.ch/uf-test/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL
Step 2: User authorizes the application
Upon clicking the link, the user must first login to Faces (unless they are already logged in). Then they will be prompted by the service to authorize or deny the application access.
An example authorization prompt may look like this:
Step 3: Application receives authorization code
If the user clicks "Authorize", Faces redirects to the application redirect URI which was specified in the request, along with an authorization code.
The redirect would look something like this:
https://your.application.com/callback?code=THE_AUTH_CODE
Step 4: Application requests refresh and access token
The application requests an access token from the API, by passing the authorization code along with authentication details using HTTP POST:
Parameter | Description |
---|---|
CLIENT_ID:CLIENT_SECRET | The clientId and clientSecret which has been setup for the application, sent as HTTP Basic authentication |
code=THE_AUTH_CODE | The authorization code received in step 3 |
redirect_uri=CALLBACK_URL | The same callback url as used in step 2 |
grant_type=authorization_code | Specifies that you are wanting to trade an authorization_code for a long-lived request token. |
# https://CLIENT_ID:CLIENT_SECRET@hurricane.umbrellanet.ch/uf-test/oauth/token?grant_type=authorization_code&code=THE_AUTH_CODE&redirect_uri=CALLBACK_URL curl -v -X POST \ -H "Content-type: application/x-www-form-urlencoded" \ -u client-id:client-secret \ -d "grant_type=authorization_code" \ -d "code=THE_AUTH_CODE" \ -d "redirect_uri=CALLBACK_URL" \ https://hurricane.umbrellanet.ch/uf-test/oauth/token
As a result, the application is granted short-lived access token used during API calls, as well as a long-lived refresh token which can be used for obtaining further access tokens:
{ "access_token": "eb0afd63-7ad3-4b0f-a3cb-bacbbf4cac7c", "token_type": "bearer", "refresh_token": "0561038e-02d3-48e4-a859-399acacad59c", "expires_in": 3599 }
Step 5: Get new access token
After the access token expires, a new one may be obtained similar to step 4:
# https://CLIENT_ID:CLIENT_SECRET@hurricane.umbrellanet.ch/uf-test/oauth/token?grant_type=refresh_token&refresh_token=REFRESH_TOKEN curl -v -X POST \ -H "Content-type: application/x-www-form-urlencoded" \ -u client-id:client-secret \ -d "grant_type=refresh_token" \ -d "refresh_token=REFRESH_TOKEN" \ https://hurricane.umbrellanet.ch/uf-test/oauth/token
As a result, a new access token will be issued. Our application may also issue a new refresh token in case the currently used one is due for expiration, which shall be stored upon reception and used from this point in time onwards.
Oauth2 Client Credentials Flow by example
When using the Client Credentials Flow, no user interaction is required, instead the authorization level of your application is directly configured within Umbrella Faces. As a result the Client Credentials Flow comprises of only a single step:
Step 1 out of 1: Get new access token
Whenever a new access token is needed (either because none is available or the old one has expired), a new one may be obtained by issuing a HTTP POST request to our token endpoint, supplying client_id and client_secret as HTTP Basic authentication, along with a grant_type of client_credentials:
# https://CLIENT_ID:CLIENT_SECRET@hurricane.umbrellanet.ch/uf-test/oauth/token?grant_type=client_credentials curl -v -X POST \ -H "Content-type: application/x-www-form-urlencoded" \ -u client-id:client-secret \ -d "grant_type=client_credentials" \ https://hurricane.umbrellanet.ch/uf-test/oauth/token
As a result, a new access token will be issued.
ID token
In addition(or instead) of our OAuth API scopes, we do also support scopes resulting in generation of an ID-Token, which will be returned in Step 4 as well as Step 5 of the Authorization flow.
If only an ID-Token is desired, the OAuth process may be called with response_type=token which will trigger the OAuth 2.0 Implicit flow and only generate a short-lived access token without providing a refresh token.
Scope | Description |
---|---|
openid | Required scope, triggers generation of an ID token containing the Faces-UUID of the profile in an “openid” attribute |
profile | Outputs the user profile in a “profile” attribute containing a displayname and (depending on availability) firstname / name / phone |
Outputs the users e-mail address as “email” attribute | |
agencyid | Outputs the UUID of the associated users travel agency (the main agency if access to multiple agencies is granted in case of an administrator) in the “agencyid” attribute of the token |
The ID-Token will be presented in form of a JSON Web Token and will be cryptographically signed using our Service Provider Certificate available at <faces_url>/saml/metadata,
i.e. https://hurricane.umbrellanet.ch/uf-test/saml/metadata
{ "access_token": "f88a7119-b585-4c9c-9867-88a40aae41f8", "token_type": "bearer", "refresh_token": "bab32afe-acf8-4a8e-ba7c-ed567daa0ee4", "expires_in": 3599, "scope": "email openid profile", "id_token": "eyJhbGciOiJSUzI1NiJ9.eyJvcGVuaWQiOiIzZDkyMDVjYS1mMjY0LTRhZDgtYjFhYy1lNjQ1NTU3ZWFhOTkiLCJwcm9maWxlIjp7ImZpcnN0bmFtZSI6IlJlbW8iLCJwaG9uZSI6Iis0MTQ0MTIzNDU2NyIsImRpc3BsYXluYW1lIjoiSGVyciBSZW1vIFLDpGJlciIsIm5hbWUiOiJSw6RiZXIifSwiZW1haWwiOiJyZW1vLnRlc3RAdW1icmVsbGEuY2gifQ.ni2_4eszvqV5JgWBzJNmQ8jq225_7i-TiMAFzSGDSkPt6J5CTPSQF5wsq_Og5tOzd39nybGfwRzDyAkAOWinU2_djUv58gMx095U77ccSlSVYca6sn8t8WL62v8AOPSO9h8ok52nQpjtZFWcni4KABlcCKd_feT_5KjAmsRQwf7NZ0gqkoP3Y4Ymo454N8ezu822slF-ub4UdA1VBHDZuCJtQWbdsT2Cfep1NWRf3by_uP2s6yxHcHmQ0R_kYwXKMW2SbxyGo821cN-sxXYmppb4ipDtPKC7ANUYc5wZQ2Gp0gAenMIfxooz0njkEWKKMq3pwZWNJnWHDwVsluqI_w" }
Decoded ID-Token
The following extract depicts a decoded ID-Token from the value of "id_token" in the response above
{ "openid": "3d9205ca-f264-4ad8-b1ac-e645557eaa99", "profile": { "firstname": "Remo", "phone": "+41441234567", "displayname": "Herr Remo Räber", "name": "Räber" }, "email": "remo.test@umbrella.ch" }
Profiles API
Search company profile
Scope | api.profilesondemand.read |
---|---|
Endpoint | api/v1/profiles/companies |
Request method | GET |
Allows searching through a paged list of company profiles. This API can be used to narrow-down the traveler profile search by company.
Parameters
Name | Description | Validation |
---|---|---|
q | Freetext query for finding matching profiles | Required parameter |
page | Current page within the result set, starts at 0 | Optional, number >= 0 |
pageSize | Maximum number of results per page. Default 10 | Optional, number > 0 and <= 100 |
includeDetails | Specify whether the search response should include detailed profile data | Boolean value: true or false Optional, default: false |
detailSections | Specify additional profile areas to be returned if includeDetails is set to true. Only explicitly specified sections will be included. | Only the following sections are currently supported:
|
curl -v -H "Authorization: Bearer <token>" https://hurricane.umbrellanet.ch/uf-test/api/v1/profiles/companies?q=acme&page=0&pageSize=10
Get company profile
Scope | api.profilesondemand.read |
---|---|
Endpoint | api/v1/profiles/company/<uuid> |
Request method | GET |
Retrieves the details of a single company profile.
Parameters
Name | Description | Validation |
---|---|---|
<uuid> | The UUID of the profile to retrieve | Required parameter |
sections | Areas of the profile to be returned. May be used to reduce the amount of data transferred, if only specific information is required All sections will be dumped if omitted. Please identify the relevant sections for your application during development and use a restricted information subset before moving to production. | Optional |
curl -v -H "Authorization: Bearer <token>" \ https://hurricane.umbrellanet.ch/uf-test/api/v1/profiles/company/b9321d7e-9d72-4e80-ac49-d3aa38169175?sections=CONTACT_DATA,MEMBERSHIPS
Company profile sections overview
The following sections are currently available in accordance with our Swagger schema definition:
Name | Contents |
---|---|
AGNCY_INFO | Agency information:
|
CONTACT_DATA | Company contact data:
|
MEMBERSHIPS | Corporate alliance Memberships
|
GENERIC_VALUES | Values (where filled) from the generic setup, output as key-value pairs where the key is the fieldname and the value is the value entered on the profile. |
Create new company profile
Scope | api.profilesondemand.write |
---|---|
Endpoint | api/v1/profiles/company |
Request method | POST |
Create a new company profile
curl -v -X POST \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ --data '{ "externalNr": "1337", "name": "Umbrella Organisation U+O AG", "shortname": "UMBRELLA", "data": { "contact": { "street": "Binzstrasse 33", "zipCode": "8620", "place": "Wetzikon", "countryCode": "CH" }, "genericValues": { "costCenter": "1230A" }, "agency": { "uuid": "52b166c5-4990-49bb-b1f1-d3aa38169175" } } }' https://hurricane.umbrellanet.ch/uf-test/api/v1/profiles/company
Example response
The profile, including any sections populated by the request, will be reported back, including the newly generated UUID - see Get company profile
Implementation notes
The data structure is the same as is output in Get company profile with the following exceptions:
Company profile UUID cannot be provided in the JSON
For creating of a new profile, the following required properties must always be populated:
name
shortname
Faces will apply default validation logic as seen on our Web UI and CSV interfaces and will report validation errors to the caller without saving the profile.
Update existing company profile
Scope | api.profilesondemand.write |
---|---|
Endpoint | api/v1/profiles/company/<uuid> |
Request method | PATCH |
Updates (part of) the details of a single company profile.
Parameters
Name | Description | Validation |
---|---|---|
<uuid> | The UUID of the profile to update | Required parameter |
curl -v -X PATCH \ -H "Authorization: Bearer <token>" \ --data '{ "externalNr": "0815", "name": "ACME Incorporated", "shortname": "ACME-INC”, "data": { "memberships": { "airline": [ { "alliance": "LH", "memberNumber": "DEMODEMO123", "type": "SPECIAL_KEYWORD" } ] } } }' https://hurricane.umbrellanet.ch/uf-test/api/v1/profiles/company/b9321d7e-9d72-4e80-ac49-d3a
Implementation notes
Depending on the authorization level of the caller, it may not be possible to edit certain properties. Changes to unmodifiable properties will be silently ignored if sent.
Callers should include only the properties they wish to edit in the PATCH request. Due to underlying synchronization logic to third party systems, it is required to perform all profile modifications within one single PATCH call (I.e. do not first edit the shortname, then add a membership code as two separate API calls).
The following logic is applied when editing collections, such as memberships to allow for modification of single elements within the collection without having separate API calls for that purpose:
If an “uuid” is supplied, the corresponding collection element is being modified
If there is no matching element with the given UUID, the update is ignored
In order to remove a collection item, it’s UUID is supplied, along with a property “_operation”, which is set to “remove”
In order to remove genericValues from a profile, please include the fieldname but set the field content to empty or null.
Delete company profile
Scope | api.profilesondemand.write |
---|---|
Endpoint | api/v1/profiles/company/<uuid> |
Request method | DELETE |
Delete a single company profile (along with all associated traveler profiles) from Faces as well as all downline systems.
Parameters
Name | Description | Validation |
---|---|---|
<uuid> | The UUID of the profile to delete | Required parameter |
curl -v -X DELETE \ -H "Authorization: Bearer <token>" \ https://hurricane.umbrellanet.ch/uf-test/api/v1/profiles/company/b9321d7e-9d72-4e80-ac49-d3aa38169175
Example response
HTTP 204 “No Content” with empty body
Search traveler profile