TypeScript SDK

@vorlek/sdk is an ESM-only Node 20+ client for the Vorlek API. It wraps the Phase 2 tool surface with generated request/response types, automatic idempotency keys, and typed errors.

Install

npm install @vorlek/sdk
# or
pnpm add @vorlek/sdk

Quickstart

import { VorlekClient } from '@vorlek/sdk';

const client = new VorlekClient({ apiKey: process.env.VORLEK_API_KEY });
const result = await client.contact.upsert({
  provider: 'sendgrid',
  email: 'test@example.com',
});
console.log(result.data.contact_id, result.meta.request_id);

Constructor

new VorlekClient({
  apiKey: 'vk_live_...',
  apiBase: 'https://api.vorlek.com',
  timeout: 30_000,
  idempotencyKey: () => '01HV...',
  fetch,
});
OptionRequiredNotes
apiKeyyesVorlek live or test key.
apiBasenoDefaults to https://api.vorlek.com.
timeoutnoRequest timeout in milliseconds. Defaults to 30000.
idempotencyKeynoFunction called per request. Defaults to a new ULID.
fetchnoInject a test/mock fetch implementation.

Methods

MethodEndpointReturns
client.contact.upsert(input, options?)POST /v1/tools/upsert_contact{ data, meta } from the success envelope.
client.send.transactional(input, options?)POST /v1/tools/send_transactional{ data, meta } from the success envelope.
client.campaign.stats(input, options?)POST /v1/tools/get_campaign_stats{ data, meta } from the success envelope.
client.connection.status(input, options?)POST /v1/tools/get_connection_status{ data, meta } from the success envelope.
client.catalog.get()GET /v1/catalogAccount-aware provider/tool support, connection state, response detail support, and operation receipt lookup shape.
client.operations.get(requestId)GET /v1/operations/{request_id}Operation receipt detail for a prior response meta.request_id.

Catalog discovery

Call client.catalog.get() before planning a multi-provider workflow. The response tells agents which provider/tool cells are supported, which connection config is required, whether the current account has each provider connected, and that the current receipt lookup identifier is meta.request_id.

const catalog = await client.catalog.get();
for (const tool of catalog.data.tools) {
  console.log(tool.name, tool.providers);
}

Operation lookup

Every successful write returns meta.request_id. Treat that value as the operation receipt id and pass it to client.operations.get(requestId) when an agent needs same-surface observability without raw REST.

const result = await client.contact.upsert({
  provider: 'sendgrid',
  email: 'test@example.com',
});
const operation = await client.operations.get(result.meta.request_id);
console.log(operation.data.status, operation.data.duration_ms);

Contact readback

client.contact.get reads one contact by email so agents can verify an upsert_contact result without leaving the SDK surface.

const readback = await client.contact.get({
  provider: 'sendgrid',
  email: 'test@example.com',
});
console.log(readback.data.found, readback.data.contact);

Response shape

Successful calls return { data, meta }. data is the normalized tool payload. meta includes request_id, quota state, rate-limit state merged from X-RateLimit-* headers, and idempotency.replay when the response came from replay protection.

Response detail

Tool methods accept { detail?: 'minimal' | 'standard' | 'full' } in the optional second argument. minimal returns only essential metadata, standard is the default, and full includes operation lookup metadata.

const result = await client.contact.upsert({
  provider: 'sendgrid',
  email: 'test@example.com',
}, { detail: 'minimal' });

Template search

client.template.list accepts query for page-scoped template search across id, name, and subject. When the returned page has no match, inspect data.search.no_match for the next action.

const result = await client.template.list({
  provider: 'sendgrid',
  query: 'welcome',
});
console.log(result.data.templates, result.data.search);

Per-call idempotency

Every tool method accepts { idempotencyKey?: string } in the optional second argument. Use this to retry one logical request with the same key.

const key = '01HV0011V0110011V011001100';
const result = await client.contact.upsert({
  provider: 'sendgrid',
  email: 'test@example.com',
}, { idempotencyKey: key });
console.log(result.meta.idempotency?.replay);

Errors

Non-2xx Vorlek envelopes are thrown as VorlekError subclasses. The original code, category, retrySafe, httpStatus, requestId, and detail fields remain available.

Server categorySDK subclassRetry signal
user_inputVorlekClientErrorUsually false; check retrySafe.
provider_faultVorlekProviderErrorUsually false until provider-side state is fixed.
transientVorlekProviderErrorUsually true; back off and retry.
systemVorlekServerErrorReport requestId or retry if retrySafe.
import { VorlekProviderError, isRetryableError } from '@vorlek/sdk';

try {
  await client.contact.upsert({ provider: 'sendgrid', email: 'test@example.com' });
} catch (error) {
  if (error instanceof VorlekProviderError && isRetryableError(error)) {
    // Retry with backoff.
  }
}

Generated Types

The package publishes generated OpenAPI types and hand-curated aliases such as UpsertContactInput, UpsertContactResult, SendTransactionalInput, GetCampaignStatsInput, and GetConnectionStatusInput.