Developer Platform

Run Workforce agents
from your own code.

A REST API, a TypeScript SDK and a starter project for calling eClips Workforce from your systems. Start a run, wait for the result, and handle the ones that need a person.

The public API is included on the Growth and Enterprise plans. The SDK and CLI aren't on the public npm registry yet; ask us for access.

npm install @eclips/sdk
API ReferenceGet API Key
20public endpoints
3webhook events
500rows per batch
0SDK runtime dependencies
Quickstart

Your first run, in four steps.

bash
npm install @eclips/sdk
create-eclips-app

Start from a working project.

The CLI asks for a project name, a template and, if you have it, your API key. Then it writes a project you can install and run.

express-apiAn Express server with a /run endpoint
nextjs-dashboardA Next.js page that lists run history
agent-onlyOne TypeScript script, no server
bash
npx create-eclips-app

Requires Node.js 18 or newer.

Webhooks

Hear about a run when it finishes.

Register a webhook and eClips POSTs to it when a run completes, fails or needs a person. Each POST carries an X-eClips-Signature header, an HMAC-SHA256 of the body made with the secret you got at registration, so you can check it came from us.

typescript
import crypto from 'crypto';
import { EClipsClient } from '@eclips/sdk';

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

// Register a webhook. The signing secret is returned once, so store it.
const { secret } = await client.createWebhook(
  'https://your-app.com/webhooks/eclips',
  ['run.completed', 'run.failed', 'run.triage_required'],
);

// Verify the request came from eClips
function verifySignature(rawBody: string, secret: string, sig: string) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return `sha256=${expected}` === sig;
}

// Express handler
app.post('/webhooks/eclips', express.raw({ type: '*/*' }), (req, res) => {
  const sig = req.headers['x-eclips-signature'] as string;
  if (!verifySignature(req.body.toString(), process.env.WEBHOOK_SECRET!, sig)) {
    return res.status(401).send('Unauthorized');
  }

  const event = JSON.parse(req.body.toString());

  switch (event.event) {
    case 'run.completed':
      console.log('Run finished:', event.run_id, event.data.output);
      break;
    case 'run.failed':
      console.error('Run failed:', event.run_id, event.data.error);
      break;
    case 'run.triage_required':
      // Notify Slack, email the team, etc.
      break;
  }

  res.json({ ok: true });
});

Delivered events

run.completed

Agent finished successfully

run.failed

Agent run encountered an error

run.triage_required

Agent needs human review

Batch processing

Run one agent over a whole list.

Send up to 500 inputs in one call with createBatch, then poll for progress. Rows run 10 at a time, and one failed row doesn't stop the rest.

One call, up to 500 rows

POST /v1/batches with a list of inputs for the same agent

Progress counts

getBatch returns completed, failed and total rows

Cancellable

cancelBatch stops an in-flight batch at any time

Listable

listBatches returns the batch history for your org

typescript
// Run the same agent over many rows in one call
const batch = await client.createBatch('ap_specialist', [
  { invoice_id: 'INV-1001' },
  { invoice_id: 'INV-1002' },
  { invoice_id: 'INV-1003' },
]);

// Poll for progress, or cancel if needed
const status = await client.getBatch(batch.id);
console.log(status.completed, '/', status.total);
SDK Reference

The SDK methods.

Every method is typed. The API reference covers parameters, errors and rate limits.

client.run()Runs

Trigger an agent run, returns run_id immediately

client.runAndWait()Runs

Trigger + poll until terminal

client.waitForRun()Runs

Poll an existing run until terminal

client.getRun()Runs

Fetch a single run by id

client.listRuns()Runs

Run history ({ data, total, limit, offset })

client.listTriage()Triage

Pending human-in-the-loop items

client.approveTriage()Triage

Approve and continue the blocked run

client.rejectTriage()Triage

Reject an item with an optional reason

client.createWebhook()Webhooks

Register a URL + events; returns the secret once

client.listWebhooks()Webhooks

List registered webhook endpoints

client.deleteWebhook()Webhooks

Delete a webhook by id

client.createBatch()Batch

Run an agent over many rows at once

client.getBatch()Batch

Fetch a batch with progress counts

client.listBatches()Batch

List batches for your org

client.cancelBatch()Batch

Cancel an in-flight batch

Full API Reference

Error handling

Each kind of failure has its own error class, so you handle the ones you care about.

typescript
import {
  EClipsClient,
  AuthenticationError,
  RateLimitError,
  ValidationError,
  NotFoundError,
  TimeoutError,
} from '@eclips/sdk';

try {
  const result = await client.runAndWait('ap_specialist', task);
} catch (err) {
  if (err instanceof AuthenticationError) {
    // Invalid or missing API key
  } else if (err instanceof RateLimitError) {
    // err.retryAfter is the wait in seconds
    await sleep(err.retryAfter ?? 60);
  } else if (err instanceof TimeoutError) {
    // The wait timed out, but the run carries on.
    // Poll client.getRun(err.runId) to check progress.
  } else if (err instanceof NotFoundError) {
    // Run, triage item, or webhook not found
  }
}
Talk to us

Start with
one problem.

Tell us where the work gets stuck, whether it's a spreadsheet at month-end or an ISO 9001 audit on the calendar. We'll show you the product that fits, or tell you if none of ours does.

A 30-minute live walkthrough. No slides.