Kivel

TypeScript SDK for Kivel

Use the @kivel.io/sdk TypeScript client to run utilities, create inboxes, mocks, files and mock MCP servers, change sharing, renew and handle typed errors.

Updated 30 October 2026

What the SDK covers

@kivel.io/sdk is a small, dependency-free TypeScript client for the Kivel HTTP API. It works in Node.js and any runtime with fetch. Use it when you want typed methods for utilities and resources instead of building requests by hand.

Install the SDK beta with npm install @kivel.io/sdk@beta. The ESM package includes JavaScript and TypeScript declarations, requires Node.js 22.13+ and uses import rather than CommonJS require. Use an explicit beta tag or version until a latest release is promoted.

Create a client

All options are optional. baseUrl defaults to https://kivel.io and must be an origin; remote origins must use HTTPS. timeoutMs defaults to 25000. You can pass your own fetch implementation.

Client setup and a first call
import { Kivel, KivelError } from '@kivel.io/sdk';

const kivel = new Kivel({
  apiKey: process.env.KIVEL_API_KEY,
});

const result = await kivel.run('json', '{"hello":true}', { action: 'format' });
console.log(result.output, result.usage.used);

Methods

Most resource creation methods default to private visibility. Webhook receivers are public by default, and OAuth test endpoints are always public while their management and logs stay private. Methods that take a token send it in X-Resource-Token, so they work alongside an API key.

Kivel methods
MethodRequest
createOAuthProvider(config, settings?)Create an OAuth test issuer and receive its client secret once.
oauthProvider(id), oauthProviders(), updateOAuthProvider(id, config), deleteOAuthProvider(id)Inspect, list, configure and delete workspace test providers.
tools()GET /api/tools
tool(id)GET /api/tools/{id}
run(toolId, input?, options?, file?)POST /api/tools/{id}/run
usage()GET /api/usage
plans() / activity() / agents()Read plan limits, MCP activity and workspace agents
startLogin(name, client?) / finishLogin(deviceCode)Device login; approved keys are delivered once. Approval remains in the human browser
startTrial(name, humanEmail?, client?)72-hour trial with anonymous limits and a human claim link
saveCredential(input) / credentials() / revealCredential(id, approvalId?)Save credentials, read metadata and reveal once after human approval
createEmailInbox(settings?) / emailInbox(id, token?) / emails(id, token?)Owned email creation, metadata and messages
emailThreads(id?, settings?) / emailThread(id, threadId)List inbox or workspace conversations with cursor pagination and read a full thread
createEmailDraft(id, content) / submitEmailDraft(id, settings?)Save a draft and submit it directly or for human approval, with an optional sendAt
waitForEmail(id, {token?, after?, timeoutSeconds?})Long-poll for messages, extracted codes and links
memorySet(namespace, key, value, ttlSeconds?)Save a JSON value within workspace memory limits
memoryGet<T>(namespace, key) / memoryList(namespace, prefix?) / memoryDelete(namespace, key)Read, list metadata and delete workspace memory
createMonitor(settings) / monitors() / monitor(id)Create and inspect HTTP, SSL or heartbeat monitors
pingMonitor(token, failed?)Report a job success or failure using the secret token from pingUrl
pauseMonitor(id, paused?) / deleteMonitor(id)Pause, resume or remove a monitor
askHuman({question, options?, details?, timeoutMinutes?})Ask the human; answerUrl is safe to show them
approvals(pendingOnly?) / approval(id) / waitForApproval(id, timeoutSeconds?)Read questions and wait; a timeout never means approval
waitForRequests(id, {token?, after?, timeoutSeconds?})Long-poll for webhook captures
setInboxResponse(id, settingsOrNull, token?) / setInboxForward(id, urlOrNull, token?)Configure responses or paid forwarding; null restores defaults
inboxDeliveries(id, token?) / mockCalls(id, token?)Read recent forwarding attempts and mock calls
inspectResource(kind, id, token?) / updateMock(id, config, token?) / resetMock(id, token?)Resource metadata, mock configuration and CRUD reset
resources()GET /api/account/resources
createInbox(settings?)POST /api/inboxes
inspectInbox(id, token?)GET /api/inboxes/{id}/requests
createMock(config, settings?)POST /api/mocks
createMcpServer(config, settings?)POST /api/mcp-servers
upload(name, bytes, settings?)POST /api/files
downloadFile(id, accessToken?)GET /files/{id}, returns Uint8Array
sharing(kind, id, visibility, token?)POST /api/{kind}/{id}/sharing
renew(kind, id, { persistent }?, token?)POST /api/{kind}/{id}/renew
remove(kind, id, token?)DELETE /api/{kind}/{id}
request(method, path, body?, token?, headers?)Relative /api/ or /mock/ paths; HEAD succeeds without a JSON body

Work with resources

Webhook, mock, mock MCP and file settings accept ttlSeconds, persistent and visibility; upload also accepts maxDownloads. Email requires an account and accepts activeDays (1–7, default 3) on Free, or an optional paid localPart. Free allows one active inbox; Pro 10 and Team 50 addresses that stay active while subscribed. emailInboxes() lists owned addresses; emailForwarding(id, url) configures a public webhook. inspectResource reads metadata. Use request() for other /api/ operations and /mock/ caller requests; its token is a caller access token for /mock/ paths.

Inbox and file lifecycle
const inbox = await kivel.createInbox({ ttlSeconds: 1800 });
// inbox.webhookUrl, inbox.accessToken; manage with your API key

const history = await kivel.inspectInbox(inbox.id);

const file = await kivel.upload('report.txt', new TextEncoder().encode('hello'), {
  maxDownloads: 1,
});
const bytes = await kivel.downloadFile(file.id, file.accessToken);

const mock = await kivel.inspectResource('mocks', 'MOCK_ID');
await kivel.remove('inboxes', inbox.id);

Errors

Failed requests throw KivelError with message, status, requestId (from X-Request-Id) and retryAfter (from Retry-After, in seconds). The SDK does not retry requests itself and does not follow redirects.

Handle a rate limit
try {
  await kivel.run('json', input);
} catch (error) {
  if (error instanceof KivelError && error.status === 429 && error.retryAfter) {
    // wait error.retryAfter seconds, then try again
  }
  throw error;
}

Frequently asked questions

Is the SDK on npm?

Yes. Install @kivel.io/sdk@beta for the published beta, or pin an exact @kivel.io/sdk version. It includes TypeScript declarations. An untagged install requires a latest-tag release.

Does the SDK create public resources?

Most resource creation and upload methods default to private visibility. Webhook receivers default to public and OAuth test endpoints stay public; inspection and management remain private.

How do I pass files to run()?

Pass { name, base64 } as the fourth argument, or an array of them for everyday-merge-pdfs and everyday-image-to-pdf. The Base64 must be canonical.