Bank IDP API Endpoint Overview

Version: 1.1

The following endpoints are to be implemented by the Bank to be compliant with the BankID system. Each of these endpoints only contains illustratory examples. Please see the referenced OpenAPI documents for a full authoritative description of these resources.

OpenID Configuration Discovery API

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Not authenticated.

This endpoint provides information about OpenID Connect configuration.

The values given in the configuration response should strictly correspond to reality. According to the declared values, BankID registers applications to IDP (parameter values) and calls individual endpoints.

GET /.well-known/openid-configuration

Response 200 OK:

{
  "request_parameter_supported": false,
  "claims_parameter_supported": false,
  "introspection_endpoint": "https://oidc.sandbox.bankid.cz/token-info",
  "profile_endpoint": "https://oidc.sandbox.bankid.cz/profile",
  "scopes_supported": [
    "openid",
    "offline_access",
    "profile.addresses",
    "profile.birthdate",
    "profile.birthnumber",
    "profile.birthplaceNationality",
    "profile.email",
    "profile.gender",
    "profile.idcards",
    "profile.legalstatus",
    "profile.locale",
    "profile.maritalstatus",
    "profile.name",
    "profile.paymentAccounts",
    "profile.phonenumber",
    "profile.titles",
    "profile.updatedat",
    "profile.zoneinfo",
    "profile.verification"
  ],
  "issuer": "https://oidc.sandbox.bankid.cz/",
  "acr_values_supported": [
    "loa2",
    "loa3"
  ],
  "userinfo_encryption_enc_values_supported": [
    "A256GCM"
  ],
  "id_token_encryption_enc_values_supported": [
    "A256GCM"
  ],
  "authorization_endpoint": "https://oidc.sandbox.bankid.cz/auth",
  "service_documentation": "https://oidc.sandbox.bankid.cz/about",
  "request_object_encryption_enc_values_supported": [
    "A256GCM"
  ],
  "device_authorization_endpoint": "https://oidc.sandbox.bankid.cz/devicecode",
  "userinfo_signing_alg_values_supported": [
    "ES512",
    "PS512"
  ],
  "claims_supported": [
    "addresses.buildingapartment",
    "addresses.city",
    "addresses.country",
    "addresses.ruian_reference",
    "addresses.street",
    "addresses.streetnumber",
    "addresses.type",
    "addresses.zipcode",
    "age",
    "birthdate",
    "birthnumber",
    "birthplace",
    "date_of_death",
    "email",
    "email_verified",
    "family_name",
    "gender",
    "given_name",
    "idcards.country",
    "idcards.description",
    "idcards.issue_date",
    "idcards.issuer",
    "idcards.number",
    "idcards.type",
    "idcards.valid_to",
    "limited_legal_capacity",
    "locale",
    "majority",
    "maritalstatus",
    "middle_name",
    "name",
    "nationalities",
    "nickname",
    "paymentAccounts",
    "pep",
    "phone_number",
    "phone_number_verified",
    "preferred_username",
    "primary_nationality",
    "sub",
    "title_prefix",
    "title_suffix",
    "txn",
    "updated_at",
    "verified_claims.verification",
    "zoneinfo"
  ],
  "claim_types_supported": [
    "normal"
  ],
  "op_policy_uri": "https://oidc.sandbox.bankid.cz/about",
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_jwt",
    "private_key_jwt"
  ],
  "response_modes_supported": [
    "query"
  ],
  "token_endpoint": "https://oidc.sandbox.bankid.cz/token",
  "response_types_supported": [
    "code",
    "token"
  ],
  "request_uri_parameter_supported": true,
  "userinfo_encryption_alg_values_supported": [
    "RSA-OAEP-256"
  ],
  "grant_types_supported": [
    "authorization_code",
    "implicit",
    "refresh_token"
  ],
  "end_session_endpoint": "https://oidc.sandbox.bankid.cz/logout",
  "userinfo_endpoint": "https://oidc.sandbox.bankid.cz/userinfo",
  "token_endpoint_auth_signing_alg_values_supported": [
    "ES512",
    "PS512"
  ],
  "op_tos_uri": "https://oidc.sandbox.bankid.cz/about",
  "require_request_uri_registration": true,
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ],
  "id_token_encryption_alg_values_supported": [
    "RSA-OAEP-256"
  ],
  "jwks_uri": "https://oidc.sandbox.bankid.cz/.well-known/jwks",
  "subject_types_supported": [
    "public",
    "pairwise"
  ],
  "id_token_signing_alg_values_supported": [
    "ES512",
    "PS512",
    "none"
  ],
  "request_object_signing_alg_values_supported": [
    "ES512",
    "PS512"
  ],
  "request_object_encryption_alg_values_supported": [
    "RSA-OAEP-256"
  ]
}

JWK Keys Discovery API

Exposed by the Bank and BankID. Authoritatively described in idp_for_bankid.yaml. Not authenticated.

This endpoint returns JSON Web Keys to be used as public keys for verifying OIDC ID Tokens and responses, as well as for encrypting requests.

GET /.well-known/jwks.json

Response 200 OK:

{
  "keys": [
    {
      "alg": "RS256",
      "kid": "1603dfe0af8f4596",
      "key_ops": [
        "sign",
        "verify"
      ],
      "use": "sig",
      "kty": "RSA",
      "x5c": "MIICUDCCAbmgAwIBAgIBADANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJjejEOMAwGA1UECAwFUHJhaGExEDAOBgNVBAoMB0V4YW1wbGUxFDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTIwMDExNjE2NDExOFoXDTIxMDExNTE2NDExOFowRTELMAkGA1UEBhMCY3oxDjAMBgNVBAgMBVByYWhhMRAwDgYDVQQKDAdFeGFtcGxlMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArOEYBRyBhcd6u3phrbU2xvTaBoy6W14CpqqfsBrfsUsuSB+JELBCj3a+zRIvy4EY9cnQbF7cPNxbXdCbGEokAUjIIuVBk/I6XhKRe01vlax82o+eFfIhUfl7Xb2Bx9U3m98Qbt3WNrv+VYJjjFP8HWSsWCHKCazj+yvozjuFXUsCAwEAAaNQME4wHQYDVR0OBBYEFN5SUrsStd4aLhBs+MWGRDxLeUP4MB8GA1UdIwQYMBaAFN5SUrsStd4aLhBs+MWGRDxLeUP4MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAL59fE6itiRrck6Z7RCjwnOnebQJxpoB/L7TUC/aUIXss40mCviBVKD+Hl4+3sGyp4J2LlzzqhFcPgR9NyxQt0bkahJGH0UXvZETJe719UA0kGFrPMdt6ujwB6/rafT6TinzXN0lEEGikersTrh3BR9Hjw+v7nCQ0D5RfuDn6s5s="
    }
  ]
}

HealthCheck API

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Not authenticated.

This endpoint returns the current Bank liveness and outage information.

GET /healthcheck

Response 200 OK:

{
  "status": "OK",
  "description": "BankID API",
  "version": "1.1.0",
  "time": "2020-05-20T11:06:27.767Z",
  "outage_planned_until": null,
  "outage_description": null,
  "poll_interval": 200,
  "details": {
    "dynamic-registration": {
      "status": "OK",
      "description": "Dynamic Registration API",
      "version": "1.1.2",
      "time": "2020-05-20T11:06:27.767Z"
    },
    "oidc-core": {
      "status": "OK",
      "description": "Core OpenID Connect APIs",
      "version": "1.1.7",
      "time": "2020-05-20T11:06:27.767Z"
    },
    "revoke": {
      "status": "OK",
      "description": "OAuth2 Token Revocation API",
      "version": "1.1.2",
      "time": "2020-05-20T11:06:27.768Z"
    },
    "kyc": {
      "status": "OK",
      "description": "KYC API",
      "version": "1.1.0",
      "time": "2020-05-20T11:06:27.768Z"
    }
  }
}

Dynamic Registration API

CRUD over registered clients. Protected by mTLS and HTTP Bearer authentication where bearer token is a JWT signed with a key from /.well-known/jwks.json of the BankID. This JWT contains claims defined in the RegistrationAuthJWT schema.

Example of RegistrationAuthJWT payload. This token is sent in signed form as the value of the client_assertion request header parameter:

{
  "aud": "https://op.example.com/register",
  "jti": "95E3440A-C986-4E8B-9678-605F9B2FE7C5",
  "exp": 1630492200,
  "iat": 1598956200
}

For dynamic registration, the aud parameter in the RegistrationAuthJWT payload always contains the URL of the POST endpoint of the called registration API (ie, also in the case of the PUT, GET and DELETE methods).

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Uses HTTP Bearer authentication using a JWT token signed on the BankID side. See the RegistrationAuthJWT specification..

POST (create) /register

GET (read), PUT (update), DELETE (remove) /register/{client_id}

Request header in case of POST:

POST /register HTTP/1.1
Host: idp.somebank.cz
Content-Type: application/json
client_assertion: eyJraWQiOiJycC1zaWduIiw......7xpA26QF5_Oung7E4y2n6
client_assertion_type: urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer

Request header in case of PUT,GET and DELETE:

POST /register HTTP/1.1
Host: idp.somebank.cz
Content-Type: application/json
client_assertion: eyJraWQiOiJycC1zaWduIiw......7xpA26QF5_Oung7E4y2n6
client_assertion_type: urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
Authorization: Bearer 44010DFF-F77F-461A-8F3D-1466B24C5CC1

Please note that the authorization_access_token value obtained in the POST call must be here sent as a Bearer token in the Authorization header parameter.

Request body (POST and PUT):

{
  "redirect_uris": [
    "https://client.example.com/callback",
    "https://rp.example.com/callback"
  ],
  "response_types": [
    "code"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "application_type": "web",
  "contacts": [
    "ve7jtb@example.com",
    "mary@example.com"
  ],
  "client_name": "My Example",
  "logo_uri": "https://client.example.com/logo.png",
  "client_uri": "https://client.example.com",
  "policy_uri": "https://client.example.com/policy",
  "tos_uri": "https://client.example.com/tos",
  "jwks_uri": "https://client.example.com/my_public_keys.jwks",
  "sector_identifier_uri": "https://other.example.net/file_of_redirect_uris.json",
  "subject_type": "pairwise",
  "id_token_signed_response_alg": "PS512",
  "id_token_encrypted_response_alg": "RSA-OAEP-256",
  "id_token_encrypted_response_enc": "A256GCM",
  "userinfo_signed_response_alg": "PS512",
  "userinfo_encrypted_response_alg": "RSA-OAEP-256",
  "userinfo_encrypted_response_enc": "A256GCM",
  "profile_signed_response_alg": "PS512",
  "profile_encrypted_response_alg": "RSA-OAEP-256",
  "profile_encrypted_response_enc": "A256GCM",
  "request_object_signing_alg": "PS512",
  "request_object_encryption_alg": "RSA-OAEP-256",
  "request_object_encryption_enc": "A256GCM",
  "token_endpoint_auth_method": "private_key_jwt",
  "token_endpoint_auth_signing_alg": "PS512",
  "default_max_age": 3600,
  "require_auth_time": false,
  "default_acr_values": [
    "loa3"
  ],
  "initiate_login_uri": "https://client.example.com/login",
  "request_uris": [
    "https://client.example.com/rf.txt",
    "#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA"
  ],
  "backchannel_logout_uri": "https://client.example.com/backchannel_logout\"",
  "scope": "openid profile.name profile.addresses offline_access",
  "required_scope": "profile.addresses",
  "notification_uri": "https://api.bankid.cz/v1/notifyme"
}

Response 200 OK:

{
  "client_id": "D40D25DB-C330-4331-A191-0A4F6CCD17D8",
  "client_secret": "689A79B8-9EE4-45A9-83B1-4F0130649394",
  "registration_access_token": "44010DFF-F77F-461A-8F3D-1466B24C5CC1",
  "registration_client_uri": "https://idp.example.com/connect/register/D40D25DB-C330-4331-A191-0A4F6CCD17D8",
  "client_id_issued_at": 1579263956,
  "redirect_uris": [
    "https://client.example.com/callback",
    "https://rp.example.com/callback"
  ],
  "response_types": [
    "code"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "application_type": "web",
  "contacts": [
    "ve7jtb@example.com",
    "mary@example.com"
  ],
  "client_name": "My Example",
  "logo_uri": "https://client.example.com/logo.png",
  "client_uri": "https://client.example.com",
  "policy_uri": "https://client.example.com/policy",
  "tos_uri": "https://client.example.com/tos",
  "jwks_uri": "https://client.example.com/my_public_keys.jwks",
  "sector_identifier_uri": "https://other.example.net/file_of_redirect_uris.json",
  "subject_type": "pairwise",
  "id_token_signed_response_alg": "PS512",
  "id_token_encrypted_response_alg": "RSA-OAEP-256",
  "id_token_encrypted_response_enc": "A256GCM",
  "userinfo_signed_response_alg": "PS512",
  "userinfo_encrypted_response_alg": "RSA-OAEP-256",
  "userinfo_encrypted_response_enc": "A256GCM",
  "profile_signed_response_alg": "PS512",
  "profile_encrypted_response_alg": "RSA-OAEP-256",
  "profile_encrypted_response_enc": "A256GCM",
  "request_object_signing_alg": "PS512",
  "request_object_encryption_alg": "RSA-OAEP-256",
  "request_object_encryption_enc": "A256GCM",
  "token_endpoint_auth_method": "private_key_jwt",
  "token_endpoint_auth_signing_alg": "PS512",
  "default_max_age": 3600,
  "require_auth_time": false,
  "default_acr_values": [
    "loa3"
  ],
  "initiate_login_uri": "https://client.example.com/login",
  "request_uris": [
    "https://client.example.com/rf.txt",
    "#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA"
  ],
  "backchannel_logout_uri": "https://client.example.com/backchannel_logout\"",
  "scope": "openid profile.name profile.addresses offline_access",
  "required_scope": "profile.addresses",
  "notification_uri": "https://api.bankid.cz/v1/notifyme"
}

Response 400 Request invalid:

{
  "error": "invalid_redirect_uri",
  "error_description": "Redirect uri must be using https scheme"
}

Sequence diagram of new application registration


Authorization API

For Service providers, BankID supports various Authorization flow types of grants for the authentication process and obtaining access_token and id_token.

Flow typeDescription
authorization_code refresh_tokenCode grant is the most common authentication flow. It allows applications to securely exchange tokens and obtain a refresh_token in case of offline access.
implicitImplicit flow is suitable in those cases where it is impossible to communicate through back-end solutions/servers.

No matter what type of grant the Service Provider has chosen for its application, all calls to the IDP are made by BankID within the code grant flow!

Diagram with example of code grant flow

The sequence diagram shows the course of the authentication flow with the exchange of code for tokens. In the case of offline access, the chart is supplemented by an example of exchanging a refresh token for an access token.

Diagram with example of implicit flow

The sequence diagram shows the acquisition of a token via the implicit flow. The diagram also shows the acquisition of a token from the IDP, which in any case takes place in the code grant flow mode.

From Service Providers, BankID recommends considering using the implicit flow approach, especially from a security perspective!

The authorization GET endpoint is a starting point for OAuth2 and OpenID Connect authorization code flows. This request authenticates the user and returns tokens to the client application as a part of the callback response.

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Not authenticated.

GET /auth?
  redirect_uri=https://bankid.cz/callback
  &client_id=D40D25DB-C330
  &response_type=code
  &state=1234
  &scope=openid%20profile.name%20profile.gender%20offline_access
Host: somebank.cz

Scope openid is required! In the context of its use, it is specified that the authorization flow control will be a process established by the OpenID standard (e.g., including the issuing of id_token).

The scope offline_access should be specified whenever the application, based on the authentication flow, requires the release of not only access_token but also refresh_token. For such a case, the application must have registered code grant flow and refresh_token grant (during dynamic registration to the IDP).

Response redirection:

HTTP/1.1 302 Found
Location: https://bankid.cz/callback?
  code=6a72a932a67cf859570a8fb986dcefce19c844995d30fe1ad32d1e5af5579eb2
  &state=1234

Error redirection:

HTTP/1.1 302 Found
Location: https://bankid.cz/callback?
  error=unauthorized_client
  &state=1234

Tokens used in the BankID solution

An overview of the tokens and their characteristics that BankID requires from IDP when issuing these tokens.

Tokens

Token typeUseRequired minimum token validity
access_tokenToken used to authorize API requests.3600 seconds
refresh_tokenToken representing offline (long-term) access. Refresh_token is used to release a new short-term access_token.1 year
id_tokenThis token was identifying the end-user within the current context and session.At least as long as access_token (3600 seconds)

Basic assumptions:

  • The issuance of these tokens MUST be independent of the context of previous and future authentications.
  • The authentication process MUST do not affect the validity of previously issued tokens. Except in specific cases where the authentication process will be evaluated as a security risk and, for example, if the authentication device will be temporarily or permanently blocked.
  • The authentication process MUST do not affect the context (scopes) of previously issued tokens.
  • Any token CAN be invalidated with immediate effect using the mechanisms provided for this purpose (revoke, logout services).
  • Whether an application has a scope registered as optional or required has no effect on the scopes' final composition

in the token. Suppose the application does not require any of the required registered scopes in a specific authentication. In that case, this scope will not appear either on the consent screen or during successful authentication at the token. The scope obligation only affects the GUI controls on the consent screen.

Access Token

The access_token is the main result of the authentication process. This token is used to call user-centric APIs (primarily /userinfo and /profile). In the case of BankID, it may be an unsigned stateless token. The access_token hash can be specified as one of the id_token claims (specifically at_hash claim), which is issued simultaneously with the access_token to ensure integrity.

This token's validity can be found directly at issue in response (authorization_code and refresh_token grant flow) to the API /token or call the API /token-info. The response to the call /token MUST also include a list of scopes for the issued token.

Refresh Token

Refresh_token is used to issue a new access_token, for example, if the access_token expires. Refresh_token is issued if the application requesting its release has a refresh_token grant registered with the IDP and the application asked for an offline_access scope in the authentication request.

The scope of this token's context corresponds to the result of the authentication at which it was issued. When exchanging refresh_token for access_token, the application can request the same or smaller range of scopes.

ID Token

The id_token represents the identification of the end-user and is issued together with the access_token. The id_token is always signed and contains information about the time of issue and validity of the token. In the case of BankID, it always contains the end-user identifier as a claim sub.

The id_token is issued signed by the issuer's key, and the application must verify this signature in each case.

The id_token can be issued in encrypted form if this IDP declares in its configuration. Encryption is performed using one of the application's public encryption keys (listed on the registered JWKs URI). BankID does not directly require this feature (because the required id_token does not contain any sensitive data).


Token exchange API

The token endpoint is used by the client to obtain an access token by presenting its authorization grant or refresh token.

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Uses client credentials for authentication.

POST /token

Authorization code exchange request:

POST /token HTTP/1.1
Host: idp.somebank.cz
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=2a54acba-f5d8-48cb-9c28-a06583724adb
&code=8BFAC1DA-3F94-4BBD-A743-473080FB6073
&redirect_uri=https://bankid.cz/callback
&client_assertion=eyJraWQiOiJycC1zaWduIiw......7xpA26QF5_Oung7E4y2n6
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer

Client assertion JWT payload for /token endpoint example:

{
  "aud": "https://idp.somebank.cz/token",
  "sub": "D40D25DB-C330",
  "iss": "D40D25DB-C330",
  "exp": 1605544030,
  "iat": 1605540430,
  "jti": "c7588da5-3732-421d-a974-1427bc5035c6"
}

Authorization code exchange response 200 OK:

{
  "access_token": "c03e997c-aa96-4b3f-ad0c-98626833145d",
  "token_type": "Bearer",
  "refresh_token": "1f703f5f-75da-4b58-a1b0-e315700e4227",
  "expires_in": 6000,
  "scope": "openid profile.name profile.addresses",
  "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

Refresh token exchange request body:

POST /token HTTP/1.1
Host: idp.somebank.cz
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&scope=openid%20profile.name%20profile.addresses
&code=A9B54609-FF9E-42F0-B089-89E1E73E224F
&redirect_uri=https://bankid.cz/callback
&client_assertion=eyJraWQiOiJycC1zaWduIiw......7xpA26QF5_Oung7E4y2n6
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer

Client assertion JWT payload for /token endpoint example:

{
  "aud": "https://idp.somebank.cz/token",
  "sub": "D40D25DB-C330",
  "iss": "D40D25DB-C330",
  "exp": 1605544030,
  "iat": 1605540430,
  "jti": "c7588da5-3732-421d-a974-1427bc5035c6"
}

Refresh token exchange response 200 OK:

{
  "access_token": "c03e997c-aa96-4b3f-ad0c-98626833145d",
  "token_type": "Bearer",
  "expires_in": 30000001,
  "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

Response 400 Request invalid:

{
  "error": "invalid_request",
  "error_description": "The request is missing a required parameter"
}

TokenInfo API

The introspection endpoint is an OAuth 2.0 endpoint that takes a parameter representing an OAuth 2.0 token and returns a JSON representing the meta information surrounding the token, including whether this token is currently active.

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Uses client credentials or a client access token for authentication.

POST /token-info

Request body:

POST /token-info HTTP/1.1
Host: idp.somebank.cz
Content-Type: application/x-www-form-urlencoded

token=WwVEraxkI7KbtP31wD3XSpZKqGpsLiXg
&token_type_hin=refresh_token
&client_assertion=eyJraWQiOiJycC1zaWduIiw......7xpA26QF5_Oung7E4y2n6
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer

Client assertion JWT payload for /token-info endpoint example:

{
  "aud": "https://idp.somebank.cz/token-info",
  "sub": "D40D25DB-C330",
  "iss": "D40D25DB-C330",
  "exp": 1605544030,
  "iat": 1605540430,
  "jti": "c7588da5-3732-421d-a974-1427bc5035c6"
}

Response:

{
  "active": true,
  "scope": "openid profile.addresses",
  "client_id": "d1bdc32e-1b06-4609-9f60-073685267f88",
  "token_type": "access_token",
  "exp": 1419356238,
  "iat": 1419350238,
  "sub": "25657805-66d4-4707-980a-f12429f17592",
  "aud": "https://idp.somebank.cz/token-info",
  "iss": "https://idp.somebank.com/"
}

Token revocation API

Token revocation endpoint. Revokes access and refresh tokens. Revoking a refresh token effectively cancels the "session".

Exposed by the Bank. Authoritatively described in idp_for_bankid.yaml. Uses client credentials or a client access token for authentication.

POST /revoke

Request body:

POST /revoke HTTP/1.1
Host: idp.somebank.cz
Content-Type: application/x-www-form-urlencoded

token=WwVEraxkI7KbtP31wD3XSpZKqGpsLiXg
&token_type_hin=refresh_token
&client_assertion=eyJraWQiOiJycC1zaWduIiw......7xpA26QF5_Oung7E4y2n6
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer

Client assertion JWT payload for /revoke endpoint example:

{
  "aud": "https://idp.somebank.cz/revoke",
  "exp": 1605544030,
  "iat": 1605540430,
  "jti": "c7588da5-3732-421d-a974-1427bc5035c6"
}

BankID API endpoint overview

The following endpoints are to be made available to the Bank by the BankID. Each of these endpoints only contains illustratory examples. Please see the referenced OpenAPI documents for a full authoritative description of these resources.

Logout API

Logout endpoint specified in OpenID.BackChannelLogout.

Exposed by BankID. Authoritatively described in bankid_for_idp.yaml. Not authenticated.

POST /back-channel/logout

Request body (Form encoded):

logout_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

User info API

The UserInfo and Profile API are the basic interfaces for retrieving authenticated user data. The range of user-approved scopes strictly controls the range of data. A detailed list of scopes and their associated claims is available in the API technical documentation idp-for-bankid.yaml.

UserInfo endpoint is intended primarily for frequently performed identification and authentication, such as repeated login processes to the system/application. This endpoint's data range corresponds to the data ranges for logins using social network identities (Google, LinkedIn).

Access is authorized using a valid end-user access_token that was obtained from a completed login flow.

GET /userinfo

Request example:

GET /userinfo HTTP/1.1
Host: idp.somebank.cz
Accept: application/jwt
Authorization: Bearer eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi

Response 200 OK (application/jwt):

eyJraWQiOiJBNjJGMjIyNUJGNzBCIiwiY3R5IjoiSldUIiwiZW5jIjoiQTI1NkdDTSIsImFsZyI6IlJTQS1PQUVQLTI1NiJ9.rHJXU29na1PQTqVbmwgyfub
RnWN9X5IhkERXrlF6pffr3vjPXfNe7M-YvPlDf7qiUvAlYGHCoeYvH31q6RmaLI9YHsHWXWjpaQjoI-ubLduY1wN2t6xUb2g0bH-RE48zawDL18ZLvEn_6f8
97Y2SAYO3xEzRTHifmDJhdLPPhoYi0mACxoSWCeeXIbe1wPs235aNY2K6CjTlbnU-aIfiBagyRWSeaHjColbTVEXFfGvoLWfyayaftvkezxP9zGjIaQbi9KNX
cx4NgCp99vk-rfchLpuQHFNVXldKd3mEXhwlKeG-rp0AMpONk8tmrXuTtD0XmaQMVOXO585mqWrvOblqeeXMXUwYQsOx02F3QdfsJ3-5irT4IBkLo-KZRzc5J
Jwh-UBKcK78IWfSssiTAsC3cbZUyG3hwjguf13lIJGbwmjlZZ6u9hPxRgP1Ke_wgJ20pUEDgtPOzZMPVppM4Iloj6XpX0S4kYDFhhH0MQCcBVTHBxTgaBVjW8
RVliL5-5yowZVVuJMJiyMWpTY1K2EdX2lUjyW-a2hkafobRag0aKQaKHLLZeDV3Q26RjJ134xI86ftEjHl-KePc_q5DqjZbqJ4-MGD-ZGXJAyk_29vdH3I3a
wu-rZineAmAXtJd0FTaBeYPBXHLiERoGN1DPQPZSTD2XonFLRDIJN_UVo.fbYdUiuJ_Q9Bl4IY.c0gJoDfJideIwVUGyG9fQWmP5CT99Ebc95WCqPx_2z9Hx
vs4cTz8OFOoKdOueUZhbPH6quVgaQsdoOD8-eotRd5uTAhWn06o3CVxUVwhOxwbgr-NGQjNLn6F6DDbPXRF_S5mZ6_1QdRW50Un119C6TWqEFWTdYewqWJKZ
97MbBSDS4hfCjQbzVFaNL5sdiAJn5hK6FZtquBcxzj84joLqMuZo5LGIPE9WWScMzzgfuf8RjRENSipNQdFqJLEeXlA9xI13jx0_iJQxv0OhR4zZUMG0UQ9v
GnTJH-agNGxClDPM4Z9f40Od34bdGIOke0-AiIAXvVPelnDVhNR14fuGcHlNZ53ftCYqP6KIECOMCW94_J8Wxz2OUhwocGYI5_bvL24opLQAC9qlHXJk5Syx
jkmPROwypa3Fwx0Al8o7oQUCr8Az2Q-e_-jugSYhVi99hQBCIO5oiK2WYB6V04Ka8tXYM9SVfyANY_82vf3GR9cwuQz_pUwfw-YjLH5FDmXCjZzBKeHooLJ0
odyA1agxUuqOhAsEz9tQ64w9wNXe3NI7PVgmEvLMvp6DPfcuBaZuR_gzomkV2JefoguirQ8dMfeulSGIBY8h5Icq9Nt5S6MTKpUsulxfgRRrlxwMP-pvGaf4
5hUUsVQTSglrZ8hU_anEuVprShwFPqdTCcYYqne9dGjfw8O8vqAi2bLNUxbfnvdi1WblbYtqS7_VgXcu7Hfzb_u1YyM0jfnwzwJaKx3ptcNwdQodiGpot0p
vSpRf1iYj4Sp806Tz3eVdnuY4UDI6XPHXIGtMal6wqR1oCNepSyAXfZ_J_HOj4KMTnpq1cW0XQQOAT6APHeL3VeMpk94WVInCkHvoc1ZJj3Sf0NATmVOj9XR
y_Z7lnvwdIu7C1J6EFebnxkPB0rWSouKEcJVnNLT8i7Nx2WiXM1JJzpVhD0bgM2VAU0UcnQQmR-DnsKsBUoPXf8NFODqQob5WYr0z-1xj_2TT5KeUBNiuKcQ
8arAeq57FLPWeN9QGun9jakdkAO76dkQYuwew6pWuAJ1prBswvQCmSkzVOGSu644WOSALwqwN4tKoQo008gEMvlpwXoBCZ0Tv5iHBoggsYExdc1dCIGsLAoS
FkhhSg26YVWBLBXs6X2uyqAZXzVBV2-Mn3dXpuyKXehZmPEEjfGQgyrXuo8XSW7hHVyOe-u-n-nJ7WLnGkBMlih8h2JUvyBJ3fXGLn5wXXlKZTRCIsvAjq1Q
D835KWloJNy0_3el1Uew2GgmY8uc2EloKmNDHbFRwQPZori0JBaW8CdZe8pFiiNt90RT837V01vWEN5YLDuDVcsHr77ueiiyu0v3ZZjRVZtUO1XqKa4RlL3IK
utb0twc6ehxbF4OQ9LfKKfS2SXljWyKV9VDqp0HhnJhJyJOwIJ9s_Aq1ue7xntbrs2D9pg17f7d6gCaqkfM5_kd4e8FertkDfx4cfBGhFEF5tL4oIUJy-l6xh
PBDwq0KqEct6MMf9oboQKjEqKnDYSvCcdeQlfd4AHooBXssRQ6uiiQ4ROJBM_MlLaPYsKCBQdp9KRzJNeb3OcDHfVWJ_C949I-YRgpyEBS6-jNJYrFrIJpPG
C2sV4KpB5lWLEZsKKSAFGGp97VPccw3pR_DIsaefC5ZCD-W5PPuVaUvUlgPtQB1oYRseutYXECbiV2VCkByLhvyt11XpK2eviZxZ0XgptmDSiyyGZrjcNF9K-
2taoS4XiDRsCC2OABcCn4TQqi4tiElQ.LWq6zSH5jUdt6V-zdo63qQ

Sequence diagram of the Userinfo API call

Profile API

Unlike UserInfo, the Profile API is designed primarily to perform KYC or AML client authentication. This corresponds to a much more extensive range of data provided. A complete overview of claims and scopes is in the detailed API documentation idp-for-bankid.yaml.

Access is authorized using a valid end-user access_token that was obtained from a completed login flow.

GET https://oidc.sandbox.bankid.cz/profile

Request example:

GET /profile HTTP/1.1
Host: idp.somebank.cz
Accept: application/json
Authorization: Bearer eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi

Response 200 OK (application/jwt):

eyJraWQiOiJBNjJGMjIyNUJGNzBCIiwiY3R5IjoiSldUIiwiZW5jIjoiQTI1NkdDTSIsImFsZyI6IlJTQS1PQUVQLTI1NiJ9.rHJXU29na1PQTqVbmwgyfub
RnWN9X5IhkERXrlF6pffr3vjPXfNe7M-YvPlDf7qiUvAlYGHCoeYvH31q6RmaLI9YHsHWXWjpaQjoI-ubLduY1wN2t6xUb2g0bH-RE48zawDL18ZLvEn_6f8
97Y2SAYO3xEzRTHifmDJhdLPPhoYi0mACxoSWCeeXIbe1wPs235aNY2K6CjTlbnU-aIfiBagyRWSeaHjColbTVEXFfGvoLWfyayaftvkezxP9zGjIaQbi9KNX
cx4NgCp99vk-rfchLpuQHFNVXldKd3mEXhwlKeG-rp0AMpONk8tmrXuTtD0XmaQMVOXO585mqWrvOblqeeXMXUwYQsOx02F3QdfsJ3-5irT4IBkLo-KZRzc5J
Jwh-UBKcK78IWfSssiTAsC3cbZUyG3hwjguf13lIJGbwmjlZZ6u9hPxRgP1Ke_wgJ20pUEDgtPOzZMPVppM4Iloj6XpX0S4kYDFhhH0MQCcBVTHBxTgaBVjW8
RVliL5-5yowZVVuJMJiyMWpTY1K2EdX2lUjyW-a2hkafobRag0aKQaKHLLZeDV3Q26RjJ134xI86ftEjHl-KePc_q5DqjZbqJ4-MGD-ZGXJAyk_29vdH3I3a
wu-rZineAmAXtJd0FTaBeYPBXHLiERoGN1DPQPZSTD2XonFLRDIJN_UVo.fbYdUiuJ_Q9Bl4IY.c0gJoDfJideIwVUGyG9fQWmP5CT99Ebc95WCqPx_2z9Hx
vs4cTz8OFOoKdOueUZhbPH6quVgaQsdoOD8-eotRd5uTAhWn06o3CVxUVwhOxwbgr-NGQjNLn6F6DDbPXRF_S5mZ6_1QdRW50Un119C6TWqEFWTdYewqWJKZ
97MbBSDS4hfCjQbzVFaNL5sdiAJn5hK6FZtquBcxzj84joLqMuZo5LGIPE9WWScMzzgfuf8RjRENSipNQdFqJLEeXlA9xI13jx0_iJQxv0OhR4zZUMG0UQ9v
GnTJH-agNGxClDPM4Z9f40Od34bdGIOke0-AiIAXvVPelnDVhNR14fuGcHlNZ53ftCYqP6KIECOMCW94_J8Wxz2OUhwocGYI5_bvL24opLQAC9qlHXJk5Syx
jkmPROwypa3Fwx0Al8o7oQUCr8Az2Q-e_-jugSYhVi99hQBCIO5oiK2WYB6V04Ka8tXYM9SVfyANY_82vf3GR9cwuQz_pUwfw-YjLH5FDmXCjZzBKeHooLJ0
odyA1agxUuqOhAsEz9tQ64w9wNXe3NI7PVgmEvLMvp6DPfcuBaZuR_gzomkV2JefoguirQ8dMfeulSGIBY8h5Icq9Nt5S6MTKpUsulxfgRRrlxwMP-pvGaf4
5hUUsVQTSglrZ8hU_anEuVprShwFPqdTCcYYqne9dGjfw8O8vqAi2bLNUxbfnvdi1WblbYtqS7_VgXcu7Hfzb_u1YyM0jfnwzwJaKx3ptcNwdQodiGpot0p
vSpRf1iYj4Sp806Tz3eVdnuY4UDI6XPHXIGtMal6wqR1oCNepSyAXfZ_J_HOj4KMTnpq1cW0XQQOAT6APHeL3VeMpk94WVInCkHvoc1ZJj3Sf0NATmVOj9XR
y_Z7lnvwdIu7C1J6EFebnxkPB0rWSouKEcJVnNLT8i7Nx2WiXM1JJzpVhD0bgM2VAU0UcnQQmR-DnsKsBUoPXf8NFODqQob5WYr0z-1xj_2TT5KeUBNiuKcQ
8arAeq57FLPWeN9QGun9jakdkAO76dkQYuwew6pWuAJ1prBswvQCmSkzVOGSu644WOSALwqwN4tKoQo008gEMvlpwXoBCZ0Tv5iHBoggsYExdc1dCIGsLAoS
FkhhSg26YVWBLBXs6X2uyqAZXzVBV2-Mn3dXpuyKXehZmPEEjfGQgyrXuo8XSW7hHVyOe-u-n-nJ7WLnGkBMlih8h2JUvyBJ3fXGLn5wXXlKZTRCIsvAjq1Q
D835KWloJNy0_3el1Uew2GgmY8uc2EloKmNDHbFRwQPZori0JBaW8CdZe8pFiiNt90RT837V01vWEN5YLDuDVcsHr77ueiiyu0v3ZZjRVZtUO1XqKa4RlL3IK
utb0twc6ehxbF4OQ9LfKKfS2SXljWyKV9VDqp0HhnJhJyJOwIJ9s_Aq1ue7xntbrs2D9pg17f7d6gCaqkfM5_kd4e8FertkDfx4cfBGhFEF5tL4oIUJy-l6xh
PBDwq0KqEct6MMf9oboQKjEqKnDYSvCcdeQlfd4AHooBXssRQ6uiiQ4ROJBM_MlLaPYsKCBQdp9KRzJNeb3OcDHfVWJ_C949I-YRgpyEBS6-jNJYrFrIJpPG
C2sV4KpB5lWLEZsKKSAFGGp97VPccw3pR_DIsaefC5ZCD-W5PPuVaUvUlgPtQB1oYRseutYXECbiV2VCkByLhvyt11XpK2eviZxZ0XgptmDSiyyGZrjcNF9K-
2taoS4XiDRsCC2OABcCn4TQqi4tiElQ.LWq6zSH5jUdt6V-zdo63qQ

Sequence diagram of the Profile API call


Notification API

Batch notification endpoint which accepts a list of notification tokens. These are mainly claim update notifications.

Exposed by RP. Authoritatively described in bankid_for_idp.yaml. Not authenticated.

POST /notify

Request body (Form encoded):

notification_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Notification token JWT:

{
  "iss": "https://idp.example.com",
  "iat": "1582797458",
  "jti": "913CC0F7-27BA-40D9-9F4F-8DF74AC3596B",
  "events": [
    {
      "type": "claim_updated",
      "original_event_at": "2020-06-15T14:16:32",
      "sub": "9456B875-62D3-4533-A502-E05D39936F3A",
      "affected_client_ids": [
        "F932FF05-E04C-4CD1-86E4-CE82F1F51EFB"
      ],
      "affected_claims": [
        "profile.phone_number"
      ]
    }
  ]
}

Sequence diagram of the full notification flow

Cookies are bad for your teeth but good for BankID • Cookie policy