How do I authenticate with the Boldem API?

To call Boldem API endpoints, you must first authorize. The authorization process, examples, and usage prerequisites are listed below.

Prerequisites

  • Created a Boldem account.
  • Paid Profi plan.
  • The API key (client ID and client secret) generated in your Boldem account that you’ll use with the API.
  • The access token and refresh token you obtain by calling the corresponding endpoint and using the API key.
  • Overview of all Boldem API endpoints, available at https://api.boldem.cz/.
  • Optionally, one of the API testing tools, such as Postman, Insomnia, or httpiness.

Generate API Key

  1. Log in to your Boldem account.
  2. Go to Settings/API.
  3. Click the New API key button.
  4. Enter a name for the key to help you identify it.
  5. A dialog will appear with the API key details – Client ID and client secret. Copy both values and store them in a safe place.

How to use access and refresh tokens

The Boldem API uses an access and refresh token system based on the OAuth protocol. The system is designed to provide both security and convenience when accessing resources through the Boldem API.

  • Access token is a credential that grants a user access to specific resources (Boldem API endpoints) for a limited time (in this case 60 minutes).
  • Refresh token has a longer lifespan and is used to generate a new access token once the previous one expires. This lets users stay authenticated without having to manually log in again.

Here are some best practices and recommendations for using tokens correctly:

  • Generating a new token on first login: When a user logs into the app for the first time, call the endpoint to create a new access token. Use this token for all subsequent calls.
  • Secure token storage: You should securely store both the access token and the refresh token on the client side. This can be in memory, in local storage, or in secure cookies, depending on the requirements and threats your application faces.
  • Refreshing the token before it expires: You don’t need to track exactly how long a token has been used. You can keep a safety margin. A Boldem access token expires after 60 minutes, so you can refresh it, for example, every 50 minutes. This way there’s no risk the access token will expire in the middle of a request.
  • Using the refresh token to generate a new access token: If the access token expires, use the refresh token to generate a new access token. This process is transparent to the user, so they don’t have to sign in again manually.
  • Handling a possible failure when generating a refresh token: If you fail to generate a new access token using the refresh token (the refresh token has expired or been revoked), you should redirect the user to the sign‑in page to re‑authenticate.
  • Invalidate old refresh tokens after use: As an additional security measure, you can invalidate old refresh tokens as soon as they’ve been used to generate a new one. That means if an attacker got hold of a refresh token, they could use it only once and the legitimate user will notice it soon after logout.
  • Regularly rotate refresh tokens: Another recommended practice is to rotate refresh tokens regularly to prevent potential harm if they are compromised.

These procedures strike a balance between user convenience—so users don’t have to sign in as often—and security.

Create an access token

To call individual API endpoints, you must first generate an access token (access_token) using your API key. The access token is valid for 60 minutes and must be refreshed afterward.

To effectively test the Boldem API, we recommend using a tool like Postman, Insomnia, or httpiness. You can import all endpoints from https://api.boldem.cz/ into these tools and easily test them before deploying them in your own application.

Request an access token by calling the /v1/oauth endpoint using POST. Examples of requests are shown below.

Replace the values in the client_id and client_secret parameters with the values copied from your Boldem account.

Example: Creating an access token (Python)

import http.client
import json

conn = http.client.HTTPSConnection("api.boldem.cz")
payload = json.dumps({
  "client_id": "e9579f436bbd4ec1a1ebxcbb1aqq12a8",
  "client_secret": "qwDpL5aA8FaFUD6FRWHb2oceOMCJWpTHiyGINbGKGCTBNeXu8OjH8HlAXCOl97Fc"
})
headers = {
  'Content-Type': 'application/json'
}
conn.request("POST", "/v1/oauth", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

Example of creating an access token (Node.js)

var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'POST',
  'hostname': 'api.boldem.cz',
  'path': '/v1/oauth',
  'headers': {
    'Content-Type': 'application/json'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = JSON.stringify({
  "client_id": "e9579f436bbd4ec1a1ebxcbb1aqq12a8",
  "client_secret": "qwDpL5aA8FaFUD6FRWHb2oceOMCJWpTHiyGINbGKGCTBNeXu8OjH8HlAXCOl97Fc"
});

req.write(postData);

req.end();

Example: Creating an access token (PHP)

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.boldem.cz/v1/oauth',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
  "client_id": "e9579f436bbd4ec1a1ebxcbb1aqq12a8",
  "client_secret": "qwDpL5aA8FaFUD6FRWHb2oceOMCJWpTHiyGINbGKGCTBNeXu8OjH8HlAXCOl97Fc"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
?>

Access token creation – call result

When calling the above endpoint, you should receive a JSON response containing an access token (access_token) and a refresh token (refresh_token):

{
    "access_token": "RC8Z4F4ctUtJu7JDCK5tunIAuSb2pNMbEFjjSfCizgXDQqaCgcoYluCvR0EN5C8zotxb1r9Us0WiWKuflxXUdUXxEeIkB1Q39I8w6U8tDtAn7wMw7iiL7mNTRVw60gDBeCcsPHFGbPbZsWc9cL3vI9DjqpEPFUE78WVVcepdckAt7EDlHr5sNkDbFlMz6OKqYVNDHSbLkIfjvXACiMrikJMiJyAg4",
    "expires_in": 3600,
    "valid_to": "2023-07-14T13:43:36.0353963Z",
    "token_type": "Bearer",
    "refresh_token": "4Nos3O2r6enN9LADZaDfyybHZ4aOcjSD"
}

Refresh access token

The access token is valid for 60 minutes, so you must refresh it before it expires. Use the /v1/oauth/refresh endpoint. Examples of calls are shown below.

Replace the values in the access_token and refresh_token parameters with the values copied from the response you received when generating the new access token.

Access token refresh example (Python)

import http.client
import json

conn = http.client.HTTPSConnection("api.boldem.cz")
payload = json.dumps({
  "access_token": "RC8Z4F4ctUtJu7JDCK5tunIAuSb2pNMbEFjjSfCizgXDQqaCgcoYluCvR0EN5C8zotxb1r9Us0WiWKuflxXUdUXxEeIkB1Q39I8w6U8tDtAn7wMw7iiL7mNTRVw60gDBeCcsPHFGbPbZsWc9cL3vI9DjqpEPFUE78WVVcepdckAt7EDlHr5sNkDbFlMz6OKqYVNDHSbLkIfjvXACiMrikJMiJyAg4",
  "refresh_token": "4Nos3O2r6enN9LADZaDfyybHZ4aOcjSD"
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/problem+json'
}
conn.request("POST", "/v1/oauth/refresh", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

Example: Refreshing an access token (Node.js)

var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'POST',
  'hostname': 'api.boldem.cz',
  'path': '/v1/oauth/refresh',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/problem+json'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = JSON.stringify({
  "access_token": "RC8Z4F4ctUtJu7JDCK5tunIAuSb2pNMbEFjjSfCizgXDQqaCgcoYluCvR0EN5C8zotxb1r9Us0WiWKuflxXUdUXxEeIkB1Q39I8w6U8tDtAn7wMw7iiL7mNTRVw60gDBeCcsPHFGbPbZsWc9cL3vI9DjqpEPFUE78WVVcepdckAt7EDlHr5sNkDbFlMz6OKqYVNDHSbLkIfjvXACiMrikJMiJyAg4",
  "refresh_token": "4Nos3O2r6enN9LADZaDfyybHZ4aOcjSD"
});

req.write(postData);

req.end();

Example of refreshing an access token (PHP)

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.boldem.cz/v1/oauth/refresh',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
  "access_token": "RC8Z4F4ctUtJu7JDCK5tunIAuSb2pNMbEFjjSfCizgXDQqaCgcoYluCvR0EN5C8zotxb1r9Us0WiWKuflxXUdUXxEeIkB1Q39I8w6U8tDtAn7wMw7iiL7mNTRVw60gDBeCcsPHFGbPbZsWc9cL3vI9DjqpEPFUE78WVVcepdckAt7EDlHr5sNkDbFlMz6OKqYVNDHSbLkIfjvXACiMrikJMiJyAg4",
  "refresh_token": "4Nos3O2r6enN9LADZaDfyybHZ4aOcjSD"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Accept: application/problem+json'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Access Token Refresh – Call Result

If the call is successful, you should receive a JSON response containing a new access token (access_token) and a refresh token (refresh_token):

{
    "access_token": "3w6G3bacJLp3YwiOEiyCvTQx6RPntkx8Z7Kwx5nrZiFvAEtYGeSNDWOKqaZTgNvPOoQ947E4pRfxpe7u5kj5oRJDCFXqXrEb1xfFpvrXNdzh3YsCnqkRwJYnHvGR3231uJEJoo1jTbtFVyn621YMk648QHDY6839mNzT1B3YrGnZvENWcGVKd3p7PI1B9JtO3QzRLnPONPCEbHD1Nu8XLiTxtE9Iq",
    "expires_in": 3600,
    "valid_to": "2023-07-14T14:56:15.3827468Z",
    "token_type": "Bearer",
    "refresh_token": "WFCwG66ho9Zbx0CBR6bFat2YR4Czoxln"
}

Revocation of a specific refresh token

To revoke a specific refresh token, call the /v1/oauth/revoke endpoint. Examples of calls are shown below.

Replace the values in the access_token and refresh_token parameters with the values you copied from the response you received when generating these tokens.

Example of revoking a specific refresh token (Node.js)

var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'POST',
  'hostname': 'api.boldem.cz',
  'path': '/v1/oauth/revoke',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/problem+json'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = JSON.stringify({
  "access_token": "3w6G3bacJLp3YwiOEiyCvTQx6RPntkx8Z7Kwx5nrZiFvAEtYGeSNDWOKqaZTgNvPOoQ947E4pRfxpe7u5kj5oRJDCFXqXrEb1xfFpvrXNdzh3YsCnqkRwJYnHvGR3231uJEJoo1jTbtFVyn621YMk648QHDY6839mNzT1B3YrGnZvENWcGVKd3p7PI1B9JtO3QzRLnPONPCEbHD1Nu8XLiTxtE9Iq",
  "refresh_token": "WFCwG66ho9Zbx0CBR6bFat2YR4Czoxln"
});

req.write(postData);

req.end();

Example of revoking a specific refresh token (Python)

import http.client
import json

conn = http.client.HTTPSConnection("api.boldem.cz")
payload = json.dumps({
  "access_token": "3w6G3bacJLp3YwiOEiyCvTQx6RPntkx8Z7Kwx5nrZiFvAEtYGeSNDWOKqaZTgNvPOoQ947E4pRfxpe7u5kj5oRJDCFXqXrEb1xfFpvrXNdzh3YsCnqkRwJYnHvGR3231uJEJoo1jTbtFVyn621YMk648QHDY6839mNzT1B3YrGnZvENWcGVKd3p7PI1B9JtO3QzRLnPONPCEbHD1Nu8XLiTxtE9Iq",
  "refresh_token": "WFCwG66ho9Zbx0CBR6bFat2YR4Czoxln"
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/problem+json'
}
conn.request("POST", "/v1/oauth/revoke", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

Example of revoking a specific refresh token (PHP)

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.boldem.cz/v1/oauth/revoke',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
  "access_token": "3w6G3bacJLp3YwiOEiyCvTQx6RPntkx8Z7Kwx5nrZiFvAEtYGeSNDWOKqaZTgNvPOoQ947E4pRfxpe7u5kj5oRJDCFXqXrEb1xfFpvrXNdzh3YsCnqkRwJYnHvGR3231uJEJoo1jTbtFVyn621YMk648QHDY6839mNzT1B3YrGnZvENWcGVKd3p7PI1B9JtO3QzRLnPONPCEbHD1Nu8XLiTxtE9Iq",
  "refresh_token": "WFCwG66ho9Zbx0CBR6bFat2YR4Czoxln"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Accept: application/problem+json'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
?>

Revocation of a specific refresh token – call result

When calling the above endpoint, you should receive a 204 No Content status code on success.

Log out and invalidate all refresh tokens

To log a user out and revoke all refresh tokens, call the /v1/oauth/signout endpoint with no additional parameters.

Specific examples of using the token when calling API endpoints.

Below you’ll find examples of API endpoint calls and how to correctly use the generated token in them.

Example cURL request (Linux)

curl -X GET "https://api.boldem.cz/v1/contacts" \
-H "Authorization: Bearer YourAccessToken" \
-H "Content-Type: application/json"

Example call using Python 3.x (Windows/Linux)

import requests

# Endpoint and token
url = "https://api.boldem.cz/v1/mailing-lists"
headers = {
    "Authorization": "Bearer YourAccessToken",
    "Content-Type": "application/json"
}

# Parameters (optional)
params = {
    "page": 1,
    "pageSize": 20
}

# Request
response = requests.get(url, headers=headers, params=params)

# Output response
print(response.json())

Example call using PHP (Windows/Linux)

<?php

// Endpoint and token specification
$url = "https://api.boldem.cz/v1/mailing-lists";
$token = "YourAccessToken";

// Parameters (optional)
$params = [
    "page" => 1,
    "pageSize" => 20
];

// Build URL with query parameters
$query = http_build_query($params);
$fullUrl = $url . '?' . $query;

// Initialize cURL
$ch = curl_init();

// cURL settings
curl_setopt($ch, CURLOPT_URL, $fullUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer $token",
    "Content-Type: application/json"
]);

// Send request
$response = curl_exec($ch);

// Check for errors
if (curl_errno($ch)) {
    echo 'Error: ' . curl_error($ch);
} else {
    // Decode JSON response
    $data = json_decode($response, true);
    print_r($data);
}

// Close cURL
curl_close($ch);

?>
Michal Michal Krejčí
8. September 2025