Docs / Reliability

Error handling

Every failure throws ZpiError or a subclass. The base class carries status, code?, raw, and requestId? (from the x-request-id header) — include the request id when reporting issues.

ClassTriggerStatusExtra fields
ZpiInvalidParamsErrorParameter validation failed400 / 422errors[{ path?, message? }]
ZpiExecErrorScraper ran but failed400error, errors, context?, project?
ZpiBulkCapErrorBulk item cap exceeded400cap?, submitted?
ZpiAuthErrorBad or missing API key401—
ZpiPlanGateErrorPlan tier too low403requiredPlan?, upgradeUrl?
ZpiBulkNotEnabledErrorBulk disabled for endpoint403—
ZpiNotFoundErrorScraper/endpoint not found404—
ZpiMethodNotAllowedErrorWrong HTTP method405—
ZpiIdempotencyErrorIdempotency key conflict422—
ZpiRateLimitErrorRate limit exceeded429limit?, used?, window?, retryAfterSec?, retryAfter?, requested?
ZpiServerErrorBackend error500—
ZpiDisabledErrorEndpoint disabled503—
ZpiNetworkError / ZpiTimeoutError / ZpiAbortErrorTransport failure / timeout / abort0cause
ZpiMcpErrorMCP JSON-RPC error0code, data

ZpiInvalidParamsError

Trigger: Parameter validation failed

Status: 400 / 422

Extra fields: errors[{ path?, message? }]

ZpiExecError

Trigger: Scraper ran but failed

Status: 400

Extra fields: error, errors, context?, project?

ZpiBulkCapError

Trigger: Bulk item cap exceeded

Status: 400

Extra fields: cap?, submitted?

ZpiAuthError

Trigger: Bad or missing API key

Status: 401

Extra fields: —

ZpiPlanGateError

Trigger: Plan tier too low

Status: 403

Extra fields: requiredPlan?, upgradeUrl?

ZpiBulkNotEnabledError

Trigger: Bulk disabled for endpoint

Status: 403

Extra fields: —

ZpiNotFoundError

Trigger: Scraper/endpoint not found

Status: 404

Extra fields: —

ZpiMethodNotAllowedError

Trigger: Wrong HTTP method

Status: 405

Extra fields: —

ZpiIdempotencyError

Trigger: Idempotency key conflict

Status: 422

Extra fields: —

ZpiRateLimitError

Trigger: Rate limit exceeded

Status: 429

Extra fields: limit?, used?, window?, retryAfterSec?, retryAfter?, requested?

ZpiServerError

Trigger: Backend error

Status: 500

Extra fields: —

ZpiDisabledError

Trigger: Endpoint disabled

Status: 503

Extra fields: —

ZpiNetworkError / ZpiTimeoutError / ZpiAbortError

Trigger: Transport failure / timeout / abort

Status: 0

Extra fields: cause

ZpiMcpError

Trigger: MCP JSON-RPC error

Status: 0

Extra fields: code, data

errors.ts
import {  ZpiError,  ZpiPlanGateError,  ZpiRateLimitError,} from "zpi-sdk"; try {  const data = await client.run("social:instagram", "profile", {    username: "instagram",  });} catch (e) {  if (e instanceof ZpiPlanGateError) {    console.log("upgrade:", e.requiredPlan, e.upgradeUrl);  } else if (e instanceof ZpiRateLimitError) {    console.log("retry after", e.retryAfterSec, "s");  } else if (e instanceof ZpiError) {    console.log(e.status, e.code, e.raw);  }}
import {  ZpiError,  ZpiPlanGateError,  ZpiRateLimitError,} from "zpi-sdk"; try {  const data = await client.run("social:instagram", "profile", {    username: "instagram",  });} catch (e) {  if (e instanceof ZpiPlanGateError) {    console.log("upgrade:", e.requiredPlan, e.upgradeUrl);  } else if (e instanceof ZpiRateLimitError) {    console.log("retry after", e.retryAfterSec, "s");  } else if (e instanceof ZpiError) {    console.log(e.status, e.code, e.raw);  }}
Edit this page on GitHubWas this page helpful? ·