Skip to content

Authorization

Login and authorization flows

Client Application

Info

To access the API v2 you need to create Client Application and obtain Client Application credentials. Please follow the Getting started guide.

The Client Application is used to differentiate API usages and allows you to offer the same integration for multiple independent customers.

The Client ID and Client Secret is used only to connect your Application with the Cloud of Dotypos User. Provided Client ID and Client Secret should be kept private and used only for the connection of your Application.

Success

TIP: For your first steps you can use our Postman collection.

Connecting Client Application (Refresh Token)

To use the API you need to obtain the Refresh Token first.

Flow description

To retrieve the Refresh Token, you need to redirect the user from your application to the connector web page where the user has to allow access for your application (see the screenshot below). After granting the access, the user will be redirected to the webhook redirect_uri with query parameters which contain the Refresh Token.

This Refresh Token should be stored safely in your application and used for retrieving Access Token required for all authenticated API endpoints.

Connector web page

Connector endpoint

Deprecated GET Method

The legacy GET method (/client/connect) is deprecated. If you are currently using the GET method, please follow the Migration Guide to upgrade to the Connector v2 POST authentication.


POST https://admin.dotykacka.cz/client/connect/v2

Info

This is not a REST API endpoint. It must be opened using a web browser (via form submission) to allow users to interact with the page and grant access.


Request Parameters

All parameters except state are required and must be sent as form data (application/x-www-form-urlencoded).

Name Type Description
client_id* string Client ID (received after registration)
timestamp* integer Unix timestamp in seconds (current time)
signature* string HMAC-SHA256 signature (see calculation below)
scope* string Scope of requested access - * is the only supported value
redirect_uri* string URI to return the user to after registration is complete
state string A value to maintain state between request and callback (CSRF protection)

Timestamp Format

Unix timestamp in seconds (integer)

  • Example: 1704123456
  • Generation: Current UTC time in seconds since January 1, 1970

Example Generation:

timestamp = Math.floor(Date.now() / 1000);

Signature Calculation

The signature is calculated using HMAC-SHA256 algorithm.

Step-by-step:

  1. Generate current timestamp (Unix time in seconds)
  2. Convert the timestamp to a string
  3. Apply HMAC-SHA256 using your client_secret as the key and timestamp string as the message
  4. Convert the result to hexadecimal format (64 characters)
timestamp = 1704123456                                    (current time in seconds)
message = "1704123456"                                    (convert to string)
signature = HMAC_SHA256(key: client_secret, message)      (apply HMAC)
result = "a1b2c3d4e5f6..."                                (64 hex characters)

Implementation Example

The following example can be used for testing the new connector. This page allows a developer to manually input their credentials to generate their refresh token.

What this example does:

  1. Show simple HTML form for entering credentials
  2. When submitted, generates a current Unix timestamp (in seconds)
  3. Calculates the HMAC-SHA256 signature using the client secret and timestamp
  4. Creates a dynamic POST form with all required parameters (client_id, timestamp, signature, scope, redirect_uri, state)
  5. Submits the form to the connector endpoint in a new browser window
  6. Browser opens the authentication flow where the user can log in and authorize the application
    <form id="oauth-form">
        <p>
            <label for="client_id">Client ID *</label><br>
            <input type="text" id="client_id">
        </p>
        <p>
            <label for="client_secret">Client Secret *</label><br>
            <input type="password" id="client_secret"><br>
        </p>
        <p>
            <label for="redirect_uri">Redirect URI *</label><br>
            <input type="url" id="redirect_uri" value="https://dotykacka.cz">
        </p>
        <p>
            <label for="state">State (optional)</label><br>
            <input type="text" id="state">
        </p>
        <p>
            <button type="submit">Connect</button>
        </p>
    </form>

    <script>
        // HMAC-SHA256 helper function
        async function hmacSHA256(key, message) {
            const encoder = new TextEncoder();
            const keyData = encoder.encode(key);
            const messageData = encoder.encode(message);

            const cryptoKey = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
            const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageData);
            // Convert to hex string
            return Array.from(new Uint8Array(signature)).map(b => b.toString(16).padStart(2, '0')).join('');
        }

        document.getElementById('oauth-form').addEventListener('submit', async function(e) {
            e.preventDefault();                
            const clientId = document.getElementById('client_id').value;
            const clientSecret = document.getElementById('client_secret').value;
            const redirectUri = document.getElementById('redirect_uri').value;
            let state = document.getElementById('state').value;
            if (!state) state = 'state_' + Math.random().toString(36).substring(2, 15);

            const timestamp = Math.floor(Date.now() / 1000);
            const signature = await hmacSHA256(clientSecret, String(timestamp));

            const form = document.createElement('form');
            form.method = 'POST';
            form.action = 'https://admin.dotykacka.cz/client/connect/v2';
            form.target = 'dotykacka_oauth';

            const fields = { client_id: clientId, timestamp: timestamp, signature: signature, scope: '*', redirect_uri: redirectUri, state: state };
            for (const [name, value] of Object.entries(fields)) {
                const input = document.createElement('input');
                input.type = 'hidden';
                input.name = name;
                input.value = value;
                form.appendChild(input);
            }

            document.body.appendChild(form);
            form.submit();
        });
    </script>

Time Synchronization

Ensure your system clock is synchronized (e.g., using NTP). If the timestamp is outside the valid window, the request will be rejected with an authentication error.

Authentication Flow

After initiating the connection, users have approximately 15 minutes to complete the login and cloud selection process.

Response

After successful authentication and approval, the user will be redirected to redirect_uri with the following query parameters:

Name Description
token Refresh Token
cloudid Selected Cloud ID
state CSRF parameter (provided only if presented in redirect request)

Example redirect:

https://your-app.com/callback?token=abc123def456&cloudid=789&state=random-csrf-token

Testing Tip

If your application is internal and single purpose only you can use a dummy url (e.g. https://dotykacka.cz) and copy the token value from the url after the redirection.
Don't use this for external client implementations.


Troubleshooting

Error: "The connection has expired. Check the time settings on your device."

This error occurs when:

  • Your timestamp is outside the valid time window (±1 minute during connection, or older than 15 minutes after login)
  • Your system clock is not synchronized

Solution:

  • Ensure your system clock is synchronized with an NTP server
  • Try connecting again with current timestamp
  • Check if your device's date and time settings are correct

Error: "Unknown client application or wrong application secret"

This error occurs when:

  • The client_id is invalid or not registered
  • The HMAC signature is incorrect
  • The client_secret used for signature calculation is wrong

Solution:

  • Verify your client_id is correct
  • Verify your client_secret is correct
  • Check the signature calculation:
    • timestamp parameter must be the timestamp as a string
    • Use HMAC-SHA256 algorithm
    • Output must be hex-encoded (64 characters)

Signing into API v2 (Access Token)

To call any of the authenticated API v2 endpoints you need to obtain the Access Token first.

Get Access Token

POST https://api.dotykacka.cz/v2/signin/token

Returns Access Token for a provided Refresh Token. Default validity of Access Token is one hour (not guaranteed). The request body must be in the JSON format (form-data is not accepted and returns error).

Headers

Name Type Description
Authorization* string User $refreshToken

Request Body

Name Type Description
_cloudId string Cloud ID, should be specified to get access to the most endpoints
{
    "accessToken": "eyJ0.eyJ1.eyJ2..."
}
{}

Access Token without Cloud ID (special case)

In some special cases you may want to get an Access Token without specifying the cloud ID. To do this, send an empty JSON object in the request body. Such token allows you only to Get list of clouds. Access to all other endpoints with _cloudId in the URI will be denied.

{
}

Access Token with Cloud ID (standard use-case)

To get access to all endpoints (standard use-case) you need to retrieve the Access Token for the specific cloud. This is done by specifying the cloud ID in the request JSON body.

{
    "_cloudId": {cloudId}
}

Info

The returned Access Token will allow you to access the specified cloud only. To obtain access into another cloud you need to call the Get Access Token again with a new cloud ID in the JSON body and use the new Access Token to call endpoints for this cloud.

Access Token usage

For each API v2 authenticated request, you need to include the Access Token in the HTTP request headers:

Authorization: Bearer {AccessToken}

This is described with every endpoint method in the documentation.

Warning

Please see the Breaking changes page for more info on the planned changes in validation.