Developer Manual

TypeScript SDK

@eclips/sdk is a fully typed, zero-dependency client over the same REST API. Construct it with new EClipsClient({ apiKey }); the base URL defaults to https://api.eclips.tech. Every method derives your organization from the key.

Construct a client

typescript
import { EClipsClient } from "@eclips/sdk";

// Minimal — base URL defaults to https://api.eclips.tech.
const client = new EClipsClient({ apiKey: process.env.ECLIPS_API_KEY! });

// Override the base URL (e.g. a self-hosted gateway) if needed.
const staging = new EClipsClient({
  apiKey: process.env.ECLIPS_API_KEY!,
  baseUrl: "https://staging-api.eclips.tech",
});
Tip:The constructor throws if apiKey is missing. You never pass an organization id for the /v1 methods below — it rides on the key.

Runs

run() fires and returns { run_id, status }. runAndWait() fires and polls. waitForRun() polls an existing run until completed, failed, or pending_triage (throwing TimeoutError past the deadline). getRun() fetches one run; listRuns() lists them.

typescript
// Fire-and-forget: returns { run_id, status } immediately.
const { run_id } = await client.run(
  "ap_specialist",
  "Process invoice INV-2024-001",
  { amount: 5000 },        // optional structured data
);

// Fetch the current state of one run.
const run = await client.getRun(run_id);

// Poll an existing run until it reaches a terminal state.
const final = await client.waitForRun(run_id, { timeoutMs: 120_000, pollIntervalMs: 2_000 });

// Or do both at once — fire and poll.
const result = await client.runAndWait("ap_specialist", "Process invoice INV-2024-001");
console.log(result.status, result.result, result.confidence_score);

// List recent runs (org derived from the key).
const runs = await client.listRuns({ status: "completed", limit: 20, offset: 0 });
run(agentType, task, data?)POST /v1/run — returns { run_id, status }.
runAndWait(agentType, task, data?, options?)run() then waitForRun(). options: { timeoutMs, pollIntervalMs }.
waitForRun(runId, options?)Polls GET /v1/runs/:id until terminal; default timeout 120 000 ms, interval 2 000 ms.
getRun(runId)GET /v1/runs/:id — single run result.
listRuns({ limit?, offset?, agentType?, status? })GET /v1/runs — array of runs.

Triage

listTriage(), approveTriage(id, note?), and rejectTriage(id, reason?) drive the human-in-the-loop flow.

typescript
// List pending human-in-the-loop items.
const items = await client.listTriage({ status: "pending", limit: 20 });

// Approve — completes the blocked run.
await client.approveTriage(items[0].id, "Verified against PO");

// Reject — cancels the pending action.
await client.rejectTriage(items[0].id, "Amount exceeds budget");
listTriage({ status?, limit?, offset? })GET /v1/triage — defaults to status "pending".
approveTriage(triageId, resolutionNote?)POST /v1/triage/:id/approve.
rejectTriage(triageId, reason?)POST /v1/triage/:id/reject (sent as resolution_note).

Webhooks

createWebhook(url, events) validates that the URL is HTTPS and that at least one event is supplied (throwing ValidationError otherwise), then returns the webhook including its one-time secret. listWebhooks() and deleteWebhook(id) round out the set.

typescript
// createWebhook validates URL is HTTPS and events is non-empty,
// then returns the webhook including its one-time secret.
const webhook = await client.createWebhook(
  "https://your-app.com/webhooks/eclips",
  ["run.completed", "run.failed", "run.triage_required"],
);
console.log(webhook.secret); // whsec_… — store it now, shown once

const all = await client.listWebhooks();
await client.deleteWebhook(webhook.id);

Batches

createBatch(agentType, rows, options?), getBatch(id), listBatches(options?), and cancelBatch(id) mirror the batch endpoints.

typescript
const batch = await client.createBatch("ap_specialist", [
  { task: "Process invoice INV-1001" },
  { task: "Process invoice INV-1002", data: { amount: 12000 } },
], { name: "June invoices" });

// Poll for progress.
const status = await client.getBatch(batch.id);
console.log(status.completed_rows, "/", status.total_rows);

const jobs = await client.listBatches({ status: "running" });
await client.cancelBatch(batch.id);

Worked example

Example · Run, wait, and resolve triage

A full agent-run lifecycle: fire a run, wait (tolerating a client-side timeout), and approve the triage gate from your own system.

typescript
import { EClipsClient, TimeoutError } from "@eclips/sdk";

const client = new EClipsClient({ apiKey: process.env.ECLIPS_API_KEY! });

// 1. Fire the run.
const { run_id } = await client.run("ap_specialist", "Process invoice INV-2024-001", { amount: 18000 });

// 2. Wait for a terminal state.
let run;
try {
  run = await client.waitForRun(run_id, { timeoutMs: 90_000 });
} catch (err) {
  if (err instanceof TimeoutError) {
    // The run is still valid — re-poll later with client.getRun(run_id).
    run = await client.getRun(run_id);
  } else throw err;
}

// 3. If a human gate fired, resolve it from your own system.
if (run.status === "pending_triage") {
  const [item] = await client.listTriage({ status: "pending", limit: 1 });
  await client.approveTriage(item.id, "Manager sign-off in ERP #4821");
}
Note:Error handling is covered in detail in Errors — every failure is a catchable subclass of EClipsError.