Examples
Worked SDK snippets — list projects, create monitors, fetch runs with citations, kick off prompt ingestion.
Every snippet here assumes you’ve already configured the SDK per the overview. All examples are TypeScript and run on Node 20+ and modern runtimes (Edge, Bun, Deno).
List all projects (paginated)
import { DefaultService } from "@citefoundry/api-client";
const projects: { id: string; name: string }[] = [];
let cursor: string | undefined;do { const page = await DefaultService.listProjects({ limit: 100, cursor }); projects.push(...page.items.map((p) => ({ id: p.id, name: p.name }))); cursor = page.nextCursor;} while (cursor);
console.log(`Found ${projects.length} projects.`);See Pagination for the cursor model.
Create a monitor
import { DefaultService } from "@citefoundry/api-client";
const monitor = await DefaultService.createMonitor({ projectId: "proj_01J...", requestBody: { promptId: "prom_01J...", surface: "chatgpt", // see /v1/monitoring-surfaces for the catalog cadence: "daily", // "daily" | "weekly" },});
console.log("Created", monitor.id);The first run usually fires within a minute or two on Free and is near-instant on Pro/Business.
Fetch a run and iterate citations
import { DefaultService } from "@citefoundry/api-client";
const run = await DefaultService.getRun({ projectId, runId });
console.log(`Answer (${run.surface}, ${run.modelVersion}):`);console.log(run.answer);
console.log("\nCitations:");for (const c of run.citations) { const owner = c.brand?.displayName ?? "(unknown)"; console.log(` [${owner}] ${c.url}`);}
console.log("\nMentions:");for (const m of run.mentions) { console.log(` ${m.brand.displayName} (${m.surface})`);}Kick off prompt ingestion from CSV
import { DefaultService } from "@citefoundry/api-client";import { readFile } from "node:fs/promises";
const csv = await readFile("./keywords.csv", "utf8");
const job = await DefaultService.startPromptSource({ projectId, kind: "csv", requestBody: { csv, defaultPersonaId: null },});
console.log("Ingestion job started:", job.id);
// Poll until done — 5s intervals are fine for CSV-sized jobs.while (true) { const status = await DefaultService.getIngestionJob({ projectId, jobId: job.id }); if (status.state !== "pending" && status.state !== "running") break; await new Promise((r) => setTimeout(r, 5000));}
console.log("Done. Candidates ready for review in the dashboard.");Pull GSC queries and start an ingestion
import { DefaultService } from "@citefoundry/api-client";
// Make sure the project has GSC connected first (use the dashboard// for the OAuth dance).const properties = await DefaultService.listGscProperties();const property = properties[0];
const job = await DefaultService.startPromptSource({ projectId, kind: "gsc", requestBody: { siteUrl: property.siteUrl, country: "USA", minImpressions: 100, strict: true, // drop branded queries },});
console.log("GSC ingestion started:", job.id);Get share-of-voice for a window
import { DefaultService } from "@citefoundry/api-client";
const sov = await DefaultService.getShareOfVoice({ projectId, from: "2026-04-01", to: "2026-04-30", surface: "chatgpt",});
for (const row of sov.brands) { console.log(`${row.brand.displayName.padEnd(20)} ${row.share.toFixed(1)}%`);}Stream the runs of a monitor as JSON Lines
A small CLI utility — useful for piping into jq or a warehouse load.
import { DefaultService } from "@citefoundry/api-client";
const [, , projectId, monitorId] = process.argv;
let cursor: string | undefined;do { const page = await DefaultService.listRuns({ projectId, monitorId, limit: 100, cursor, }); for (const run of page.items) { process.stdout.write(JSON.stringify(run) + "\n"); } cursor = page.nextCursor;} while (cursor);What’s next
- Error handling — wrap any of the above with retries, refresh, and graceful degradation.
- API reference — schemas for every request and response shape used in these examples.