Developer Manual

TypeScript SDK

@eclips/sdk is a typed client for the same REST API, with no runtime dependencies. Create it with new EClipsClient({ apiKey }). The base URL defaults to https://api.eclips.tech, and your organization comes from the key.

Construct a client

The package is not on the public npm registry yet. Ask us for access.

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

// Minimal. The 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 comes from the key.

Runs

run() starts a run and returns { run_id, status }. runAndWait() starts one and polls. waitForRun() polls an existing run until it is completed, failed or pending_triage, and throws TimeoutError past the deadline. getRun() fetches one run and 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: start the run 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 the run finishes. Default timeout 120,000 ms, interval 2,000 ms.
getRun(runId)GET /v1/runs/:id. One run's result.
listRuns({ limit?, offset?, agentType?, status? })GET /v1/runs. An array of runs.

Triage

listTriage(), approveTriage(id, note?), and rejectTriage(id, reason?) handle the items that wait for a person.

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

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

// Reject: the pending action is cancelled.
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) checks that the URL is HTTPS and that there is at least one event, and throws ValidationError if not. It returns the webhook with its secret, which is shown once. There are also listWebhooks() and deleteWebhook(id).

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. It is shown once.

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

Batches

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

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

One agent run from start to finish: start it, wait (and cope with a client-side timeout), then approve the triage item 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 going. Poll again 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 Errors. Every failure is a subclass of EClipsError.