@zeridion/flare
v0.2.992
Published
Managed background jobs. TypeScript/JavaScript SDK for the Zeridion Flare API.
Maintainers
Readme
@zeridion/flare
TypeScript/JavaScript SDK for the Zeridion Flare managed background jobs API.
Full documentation at docs.zeridion.com/flare
Installation
npm install @zeridion/flareRequires Node 20+ or a modern browser (native fetch is used — no runtime dependencies).
Quick start
import { FlareClient } from "@zeridion/flare";
const flare = new FlareClient({ apiKey: "zf_live_sk_..." });
// Or, with FLARE_API_KEY set in the environment:
// const flare = new FlareClient();
// Enqueue a job
const job = await flare.createJob({
job_type: "SendWelcomeEmail",
payload: { email: "[email protected]" },
queue: "default",
max_attempts: 3,
});
console.log(job.id, job.state); // "job_abc123", "pending"API
new FlareClient(opts)
| Option | Type | Required | Default |
|-----------|----------|----------|--------------------------------------|
| apiKey | string | no | process.env.FLARE_API_KEY |
| baseUrl | string | no | "https://api.zeridion.com" |
All methods accept an optional second RequestOptions argument (except listJobs, whose RequestOptions fields are merged into its single options object):
interface RequestOptions {
idempotencyKey?: string; // sent as Idempotency-Key header
requestId?: string; // sent as X-Request-Id header (log correlation)
signal?: AbortSignal;
}Jobs
// Create a job
const job = await flare.createJob(req, opts?);
// Get a job (returns null if not found)
const detail = await flare.getJob(id, opts?);
// List jobs with filtering and pagination
const list = await flare.listJobs({ state: "failed", queue: "critical", limit: 25, requestId: "..." });
// Cancel a job (returns null if already in a non-cancellable state)
const cancelled = await flare.cancelJob(id, opts?);
// Retry a failed or dead-lettered job (returns null if not retryable)
const retried = await flare.retryJob(id, opts?);Workers (advanced)
// Poll for available jobs
const poll = await flare.pollWorker({ worker_id: "w1", queues: ["default"], capacity: 5 });
// Acknowledge a completed job
const ack = await flare.ackWorker({
job_id: poll.jobs[0].id,
worker_id: "w1",
status: "succeeded",
duration_ms: 120,
});Error handling
The SDK throws typed errors derived from FlareError:
import {
FlareError,
AuthError, // 401 — invalid API key
NotFoundError, // 404 — job not found
ConflictError, // 409 — idempotency conflict / invalid state
RateLimitError, // 429 — rate limit exceeded
QuotaError, // 402 — quota exceeded
} from "@zeridion/flare";
try {
await flare.createJob({ job_type: "MyJob" });
} catch (err) {
if (err instanceof RateLimitError) {
console.log("Retry after epoch:", err.retryAfter);
} else if (err instanceof AuthError) {
console.error("Check your API key");
} else if (err instanceof FlareError) {
console.error(err.code, err.requestId, err.statusCode);
}
}See the stable error-code registry for every error.code string the API can return.
Automatic retries
The SDK automatically retries HTTP 429 / 502 / 503 / 504 responses and transient network errors with exponential backoff + jitter. The Retry-After header is honored when present.
| Option | Default | Notes |
|---------------------|----------|--------------------------------------------------------|
| maxRetries | 3 | Set to 0 to disable retries entirely. |
| retryBaseDelayMs | 500 | Base for the exponential schedule. |
| retryMaxDelayMs | 30000 | Cap on a single backoff wait (and on Retry-After). |
const flare = new FlareClient({
apiKey: "...",
maxRetries: 5,
retryBaseDelayMs: 200,
});A user-initiated AbortSignal always wins — the SDK never retries past an explicit abort.
Verifying webhook signatures
If you've configured outbound webhooks via the /flare/v1/webhooks API, verify the X-Zeridion-Signature header on each incoming delivery before processing the event:
import { verifyWebhook } from "@zeridion/flare";
export async function POST(req: Request) {
const rawBody = await req.text();
const header = req.headers.get("x-zeridion-signature") ?? "";
const secret = process.env.ZERIDION_WEBHOOK_SECRET!;
const ok = await verifyWebhook(rawBody, header, secret, { toleranceSeconds: 300 });
if (!ok) return new Response("invalid signature", { status: 400 });
// ... process the event ...
return new Response("ok");
}verifyWebhook is HMAC-SHA256 over <unix_timestamp>.<raw_body>, constant-time-compared against every v1= value in the header (supports secret rotation). The optional toleranceSeconds parameter rejects replays older than that many seconds. Uses Web Crypto — works in Node 20+, Bun, Deno, Cloudflare Workers, Vercel Edge, and Fastly Compute@Edge JS.
Links
- Documentation: https://docs.zeridion.com/flare
- Dashboard: https://dashboard.zeridion.com/
- .NET SDK: ../csharp/README.md
- Runnable example: samples/typescript-starter/ — create + poll a job, worker poll + ack
