Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Sv translation
languagefr

Cet article n'est pas disponible en français.




Web service integration

Which data can be requested via the ZSR web service?

The data delivered via the web service correspond in principle to the data delivered in the backwards-compatible subscriptions. The modules to which the customer has subscribed thus determine which data can be requested. See Subscription options
Data can be requested on clearing numbers/employee numbers that have not been suspended for more than ten years.


Are the data delivered with the same structure as in the subscription files?

The web service uses a different data model from that of the subscription files. See also Mapping Subscription Files- Webservice.

The key entities are as follows:

  • CareProvider - service provider
  • CareProviderBusiness - location
  • ClearingNumber - ZSR number
  • EmployeeNumber - K number


Expand
titleMain ClearingNumber entities (simplified view)

clearingNumber

  • number (clearingNumber)
  • correspondenceParty (correspondence address)
  • account (bank account)
  • clearingNumberLaws
  • careProvider
    • careProviderParties (addresses)
    • qualifications
    • employeeNumbers
  • careProviderBusinesses (business location)
    • careProviderBusinessParties (addresses)
    • facilities (business facilities)
    • healthServices (certifier methods)
    • affiliations
  • businessScope (OG/UG)
  • businessActivity
  • relatedClearingNumbers
  • relatedEmployees
  • licenses (cantonal authorizations)
  • admissions (cantonal admissions)
  • tariffSystems

Remarks:
This is a highly simplified view – for details, see the Swagger-Schema.
It incorporates the changes set out in the Release Notes ZSR Webservice (24.06.22)



Why was the data model changed (compared with the subscription files)?

The reasons for changing the data model are as follows:

  • Reality check: The old data model allowed multiple sets of master data to be required for the same service provider. This led to a lack of clarity in the specialist data and made uniform identification harder. With the new data model, attention has been paid to ensuring that the legacy data can be collated over time so that a single data set can be delivered for each service provider. The English working title of the application is now CareProviderRegister – the term “paying agent” has been dropped.
  • Specialist data: The old data model could not create a specialist history in all areas. The new data model ensures that a specialist history containing all relevant data can be created and updated easily.
  • Future-proof: The old data model could not easily meet the requirements that will be placed on CareProviderRegister going forward. The new data model offers the flexibility to adapt more quickly to changes in the specialist workflows.


Which response format does the ZSR web service use?

Data are delivered in JSON format (XML is not supported).


Can reference data (master data) be loaded separately?

Reference/master data for ZSR/K number values (methods, qualifications, banks etc.) do not have to be loaded separately. All required data are delivered directly in the detailed response for the individual number.

If needed, reference/master data can be entered separately as follows:

  • All enum values (e.g. gender, canton etc.) are already contained in full in swagger.json (JSON). The Swagger Editor or other tools can be used to generate ZSR web service reference classes automatically, complete with the corresponding enum values.
  • The following values are not contained in swagger.json as enum values, but they can be requested via a dedicated ZSR web service endpoint:
    • Affiliations (association codes)
    • BusinessScopes (partner type groups/sub-groups)
    • ClearingNumberSuffixes (number groups)
    • Countries
    • Facilities (location features)
    • HealthServices (methods)
    • Qualifications
    • TariffSystems


Where can I find the technical API documentation?

An Open API Specification is available.

In addition to Swagger, (for example) ReDoc can be used to display the open API specification: ZSRN-API Live (ReDoc).


Is there a version history for the ZSR web service?

The ZSR web service is currently at version v1.x. For the time being, all changes to the ZSR web service will not be implemented via new versions in parallel operation but will instead be made directly in version v1.x. However, all changes will be published in release notes at the appropriate time and made available via the stage system. The SASIS SLAs apply.

As there will not be a version history for the ZSR web service for the time being, SASIS AG recommends that its integrators follow an adapter pattern that allows changes to the client-system interfaces to the ZSR web service via release-independent settings.


What are the current SASIS AG IT SLAs?

The SASIS IT Service Level Agreement applies to the web service.



Questions and support

Where can I request access to the ZSR web service?

Please contact us to request access to the ZSR web service.


Who can provide support if I have an issue with the ZSR web service?

Please contact us.



Authentication and submitting requests

How do I access the ZSR web service?

Please contact us to request access to the ZSR web service.


How does authentication work?

Authentication is based on OpenID Connect or OAuth 2.0 using password grant.

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameapi_access_sequence
simpleViewerfalse
width600
diagramWidth676
revision2

  1. The API Client requests the token endpoint from the auth server.
  2. The token endpoint is returned to the API Client.
  3. Request an access token from the auth server by providing the following post request parameters:
    1. grant_type: set to 'password'
    2. client_id: provided individually by SASIS
    3. client_secret: provided individually by SASIS
    4. username: provided individually by SASIS
    5. password: provided individually by SASIS
    6. scope: set constantly to 'openid profile email offline_access roles c1s_profile cpr'
  4. The access token as well as the refresh token is returned to the API Client.
  5. The specific API resource is called providing the access token in as bearer in the Authorization http header:
    'Authorization: Bearer <access token>'
  6. The API responds to the request.
  7. Once the access token expired, the previously received refresh token is used to request a new access token from the auth server by providing the following parameters:
    1. grant_type: set to 'refresh_token'
    2. client_id: provided individually by SASIS
    3. client_secret: provided individually by SASIS
    4. scope: set constantly to 'openid profile email offline_access roles c1s_profile cpr'
    5. refresh_token: The refresh token received with the last access token.
  8. A new access token as well as a new refresh token is returned to the API Client.
  9. The specific API resource is called providing the new access token in as bearer in the Authorization http header:
    'Authorization: Bearer <access token>'
  10. The API responds to the request.

Access token

The access token response contains additional information:

Code Block
languagejava
titleAccess token response
{
  "access_token": "MTQ0NjOkZmQ5OTM5NDE9ZTZjNGZmZjI3",
  "refresh_token": "GEbRxBNZmQOTM0NjOkZ5NDE9ZedjnXbL",
  "token_type": "bearer",
  "expires_in": 300,
  "scope": "openid profile email offline_access roles c1s_profile cpr"
}

The token itself is a JWT and can therefore be decoded on the JWT website.

The expires_in field defines the validity period of the token in seconds. Afterwards, a new token must be retrieved.

Code samples

A complete c# sample shows how to access one specific API resource (numbers): 

HTML
<div class="references">

CprApiAccessSample.zip

HTML
</div>

Authentication in other languages follows the same procedure.

The following code snippets explain the procedure on a step-by-step basis:

Code Block
languagec#
themeConfluence
title1./2. Retrieve the auth servers token endpoint
collapsetrue
        /// <summary>
        /// Loads the IAM configuration.
        /// </summary>
        private async Task<DiscoveryResponse> GetDiscoveryDocumentAsync(CancellationToken ct)
        {
            using (var client = new HttpClient())
            {
                var discoveryResponse = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
                {
                    Address = "[AuthorityUrl]"
                }, ct).ConfigureAwait(false);

                if (discoveryResponse.IsError)
                    throw new Exception(discoveryResponse.Error);

                return discoveryResponse;
            }
        }


Code Block
languagec#
themeConfluence
title3./4. Request access and refresh token
collapsetrue
        /// <summary>
        /// Gets a new token response with a username and password.
        /// </summary>
        private async Task<TokenResponse> RequestTokenAsync(CancellationToken ct)
        {
            using (var client = new HttpClient())
            {
                var discoveryResponse = await GetDiscoveryDocumentAsync(ct).ConfigureAwait(false);

                var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                {
                    ClientId = "[ClientId]",
                    ClientSecret = "[ClientSecret]",
                    UserName = "[UserName]",
                    Password = "[Password]",
                    Address = discoveryResponse.TokenEndpoint,
                    GrantType = OidcConstants.GrantTypes.Password,
                    Scope = string.Join(" ", _scopes),
                }, ct).ConfigureAwait(false);

                if (tokenResponse.IsError)
                    throw new Exception(tokenResponse.Error);

                return tokenResponse;
            }
        }


Code Block
languagec#
themeConfluence
title7./8. Token refresh strategy based validity of cached token response and request new access token
collapsetrue
        /// <summary>
        /// Gets the access token by either requesting a new token or by using the refresh token of an already existing token.
        /// </summary>
        private async Task<string> GetAccessTokenAsync(CancellationToken ct)
        {
            if (_tokenResponse == null)
            {
                // Creates a new token response
                _tokenResponse = await RequestTokenAsync(ct).ConfigureAwait(false);
            }
            else
            {
                var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();

                // Parses JWT access token
                var jwtSecurityToken = jwtSecurityTokenHandler.ReadToken(_tokenResponse.AccessToken) as JwtSecurityToken;

                // The access token might be valid now, but expired the very next millisecond.
                // Thus, add a reasonable reserve in minutes for the validity time comparison below.
                var comparisionCorrectionInMinutes = 1;

                // Compares the access token life time with the current time, modified by the comparison correction value.
                if (jwtSecurityToken.ValidTo < DateTime.UtcNow.AddMinutes(comparisionCorrectionInMinutes))
                {
                    // Updates the existing token response
                    _tokenResponse = await RefreshTokenAsync(_tokenResponse.RefreshToken, ct).ConfigureAwait(false);
                }
            }

            return _tokenResponse.AccessToken;
        }

        /// <summary>
        /// Gets an updated token response by using a refresh token.
        /// </summary>
        private async Task<TokenResponse> RefreshTokenAsync(string refreshToken, CancellationToken ct)
        {
            using (var client = new HttpClient())
            {
                var discoveryResponse = await GetDiscoveryDocumentAsync(ct).ConfigureAwait(false);

                var tokenResponse = await client.RequestTokenAsync(new TokenRequest
                {
                    ClientId = "[ClientId]",
                    ClientSecret = "[ClientSecret]",
                    Address = discoveryResponse.TokenEndpoint,
                    ClientCredentialStyle = ClientCredentialStyle.AuthorizationHeader,
                    GrantType = OidcConstants.GrantTypes.RefreshToken,
                    Parameters =
                    {
                        { "refresh_token", refreshToken },
                        { "scope", string.Join(" ", _scopes) }
                    }
                });

                if (tokenResponse.IsError)
                    throw new Exception(tokenResponse.Error);

                return tokenResponse;
            }
        }


Code Block
languagec#
themeConfluence
title5./6./9./10. API resource call using the access token in the Authorization http header
collapsetrue
        /// <summary>
        /// A simple CPR API number search request.
        /// </summary>
        private async Task<BulkResponse> CprApiSampleRequestAsync(string accessToken, CancellationToken ct)
        {
            BulkResponse bulkResponse = new BulkResponse();

            using (var client = new HttpClient())
            {
                client.SetBearerToken(accessToken);

                var response = await client.GetAsync($"https://[CprBaseUrl]/ApiGateway/api/v1/numbers?searchOptions=Okp&offset=0&limit=10", ct).ConfigureAwait(false);

                if (!response.IsSuccessStatusCode)
                    throw new Exception("There was a problem with the request");

                string content = await response.Content.ReadAsStringAsync();

                if (content != null && content.Length > 0)
                {
                    bulkResponse = JsonConvert.DeserializeObject<BulkResponse>(content);
                }
            }

            return bulkResponse;
        }


Code Block
languagec#
themeConfluence
titlePlain API Call (putting everything together)
collapsetrue
        var accessToken = await GetAccessTokenAsync(ct).ConfigureAwait(false);

        var cprApiResponse = await CprApiSampleRequestAsync(accessToken, ct).ConfigureAwait(false);



What are the limits on batch requests?

Batch requests are defined as involving more than 50 requests per minute for a given customer.
Requests from batch processes on online services provided by SASIS AG may only be carried out between 10.00 pm and 4.00 am.
SASIS AG’s online services have limits in place that cause batches of more than 1,000 requests per minute for a given customer to be rejected (http status code 503).

See also the SASIS IT Service Level Agreement.


Why can I only call up 500 numbers in the detail view?

Requests involving the endpoints ClearingNumbers and EmployeeNumbers are limited to 500 numbers for performance reasons. The request process must be planned such that no request contains more than 500 numbers.


Which status codes does the web service return?

The web service uses http status codes. The following codes may be returned:

Status Code

Description

200Success
202Accepted; Request is valid and business process could be triggered successfully.
400Bad Request; The request data is invalid.
401Unauthorized; The caller does not have sufficient privileges to perform the call.
403Forbidden;  The server is refusing the action.
500Internal Server Error; Any unexpected internal failure.



How can 503 errors be avoided?

If the API is overloaded with large numbers of parallel requests, it returns 503 errors. To avoid these, it is very important to follow the instructions for loading the number list and the number details (see also How can data on ZSR and K numbers be requested via the web service?). The number of requests can be reduced further, for example, by requesting only changes via a daily change batch request (see also How can changes be requested?). When a 503 error occurs, it is advisable to wait five minutes before making another request. If possible, customers should check whether API requests can be deferred to a time slot during the night.


How can 400 errors be avoided?

When the client sends an invalid request to the API, it returns a 400 error. To avoid these, it is very important to follow the instructions for loading the number list and the number details (see also How can data on ZSR and K numbers be requested via the web service?). The request process must be planned such that no request contains more than 500 numbers.



ZSR and K number requests

How is the Numbers endpoint used?

The Numbers endpoint delivers ZSR and K numbers that match the filter criteria.

See also How can data on ZSR and K numbers be requested via the web service?


What are the possible filter criteria for the Numbers endpoint?

Filter criteria:

  • filterOptions: limits the numbers returned to specific categories/certifiers. The modules available are as for the subscription options.
  • numberTypes: sets the type of number returned (ZSR or K number).
  • offset: paging value that skips a set number of numbers. As a rule, this can be set to 0.
  • limit: paging value that limits how many numbers are returned. To ensure that all numbers can be loaded at once with a request, a relatively high value can be set here, e.g. 200,000.
  • modifiedFrom: the “modified from” date; see How can changes be requested?


Are extended search functions available?

Extended search queries with filter criteria at field level, e.g. by name and postcode, are not offered via the web service. The full version of ZSR is available for advanced search queries.

For the ZSR web service filter criteria, see the section on data requests.


How can data on ZSR and K numbers be requested via the web service?

Data are requested in two steps.

Step 1 – Loading the number list:

Request all the required ZSR/K numbers via the Numbers endpoint. The filter criteria employed and user authorisations affect the search results. The Numbers endpoint delivers all ZSR/K numbers that match the filter criteria and for which the customer is authorised. It does not deliver ZSR/K numbers that have been suspended for more than ten years.

Filter criteria:

  • filterOptions: limits the numbers returned to specific categories/certifiers. The modules available are as for the subscription options.
  • numberTypes: sets the type of number returned (ZSR or K number).
  • offset: paging value that skips a set number of numbers. As a rule, this can be set to 0.
  • limit: paging value that limits how many numbers are returned. To ensure that all numbers can be loaded at once with a request, a relatively high value can be set here, e.g. 200,000.
  • modifiedFrom: the “modified from” date; see How can changes be requested?

Step 2 – Loading the number details:

The result from step 1 is used to make a request via the appropriate detail endpoint for 500 numbers at a time. The response from the detail endpoint contains the complete number details for which the user is authorised. For performance reasons, it is important to avoid making large numbers of parallel individual requests.

Endpoints:

  • For ZSR numbers: ClearingNumbers endpoint
    For K numbers: EmployeeNumbers endpoint


What are subscription options?

The data delivered via the web service correspond in principle to the data delivered in the backwards-compatible subscriptions. The subscription options depend on the modules to which the customer has subscribed. See Subscription options.


How can the subscription options be changed?

Please contact us.


How is the ClearingNumbers endpoint used?

The ClearingNumbers endpoint delivers details of ZSR numbers.

See How can data on ZSR and K numbers be requested via the web service?


How is the EmployeeNumbers endpoint used?

The EmployeeNumbers endpoint delivers details of K numbers.

See How can data on ZSR and K numbers be requested via the web service?


How can deleted numbers be identified?

If a specialist value has been delivered (with a specific ID/ZSR/K number) but is no longer contained in the response at a later point in time, it is a deleted/cancelled value.


How can changes be requested?

A “modified from” date can be set as a parameter via the Numbers endpoint. The response then contains only numbers that have been changed since that date. Modifications can be specialist in nature or concern purely technical values. Numbers that have been suspended or cancelled for more than ten years are not delivered via the Numbers endpoint. To find out which numbers are affected, all active numbers must first be loaded via the Numbers endpoint. Any numbers that are still active in the client system but are not contained in the results should be cancelled or deleted from the client system.

Once all modified numbers have been loaded, their details can be requested in the usual way via the detail endpoints. The response from these endpoints always contains all available data on a ZSR/K number, not just the values that have been changed.
Changes can be processed from the client system, e.g. by comparing the JSON result from the last request with the JSON result from the new request. The following cases must be borne in mind:

  • An element with the technical ID x exists in the client system and is delivered in the JSON result: it is important to check whether a field value of the element that is relevant for the client system has changed.
  • An element with the technical ID y exists in the client system and is not delivered in the JSON result: all of the element’s field values are regarded as cancelled and must be removed.
  • An element with the technical ID z does not exist in the client system and is delivered in the JSON result: all of the element’s field values are new and must be entered.

The API should always be integrated such that it works regardless of the number of changes reported, i.e. threshold values set by the customer should not cause the data import to fail.


Is it possible to load only ZSR/K numbers that have been changed?

Yes. The filter criterion “modifiedFrom” makes it possible to request changes by date. See also How can changes be requested?


How are changes handled?

  • An element with the technical ID x exists in the client system and is delivered in the JSON result: it is important to check whether a field value of the element that is relevant for the client system has changed.
  • An element with the technical ID y exists in the client system and is not delivered in the JSON result: all of the element’s field values are regarded as cancelled and must be removed.
  • An element with the technical ID z does not exist in the client system and is delivered in the JSON result: all of the element’s field values are new and must be entered.


Interpreting the data

How are

K numbers and ZSR numbers linked?

ZSR number relationships delivered in the web service?

  • relatedClearingNumberscontains ZSR number relationships recorded manually by SASIS. These are only kept on record until data confirmed by the service provider are available.
  • ClearingNumberscontains ZSR number relationships confirmed by the service provider.
  • EmployeeNumberscontains K number relationships confirmed by the service provider (these are NOT employee relationships).

To receive all ZSR number relationships, therefore, it is essential to take account of both ClearingNumber.relatedClearingNumbers and CareProvider.ClearingNumbers

Expand
titleExamples


Code Block
titleClearingNumber.relatedClearingNumbers
    "relatedClearingNumbers": [
        {
          "clearingNumber": "B222222",
          "clearingNumberRelationType": "CHANGE_OF_HANDS",
          "clearingNumberRelationTypeTranslations": {
            "de": "Besitzerwechsel",
            "fr": "Changement de propriétaire",
            "it": "Cambiamento di proprietario"
          },
          "id": 520754
        }
      ] 


Code Block
titleCareProvider.ClearingNumbers
"clearingNumbers": [
          {
            "number": "N111111"
          }
        ] 


Code Block
titleCareProvider.EmployeeNumbers
 "employeeNumbers": [
          {
            "number": "999999K"
          }
        ] 

Remarks: Relationship types are not recorded and can thus not be delivered for CareProvider.ClearingNumbers and CareProvider.EmployeeNumbers.

Employee relationships are delivered under clearingNumber.relatedEmployees or in the EmployeeNumbers endpoint under employeeNumber.relatedEmployers.


The CareProvider (service provider) is a property on the detail record for a ZSR/K number.

ClearingNumber → CareProvider (service provider)
EmployeeNumber → CareProvider (service provider)Employment relationships are shown as follows:
ClearingNumber → RelatedEmployees (all employees linked to a ZSR number)
EmployeeNumber → RelatedEmployers (all employers linked to a K number)

On which data is the displayed validity period of a ZSR/K number based?

The validity of a ZSR/K number is no longer defined only as a time period with a start date and an end date. It is now defined using multiple time periods (ValidityPeriods), which are delivered as a list. The list clearly shows gaps in validity.

Validity periods are defined as follows::

ClearingNumber

  • Mandatory health insurance: start date (S5) to end date (S6) minus any past or active suspension periods.
  • Partner type groups 52/56: all aggregated periods of the methods (HealthServices) plus any periods for location features (Facilities) such as FitnessClassification or SPAK recognition.

EmployeeNumber

  • All aggregated periods of the employment relationships.


How can I tell the difference between a bank account and a post office account?

The ZSR web service no longer distinguishes between bank and post office accounts.

The field “hasPaymentOrderReferenceNumber” under ClearingNumberAccount shows whether payments using a standard Swiss payment slip are possible.

Endpoint: ClearingNumbers; object: ClearingNumberAccount


What do the data items “0001-01-01” and “9999-12-31” mean?

The ZSR web service always delivers a start date and an end date for time periods, even if it is not possible to determine the exact dates due to the legacy data or for other reasons.

Placeholder values for the start and end date are therefore used. These are to be interpreted as follows:

  • “0001-01-01” is a placeholder value for the start date and means that the actual start date is not known (NULL).
  • “9999-12-31” is a placeholder value for the end date and means that the actual end date is not known (NULL).

A time period with the start date “0001-01-01” and the end date “9999-12-31” is thus valid for any given point in time.


Are technical IDs delivered?

Element id

The IDs delivered in the detailed response have no specialist meaning and should not be used to interpret values. They are purely technical identifiers of the delivered data and can serve to process changes (see How can changes be requested? and How are changes handled?). No logic should ever be coded to technical IDs.

In addition, no technical IDs whatsoever are delivered for the main ZSR/K number record. Identification is only possible using the ZSR/K number itself. A replacement for the old paying agent ID is not delivered.

Element key

Master/reference data, e.g. canton, country, qualification etc., are delivered with a permanent GUID as identifier. See also Can reference data (master data) be loaded separately?

Unique identification is possible using the element “key” (string) for the following entities: 

  • xxx
  • yyy

Example: "key": "3fa85f64-5717-4562-b3fc-2c963f66afa6"


How can dummy numbers be identified?

So-called “dummy” numbers are a legacy construct. They are still in use and can be retrieved via the ZSR web service.

If a value for the property "clearingNumberDummy" is delivered on the ClearingNumber object, the number in question is a dummy number.

Example of structure:

Code Block
languagejs
{
	"clearingNumber": {
		"clearingNumberDummy": {
			"id": 912
			"name": "CH-Arzt",
		}
	}
}




General information on the paying agent register

How is a valid  valid number constructed?

The clearing number has the following structure:

  • A leading char as check digit
  • A four digit sequential number
  • A two digit number circle / canton number

The leading char of the clearing number is created and validated as follows:

  • Each number is multiplied with its position (calculate from the right end).
  • All products are summarized into one sum.
  • Modulo 26 of the sum denotes the char in the alphabet (result 0 results in char 'Z'). 

Example L248519:
(9*1)+(1*2)+(5*3)+(8*4)+(4*5)+(2*6) = 90
90 mod 26 = 12
12th char in the alphabet = L


How is a valid K number constructed?

K numbers consist of a six-digit serial number followed by the letter K.






Sv translation
languageit

Questo articolo non è disponibile in italiano.




Web service integration

Which data can be requested via the ZSR web service?

The data delivered via the web service correspond in principle to the data delivered in the backwards-compatible subscriptions. The modules to which the customer has subscribed thus determine which data can be requested. See Subscription options

Data can be requested on clearing numbers/employee numbers that have not been suspended for more than ten years.


Are the data delivered with the same structure as in the subscription files?

The web service uses a different data model from that of the subscription files. See also Mapping Subscription Files- Webservice.

The key entities are as follows:

  • CareProvider - service provider
  • CareProviderBusiness - location
  • ClearingNumber - ZSR number
  • EmployeeNumber - K number


Expand
titleMain ClearingNumber entities (simplified view)

clearingNumber

  • number (clearingNumber)
  • correspondenceParty (correspondence address)
  • account (bank account)
  • clearingNumberLaws
  • careProvider
    • careProviderParties (addresses)
    • qualifications
    • employeeNumbers
  • careProviderBusinesses (business location)
    • careProviderBusinessParties (addresses)
    • facilities (business facilities)
    • healthServices (certifier methods)
    • affiliations
  • businessScope (OG/UG)
  • businessActivity
  • relatedClearingNumbers
  • relatedEmployees
  • licenses (cantonal authorizations)
  • admissions (cantonal admissions)
  • tariffSystems

Remarks:
This is a highly simplified view – for details, see the Swagger-Schema.
It incorporates the changes set out in the Release Notes ZSR Webservice (24.06.22)



Why was the data model changed (compared with the subscription files)?

The reasons for changing the data model are as follows:

  • Reality check: The old data model allowed multiple sets of master data to be required for the same service provider. This led to a lack of clarity in the specialist data and made uniform identification harder. With the new data model, attention has been paid to ensuring that the legacy data can be collated over time so that a single data set can be delivered for each service provider. The English working title of the application is now CareProviderRegister – the term “paying agent” has been dropped.
  • Specialist data: The old data model could not create a specialist history in all areas. The new data model ensures that a specialist history containing all relevant data can be created and updated easily.
  • Future-proof: The old data model could not easily meet the requirements that will be placed on CareProviderRegister going forward. The new data model offers the flexibility to adapt more quickly to changes in the specialist workflows.


Which response format does the ZSR web service use?

Data are delivered in JSON format (XML is not supported).


Can reference data (master data) be loaded separately?

Reference/master data for ZSR/K number values (methods, qualifications, banks etc.) do not have to be loaded separately. All required data are delivered directly in the detailed response for the individual number.

If needed, reference/master data can be entered separately as follows:

  • All enum values (e.g. gender, canton etc.) are already contained in full in swagger.json (JSON). The Swagger Editor or other tools can be used to generate ZSR web service reference classes automatically, complete with the corresponding enum values.
  • The following values are not contained in swagger.json as enum values, but they can be requested via a dedicated ZSR web service endpoint:
    • Affiliations (association codes)
    • BusinessScopes (partner type groups/sub-groups)
    • ClearingNumberSuffixes (number groups)
    • Countries
    • Facilities (location features)
    • HealthServices (methods)
    • Qualifications
    • TariffSystems


Where can I find the technical API documentation?

An Open API Specification is available.

In addition to Swagger, (for example) ReDoc can be used to display the open API specification: ZSRN-API Live (ReDoc).


Is there a version history for the ZSR web service?

The ZSR web service is currently at version v1.x. For the time being, all changes to the ZSR web service will not be implemented via new versions in parallel operation but will instead be made directly in version v1.x. However, all changes will be published in release notes at the appropriate time and made available via the stage system. The SASIS SLAs apply.

As there will not be a version history for the ZSR web service for the time being, SASIS AG recommends that its integrators follow an adapter pattern that allows changes to the client-system interfaces to the ZSR web service via release-independent settings.


What are the current SASIS AG IT SLAs?

The SASIS IT Service Level Agreement applies to the web service.



Questions and support

Where can I request access to the ZSR web service?

Please contact us to request access to the ZSR web service.


Who can provide support if I have an issue with the ZSR web service?

Please contact us.



Authentication and submitting requests

How do I access the ZSR web service?

Please contact us to request access to the ZSR web service.


How does authentication work?

Authentication is based on OpenID Connect or OAuth 2.0 using password grant.

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameapi_access_sequence
simpleViewerfalse
width600
diagramWidth676
revision2

  1. The API Client requests the token endpoint from the auth server.
  2. The token endpoint is returned to the API Client.
  3. Request an access token from the auth server by providing the following post request parameters:
    1. grant_type: set to 'password'
    2. client_id: provided individually by SASIS
    3. client_secret: provided individually by SASIS
    4. username: provided individually by SASIS
    5. password: provided individually by SASIS
    6. scope: set constantly to 'openid profile email offline_access roles c1s_profile cpr'
  4. The access token as well as the refresh token is returned to the API Client.
  5. The specific API resource is called providing the access token in as bearer in the Authorization http header:
    'Authorization: Bearer <access token>'
  6. The API responds to the request.
  7. Once the access token expired, the previously received refresh token is used to request a new access token from the auth server by providing the following parameters:
    1. grant_type: set to 'refresh_token'
    2. client_id: provided individually by SASIS
    3. client_secret: provided individually by SASIS
    4. scope: set constantly to 'openid profile email offline_access roles c1s_profile cpr'
    5. refresh_token: The refresh token received with the last access token.
  8. A new access token as well as a new refresh token is returned to the API Client.
  9. The specific API resource is called providing the new access token in as bearer in the Authorization http header:
    'Authorization: Bearer <access token>'
  10. The API responds to the request.

Access token

The access token response contains additional information:

Code Block
languagejava
titleAccess token response
{
  "access_token": "MTQ0NjOkZmQ5OTM5NDE9ZTZjNGZmZjI3",
  "refresh_token": "GEbRxBNZmQOTM0NjOkZ5NDE9ZedjnXbL",
  "token_type": "bearer",
  "expires_in": 300,
  "scope": "openid profile email offline_access roles c1s_profile cpr"
}

The token itself is a JWT and can therefore be decoded on the JWT website.

The expires_in field defines the validity period of the token in seconds. Afterwards, a new token must be retrieved.

Code samples

A complete c# sample shows how to access one specific API resource (numbers): 

HTML
<div class="references">

CprApiAccessSample.zip

HTML
</div>

Authentication in other languages follows the same procedure.

The following code snippets explain the procedure on a step-by-step basis:

Code Block
languagec#
themeConfluence
title1./2. Retrieve the auth servers token endpoint
collapsetrue
        /// <summary>
        /// Loads the IAM configuration.
        /// </summary>
        private async Task<DiscoveryResponse> GetDiscoveryDocumentAsync(CancellationToken ct)
        {
            using (var client = new HttpClient())
            {
                var discoveryResponse = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
                {
                    Address = "[AuthorityUrl]"
                }, ct).ConfigureAwait(false);

                if (discoveryResponse.IsError)
                    throw new Exception(discoveryResponse.Error);

                return discoveryResponse;
            }
        }


Code Block
languagec#
themeConfluence
title3./4. Request access and refresh token
collapsetrue
        /// <summary>
        /// Gets a new token response with a username and password.
        /// </summary>
        private async Task<TokenResponse> RequestTokenAsync(CancellationToken ct)
        {
            using (var client = new HttpClient())
            {
                var discoveryResponse = await GetDiscoveryDocumentAsync(ct).ConfigureAwait(false);

                var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                {
                    ClientId = "[ClientId]",
                    ClientSecret = "[ClientSecret]",
                    UserName = "[UserName]",
                    Password = "[Password]",
                    Address = discoveryResponse.TokenEndpoint,
                    GrantType = OidcConstants.GrantTypes.Password,
                    Scope = string.Join(" ", _scopes),
                }, ct).ConfigureAwait(false);

                if (tokenResponse.IsError)
                    throw new Exception(tokenResponse.Error);

                return tokenResponse;
            }
        }


Code Block
languagec#
themeConfluence
title7./8. Token refresh strategy based validity of cached token response and request new access token
collapsetrue
        /// <summary>
        /// Gets the access token by either requesting a new token or by using the refresh token of an already existing token.
        /// </summary>
        private async Task<string> GetAccessTokenAsync(CancellationToken ct)
        {
            if (_tokenResponse == null)
            {
                // Creates a new token response
                _tokenResponse = await RequestTokenAsync(ct).ConfigureAwait(false);
            }
            else
            {
                var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();

                // Parses JWT access token
                var jwtSecurityToken = jwtSecurityTokenHandler.ReadToken(_tokenResponse.AccessToken) as JwtSecurityToken;

                // The access token might be valid now, but expired the very next millisecond.
                // Thus, add a reasonable reserve in minutes for the validity time comparison below.
                var comparisionCorrectionInMinutes = 1;

                // Compares the access token life time with the current time, modified by the comparison correction value.
                if (jwtSecurityToken.ValidTo < DateTime.UtcNow.AddMinutes(comparisionCorrectionInMinutes))
                {
                    // Updates the existing token response
                    _tokenResponse = await RefreshTokenAsync(_tokenResponse.RefreshToken, ct).ConfigureAwait(false);
                }
            }

            return _tokenResponse.AccessToken;
        }

        /// <summary>
        /// Gets an updated token response by using a refresh token.
        /// </summary>
        private async Task<TokenResponse> RefreshTokenAsync(string refreshToken, CancellationToken ct)
        {
            using (var client = new HttpClient())
            {
                var discoveryResponse = await GetDiscoveryDocumentAsync(ct).ConfigureAwait(false);

                var tokenResponse = await client.RequestTokenAsync(new TokenRequest
                {
                    ClientId = "[ClientId]",
                    ClientSecret = "[ClientSecret]",
                    Address = discoveryResponse.TokenEndpoint,
                    ClientCredentialStyle = ClientCredentialStyle.AuthorizationHeader,
                    GrantType = OidcConstants.GrantTypes.RefreshToken,
                    Parameters =
                    {
                        { "refresh_token", refreshToken },
                        { "scope", string.Join(" ", _scopes) }
                    }
                });

                if (tokenResponse.IsError)
                    throw new Exception(tokenResponse.Error);

                return tokenResponse;
            }
        }


Code Block
languagec#
themeConfluence
title5./6./9./10. API resource call using the access token in the Authorization http header
collapsetrue
        /// <summary>
        /// A simple CPR API number search request.
        /// </summary>
        private async Task<BulkResponse> CprApiSampleRequestAsync(string accessToken, CancellationToken ct)
        {
            BulkResponse bulkResponse = new BulkResponse();

            using (var client = new HttpClient())
            {
                client.SetBearerToken(accessToken);

                var response = await client.GetAsync($"https://[CprBaseUrl]/ApiGateway/api/v1/numbers?searchOptions=Okp&offset=0&limit=10", ct).ConfigureAwait(false);

                if (!response.IsSuccessStatusCode)
                    throw new Exception("There was a problem with the request");

                string content = await response.Content.ReadAsStringAsync();

                if (content != null && content.Length > 0)
                {
                    bulkResponse = JsonConvert.DeserializeObject<BulkResponse>(content);
                }
            }

            return bulkResponse;
        }


Code Block
languagec#
themeConfluence
titlePlain API Call (putting everything together)
collapsetrue
        var accessToken = await GetAccessTokenAsync(ct).ConfigureAwait(false);

        var cprApiResponse = await CprApiSampleRequestAsync(accessToken, ct).ConfigureAwait(false);



What are the limits on batch requests?

Batch requests are defined as involving more than 50 requests per minute for a given customer.
Requests from batch processes on online services provided by SASIS AG may only be carried out between 10.00 pm and 4.00 am.
SASIS AG’s online services have limits in place that cause batches of more than 1,000 requests per minute for a given customer to be rejected (http status code 503).

See also the SASIS IT Service Level Agreement.


Why can I only call up 500 numbers in the detail view?

Requests involving the endpoints ClearingNumbers and EmployeeNumbers are limited to 500 numbers for performance reasons. The request process must be planned such that no request contains more than 500 numbers.


Which status codes does the web service return?

The web service uses http status codes. The following codes may be returned:

Status Code

Description

200Success
202Accepted; Request is valid and business process could be triggered successfully.
400Bad Request; The request data is invalid.
401Unauthorized; The caller does not have sufficient privileges to perform the call.
403Forbidden;  The server is refusing the action.
500Internal Server Error; Any unexpected internal failure.



How can 503 errors be avoided?

If the API is overloaded with large numbers of parallel requests, it returns 503 errors. To avoid these, it is very important to follow the instructions for loading the number list and the number details (see also How can data on ZSR and K numbers be requested via the web service?). The number of requests can be reduced further, for example, by requesting only changes via a daily change batch request (see also How can changes be requested?). When a 503 error occurs, it is advisable to wait five minutes before making another request. If possible, customers should check whether API requests can be deferred to a time slot during the night.


How can 400 errors be avoided?

When the client sends an invalid request to the API, it returns a 400 error. To avoid these, it is very important to follow the instructions for loading the number list and the number details (see also How can data on ZSR and K numbers be requested via the web service?). The request process must be planned such that no request contains more than 500 numbers.



ZSR and K number requests

How is the Numbers endpoint used?

The Numbers endpoint delivers ZSR and K numbers that match the filter criteria.

See also How can data on ZSR and K numbers be requested via the web service?


What are the possible filter criteria for the Numbers endpoint?

Filter criteria:

  • filterOptions: limits the numbers returned to specific categories/certifiers. The modules available are as for the subscription options.
  • numberTypes: sets the type of number returned (ZSR or K number).
  • offset: paging value that skips a set number of numbers. As a rule, this can be set to 0.
  • limit: paging value that limits how many numbers are returned. To ensure that all numbers can be loaded at once with a request, a relatively high value can be set here, e.g. 200,000.
  • modifiedFrom: the “modified from” date; see How can changes be requested?


Are extended search functions available?

Extended search queries with filter criteria at field level, e.g. by name and postcode, are not offered via the web service. The full version of ZSR is available for advanced search queries.

For the ZSR web service filter criteria, see the section on data requests.


How can data on ZSR and K numbers be requested via the web service?

Data are requested in two steps.

Step 1 – Loading the number list:

Request all the required ZSR/K numbers via the Numbers endpoint. The filter criteria employed and user authorisations affect the search results. The Numbers endpoint delivers all ZSR/K numbers that match the filter criteria and for which the customer is authorised. It does not deliver ZSR/K numbers that have been suspended for more than ten years.

Filter criteria:

  • filterOptions: limits the numbers returned to specific categories/certifiers. The modules available are as for the subscription options.
  • numberTypes: sets the type of number returned (ZSR or K number).
  • offset: paging value that skips a set number of numbers. As a rule, this can be set to 0.
  • limit: paging value that limits how many numbers are returned. To ensure that all numbers can be loaded at once with a request, a relatively high value can be set here, e.g. 200,000.
  • modifiedFrom: the “modified from” date; see How can changes be requested?

Step 2 – Loading the number details:

The result from step 1 is used to make a request via the appropriate detail endpoint for 500 numbers at a time. The response from the detail endpoint contains the complete number details for which the user is authorised. For performance reasons, it is important to avoid making large numbers of parallel individual requests.

Endpoints:

  • For ZSR numbers: ClearingNumbers endpoint
    For K numbers: EmployeeNumbers endpoint


What are subscription options?

The data delivered via the web service correspond in principle to the data delivered in the backwards-compatible subscriptions. The subscription options depend on the modules to which the customer has subscribed. See Subscription options.


How can the subscription options be changed?

Please contact us.


How is the ClearingNumbers endpoint used?

The ClearingNumbers endpoint delivers details of ZSR numbers.

See How can data on ZSR and K numbers be requested via the web service?


How is the EmployeeNumbers endpoint used?

The EmployeeNumbers endpoint delivers details of K numbers.

See How can data on ZSR and K numbers be requested via the web service?


WHow can deleted numbers be identified?

If a specialist value has been delivered (with a specific ID/ZSR/K number) but is no longer contained in the response at a later point in time, it is a deleted/cancelled value.


How can changes be requested?

A “modified from” date can be set as a parameter via the Numbers endpoint. The response then contains only numbers that have been changed since that date. Modifications can be specialist in nature or concern purely technical values. Numbers that have been suspended or cancelled for more than ten years are not delivered via the Numbers endpoint. To find out which numbers are affected, all active numbers must first be loaded via the Numbers endpoint. Any numbers that are still active in the client system but are not contained in the results should be cancelled or deleted from the client system.

Once all modified numbers have been loaded, their details can be requested in the usual way via the detail endpoints. The response from these endpoints always contains all available data on a ZSR/K number, not just the values that have been changed.
Changes can be processed from the client system, e.g. by comparing the JSON result from the last request with the JSON result from the new request. The following cases must be borne in mind:

  • An element with the technical ID x exists in the client system and is delivered in the JSON result: it is important to check whether a field value of the element that is relevant for the client system has changed.
  • An element with the technical ID y exists in the client system and is not delivered in the JSON result: all of the element’s field values are regarded as cancelled and must be removed.
  • An element with the technical ID z does not exist in the client system and is delivered in the JSON result: all of the element’s field values are new and must be entered.

The API should always be integrated such that it works regardless of the number of changes reported, i.e. threshold values set by the customer should not cause the data import to fail.


Is it possible to load only ZSR/K numbers that have been changed?

Yes. The filter criterion “modifiedFrom” makes it possible to request changes by date. See also How can changes be requested?


How are changes handled?

  • An element with the technical ID x exists in the client system and is delivered in the JSON result: it is important to check whether a field value of the element that is relevant for the client system has changed.
  • An element with the technical ID y exists in the client system and is not delivered in the JSON result: all of the element’s field values are regarded as cancelled and must be removed.
  • An element with the technical ID z does not exist in the client system and is delivered in the JSON result: all of the element’s field values are new and must be entered.


Interpreting the data

How are K numbers and ZSR numbers linked?

The CareProvider (service provider) is a property on the detail record for a ZSR/K number.


ClearingNumber → CareProvider (service provider)
EmployeeNumber → CareProvider (service provider)


Employment relationships are shown as follows:
ClearingNumber → RelatedEmployees (all employees linked to a ZSR number)
EmployeeNumber → RelatedEmployers (all employers linked to a K number)


On which data is the displayed validity period of a ZSR/K number based?

The validity of a ZSR/K number is no longer defined only as a time period with a start date and an end date. It is now defined using multiple time periods (ValidityPeriods), which are delivered as a list. The list clearly shows gaps in validity.

Validity periods are defined as follows::

ClearingNumber

  • Mandatory health insurance: start date (S5) to end date (S6) minus any past or active suspension periods.
  • Partner type groups 52/56: all aggregated periods of the methods (HealthServices) plus any periods for location features (Facilities) such as FitnessClassification or SPAK recognition.

EmployeeNumber

  • All aggregated periods of the employment relationships.


How can I tell the difference between a bank account and a post office account?

The ZSR web service no longer distinguishes between bank and post office accounts.

The field “hasPaymentOrderReferenceNumber” under ClearingNumberAccount shows whether payments using a standard Swiss payment slip are possible.

Endpoint: ClearingNumbers; object: ClearingNumberAccount


What do the data items “0001-01-01” and “9999-12-31” mean?

The ZSR web service always delivers a start date and an end date for time periods, even if it is not possible to determine the exact dates due to the legacy data or for other reasons.

Placeholder values for the start and end date are therefore used. These are to be interpreted as follows:

  • “0001-01-01” is a placeholder value for the start date and means that the actual start date is not known (NULL).
  • “9999-12-31” is a placeholder value for the end date and means that the actual end date is not known (NULL).

A time period with the start date “0001-01-01” and the end date “9999-12-31” is thus valid for any given point in time.


Are technical IDs delivered?

The IDs delivered in the detailed response have no specialist meaning and should not be used to interpret values. They are purely technical identifiers of the delivered data and can serve to process changes (see How can changes be requested? and How are changes handled?).

Ideally, technical IDs would not be used at all as permanence is not guaranteed. This applies to both volatile, technical IDs of allocations and technical IDs of “master data”, e.g. canton, country etc., even if these are in principle maintained.

In addition, no technical IDs whatsoever are delivered for the main ZSR/K number record. Identification is only possible using the ZSR/K number itself. A replacement for the old paying agent ID is not delivered.


How can dummy numbers be identified?

So-called “dummy” numbers are a legacy construct. They are still in use and can be retrieved via the ZSR web service.

If a value for the property "clearingNumberDummy" is delivered on the ClearingNumber object, the number in question is a dummy number.

Example of structure:

Code Block
languagejs
{
	"clearingNumber": {
		"clearingNumberDummy": {
			"id": 912
			"name": "CH-Arzt",
		}
	}
}




General information on the paying agent register

How is a valid  number constructed?

The clearing number has the following structure:

  • A leading char as check digit
  • A four digit sequential number
  • A two digit number circle / canton number

The leading char of the clearing number is created and validated as follows:

  • Each number is multiplied with its position (calculate from the right end).
  • All products are summarized into one sum.
  • Modulo 26 of the sum denotes the char in the alphabet (result 0 results in char 'Z'). 

Example L248519:
(9*1)+(1*2)+(5*3)+(8*4)+(4*5)+(2*6) = 90
90 mod 26 = 12
12th char in the alphabet = L


How is a valid K number constructed?

K numbers consist of a six-digit serial number followed by the letter K.