Developer Manual
Errors
Errors use standard HTTP status codes and a JSON error field. The SDK maps each status to a catchable subclass of EClipsError, every one carrying statusCode and code so you can branch precisely.
Error shape
Failures return a JSON body with an error message; some add fields such as required and provided (scope checks) or field (validation).
json
{ "error": "task is required" }
// Some errors carry extra fields. A 403 from a scope check:
{ "error": "Insufficient scope", "required": "agents:run", "provided": ["agents:read"] }Status codes → SDK classes
Every EClipsError exposes statusCode (the HTTP status) and code (a machine-readable string).
| 400 | Validation error — the request body or parameters failed validation (e.g. missing task, unknown agent_type, >500 batch rows). SDK: ValidationError (err.field names the offending field when reported). |
| 401 | Authentication error — missing, invalid, expired, or revoked API key. SDK: AuthenticationError. |
| 403 | Permission — the key lacks the required scope, or the org's plan does not include API access. SDK: PermissionError. |
| 404 | Not found — the run, triage item, webhook, or batch does not exist for your org. SDK: NotFoundError. |
| 408 | Timeout — the SDK's waitForRun gave up before the run finished (the run itself may still complete). SDK: TimeoutError. This is raised client-side, not returned by the API. |
| 422 | Unprocessable — semantic validation failure. The SDK has no dedicated subclass; it surfaces as a base EClipsError with statusCode 422. |
| 429 | Rate limited or out of credits — too many requests, or the org has exhausted its plan/top-up credits. Respect Retry-After. SDK: RateLimitError (err.retryAfter in seconds). |
Note:The SDK maps
400 → ValidationError, 401 → AuthenticationError, 403 → PermissionError, 404 → NotFoundError, and 429 → RateLimitError. TimeoutError (status 408) is thrown locally by waitForRun. Any other status — including 422 and 5xx — surfaces as the base EClipsError.Handling errors
Branch on the error class to handle each case. Order matters: check subclasses before the base EClipsError.
typescript
import {
EClipsError,
AuthenticationError,
PermissionError,
RateLimitError,
ValidationError,
NotFoundError,
TimeoutError,
} from "@eclips/sdk";
try {
const result = await client.runAndWait("ap_specialist", task);
} catch (err) {
if (err instanceof AuthenticationError) {
// 401 — missing, invalid, expired, or revoked API key
} else if (err instanceof PermissionError) {
// 403 — the key lacks the required scope, or the plan lacks API access
} else if (err instanceof RateLimitError) {
await sleep((err.retryAfter ?? 60) * 1000); // seconds from Retry-After
} else if (err instanceof ValidationError) {
// 400 — err.field names the offending field, if reported
} else if (err instanceof NotFoundError) {
// 404 — run, triage item, webhook, or batch not found for your org
} else if (err instanceof TimeoutError) {
// 408 — waitForRun gave up; the run may still complete — poll getRun(...) later
} else if (err instanceof EClipsError) {
// Any other status (e.g. 422, 500) — inspect err.statusCode and err.code
}
}Error class reference
| EClipsError | Base class. Carries statusCode and code. Catches any failure the SDK does not map to a more specific class. |
| AuthenticationError | 401 / authentication_error — bad or missing API key. |
| PermissionError | 403 / permission_error — missing scope or no plan API access. |
| RateLimitError | 429 / rate_limit_error — adds retryAfter (number | null). |
| ValidationError | 400 / validation_error — adds field (string | null). |
| NotFoundError | 404 / not_found — resource not found for your org. |
| TimeoutError | 408 / timeout — raised by waitForRun; the run may still complete. |
Tip:An out-of-credit condition surfaces as a credit-related
429; check the error message and your /v1/usage summary to distinguish a frequency rate limit from an exhausted balance. See Rate limits & plans.