curl --request POST \
--url https://api.tamtam.ai/api/v2/news-content-signals \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"use_cases": [
{
"name": "<string>",
"prompt": "<string>"
}
],
"companies_list_id": "<string>",
"contacts_list_id": "<string>",
"include_domains": [
"<string>"
],
"is_enabled": true,
"max_articles_per_query": 2,
"max_companies_per_sweep": 2,
"queries": [
"<string>"
],
"search_keywords": [
"<string>"
]
}
'import requests
url = "https://api.tamtam.ai/api/v2/news-content-signals"
payload = {
"name": "<string>",
"use_cases": [
{
"name": "<string>",
"prompt": "<string>"
}
],
"companies_list_id": "<string>",
"contacts_list_id": "<string>",
"include_domains": ["<string>"],
"is_enabled": True,
"max_articles_per_query": 2,
"max_companies_per_sweep": 2,
"queries": ["<string>"],
"search_keywords": ["<string>"]
}
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>',
use_cases: [{name: '<string>', prompt: '<string>'}],
companies_list_id: '<string>',
contacts_list_id: '<string>',
include_domains: ['<string>'],
is_enabled: true,
max_articles_per_query: 2,
max_companies_per_sweep: 2,
queries: ['<string>'],
search_keywords: ['<string>']
})
};
fetch('https://api.tamtam.ai/api/v2/news-content-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/news-content-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>',
'use_cases' => [
[
'name' => '<string>',
'prompt' => '<string>'
]
],
'companies_list_id' => '<string>',
'contacts_list_id' => '<string>',
'include_domains' => [
'<string>'
],
'is_enabled' => true,
'max_articles_per_query' => 2,
'max_companies_per_sweep' => 2,
'queries' => [
'<string>'
],
'search_keywords' => [
'<string>'
]
]),
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/news-content-signals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"use_cases\": [\n {\n \"name\": \"<string>\",\n \"prompt\": \"<string>\"\n }\n ],\n \"companies_list_id\": \"<string>\",\n \"contacts_list_id\": \"<string>\",\n \"include_domains\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"max_articles_per_query\": 2,\n \"max_companies_per_sweep\": 2,\n \"queries\": [\n \"<string>\"\n ],\n \"search_keywords\": [\n \"<string>\"\n ]\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/news-content-signals")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"use_cases\": [\n {\n \"name\": \"<string>\",\n \"prompt\": \"<string>\"\n }\n ],\n \"companies_list_id\": \"<string>\",\n \"contacts_list_id\": \"<string>\",\n \"include_domains\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"max_articles_per_query\": 2,\n \"max_companies_per_sweep\": 2,\n \"queries\": [\n \"<string>\"\n ],\n \"search_keywords\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tamtam.ai/api/v2/news-content-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 \"use_cases\": [\n {\n \"name\": \"<string>\",\n \"prompt\": \"<string>\"\n }\n ],\n \"companies_list_id\": \"<string>\",\n \"contacts_list_id\": \"<string>\",\n \"include_domains\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"max_articles_per_query\": 2,\n \"max_companies_per_sweep\": 2,\n \"queries\": [\n \"<string>\"\n ],\n \"search_keywords\": [\n \"<string>\"\n ]\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 a news signal
A standing news search whose articles an AI scores against your own use-cases, turning the relevant ones into leads.
Two shapes, and the shape follows the target you pass. Discovery: pass queries, and each sweep searches the whole news for those themes, finding companies you do not follow yet. Watch: pass companies_list_id or contacts_list_id instead, and each sweep reads the news of the companies on that list. Exactly one target; queries plus a list, or both lists, is a 422.
use_cases is the whole relevance definition: an article becomes a lead when it falls into at least one, judged on that use-case’s own prompt. Write each prompt as a test the article must pass, in your words, and say what to extract.
Cost when it runs: one credit per article judged, up to max_articles_per_query per query 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/news-content-signals \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"use_cases": [
{
"name": "<string>",
"prompt": "<string>"
}
],
"companies_list_id": "<string>",
"contacts_list_id": "<string>",
"include_domains": [
"<string>"
],
"is_enabled": true,
"max_articles_per_query": 2,
"max_companies_per_sweep": 2,
"queries": [
"<string>"
],
"search_keywords": [
"<string>"
]
}
'import requests
url = "https://api.tamtam.ai/api/v2/news-content-signals"
payload = {
"name": "<string>",
"use_cases": [
{
"name": "<string>",
"prompt": "<string>"
}
],
"companies_list_id": "<string>",
"contacts_list_id": "<string>",
"include_domains": ["<string>"],
"is_enabled": True,
"max_articles_per_query": 2,
"max_companies_per_sweep": 2,
"queries": ["<string>"],
"search_keywords": ["<string>"]
}
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>',
use_cases: [{name: '<string>', prompt: '<string>'}],
companies_list_id: '<string>',
contacts_list_id: '<string>',
include_domains: ['<string>'],
is_enabled: true,
max_articles_per_query: 2,
max_companies_per_sweep: 2,
queries: ['<string>'],
search_keywords: ['<string>']
})
};
fetch('https://api.tamtam.ai/api/v2/news-content-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/news-content-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>',
'use_cases' => [
[
'name' => '<string>',
'prompt' => '<string>'
]
],
'companies_list_id' => '<string>',
'contacts_list_id' => '<string>',
'include_domains' => [
'<string>'
],
'is_enabled' => true,
'max_articles_per_query' => 2,
'max_companies_per_sweep' => 2,
'queries' => [
'<string>'
],
'search_keywords' => [
'<string>'
]
]),
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/news-content-signals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"use_cases\": [\n {\n \"name\": \"<string>\",\n \"prompt\": \"<string>\"\n }\n ],\n \"companies_list_id\": \"<string>\",\n \"contacts_list_id\": \"<string>\",\n \"include_domains\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"max_articles_per_query\": 2,\n \"max_companies_per_sweep\": 2,\n \"queries\": [\n \"<string>\"\n ],\n \"search_keywords\": [\n \"<string>\"\n ]\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/news-content-signals")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"use_cases\": [\n {\n \"name\": \"<string>\",\n \"prompt\": \"<string>\"\n }\n ],\n \"companies_list_id\": \"<string>\",\n \"contacts_list_id\": \"<string>\",\n \"include_domains\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"max_articles_per_query\": 2,\n \"max_companies_per_sweep\": 2,\n \"queries\": [\n \"<string>\"\n ],\n \"search_keywords\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tamtam.ai/api/v2/news-content-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 \"use_cases\": [\n {\n \"name\": \"<string>\",\n \"prompt\": \"<string>\"\n }\n ],\n \"companies_list_id\": \"<string>\",\n \"contacts_list_id\": \"<string>\",\n \"include_domains\": [\n \"<string>\"\n ],\n \"is_enabled\": true,\n \"max_articles_per_query\": 2,\n \"max_companies_per_sweep\": 2,\n \"queries\": [\n \"<string>\"\n ],\n \"search_keywords\": [\n \"<string>\"\n ]\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. Name it after the question, e.g. 'Series B in fintech'.
1One to ten use-cases: the whole relevance definition. An article is relevant when it falls into at least one, judged on that use-case's own prompt.
1 - 10 elementsShow child attributes
Show child attributes
WATCH shape: a companies list whose companies' news to read. Pass this OR queries, never both.
WATCH shape: a contacts list whose companies' news to read. Pass this OR queries, never both.
DISCOVERY shape only: bare hostnames to trust, e.g. techcrunch.com. Omit for the whole web.
Defaults to true.
Articles judged per query per sweep: the cost dial, one credit per judged article. Omit for the default.
x >= 1WATCH shape only: how many companies of the list to read per sweep. Omit for the default.
x >= 1DISCOVERY shape: short search themes, each run as its own search per sweep, finding companies you do not follow yet. Pass this OR a list id, never both.
WATCH shape only: narrow the search to company AND one of these topics. Omit to read everything stored for the company.
How far back each sweep looks. Defaults to last_week.
last_day, last_week, last_month, last_3_months