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,
});
| Option | Required | Notes |
|---|---|---|
apiKey | yes | Vorlek live or test key. |
apiBase | no | Defaults to https://api.vorlek.com. |
timeout | no | Request timeout in milliseconds. Defaults to 30000. |
idempotencyKey | no | Function called per request. Defaults to a new ULID. |
fetch | no | Inject a test/mock fetch implementation. |
Methods
| Method | Endpoint | Returns |
|---|---|---|
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/catalog | Account-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 category | SDK subclass | Retry signal |
|---|---|---|
user_input | VorlekClientError | Usually false; check retrySafe. |
provider_fault | VorlekProviderError | Usually false until provider-side state is fixed. |
transient | VorlekProviderError | Usually true; back off and retry. |
system | VorlekServerError | Report 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.