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-sdkpnpm add zerokit-sdkyarn add zerokit-sdkbun add zerokit-sdkInitialise
import { Zerokit } from 'zerokit-sdk';
const zerokit = new Zerokit({
apiKey: process.env.ZEROKIT_API_KEY!,
});Options
| Option | Type | Description |
|---|---|---|
apiKey | string | Required. Workspace key (zk_live_* / zk_test_*). |
baseUrl | string | Override the API origin. Defaults to https://api.zerokit.co. |
fetch | typeof fetch | Inject 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:
| Prop | Type | Description |
|---|---|---|
status | number | HTTP status code. |
payload | unknown | Parsed JSON response body, or null if parsing failed. |
message | string | "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:
- Mirror the REST spec. One method per endpoint, no abstractions that map awkwardly back to HTTP.
- Surface the full error payload. Pass through the body so users can branch on plan / validation errors.
- Type the response shapes. Use the OpenAPI spec
(
openapi.yamlin the docs repo) as the source of truth for request/response types. - 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.