These examples use the native fetch API with modern ES modules.
All requests require an X-API-Key header for authentication.
const SIGNALS_API_KEY = "your-api-key-here";
const BASE_URL = "https://api.signals.actor/v1";
async function signalsApi(path, options = {}) {
const { method = "GET", body, params } = options;
let url = `${BASE_URL}${path}`;
if (params) {
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null) {
searchParams.set(key, String(value));
}
}
const qs = searchParams.toString();
if (qs) url += `?${qs}`;
}
const headers = {
"X-API-Key": SIGNALS_API_KEY,
...(body ? { "Content-Type": "application/json" } : {}),
};
const response = await fetch(url, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(
`API error ${response.status}: ${error.error || response.statusText}`
);
}
return response.json();
}Search, filter, and sort your creator database.
// Search for creators matching "marketing", sorted by engagement
const results = await signalsApi("/creators", {
params: {
search: "marketing",
sort: "engagement",
order: "desc",
limit: 10,
},
});
console.log(`Found ${results.meta.total} creators`);
for (const creator of results.data) {
console.log(`${creator.name} - ${creator.headline}`);
console.log(` Followers: ${creator.total_followers}`);
console.log(` Engagement rate: ${creator.engagement_rate}%`);
}
// Filter by vertical and minimum followers
const saasCreators = await signalsApi("/creators", {
params: {
vertical: "SaaS",
min_followers: 5000,
sort: "followers",
order: "desc",
},
});
// Get a single creator
const creator = await signalsApi("/creators/550e8400-e29b-41d4-a716-446655440000");
console.log(creator.data);Fetch paginated posts for a specific creator.
const creatorId = "550e8400-e29b-41d4-a716-446655440000";
// Get the latest 20 posts
const posts = await signalsApi(`/creators/${creatorId}/posts`, {
params: { page: 1, limit: 20 },
});
console.log(`Total posts: ${posts.meta.total}`);
for (const post of posts.data) {
console.log(`[${new Date(post.posted_at * 1000).toLocaleDateString()}]`);
console.log(` ${post.text_preview}`);
console.log(` Engagement: ${post.engagement} | Likes: ${post.likes} | Comments: ${post.comments}`);
}
// Paginate through all posts
async function getAllPosts(creatorId) {
const allPosts = [];
let page = 1;
let totalPages = 1;
while (page <= totalPages) {
const result = await signalsApi(`/creators/${creatorId}/posts`, {
params: { page, limit: 100 },
});
allPosts.push(...result.data);
totalPages = result.meta.totalPages;
page++;
}
return allPosts;
}Create a list, add existing creators, and import new ones by LinkedIn URL.
// Step 1: Create a new list
const newList = await signalsApi("/lists", {
method: "POST",
body: {
name: "Top SaaS Creators",
description: "High-engagement SaaS thought leaders",
},
});
const listId = newList.data.id;
console.log(`Created list: ${listId}`);
// Step 2: Add existing creators by ID
const addResult = await signalsApi(`/lists/${listId}/members`, {
method: "POST",
body: {
creator_ids: ["creator-uuid-1", "creator-uuid-2", "creator-uuid-3"],
},
});
console.log(`Added ${addResult.data.added} creators (total: ${addResult.data.total})`);
// Step 3: Import creators by LinkedIn URL
// Unknown URLs will be automatically enriched
const importResult = await signalsApi(`/lists/${listId}/import`, {
method: "POST",
body: {
linkedin_urls: [
"https://www.linkedin.com/in/johndoe",
"https://www.linkedin.com/in/janedoe",
"https://www.linkedin.com/in/alexsmith",
],
},
});
console.log(`Import results:`);
console.log(` Added: ${importResult.data.added}`);
console.log(` New creators: ${importResult.data.created}`);
console.log(` Already existed: ${importResult.data.existing}`);
console.log(` Skipped: ${importResult.data.skipped}`);
// Step 4: Check which URLs already exist (optional pre-check)
const checkResult = await signalsApi("/lists/check-urls", {
method: "POST",
body: {
linkedin_urls: [
"https://www.linkedin.com/in/johndoe",
"https://www.linkedin.com/in/unknown-person",
],
},
});
for (const entry of checkResult.data) {
console.log(`${entry.url}: ${entry.exists ? "exists" : "not found"}`);
}Search and filter posts across all creators.
// Search post content
const posts = await signalsApi("/posts", {
params: {
search: "product launch",
sort: "engagement",
order: "desc",
limit: 10,
},
});
for (const post of posts.data) {
console.log(`${post.creator_name} (${post.creator_company})`);
console.log(` ${post.text_preview}`);
console.log(` Engagement: ${post.engagement} | Likes: ${post.likes}`);
}
// Get posts filtered by list
const listPosts = await signalsApi("/posts", {
params: {
list_id: "your-list-id",
sort: "posted_at",
order: "desc",
limit: 50,
},
});
// Get top posts by engagement
const topPosts = await signalsApi("/posts/top/engagement", {
params: { limit: 10 },
});
// Get post statistics for a date range
const stats = await signalsApi("/posts/stats/period", {
params: {
date_from: Math.floor(Date.now() / 1000) - 30 * 86400, // 30 days ago
date_to: Math.floor(Date.now() / 1000),
},
});
console.log(`Posts in period: ${stats.data.total_posts} (${stats.data.personal_posts} original, ${stats.data.reposts} reposts)`);Find someone's LinkedIn profile by name and company.
// Single lookup
const lookup = await signalsApi("/linkedin-lookups", {
method: "POST",
body: {
fullName: "Jane Smith",
company: "Stripe",
listName: "Q1 Prospects",
},
});
console.log(`Lookup created: ${lookup.data.id} (status: ${lookup.data.status})`);
// Bulk lookup (up to 500)
const bulkResult = await signalsApi("/linkedin-lookups/bulk", {
method: "POST",
body: {
lookups: [
{ fullName: "Jane Smith", company: "Stripe" },
{ fullName: "Alex Johnson", company: "Notion" },
{ fullName: "Sarah Lee" },
],
listName: "Q1 Prospects",
},
});
console.log(`Created: ${bulkResult.data.created}, Duplicates: ${bulkResult.data.duplicates}`);
// Poll for completion
async function waitForLookup(lookupId, maxWaitMs = 120000) {
const startTime = Date.now();
while (Date.now() - startTime < maxWaitMs) {
const result = await signalsApi(`/linkedin-lookups/${lookupId}`);
const status = result.data.status;
if (status === "completed") {
console.log(`Found: ${result.data.linkedinUrlFound}`);
return result.data;
}
if (status === "failed" || status === "no_results") {
console.log(`Lookup ${status}: ${result.data.error || "no results"}`);
return result.data;
}
console.log(`Status: ${status}, waiting...`);
await new Promise((resolve) => setTimeout(resolve, 5000));
}
throw new Error("Lookup timed out");
}
// Get lookup stats
const lookupStats = await signalsApi("/linkedin-lookups/stats");
console.log(`Total: ${lookupStats.data.total}, Completed: ${lookupStats.data.completed}, Pending: ${lookupStats.data.pending}`);Monitor your API key activity and error rates.
// Get usage for the last 7 days
const usage = await signalsApi("/usage", {
params: { period: "7d" },
});
const summary = usage.data.summary;
console.log(`API Usage (7d):`);
console.log(` Total requests: ${summary.total_requests}`);
console.log(` Error rate: ${summary.error_rate}%`);
console.log(` Avg response time: ${summary.avg_response_time_ms}ms`);
console.log(`\nTop endpoints:`);
for (const ep of usage.data.by_endpoint.slice(0, 5)) {
console.log(` ${ep.method} ${ep.endpoint}: ${ep.count} requests`);
}
// Check recent errors
const errors = await signalsApi("/usage/errors", {
params: { limit: 10 },
});
if (errors.data.total > 0) {
console.log(`\nRecent errors (${errors.data.total} total):`);
for (const err of errors.data.errors) {
console.log(` ${err.method} ${err.endpoint} -> ${err.status_code} (${new Date(err.timestamp * 1000).toISOString()})`);
}
}