fetch for the TalkPilot API — no external dependencies required.
Setup
const BASE_URL = "https://{project_ref}.supabase.co/functions/v1/api/v1";
const API_KEY = "tp_live_YOUR_KEY_HERE";
async function talkpilot(
path: string,
options: RequestInit = {}
): Promise<any> {
const response = await fetch(`${BASE_URL}${path}`, {
...options,
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
...options.headers,
},
});
// Handle rate limiting with automatic retry
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
console.log(`Rate limited. Retrying in ${retryAfter}s...`);
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return talkpilot(path, options);
}
if (response.status === 204) return null;
const body = await response.json();
if (!response.ok) {
const err = body.error;
throw new Error(`[${err.code}] ${err.message} (${err.request_id})`);
}
return body;
}
List agents
const { data: agents, pagination } = await talkpilot("/agents");
console.log(`Found ${pagination.total} agents:`);
agents.forEach((agent) => {
console.log(`- ${agent.name} (${agent.is_active ? "active" : "inactive"})`);
});
Get agent details
const agent = await talkpilot(`/agents/${agentId}`);
console.log(`Agent: ${agent.name}`);
console.log(`Model: ${agent.llm_provider}/${agent.llm_model}`);
console.log(`Voice: ${agent.voice_id}`);
console.log(`Active: ${agent.is_active}`);
Update agent settings
// Update prompt and greeting
const updated = await talkpilot(`/agents/${agentId}`, {
method: "PATCH",
body: JSON.stringify({
prompt: "Du bist ein professioneller Kundenservice-Agent fuer Firma X.",
greeting: "Willkommen bei Firma X, wie kann ich Ihnen helfen?",
}),
});
console.log(`Agent updated: ${updated.name}`);
Toggle vacation mode
// Enable vacation mode
await talkpilot(`/agents/${agentId}`, {
method: "PATCH",
body: JSON.stringify({
vacation_mode: true,
vacation_end: "2026-04-01T00:00:00Z",
vacation_notdienst: true,
}),
});
// Disable vacation mode
await talkpilot(`/agents/${agentId}`, {
method: "PATCH",
body: JSON.stringify({ vacation_mode: false }),
});
Manage employees
// List employees for an agent
const { data: employees } = await talkpilot(
`/agents/${agentId}/employees?status=anwesend`
);
// Create a new employee
const newEmployee = await talkpilot(`/agents/${agentId}/employees`, {
method: "POST",
body: JSON.stringify({
name: "Max Mustermann",
phone_number: "+491701234567",
email: "max@example.com",
status: "anwesend",
active: true,
get_mail: true,
}),
});
// Update employee status (e.g., mark as on vacation)
await talkpilot(`/agents/${agentId}/employees/${employeeId}`, {
method: "PATCH",
body: JSON.stringify({ status: "urlaub" }),
});
// Delete an employee
await talkpilot(`/agents/${agentId}/employees/${employeeId}`, {
method: "DELETE",
});
Sync forwarding slots from external system
// Replace all forwarding slots in one request
const result = await talkpilot(`/agents/${agentId}/forwarding-slots`, {
method: "PUT",
body: JSON.stringify({
slots: [
{
slotnummer: "01",
cases: "Rechnungsfragen, Zahlungsprobleme",
slot_belegung: "Max Mustermann",
prioritaet_1: "+491701234567",
prioritaet_2: "+491709876543",
},
{
slotnummer: "02",
cases: "Technischer Support",
slot_belegung: "Erika Musterfrau",
prioritaet_1: "+491705555555",
},
],
}),
});
console.log(`Replaced ${result.replaced_count} slots with ${result.data.length} new slots`);
Fetch calls with filtering
// Recent calls from the last 7 days
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const { data: calls, pagination } = await talkpilot(
`/agents/${agentId}/calls?from=${sevenDaysAgo}&limit=50`
);
console.log(`${pagination.total} calls in the last 7 days`);
// Get full call details with transcript
const call = await talkpilot(`/agents/${agentId}/calls/${callId}`);
console.log(`Customer: ${call.customer_name}`);
console.log(`Duration: ${call.duration}s`);
console.log(`Summary: ${call.call_summary}`);
if (call.transcript) {
console.log(`Transcript: ${call.transcript}`);
}
Fetch all pages
async function fetchAll<T>(path: string): Promise<T[]> {
const allItems: T[] = [];
let page = 1;
let totalPages = 1;
while (page <= totalPages) {
const response = await talkpilot(`${path}${path.includes("?") ? "&" : "?"}page=${page}&limit=100`);
allItems.push(...response.data);
totalPages = response.pagination.pages;
page++;
}
return allItems;
}
// Usage
const allCalls = await fetchAll(`/agents/${agentId}/calls?from=2026-03-01T00:00:00Z`);
console.log(`Fetched ${allCalls.length} calls total`);
Add knowledge base content
const doc = await talkpilot(`/agents/${agentId}/knowledge-base`, {
method: "POST",
body: JSON.stringify({
title: "Preisliste 2026",
content: `
Produkt A: 29,99 EUR/Monat
Produkt B: 49,99 EUR/Monat
Produkt C: 99,99 EUR/Monat
Alle Preise zzgl. MwSt.
`.trim(),
}),
});
console.log(`Document created: ${doc.title} (status: ${doc.status})`);
Upload pre-processed chunks with embeddings
import OpenAI from "openai";
const openai = new OpenAI();
async function getEmbeddings(texts: string[]): Promise<number[][]> {
const response = await openai.embeddings.create({
model: "text-embedding-3-small",
input: texts,
});
return response.data.map((item) => item.embedding);
}
interface ChunkInput {
content: string;
metadata?: Record<string, unknown>;
}
async function uploadChunks(
agentId: string,
title: string,
chunksData: ChunkInput[]
) {
// 1. Create parent document
const doc = await talkpilot(`/agents/${agentId}/knowledge-base`, {
method: "POST",
body: JSON.stringify({ title, content: "" }),
});
const docId = doc.id;
// 2. Generate embeddings
const texts = chunksData.map((c) => c.content);
const embeddings = await getEmbeddings(texts);
// 3. Build chunk payloads
const chunks = chunksData.map((chunk, i) => ({
content: chunk.content,
embedding: embeddings[i],
chunk_index: i,
token_count: chunk.content.split(/\s+/).length,
metadata: chunk.metadata ?? {},
}));
// 4. Upload chunks
const result = await talkpilot(
`/agents/${agentId}/knowledge-base/${docId}/chunks`,
{
method: "POST",
body: JSON.stringify({ chunks }),
}
);
console.log(`Uploaded ${result.inserted_count} chunks for "${title}"`);
// 5. Mark document as completed
await talkpilot(`/agents/${agentId}/knowledge-base/${docId}`, {
method: "PATCH",
body: JSON.stringify({ status: "completed" }),
});
return docId;
}
// Usage
await uploadChunks(agentId, "Product Catalog", [
{ content: "Produkt A kostet 29,99 EUR...", metadata: { category: "pricing" } },
{ content: "Produkt B kostet 49,99 EUR...", metadata: { category: "pricing" } },
]);
Node.js example (complete script)
// talkpilot-sync.ts
// Sync employee statuses from your HR system to TalkPilot
const BASE_URL = process.env.TALKPILOT_BASE_URL!;
const API_KEY = process.env.TALKPILOT_API_KEY!;
const AGENT_ID = process.env.TALKPILOT_AGENT_ID!;
async function talkpilot(path: string, options: RequestInit = {}) {
const res = await fetch(`${BASE_URL}${path}`, {
...options,
headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", ...options.headers },
});
if (res.status === 204) return null;
const body = await res.json();
if (!res.ok) throw new Error(`[${body.error.code}] ${body.error.message}`);
return body;
}
// Simulated HR data
const hrEmployees = [
{ name: "Max Mustermann", status: "anwesend" },
{ name: "Erika Musterfrau", status: "urlaub" },
];
async function syncStatuses() {
const { data: employees } = await talkpilot(`/agents/${AGENT_ID}/employees`);
for (const hrEmployee of hrEmployees) {
const match = employees.find((e: any) => e.name === hrEmployee.name);
if (match && match.status !== hrEmployee.status) {
await talkpilot(`/agents/${AGENT_ID}/employees/${match.id}`, {
method: "PATCH",
body: JSON.stringify({ status: hrEmployee.status }),
});
console.log(`Updated ${match.name}: ${match.status} -> ${hrEmployee.status}`);
}
}
}
syncStatuses().catch(console.error);