
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
Typed TypeScript/JavaScript client for the Zvid JSON-to-video/image rendering API. Fetch-based with zero runtime dependencies, ESM + CJS, strict types derived from the maintained API contract, automatic transient-failure retries, polling helpers, media uploads, and timing-safe webhook signature verification.
npm install @zvid/sdk
Requires Node 18+ (native fetch). The API client itself is runtime-agnostic;
the webhook helpers use node:crypto.
import { ZvidClient, outputUrl } from "@zvid/sdk";
const zvid = new ZvidClient(); // reads ZVID_API_KEY; create one at https://app.zvid.io/api-keys
const job = await zvid.renders.createImage({
payload: {
type: "image",
width: 1200,
height: 630,
visuals: [{ type: "TEXT", text: "Hello Zvid", position: "center-center" }],
},
});
const done = await zvid.waitForRender(job.jobId, { timeoutMs: 120_000 });
console.log(outputUrl(done)); // https://cdn.zvid.io/...
| Option | Env var | Default |
|---|---|---|
apiKey | ZVID_API_KEY | — (required) |
baseUrl | ZVID_BASE_URL | https://api.zvid.io |
fetch | — | global fetch |
maxRetries | — | 3 |
retryBaseDelayMs | — | 1000 |
retryMaxDelayMs | — | 30000 |
Network failures and HTTP 429, 502, 503, and 504 responses are retried with
exponential backoff and jitter. Retry-After is honored up to retryMaxDelayMs.
Set maxRetries: 0 when the caller must never repeat a request. onRetry can feed
application logs or metrics without replacing the retry implementation.
| Namespace | Methods |
|---|---|
zvid.account | profile |
zvid.apiKeys | list, create, update, stats, revoke / delete |
zvid.authoring | getSchema, listElements, getElementDocs, getExamples, creativePlan, repair, validate (plan-aware; no render credits) |
zvid.renders | create, createImage, createBulk, createImageBulk, listBulk, getBulk |
zvid.jobs | get, list, wait |
zvid.templates | list, get, create, update, duplicate, preview, archive / delete |
zvid.projects | list, get, create, update, delete |
zvid.uploads | list, create, delete |
zvid.webhooks | list, get, create, update, delete, test, deliveries |
zvid.credits | balance, transactions, usageStats |
Renders are asynchronous: every renders.create* call returns { jobId }.
Poll zvid.jobs.get(jobId) yourself, or block with
zvid.waitForRender(jobId, { timeoutMs, pollIntervalMs, signal }) — it resolves with
the terminal JobStatus (use the outputUrl() / thumbnailUrl() helpers on it),
rejects with RenderFailedError on failure and WaitTimeoutError on timeout, and
supports AbortSignal.
Every render call takes exactly one of payload (inline project JSON, typed as
RenderPayload) or template (stored tpl_… id), plus optional variables,
overrides, and a one-off webhookUrl. The authoritative payload schema is
published at docs.zvid.io (render-payload.schema.json).
zvid.authoring.validate() always resolves for schema validation: check its valid
field. Invalid payloads return { valid: false, errors, warnings }; authentication,
network, and other API failures still throw.
Upload a browser File or a Blob created in Node.js. The returned CDN URL can be
used directly as an image, video, GIF, or audio element source.
import { readFile } from "node:fs/promises";
const bytes = await readFile("./poster.png");
const poster = await zvid.uploads.create(
new Blob([bytes], { type: "image/png" }),
{ fileName: "poster.png", width: 1200, height: 630 },
);
console.log(poster.url);
For AI generation, read zvid.authoring.getSchema() and the relevant element docs, start from a validated example, then repair and validate before calling zvid.renders.create*.
All API errors extend ZvidAPIError (with .status, .error, .details, .body):
| Class | When |
|---|---|
AuthenticationError | 401 |
InsufficientCreditsError | 402 — has .creditsRequired / .creditsAvailable |
NotFoundError | 404 |
RateLimitError | 429 — has .retryAfter (seconds) |
RenderFailedError | thrown by waitForRender when the job fails (.job) |
WaitTimeoutError | thrown by waitForRender on timeout |
Deliveries to registered endpoints are signed:
X-Zvid-Signature: sha256=hex(HMAC_SHA256(secret, "<X-Zvid-Timestamp>.<raw body>")).
import { verifyWebhookSignature } from "@zvid/sdk";
// Express example — use the RAW body (express.raw / rawBody), not re-serialized JSON
app.post("/hooks/zvid", express.raw({ type: "application/json" }), (req, res) => {
if (!verifyWebhookSignature(req.body, req.headers, process.env.ZVID_WEBHOOK_SECRET!)) {
return res.status(400).end();
}
const event = JSON.parse(req.body.toString());
// event.event === "render.completed" | "render.failed", event.data.url, …
res.status(200).end();
});
verifyWebhookSignature uses crypto.timingSafeEqual and rejects deliveries older
than 5 minutes ({ toleranceSeconds: null } disables the freshness check). It accepts
fetch Headers, Node request headers, or plain objects. Per-request webhookUrl
deliveries are not signed — only account endpoints are.
npm install
npm run typecheck && npm test && npm run build
Live smoke test against a running orchestrator (spends ~1 credit):
ZVID_API_KEY=zvid_… ZVID_BASE_URL=http://localhost:4000 node examples/e2e.mjs
Not published yet. To release version 0.2.0:
npm run prepublishOnly # typecheck + tests + build
npm publish # publish the public `@zvid/sdk` package to npm
FAQs
Official TypeScript/JavaScript SDK for the Zvid JSON-to-video/image rendering API
We found that @zvid/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.