curl --request PATCH \
--url https://api.tamtam.ai/api/v2/personas/{id} \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"canonical_job_titles_excludes_ids": [
"<string>"
],
"canonical_job_titles_includes_ids": [
"<string>"
],
"countries": [
"FR"
],
"country_excludes": [
"BE"
],
"criteria_only": false,
"job_titles_excludes": [
"Intern"
],
"job_titles_includes": [
"Head of Sales"
],
"name": "Head of Sales — France",
"profile_keywords": "\"supply chain\" AND SAP",
"seniority_excludes": [
"In Training"
],
"seniority_includes": [
"Director"
],
"tier_level": 1,
"usages": [
"prospecting"
]
}
'import requests
url = "https://api.tamtam.ai/api/v2/personas/{id}"
payload = {
"canonical_job_titles_excludes_ids": ["<string>"],
"canonical_job_titles_includes_ids": ["<string>"],
"countries": ["FR"],
"country_excludes": ["BE"],
"criteria_only": False,
"job_titles_excludes": ["Intern"],
"job_titles_includes": ["Head of Sales"],
"name": "Head of Sales — France",
"profile_keywords": "\"supply chain\" AND SAP",
"seniority_excludes": ["In Training"],
"seniority_includes": ["Director"],
"tier_level": 1,
"usages": ["prospecting"]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
canonical_job_titles_excludes_ids: ['<string>'],
canonical_job_titles_includes_ids: ['<string>'],
countries: ['FR'],
country_excludes: ['BE'],
criteria_only: false,
job_titles_excludes: ['Intern'],
job_titles_includes: ['Head of Sales'],
name: 'Head of Sales — France',
profile_keywords: '"supply chain" AND SAP',
seniority_excludes: ['In Training'],
seniority_includes: ['Director'],
tier_level: 1,
usages: ['prospecting']
})
};
fetch('https://api.tamtam.ai/api/v2/personas/{id}', 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.tamtam.ai/api/v2/personas/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'canonical_job_titles_excludes_ids' => [
'<string>'
],
'canonical_job_titles_includes_ids' => [
'<string>'
],
'countries' => [
'FR'
],
'country_excludes' => [
'BE'
],
'criteria_only' => false,
'job_titles_excludes' => [
'Intern'
],
'job_titles_includes' => [
'Head of Sales'
],
'name' => 'Head of Sales — France',
'profile_keywords' => '"supply chain" AND SAP',
'seniority_excludes' => [
'In Training'
],
'seniority_includes' => [
'Director'
],
'tier_level' => 1,
'usages' => [
'prospecting'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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.tamtam.ai/api/v2/personas/{id}"
payload := strings.NewReader("{\n \"canonical_job_titles_excludes_ids\": [\n \"<string>\"\n ],\n \"canonical_job_titles_includes_ids\": [\n \"<string>\"\n ],\n \"countries\": [\n \"FR\"\n ],\n \"country_excludes\": [\n \"BE\"\n ],\n \"criteria_only\": false,\n \"job_titles_excludes\": [\n \"Intern\"\n ],\n \"job_titles_includes\": [\n \"Head of Sales\"\n ],\n \"name\": \"Head of Sales — France\",\n \"profile_keywords\": \"\\\"supply chain\\\" AND SAP\",\n \"seniority_excludes\": [\n \"In Training\"\n ],\n \"seniority_includes\": [\n \"Director\"\n ],\n \"tier_level\": 1,\n \"usages\": [\n \"prospecting\"\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "<api-key>")
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.patch("https://api.tamtam.ai/api/v2/personas/{id}")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"canonical_job_titles_excludes_ids\": [\n \"<string>\"\n ],\n \"canonical_job_titles_includes_ids\": [\n \"<string>\"\n ],\n \"countries\": [\n \"FR\"\n ],\n \"country_excludes\": [\n \"BE\"\n ],\n \"criteria_only\": false,\n \"job_titles_excludes\": [\n \"Intern\"\n ],\n \"job_titles_includes\": [\n \"Head of Sales\"\n ],\n \"name\": \"Head of Sales — France\",\n \"profile_keywords\": \"\\\"supply chain\\\" AND SAP\",\n \"seniority_excludes\": [\n \"In Training\"\n ],\n \"seniority_includes\": [\n \"Director\"\n ],\n \"tier_level\": 1,\n \"usages\": [\n \"prospecting\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tamtam.ai/api/v2/personas/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"canonical_job_titles_excludes_ids\": [\n \"<string>\"\n ],\n \"canonical_job_titles_includes_ids\": [\n \"<string>\"\n ],\n \"countries\": [\n \"FR\"\n ],\n \"country_excludes\": [\n \"BE\"\n ],\n \"criteria_only\": false,\n \"job_titles_excludes\": [\n \"Intern\"\n ],\n \"job_titles_includes\": [\n \"Head of Sales\"\n ],\n \"name\": \"Head of Sales — France\",\n \"profile_keywords\": \"\\\"supply chain\\\" AND SAP\",\n \"seniority_excludes\": [\n \"In Training\"\n ],\n \"seniority_includes\": [\n \"Director\"\n ],\n \"tier_level\": 1,\n \"usages\": [\n \"prospecting\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"persona": {
"canonical_job_titles_excludes": [
{
"id": "b3c6f5e2-1234-4abc-9def-0123456789ab",
"title": "Head of Sales",
"acronym": "CRO",
"function": "Sales"
}
],
"canonical_job_titles_includes": [
{
"id": "b3c6f5e2-1234-4abc-9def-0123456789ab",
"title": "Head of Sales",
"acronym": "CRO",
"function": "Sales"
}
],
"countries": [
"FR"
],
"country_excludes": [
"BE"
],
"criteria_only": false,
"id": "b3c6f5e2-1234-4abc-9def-0123456789ab",
"job_titles_excludes": [
"Intern"
],
"job_titles_includes": [
"Head of Sales"
],
"name": "Head of Sales — France",
"seniority_excludes": [
"In Training"
],
"seniority_includes": [
"Director"
],
"tier_level": 1,
"usages": [
"prospecting"
],
"profile_keywords": "\"supply chain\" AND SAP"
},
"promoted_to_canonical": [
{
"canonical_title": "Head of Sales",
"job_title": "Head of Sales"
}
],
"warnings": [
"<string>"
]
}{
"detail": "Property foo is required but is missing.",
"errors": [
{
"location": "<string>",
"message": "<string>",
"value": "<unknown>"
}
],
"instance": "https://example.com/error-log/abc123",
"status": 400,
"title": "Bad Request",
"type": "https://example.com/errors/example"
}Update a persona
Change the fields you send and keep the rest: {"tier_level": 2} re-prioritises a persona without resending a definition you may not have at hand.
A list you send replaces the saved one whole, so to add one country send the current countries plus the new one. [] clears a list, and "profile_keywords": "" removes the keyword expression.
The change applies immediately to everything that searches or matches from this persona: Contact Search, PipeGen, Key Contacts, job change alerts and the persona badges on your lists. Already-stored contacts keep the persona matches they were given.
At least one job title is required (job_titles_includes or canonical_job_titles_includes_ids): seniority and countries only narrow, so a persona with no title would match every contact at every company.
Prefer canonical IDs over free text — a canonical title searches every language LinkedIn localizes it into, while the same words typed as free text reach far fewer profiles. A free-text title that exactly names a canonical one is resolved for you and reported in promoted_to_canonical.
Returns the saved persona in the List personas shape. warnings names anything that makes the persona work against itself: an exclude that cancels an included title, seniority bands that reject the band an included title names, a title too ambiguous to resolve, a seniority value that names no band. The persona is saved regardless.
Free: no credits.
curl --request PATCH \
--url https://api.tamtam.ai/api/v2/personas/{id} \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"canonical_job_titles_excludes_ids": [
"<string>"
],
"canonical_job_titles_includes_ids": [
"<string>"
],
"countries": [
"FR"
],
"country_excludes": [
"BE"
],
"criteria_only": false,
"job_titles_excludes": [
"Intern"
],
"job_titles_includes": [
"Head of Sales"
],
"name": "Head of Sales — France",
"profile_keywords": "\"supply chain\" AND SAP",
"seniority_excludes": [
"In Training"
],
"seniority_includes": [
"Director"
],
"tier_level": 1,
"usages": [
"prospecting"
]
}
'import requests
url = "https://api.tamtam.ai/api/v2/personas/{id}"
payload = {
"canonical_job_titles_excludes_ids": ["<string>"],
"canonical_job_titles_includes_ids": ["<string>"],
"countries": ["FR"],
"country_excludes": ["BE"],
"criteria_only": False,
"job_titles_excludes": ["Intern"],
"job_titles_includes": ["Head of Sales"],
"name": "Head of Sales — France",
"profile_keywords": "\"supply chain\" AND SAP",
"seniority_excludes": ["In Training"],
"seniority_includes": ["Director"],
"tier_level": 1,
"usages": ["prospecting"]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
canonical_job_titles_excludes_ids: ['<string>'],
canonical_job_titles_includes_ids: ['<string>'],
countries: ['FR'],
country_excludes: ['BE'],
criteria_only: false,
job_titles_excludes: ['Intern'],
job_titles_includes: ['Head of Sales'],
name: 'Head of Sales — France',
profile_keywords: '"supply chain" AND SAP',
seniority_excludes: ['In Training'],
seniority_includes: ['Director'],
tier_level: 1,
usages: ['prospecting']
})
};
fetch('https://api.tamtam.ai/api/v2/personas/{id}', 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.tamtam.ai/api/v2/personas/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'canonical_job_titles_excludes_ids' => [
'<string>'
],
'canonical_job_titles_includes_ids' => [
'<string>'
],
'countries' => [
'FR'
],
'country_excludes' => [
'BE'
],
'criteria_only' => false,
'job_titles_excludes' => [
'Intern'
],
'job_titles_includes' => [
'Head of Sales'
],
'name' => 'Head of Sales — France',
'profile_keywords' => '"supply chain" AND SAP',
'seniority_excludes' => [
'In Training'
],
'seniority_includes' => [
'Director'
],
'tier_level' => 1,
'usages' => [
'prospecting'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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.tamtam.ai/api/v2/personas/{id}"
payload := strings.NewReader("{\n \"canonical_job_titles_excludes_ids\": [\n \"<string>\"\n ],\n \"canonical_job_titles_includes_ids\": [\n \"<string>\"\n ],\n \"countries\": [\n \"FR\"\n ],\n \"country_excludes\": [\n \"BE\"\n ],\n \"criteria_only\": false,\n \"job_titles_excludes\": [\n \"Intern\"\n ],\n \"job_titles_includes\": [\n \"Head of Sales\"\n ],\n \"name\": \"Head of Sales — France\",\n \"profile_keywords\": \"\\\"supply chain\\\" AND SAP\",\n \"seniority_excludes\": [\n \"In Training\"\n ],\n \"seniority_includes\": [\n \"Director\"\n ],\n \"tier_level\": 1,\n \"usages\": [\n \"prospecting\"\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "<api-key>")
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.patch("https://api.tamtam.ai/api/v2/personas/{id}")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"canonical_job_titles_excludes_ids\": [\n \"<string>\"\n ],\n \"canonical_job_titles_includes_ids\": [\n \"<string>\"\n ],\n \"countries\": [\n \"FR\"\n ],\n \"country_excludes\": [\n \"BE\"\n ],\n \"criteria_only\": false,\n \"job_titles_excludes\": [\n \"Intern\"\n ],\n \"job_titles_includes\": [\n \"Head of Sales\"\n ],\n \"name\": \"Head of Sales — France\",\n \"profile_keywords\": \"\\\"supply chain\\\" AND SAP\",\n \"seniority_excludes\": [\n \"In Training\"\n ],\n \"seniority_includes\": [\n \"Director\"\n ],\n \"tier_level\": 1,\n \"usages\": [\n \"prospecting\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tamtam.ai/api/v2/personas/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"canonical_job_titles_excludes_ids\": [\n \"<string>\"\n ],\n \"canonical_job_titles_includes_ids\": [\n \"<string>\"\n ],\n \"countries\": [\n \"FR\"\n ],\n \"country_excludes\": [\n \"BE\"\n ],\n \"criteria_only\": false,\n \"job_titles_excludes\": [\n \"Intern\"\n ],\n \"job_titles_includes\": [\n \"Head of Sales\"\n ],\n \"name\": \"Head of Sales — France\",\n \"profile_keywords\": \"\\\"supply chain\\\" AND SAP\",\n \"seniority_excludes\": [\n \"In Training\"\n ],\n \"seniority_includes\": [\n \"Director\"\n ],\n \"tier_level\": 1,\n \"usages\": [\n \"prospecting\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"persona": {
"canonical_job_titles_excludes": [
{
"id": "b3c6f5e2-1234-4abc-9def-0123456789ab",
"title": "Head of Sales",
"acronym": "CRO",
"function": "Sales"
}
],
"canonical_job_titles_includes": [
{
"id": "b3c6f5e2-1234-4abc-9def-0123456789ab",
"title": "Head of Sales",
"acronym": "CRO",
"function": "Sales"
}
],
"countries": [
"FR"
],
"country_excludes": [
"BE"
],
"criteria_only": false,
"id": "b3c6f5e2-1234-4abc-9def-0123456789ab",
"job_titles_excludes": [
"Intern"
],
"job_titles_includes": [
"Head of Sales"
],
"name": "Head of Sales — France",
"seniority_excludes": [
"In Training"
],
"seniority_includes": [
"Director"
],
"tier_level": 1,
"usages": [
"prospecting"
],
"profile_keywords": "\"supply chain\" AND SAP"
},
"promoted_to_canonical": [
{
"canonical_title": "Head of Sales",
"job_title": "Head of Sales"
}
],
"warnings": [
"<string>"
]
}{
"detail": "Property foo is required but is missing.",
"errors": [
{
"location": "<string>",
"message": "<string>",
"value": "<unknown>"
}
],
"instance": "https://example.com/error-log/abc123",
"status": 400,
"title": "Bad Request",
"type": "https://example.com/errors/example"
}Authorizations
Account API key passed in the Authorization header
Path Parameters
Body
Canonical job title IDs to exclude.
Canonical job title IDs to include. Take them from canonical_job_titles_includes on a persona you read back. Prefer these over free text: a canonical title searches every language LinkedIn localizes it into.
ISO 3166-1 alpha-2 codes of the countries people must be in. Empty means every country. A value that is not a code is refused rather than stored: a persona filters on the profile's country code, so a country name matches nobody.
["FR"]
ISO 3166-1 alpha-2 codes of the countries to leave out.
["BE"]
true makes the persona a filter only: it still matches and scores contacts, but defines no people search and is rejected by People search's persona_id. Defaults to false on create.
false
Free-text words that remove a person entirely, matched as whole words. Never exclude a word that appears in a title you include ('engineer' beside 'Cloud Engineer' cancels it); warnings says when one does.
["Intern"]
Free-text job titles to include, matched as whole words against the title the person holds, case-insensitively. Unquoted words must all appear ('VP Sales' matches 'VP of Sales EMEA'); quote a phrase to require it whole. A title that exactly names a canonical one is resolved to it and reported in promoted_to_canonical.
["Head of Sales"]
Display name. Required on create.
1"Head of Sales — France"
Keyword expression matched against the whole LinkedIn profile (headline, About, every role's description, skills), for what a person works ON — use the job title fields for their role. AND and OR in capitals, quotes around phrases. NOT, and an OR inside brackets, are refused because the provider answers both wrongly. Send an empty string to remove the expression.
"\"supply chain\" AND SAP"
Seniority bands to drop, read the same way. A title carrying no seniority signal is kept here too.
["In Training"]
Seniority bands to keep, read from the job title by Tamtam's own classifier. A title carrying no seniority signal is always kept, so this narrows without discarding the unclassified. Empty keeps every band. A value naming no band is ignored and reported in warnings rather than refused.
["Director"]
Priority tier, 1 = highest. Defaults to 1 on create.
x >= 11
What the persona is used for: 'prospecting', 'closing_deals', or both. At least one. Defaults to both on create.
1["prospecting"]
Response
OK
The persona as saved, in the same shape List personas returns.
Show child attributes
Show child attributes
Free-text job titles that exactly named a canonical title and were resolved to it. Empty when none were.
Show child attributes
Show child attributes
Anything that makes the saved persona work against itself: an exclude cancelling an included title, seniority bands rejecting the band an included title names, a title too ambiguous to resolve, a seniority value naming no band. Empty when nothing is wrong.