Zerokit

SDKs

First-party language clients for the Zerokit REST API.

TypeScript / JavaScript

The official zerokit-sdk package ships a typed client for every public REST endpoint. Works in Node.js, Bun, Deno, Cloudflare Workers — anywhere fetch is available.

Install

npm install zerokit-sdk
pnpm add zerokit-sdk
yarn add zerokit-sdk
bun add zerokit-sdk

Initialise

import { Zerokit } from 'zerokit-sdk';

const zerokit = new Zerokit({
  apiKey: process.env.ZEROKIT_API_KEY!,
});

Options

OptionTypeDescription
apiKeystringRequired. Workspace key (zk_live_* / zk_test_*).
baseUrlstringOverride the API origin. Defaults to https://api.zerokit.co.
fetchtypeof fetchInject a custom fetch (testing, instrumentation, retry wrapper).

Send an email

const { id } = await zerokit.sendEmail({
  from: 'Acme <[email protected]>',
  to: ['[email protected]'],
  subject: 'Welcome to Acme',
  html: '<p>Hello Jane</p>',
  text: 'Hello Jane',
});

console.log('Queued:', id);

Returns { id, status: 'queued' }. The send happens asynchronously — subscribe to a webhook to learn about delivery, bounces, opens, and clicks.

List emails

const emails = await zerokit.listEmails();

for (const email of emails) {
  console.log(email.id, email.status, email.subject);
}

Retrieve a single email

const email = await zerokit.getEmail('email_2bV4dXyZ8AfQpkw7Lp');
console.log(email.status, email.providerMessageId);

Error handling

Every non-2xx response throws a ZerokitError. The error carries the HTTP status + the raw response body so you can branch on specific failure modes:

import { Zerokit, ZerokitError } from 'zerokit-sdk';

try {
  await zerokit.sendEmail({
    from: '[email protected]',
    to: ['[email protected]'],
    subject: 'Hi',
    text: 'Hi',
  });
} catch (err) {
  if (err instanceof ZerokitError) {
    if (err.status === 401) {
      // Bad API key — re-issue from the dashboard.
    } else if (err.status === 400) {
      // Domain not verified, or body validation failed.
      console.error(err.payload);
    } else if (err.status === 429) {
      // Plan cap hit. Read err.payload.error for the limit + plan name.
    }
  }
  throw err;
}

ZerokitError props:

PropTypeDescription
statusnumberHTTP status code.
payloadunknownParsed JSON response body, or null if parsing failed.
messagestring"Zerokit request failed with <status>".

The SDK is intentionally thin — no automatic retries, no configurable backoff, no built-in queue. Wrap it in your own retry helper (e.g. p-retry) if you want resilience to transient 5xx upstream.

Cloudflare Workers / edge runtimes

The SDK uses global fetch — no Node-only dependencies. Drop it into a Worker as-is:

import { Zerokit } from 'zerokit-sdk';

export default {
  async fetch(req: Request, env: { ZEROKIT_API_KEY: string }) {
    const zerokit = new Zerokit({ apiKey: env.ZEROKIT_API_KEY });
    await zerokit.sendEmail({
      from: 'Acme <[email protected]>',
      to: ['[email protected]'],
      subject: 'Hello',
      html: '<p>Hello</p>',
    });
    return new Response('ok');
  },
};

Other languages

First-party SDKs for Python / Go / Ruby are on the roadmap. Until then, drive the REST API directly with your language's idiomatic HTTP client — the spec is the source of truth, see API Reference.

Python (httpx)

import os
import httpx

def send_email(payload: dict):
    res = httpx.post(
        "https://api.zerokit.co/emails",
        headers={
            "Authorization": f"Bearer {os.environ['ZEROKIT_API_KEY']}",
            "Content-Type": "application/json",
        },
        json=payload,
        timeout=10,
    )
    res.raise_for_status()
    return res.json()

Go (net/http)

package zerokit

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

func SendEmail(payload map[string]any) (*http.Response, error) {
    body, err := json.Marshal(payload)
    if err != nil {
        return nil, err
    }
    req, err := http.NewRequest("POST", "https://api.zerokit.co/emails", bytes.NewReader(body))
    if err != nil {
        return nil, err
    }
    req.Header.Set("Authorization", "Bearer "+os.Getenv("ZEROKIT_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    return http.DefaultClient.Do(req)
}

Contributing an SDK

Want to publish a community SDK? The patterns we'd like to see:

  1. Mirror the REST spec. One method per endpoint, no abstractions that map awkwardly back to HTTP.
  2. Surface the full error payload. Pass through the body so users can branch on plan / validation errors.
  3. Type the response shapes. Use the OpenAPI spec (openapi.yaml in the docs repo) as the source of truth for request/response types.
  4. Retry only on 503 / 429. Other 4xx errors mean you sent something wrong; retrying won't help.

Get in touch via the dashboard and we'll link your SDK from this page once it's stable.

On this page