curl --request POST \
--url https://api.cloudtalk.io/v1/contact-tags \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "renewal-q1"
}
'import requests
url = "https://api.cloudtalk.io/v1/contact-tags"
payload = { "name": "renewal-q1" }
headers = {
"Authorization": "Basic <encoded-value>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Basic <encoded-value>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'renewal-q1'})
};
fetch('https://api.cloudtalk.io/v1/contact-tags', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloudtalk.io/v1/contact-tags",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'renewal-q1'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cloudtalk.io/v1/contact-tags"
payload := strings.NewReader("{\n \"name\": \"renewal-q1\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cloudtalk.io/v1/contact-tags")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"renewal-q1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudtalk.io/v1/contact-tags")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic <encoded-value>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"renewal-q1\"\n}"
response = http.request(request)
puts response.read_body{
"id": "152",
"name": "renewal-q1",
"type": "contact",
"integrationName": null,
"readOnly": false,
"createdAt": "2026-11-02T10:10:00Z"
}{
"id": "152",
"name": "renewal-q1",
"type": "contact",
"integrationName": null,
"readOnly": false,
"createdAt": "2026-11-02T10:10:00Z"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"code": "UNAUTHORIZED",
"message": "You are not authorized to access this resource."
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}<string>{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}Create a contact tag
Creates a contact tag. Names are unique in your account, ignoring case. The name is cleaned up before it is checked and stored, as contact text fields are: emojis and other characters that take 4 bytes in UTF-8, and control characters such as line breaks and tabs, become a space; repeated whitespace becomes one space; and spaces at the start and end are removed. So " vip team " is stored as vip team. If a tag with the name already exists, you get that tag back unchanged with 200 instead of a new one, so a retry is safe. For example, creating VIP when vip exists returns vip, and a name that matches an integration tag returns that tag with type: integration.
No webhook is sent for changes to the tag catalogue.
curl --request POST \
--url https://api.cloudtalk.io/v1/contact-tags \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "renewal-q1"
}
'import requests
url = "https://api.cloudtalk.io/v1/contact-tags"
payload = { "name": "renewal-q1" }
headers = {
"Authorization": "Basic <encoded-value>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Basic <encoded-value>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'renewal-q1'})
};
fetch('https://api.cloudtalk.io/v1/contact-tags', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloudtalk.io/v1/contact-tags",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'renewal-q1'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cloudtalk.io/v1/contact-tags"
payload := strings.NewReader("{\n \"name\": \"renewal-q1\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cloudtalk.io/v1/contact-tags")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"renewal-q1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudtalk.io/v1/contact-tags")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic <encoded-value>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"renewal-q1\"\n}"
response = http.request(request)
puts response.read_body{
"id": "152",
"name": "renewal-q1",
"type": "contact",
"integrationName": null,
"readOnly": false,
"createdAt": "2026-11-02T10:10:00Z"
}{
"id": "152",
"name": "renewal-q1",
"type": "contact",
"integrationName": null,
"readOnly": false,
"createdAt": "2026-11-02T10:10:00Z"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"code": "UNAUTHORIZED",
"message": "You are not authorized to access this resource."
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}<string>{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}Authorizations
HTTP Basic Authentication. Use your API Access Key ID as the username and your API Access Key Secret as the password. Generate keys in the CloudTalk Dashboard under Account -> Settings -> API Keys (https://dashboard.cloudtalk.io/menu/account/settings/API-keys).
Body
1 to 60 characters once cleaned up: emojis and other characters that take 4 bytes in UTF-8, and control characters such as line breaks and tabs, become a space; repeated whitespace becomes one space; and spaces at the start and end are removed.
1 - 60Response
A tag with this name already existed. It is returned unchanged.
"123"
Unique in your account, ignoring case.
60"vip"
contact, integration The integration that owns an integration tag.
"hubspot"
true when this API cannot add, remove, rename or delete the tag (see the operation description). false for plain tags.