curl --request POST \
--url https://api.tamtam.ai/api/v2/past-company-move-signals \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"persona_ids": [
"<string>"
],
"companies_list_id": "<string>",
"company_headcounts": [
"<string>"
],
"company_hq_countries": [
"<string>"
],
"countries": [
"<string>"
],
"hubspot_list_id": "<string>",
"include_current_customers": true,
"include_former_customers": true,
"industry_ids": [
"<string>"
],
"is_enabled": true,
"location_geo_ids": [
"<string>"
],
"max_movers_per_sweep": 250
}
'import requests
url = "https://api.tamtam.ai/api/v2/past-company-move-signals"
payload = {
"name": "<string>",
"persona_ids": ["<string>"],
"companies_list_id": "<string>",
"company_headcounts": ["<string>"],
"company_hq_countries": ["<string>"],
"countries": ["<string>"],
"hubspot_list_id": "<string>",
"include_current_customers": True,
"include_former_customers": True,
"industry_ids": ["<string>"],
"is_enabled": True,
"location_geo_ids": ["<string>"],
"max_movers_per_sweep": 250
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
persona_ids: ['<string>'],
companies_list_id: '<string>',
company_headcounts: ['<string>'],
company_hq_countries: ['<string>'],
countries: ['<string>'],
hubspot_list_id: '<string>',
include_current_customers: true,
include_former_customers: true,
industry_ids: ['<string>'],
is_enabled: true,
location_geo_ids: ['<string>'],
max_movers_per_sweep: 250
})
};
fetch('https://api.tamtam.ai/api/v2/past-company-move-signals', 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/past-company-move-signals",
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' => '<string>',
'persona_ids' => [
'<string>'
],
'companies_list_id' => '<string>',
'company_headcounts' => [
'<string>'
],
'company_hq_countries' => [
'<string>'
],
'countries' => [
'<string>'
],
'hubspot_list_id' => '<string>',
'include_current_customers' => true,
'include_former_customers' => true,
'industry_ids' => [
'<string>'
],
'is_enabled' => true,
'location_geo_ids' => [
'<string>'
],
'max_movers_per_sweep' => 250
]),
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/past-company-move-signals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"persona_ids\": [\n \"<string>\"\n ],\n \"companies_list_id\": \"<string>\",\n \"company_headcounts\": [\n \"<string>\"\n ],\n \"company_hq_countries\": [\n \"<string>\"\n ],\n \"countries\": [\n \"<string>\"\n ],\n \"hubspot_list_id\": \"<string>\",\n \"include_current_customers\": true,\n \"include_former_customers\": true,\n \"industry_ids\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"location_geo_ids\": [\n \"<string>\"\n ],\n \"max_movers_per_sweep\": 250\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.tamtam.ai/api/v2/past-company-move-signals")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"persona_ids\": [\n \"<string>\"\n ],\n \"companies_list_id\": \"<string>\",\n \"company_headcounts\": [\n \"<string>\"\n ],\n \"company_hq_countries\": [\n \"<string>\"\n ],\n \"countries\": [\n \"<string>\"\n ],\n \"hubspot_list_id\": \"<string>\",\n \"include_current_customers\": true,\n \"include_former_customers\": true,\n \"industry_ids\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"location_geo_ids\": [\n \"<string>\"\n ],\n \"max_movers_per_sweep\": 250\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tamtam.ai/api/v2/past-company-move-signals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"persona_ids\": [\n \"<string>\"\n ],\n \"companies_list_id\": \"<string>\",\n \"company_headcounts\": [\n \"<string>\"\n ],\n \"company_hq_countries\": [\n \"<string>\"\n ],\n \"countries\": [\n \"<string>\"\n ],\n \"hubspot_list_id\": \"<string>\",\n \"include_current_customers\": true,\n \"include_former_customers\": true,\n \"industry_ids\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"location_geo_ids\": [\n \"<string>\"\n ],\n \"max_movers_per_sweep\": 250\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"is_enabled": true,
"kind": "<string>",
"name": "<string>",
"used_by_program_count": 123
}{
"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"
}Create an ex-customer move signal
The people who once worked at one of your customers, match one of your personas, and work somewhere else now, collected as leads. A person who used the product at a previous employer is a warm door into the new one.
persona_ids does both halves of who: the personas’ job titles become the search’s current-title filter, and the same personas judge the titles that come back. The population is your customers, chosen one of three ways: the companies your CRM has won deals with (include_current_customers, default), optionally the ones it later lost a deal with too (include_former_customers), or one list instead (companies_list_id or hubspot_list_id), which makes the two switches moot.
Cost when it runs: every profile read costs one credit, up to max_movers_per_sweep.
Creating a signal starts nothing and bills nothing. A signal runs only when a lead generation program picks it: Start a lead generation run sweeps it now and records a program you can put on a schedule under Settings > Signals > Lead generation. List signals reports used_by_program_count per signal; zero means it is defined and never runs. List first, so you do not create a second signal over a question you already ask: duplicates bill twice and split the leads across two names.
curl --request POST \
--url https://api.tamtam.ai/api/v2/past-company-move-signals \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"persona_ids": [
"<string>"
],
"companies_list_id": "<string>",
"company_headcounts": [
"<string>"
],
"company_hq_countries": [
"<string>"
],
"countries": [
"<string>"
],
"hubspot_list_id": "<string>",
"include_current_customers": true,
"include_former_customers": true,
"industry_ids": [
"<string>"
],
"is_enabled": true,
"location_geo_ids": [
"<string>"
],
"max_movers_per_sweep": 250
}
'import requests
url = "https://api.tamtam.ai/api/v2/past-company-move-signals"
payload = {
"name": "<string>",
"persona_ids": ["<string>"],
"companies_list_id": "<string>",
"company_headcounts": ["<string>"],
"company_hq_countries": ["<string>"],
"countries": ["<string>"],
"hubspot_list_id": "<string>",
"include_current_customers": True,
"include_former_customers": True,
"industry_ids": ["<string>"],
"is_enabled": True,
"location_geo_ids": ["<string>"],
"max_movers_per_sweep": 250
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
persona_ids: ['<string>'],
companies_list_id: '<string>',
company_headcounts: ['<string>'],
company_hq_countries: ['<string>'],
countries: ['<string>'],
hubspot_list_id: '<string>',
include_current_customers: true,
include_former_customers: true,
industry_ids: ['<string>'],
is_enabled: true,
location_geo_ids: ['<string>'],
max_movers_per_sweep: 250
})
};
fetch('https://api.tamtam.ai/api/v2/past-company-move-signals', 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/past-company-move-signals",
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' => '<string>',
'persona_ids' => [
'<string>'
],
'companies_list_id' => '<string>',
'company_headcounts' => [
'<string>'
],
'company_hq_countries' => [
'<string>'
],
'countries' => [
'<string>'
],
'hubspot_list_id' => '<string>',
'include_current_customers' => true,
'include_former_customers' => true,
'industry_ids' => [
'<string>'
],
'is_enabled' => true,
'location_geo_ids' => [
'<string>'
],
'max_movers_per_sweep' => 250
]),
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/past-company-move-signals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"persona_ids\": [\n \"<string>\"\n ],\n \"companies_list_id\": \"<string>\",\n \"company_headcounts\": [\n \"<string>\"\n ],\n \"company_hq_countries\": [\n \"<string>\"\n ],\n \"countries\": [\n \"<string>\"\n ],\n \"hubspot_list_id\": \"<string>\",\n \"include_current_customers\": true,\n \"include_former_customers\": true,\n \"industry_ids\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"location_geo_ids\": [\n \"<string>\"\n ],\n \"max_movers_per_sweep\": 250\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.tamtam.ai/api/v2/past-company-move-signals")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"persona_ids\": [\n \"<string>\"\n ],\n \"companies_list_id\": \"<string>\",\n \"company_headcounts\": [\n \"<string>\"\n ],\n \"company_hq_countries\": [\n \"<string>\"\n ],\n \"countries\": [\n \"<string>\"\n ],\n \"hubspot_list_id\": \"<string>\",\n \"include_current_customers\": true,\n \"include_former_customers\": true,\n \"industry_ids\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"location_geo_ids\": [\n \"<string>\"\n ],\n \"max_movers_per_sweep\": 250\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tamtam.ai/api/v2/past-company-move-signals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"persona_ids\": [\n \"<string>\"\n ],\n \"companies_list_id\": \"<string>\",\n \"company_headcounts\": [\n \"<string>\"\n ],\n \"company_hq_countries\": [\n \"<string>\"\n ],\n \"countries\": [\n \"<string>\"\n ],\n \"hubspot_list_id\": \"<string>\",\n \"include_current_customers\": true,\n \"include_former_customers\": true,\n \"industry_ids\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"location_geo_ids\": [\n \"<string>\"\n ],\n \"max_movers_per_sweep\": 250\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"is_enabled": true,
"kind": "<string>",
"name": "<string>",
"used_by_program_count": 123
}{
"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
Query Parameters
Target account UUID. Required for staff callers; ignored for customer API keys.
Body
Short label, unique in the account, e.g. 'Ex-customer ops leaders'.
1One to ten personas: who the search looks for and who it keeps. The personas' job titles become the search's current-title filter.
1 - 10 elementsList population: one of your companies lists to search instead of the CRM. Pass this OR hubspot_list_id, never both.
Size bands of the NEW employer, as LinkedIn letter codes: A (self-employed), B (1-10), C (11-50), D (51-200), E (201-500), F (501-1,000), G (1,001-5,000), H (5,001-10,000), I (10,001+).
Two-letter country codes where the NEW employer is headquartered.
Two-letter country codes where the PERSON is now.
List population: the id of a live HubSpot list to search instead of the CRM's won deals, resolved at every sweep. Pass this OR companies_list_id, never both. Salesforce has no live list read: import the list into a companies list first.
CRM population: search the companies your CRM has won deals with. Defaults to true. Ignored when a list is given.
CRM population: also search won companies the CRM later lost a deal with, a proxy for churned customers. Defaults to false. Ignored when a list is given.
Industry UUIDs the new employer has to be in, at most 25.
25Defaults to true.
LinkedIn geo IDs where the PERSON is, at most 25.
25Profiles read per sweep. Defaults to 100. The cost dial: each profile read costs one credit.
1 <= x <= 500