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 2026What 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.
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.
| Method | Request |
|---|---|
| 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.
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.
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.