The official JavaScript/TypeScript SDK for the Seclai API. Provides full typed coverage of all API endpoints, file uploads, SSE streaming, polling helpers, and automatic pagination.
Works in Node.js 18+, Deno, Bun, Cloudflare Workers, and any runtime with a fetch implementation.
npm install @seclai/sdk
import { Seclai } from "@seclai/sdk";
const client = new Seclai({ apiKey: process.env.SECLAI_API_KEY });
// List all sources
const sources = await client.listSources();
// Run an agent and stream the result
const result = await client.runStreamingAgentAndWait(
"agent_id",
{ input: "Summarize the latest uploads", metadata: {} },
{ timeoutMs: 120_000 },
);
console.log(result);
| Option | Environment variable | Default |
|---|---|---|
apiKey |
SECLAI_API_KEY |
— |
accessToken |
— | — |
profile |
SECLAI_PROFILE |
"default" |
configDir |
SECLAI_CONFIG_DIR |
~/.seclai |
autoRefresh |
— | true |
accountId |
— | — |
baseUrl |
SECLAI_API_URL |
https://api.seclai.com |
apiKeyHeader |
— | x-api-key |
defaultHeaders |
— | {} |
fetch |
— | globalThis.fetch |
Credentials are resolved via a chain (first match wins):
apiKey optionaccessToken option (string or () => string | Promise<string>)SECLAI_API_KEY environment variable~/.seclai/sso/cache/ (requires a prior seclai auth login)// API key
const client = new Seclai({ apiKey: "sk-..." });
// Static bearer token
const client = new Seclai({ accessToken: "eyJhbGciOi..." });
// Dynamic bearer token provider (called per request)
const client = new Seclai({
accessToken: async () => fetchTokenFromVault(),
});
// SSO profile (uses cached tokens, auto-refreshes)
const client = new Seclai({ profile: "my-profile" });
// Environment variable (no options needed)
// export SECLAI_API_KEY="sk-..."
const client = new Seclai();
SSO is the default fallback when no explicit credentials are provided. The SDK
includes built-in production SSO defaults, so seclai configure sso is not
required. You only need to log in once to populate the token cache:
npx @seclai/cli auth login # authenticate via browser — no prior setup needed
To customize SSO settings (e.g. for a staging environment), use seclai configure sso
or set environment variables:
| Variable | Description | Default |
|---|---|---|
SECLAI_SSO_DOMAIN |
Cognito domain | auth.seclai.com |
SECLAI_SSO_CLIENT_ID |
Cognito app client ID | 4bgf8v9qmc5puivbaqon9n5lmr |
SECLAI_SSO_REGION |
AWS region | us-west-2 |
Online API documentation (latest):
https://seclai.github.io/seclai-javascript/latest/
// CRUD
const agents = await client.listAgents({ page: 1, limit: 20 });
const agent = await client.createAgent({ name: "My Agent", description: "..." });
const fetched = await client.getAgent("agent_id");
const updated = await client.updateAgent("agent_id", { name: "Renamed" });
await client.deleteAgent("agent_id");
// Definition (step workflow)
const def = await client.getAgentDefinition("agent_id");
await client.updateAgentDefinition("agent_id", { steps: [...], change_id: def.change_id });
// Start a run
const run = await client.runAgent("agent_id", { input: "Hello" });
// List & search runs
const runs = await client.listAgentRuns("agent_id", { status: "completed" });
const search = await client.searchAgentRuns({ agent_id: "...", status: ["completed"] });
// Fetch run details (optionally with step outputs)
const detail = await client.getAgentRun("run_id", { includeStepOutputs: true });
// Cancel or delete
await client.cancelAgentRun("run_id");
await client.deleteAgentRun("run_id");
The SDK provides two streaming patterns over the SSE /runs/stream endpoint:
Block until done — returns the final done payload or throws on timeout:
const result = await client.runStreamingAgentAndWait(
"agent_id",
{ input: "Hello", metadata: {} },
{ timeoutMs: 60_000 },
);
Async iterator — yields every SSE event as { event, data }:
for await (const event of client.runStreamingAgent(
"agent_id",
{ input: "Hello" },
{ timeoutMs: 120_000 },
)) {
console.log(event.event, event.data);
if (event.event === "done") break;
}
For environments where SSE is not practical, poll for a completed run:
const result = await client.runAgentAndPoll(
"agent_id",
{ input: "Hello" },
{ pollIntervalMs: 2_000, timeoutMs: 120_000 },
);
const upload = await client.uploadAgentInput("agent_id", {
file: new Uint8Array([...]),
fileName: "input.pdf",
});
const status = await client.getAgentInputUploadStatus("agent_id", upload.upload_id);
const steps = await client.generateAgentSteps("agent_id", { user_input: "Build a RAG pipeline" });
const config = await client.generateStepConfig("agent_id", { step_type: "llm", user_input: "..." });
// Conversation history
const history = await client.getAgentAiConversationHistory("agent_id");
await client.markAgentAiSuggestion("agent_id", "conversation_id", { accepted: true });
const criteria = await client.listEvaluationCriteria("agent_id");
const created = await client.createEvaluationCriteria("agent_id", { name: "Accuracy", ... });
const detail = await client.getEvaluationCriteria("criteria_id");
await client.updateEvaluationCriteria("criteria_id", { ... });
await client.deleteEvaluationCriteria("criteria_id");
// Test a draft
await client.testDraftEvaluation("agent_id", { criteria: { ... }, run_id: "..." });
// Results by criteria
const results = await client.listEvaluationResults("criteria_id");
const summary = await client.getEvaluationCriteriaSummary("criteria_id");
await client.createEvaluationResult("criteria_id", { ... });
// Results by run
const runResults = await client.listRunEvaluationResults("agent_id", "run_id");
// Non-manual evaluation summary
const nonManual = await client.getNonManualEvaluationSummary("agent_id");
// Compatible runs for a criteria
const compatible = await client.listCompatibleRuns("criteria_id");
const kbs = await client.listKnowledgeBases();
const kb = await client.createKnowledgeBase({ name: "Docs KB" });
const fetched = await client.getKnowledgeBase("kb_id");
await client.updateKnowledgeBase("kb_id", { name: "Renamed KB" });
await client.deleteKnowledgeBase("kb_id");
const banks = await client.listMemoryBanks();
const bank = await client.createMemoryBank({ name: "Chat Memory", type: "conversation" });
const fetched = await client.getMemoryBank("mb_id");
await client.updateMemoryBank("mb_id", { name: "Renamed" });
await client.deleteMemoryBank("mb_id");
// Stats & compaction
const stats = await client.getMemoryBankStats("mb_id");
await client.compactMemoryBank("mb_id");
// Test compaction
const test = await client.testMemoryBankCompaction("mb_id", { ... });
const standalone = await client.testCompactionPromptStandalone({ ... });
// Templates & agents
const templates = await client.listMemoryBankTemplates();
const agents = await client.getAgentsUsingMemoryBank("mb_id");
// AI assistant
const suggestion = await client.generateMemoryBankConfig({ user_input: "..." });
const history = await client.getMemoryBankAiLastConversation();
await client.acceptMemoryBankAiSuggestion("conv_id", { ... });
// Source management
await client.deleteMemoryBankSource("mb_id");
const sources = await client.listSources({ page: 1, limit: 20, order: "asc" });
const source = await client.createSource({ name: "My Source", ... });
const fetched = await client.getSource("source_id");
await client.updateSource("source_id", { name: "Renamed" });
await client.deleteSource("source_id");
Upload a file to a source (max 200 MiB). The SDK infers MIME type from the file extension when mimeType is not provided.
import { readFile } from "node:fs/promises";
await client.uploadFileToSource("source_id", {
file: await readFile("document.pdf"),
fileName: "document.pdf",
title: "Q4 Report",
metadata: { department: "finance" },
});
Upload inline text:
await client.uploadInlineTextToSource("source_id", {
text: "Hello, world!",
title: "Greeting",
});
Replace a content version with a new file:
await client.uploadFileToContent("content_version_id", {
file: await readFile("updated.pdf"),
fileName: "updated.pdf",
mimeType: "application/pdf",
});
const exports = await client.listSourceExports("source_id");
const exp = await client.createSourceExport("source_id", { format: "json" });
const status = await client.getSourceExport("source_id", exp.id);
const estimate = await client.estimateSourceExport("source_id", {});
const response = await client.downloadSourceExport("source_id", exp.id);
await client.deleteSourceExport("source_id", exp.id);
await client.cancelSourceExport("source_id", exp.id);
const migration = await client.getSourceEmbeddingMigration("source_id");
await client.startSourceEmbeddingMigration("source_id", { target_model: "..." });
await client.cancelSourceEmbeddingMigration("source_id");
const detail = await client.getContentDetail("content_id", { start: 0, end: 1000 });
const embeddings = await client.listContentEmbeddings("content_id");
await client.deleteContent("content_id");
// Replace content with inline text
await client.replaceContentWithInlineText("content_id", { text: "Updated text", title: "Updated" });
// Upload a replacement file
await client.uploadFileToContent("content_id", {
file: await readFile("updated.pdf"),
fileName: "updated.pdf",
});
const solutions = await client.listSolutions();
const sol = await client.createSolution({ name: "My Solution" });
const fetched = await client.getSolution("solution_id");
await client.updateSolution("solution_id", { name: "Renamed" });
await client.deleteSolution("solution_id");
// Link / unlink resources
await client.linkAgentsToSolution("solution_id", { ids: ["agent_id"] });
await client.unlinkAgentsFromSolution("solution_id", { ids: ["agent_id"] });
await client.linkKnowledgeBasesToSolution("solution_id", { ids: ["kb_id"] });
await client.unlinkKnowledgeBasesFromSolution("solution_id", { ids: ["kb_id"] });
await client.linkSourceConnectionsToSolution("solution_id", { ids: ["source_id"] });
await client.unlinkSourceConnectionsFromSolution("solution_id", { ids: ["source_id"] });
// AI assistant
const plan = await client.generateSolutionAiPlan("solution_id", { user_input: "Set up a RAG pipeline" });
await client.acceptSolutionAiPlan("solution_id", "conversation_id", {});
await client.declineSolutionAiPlan("solution_id", "conversation_id");
// AI-generated knowledge base / source within the solution
await client.generateSolutionAiKnowledgeBase("solution_id", { user_input: "..." });
await client.generateSolutionAiSource("solution_id", { user_input: "..." });
// Conversations
const convs = await client.listSolutionConversations("solution_id");
await client.addSolutionConversationTurn("solution_id", { user_input: "..." });
await client.markSolutionConversationTurn("solution_id", "conversation_id", { ... });
const plan = await client.generateGovernanceAiPlan({ user_input: "Add a toxicity policy" });
const convs = await client.listGovernanceAiConversations();
await client.acceptGovernanceAiPlan("conversation_id");
await client.declineGovernanceAiPlan("conversation_id");
const alerts = await client.listAlerts({ status: "active" });
const alert = await client.getAlert("alert_id");
await client.changeAlertStatus("alert_id", { status: "resolved" });
await client.addAlertComment("alert_id", { text: "Investigating" });
// Subscriptions
await client.subscribeToAlert("alert_id");
await client.unsubscribeFromAlert("alert_id");
// Alert configs
const configs = await client.listAlertConfigs();
await client.createAlertConfig({ ... });
await client.getAlertConfig("config_id");
await client.updateAlertConfig("config_id", { ... });
await client.deleteAlertConfig("config_id");
// Organization preferences
const prefs = await client.listOrganizationAlertPreferences();
await client.updateOrganizationAlertPreference("org_id", "alert_type", { ... });
const alerts = await client.listModelAlerts();
await client.markModelAlertRead("alert_id");
await client.markAllModelAlertsRead();
const unread = await client.getUnreadModelAlertCount();
const recs = await client.getModelRecommendations("model_id");
const results = await client.search({ query: "quarterly report" });
const filtered = await client.search({ query: "my agent", entityType: "agent", limit: 5 });
// Generate plans for different resource types
const kb = await client.aiAssistantKnowledgeBase({ user_input: "Create a docs KB" });
const src = await client.aiAssistantSource({ user_input: "Add a web source" });
const sol = await client.aiAssistantSolution({ user_input: "Set up monitoring" });
const mb = await client.aiAssistantMemoryBank({ user_input: "Create a chat memory" });
// Accept or decline the generated plan
await client.acceptAiAssistantPlan("conversation_id", { confirm_deletions: true });
await client.declineAiAssistantPlan("conversation_id");
// Memory bank conversation history
const history = await client.getAiAssistantMemoryBankHistory();
await client.acceptAiMemoryBankSuggestion("conversation_id", { ... });
// Feedback
await client.submitAiFeedback({ ... });
Automatically iterate through all pages:
for await (const source of client.paginate(
(opts) => client.listSources(opts),
{ limit: 50 },
)) {
console.log(source.name);
}
All errors extend SeclaiError:
import {
SeclaiError,
SeclaiConfigurationError,
SeclaiAPIStatusError,
SeclaiAPIValidationError,
SeclaiStreamingError,
} from "@seclai/sdk";
try {
await client.getAgent("bad_id");
} catch (err) {
if (err instanceof SeclaiAPIValidationError) {
console.error("Validation:", err.validationError);
} else if (err instanceof SeclaiAPIStatusError) {
console.error(`HTTP ${err.statusCode}:`, err.responseText);
} else if (err instanceof SeclaiStreamingError) {
console.error("Stream failed for run:", err.runId);
}
}
All low-level methods support an AbortSignal for request cancellation:
const controller = new AbortController();
// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5_000);
const data = await client.request("GET", "/agents", {
signal: controller.signal,
});
For endpoints not yet covered by a convenience method, use request or requestRaw:
// JSON request/response
const data = await client.request("POST", "/custom/endpoint", {
json: { key: "value" },
query: { filter: "active" },
});
// Raw Response (e.g. binary downloads)
const response = await client.requestRaw("GET", "/files/download/123");
const blob = await response.blob();
npm install
npm run typecheck
npm run build
This also regenerates src/openapi.ts from openapi/seclai.openapi.json.
npm test
Generate HTML docs into build/docs/:
npm run docs