Authentication

Obtain token

Note

API credentials are sent to your e-mail after registration. You can regenerate them anytime in Control panel > API Access.

Request

loginstring required

Your API key.

passwordstring required

Your API secret.

POST[base]/token/

$ curl --request POST \
       --url https://[base]/token/ \
       --header 'content-type: application/vnd.api+json' \
       --data '{
            "data": {
              "type": "auth-token",
              "attributes": {
                "login": "<Change to your API key>",
                "password": "<Change to your secret>"
              }
            }
          }'
import requests

url = 'https://[base]/token/'

headers = {
    'content-type': 'application/vnd.api+json',
}

data = {
    'data': {
        'type': 'auth-token',
        'attributes': {
            'login': '<Change to your login>',
            'password': '<Change to your secret>',
        },
    },
}

requests.post(url, headers=headers, json=data)
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new GuzzleHttp\Client();
try {
    $res = $client->post('https://[base]/token/', [
        'json' => [
            'data' => [
                'type' => 'auth-token',
                'attributes' => [
                    'login' => '<Change to your login>',
                    'password' => '<Change to your secret>',
                ],
            ],
        ],
        'headers' => [
            'Content-Type' => 'application/vnd.api+json',
        ],
    ]);
    echo $res->getBody();
} catch (RequestException $e) {}

Response

access string

Your access token. It has an expiry time of about a minute and after expiration should be refreshed.

refresh string

A long-living token that is used for obtaining new access tokens.

access_expired_at string

Expiration time for access token as per ISO 8601 with μs precision and timezone included: YYYY-MM-DDThh:mm:ss[.SSSSSS]±hh:mm.

refresh_expired_at string

Expiration time for refresh token as per ISO 8601 with μs precision and timezone included: YYYY-MM-DDThh:mm:ss[.SSSSSS]±hh:mm.

is_2fa_confirmed boolean

If true, 2FA is enabled.

meta.time string

Time of request receiving as per ISO 8601 with μs precision and timezone included: YYYY-MM-DDThh:mm:ss[.SSSSSS]±hh:mm.

meta.sign string

HMAC signature for a response payload authentication. To verify that the refresh token was sent by us, generate an HMAC signature using the sha256 as algorithm: sha256 hash of the concatenation of your login and password as a key, and the concatenation of meta.time and refresh token fields as a message. Refer to Auth verification example below for sign verification instance.

RESPONSE BODY EXAMPLE
{
  "data": {
    "type": "auth-token",
    "id": "0",
    "attributes": {
      "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
      "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
      "access_expired_at": "2020-12-29T05:42:11.925654Z",
      "refresh_expired_at": "2020-12-29T11:27:11.925654Z",
      "is_2fa_confirmed": false
    }
  },
  "meta": {
    "time": "2020-12-29T05:27:11.925654Z",
    "sign": "bcd6519ce27fed2ce9efe49cd09b387f050c0122c962c18ff474132bf1e88e9a"
  }
}

Response codes

200 Success.

400 Bad Request. No active account found with the given credentials.

429 Too Many Requests. More than 15 requests were sent in 60 seconds, the request was throttled.


Refresh token

Important

Once you receive a new key pair using your refresh token, the previous refresh token can no longer be used. A refresh token that is found to be invalid while not being expired must be rendered suspicious.

Request

refreshstring required

Your refresh token from the Obtain token response.

POST[base]/token/refresh/

$ curl --request POST \
       --url https://[base]/token/refresh/ \
       --header 'content-type: application/vnd.api+json' \
       --data '{
            "data": {
              "type": "auth-token",
              "attributes": {
                "refresh": "<Change to your refresh token>"
              }
            }
          }'
import requests

url = 'https://[base]/token/refresh/'

headers = {
    'content-type': 'application/vnd.api+json',
}

data = {
    'data': {
        'type': 'auth-token',
        'attributes': {
            'refresh': '<Change to your refresh token>',
        },
    },
}

requests.post(url, headers=headers, json=data)
<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new GuzzleHttp\Client();
try {
    $res = $client->post('https://[base]/token/refresh/', [
        'json' => [
            'data' => [
                'type' => 'auth-token',
                'attributes' => [
                    'refresh' => '<Change to your refresh token>',
                ],
            ],
        ],
        'headers' => [
            'Content-Type' => 'application/vnd.api+json',
        ],
    ]);
    echo $res->getBody();
} catch (RequestException $e) {}

Response

Response body is the same as for Obtain token request, but without meta fields.

RESPONSE BODY EXAMPLE
{
  "data": {
    "type": "auth-token",
    "id": "0",
    "attributes": {
      "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
      "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
      "access_expired_at": "2020-12-29T05:42:11.925654Z",
      "refresh_expired_at": "2020-12-29T11:27:11.925654Z",
      "is_2fa_confirmed": false
    }
  }
}

Response codes

200 Success.

401 Refresh token is invalid or expired.


Auth verification

Refer to the example below for a sign verification instance.

Expand fields
// "crypto-js": "4.0.0" is installed as a dependency
const SHA256 = require("crypto-js/sha256");
const hmacSHA256 = require('crypto-js/hmac-sha256');

// set API user login and password
const login = 'nQns0adI5CZNj';
const password = '3BXNFKKthfRk07tM';

// parse /api/token/ response payload
const authResponse = JSON.parse("{\n" +
    "  \"data\": {\n" +
    "    \"type\": \"auth-token\",\n" +
    "    \"id\": \"0\",\n" +
    "    \"attributes\": {\n" +
    "      \"refresh\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUz\",\n" +
    "      \"access\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI\",\n" +
    "      \"access_expired_at\": \"2020-08-24T13:50:12.192479+03:00\",\n" +
    "      \"refresh_expired_at\": \"2020-08-24T19:33:33.192479+03:00\",\n" +
    "      \"is_2fa_confirmed\": false\n" +
    "    }\n" +
    "  },\n" +
    "  \"meta\": {\n" +
    "    \"time\": \"2020-08-24T10:33:33.192479Z\",\n" +
    "    \"sign\": \"e70adec551e26b560049e42aa0993ae42cac4e03fbbb300320d8be\"\n" +
    "  }\n" +
    "}");
    
// prepare data for hash check
const message = authResponse['meta']['time'] + authResponse['data']['attributes']['refresh'];
const responseSign = authResponse['meta']['sign'];
const secret = SHA256(login + password);
const calculatedSign = hmacSHA256(message, secret).toString();

// print result
if (responseSign === calculatedSign) {
    console.log('Verified');
} else {
    console.log('Invalid sign');
}