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
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",
});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.
// 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.
// 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.
// 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.
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.
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");
}EClipsError.