Skip to Content
SDKsTypeScript API Client

TypeScript API Client

The official TypeScript API client provides a type-safe interface for the Korala API.

Installation

npm install @korala/api-client # or yarn add @korala/api-client # or pnpm add @korala/api-client

Quick Start

import { KoralaClient } from '@korala/api-client'; const korala = new KoralaClient({ apiKeyId: process.env.KORALA_API_KEY_ID!, apiSecret: process.env.KORALA_API_SECRET!, }); // Create a document const { documentId, uploadUrl } = await korala.documents.createUploadUrl({ filename: 'contract.pdf', contentType: 'application/pdf', }); // Upload the file to S3 await fetch(uploadUrl, { method: 'PUT', body: pdfBuffer, headers: { 'Content-Type': 'application/pdf' }, }); // Confirm the upload await korala.documents.confirmUpload(documentId); // Add a signer const signer = await korala.signers.create(documentId, { email: '[email protected]', name: 'John Doe', }); // Add a signature field await korala.fields.create(documentId, { signerId: signer.id, fieldType: 'signature', pageNumber: 1, xPosition: 100, yPosition: 500, width: 200, height: 50, }); // Send for signing await korala.documents.send(documentId);

Configuration

interface KoralaClientConfig { // Required apiKeyId: string; // API key ID apiSecret: string; // API secret for HMAC signing // Optional baseUrl?: string; // API base URL (default: https://api.korala.ai/api/v1) timeout?: number; // Request timeout in ms (default: 30000) }

Documents

Create Upload URL

const { documentId, uploadUrl, key } = await korala.documents.createUploadUrl({ filename: 'contract.pdf', contentType: 'application/pdf', }); // Upload the file to the presigned URL await fetch(uploadUrl, { method: 'PUT', body: pdfBuffer, headers: { 'Content-Type': 'application/pdf' }, }); // Confirm upload await korala.documents.confirmUpload(documentId);

Get Document

const document = await korala.documents.get(documentId); console.log(document.status); console.log(document.originalFileUrl); console.log(document.signedFileUrl);

List Documents

const documents = await korala.documents.list();

Send Document

await korala.documents.send(documentId);

Void Document

await korala.documents.void(documentId);

Get Audit Trail

const events = await korala.documents.getAuditTrail(documentId);

Bulk Sign

Sign multiple documents at once using a saved signature:

const result = await korala.documents.bulkSign({ documentIds: ['doc-1', 'doc-2', 'doc-3'], signerEmail: '[email protected]', autoFillDateValue: '2026-02-18', // optional, defaults to today }); console.log(`Signed: ${result.signed}, Failed: ${result.failed}`); for (const doc of result.results) { if (!doc.success) { console.error(`${doc.documentId}: ${doc.error}`); } }

IP Attribution

When calling bulk sign on behalf of an end user, pass their IP for audit trail attribution:

const result = await korala.documents.bulkSign( { documentIds: ['doc-1', 'doc-2'], signerEmail: '[email protected]', }, { clientIp: '203.0.113.42' }, );

See the Bulk Signing guide for the complete workflow.

Signatures

Manage saved signatures for signers. Saved signatures are used by bulk sign to auto-fill Signature and Initials fields.

Create Signature

const signature = await korala.signatures.create({ email: '[email protected]', name: 'Jane Smith', signatureImageUrl: 'data:image/png;base64,...', isDefault: true, // optional, defaults to true });

List Signatures

// List all const signatures = await korala.signatures.list(); // Filter by email const ceoSignatures = await korala.signatures.list({ email: '[email protected]' });

Get Signature

const signature = await korala.signatures.get(signatureId);

Delete Signature

await korala.signatures.delete(signatureId);

Signers

Add Signer

const signer = await korala.signers.create(documentId, { email: '[email protected]', name: 'John Doe', signingOrder: 1, // optional });

List Signers

const signers = await korala.signers.list(documentId);

Remove Signer

await korala.signers.delete(documentId, signerId);

Fields

Add Field

const field = await korala.fields.create(documentId, { signerId: signer.id, fieldType: 'signature', // 'signature' | 'initials' | 'date' | 'text' | 'checkbox' pageNumber: 1, xPosition: 100, yPosition: 500, width: 200, height: 50, });

List Fields

const fields = await korala.fields.list(documentId);

Remove Field

await korala.fields.delete(documentId, fieldId);

Webhooks

Create Webhook

const webhook = await korala.webhooks.create({ url: 'https://your-app.com/webhooks/korala', events: ['document_completed', 'document_signed'], }); // Save the secret for signature verification! console.log(webhook.secret);

List Webhooks

const webhooks = await korala.webhooks.list();

Get Webhook

const webhook = await korala.webhooks.get(webhookId);

Update Webhook

await korala.webhooks.update(webhookId, { events: ['document_completed'], isActive: true, });

Delete Webhook

await korala.webhooks.delete(webhookId);

Get Delivery History

const deliveries = await korala.webhooks.getDeliveries(webhookId);

Send Test Event

const delivery = await korala.webhooks.sendTestEvent(webhookId);

Error Handling

import { KoralaError, KoralaValidationError } from '@korala/api-client'; try { await korala.documents.send(documentId); } catch (error) { if (error instanceof KoralaValidationError) { console.error('Validation failed:', error.errors); } else if (error instanceof KoralaError) { console.error(`API error ${error.status}: ${error.message}`); } else { throw error; } }

TypeScript Types

All response types are fully typed:

import type { DocumentDto, DocumentStatus, SignerDto, SignerStatus, FieldDto, FieldType, WebhookDto, WebhookEventType, WebhookPayloadDto, // Event-specific data types DocumentCreatedEventData, DocumentSentEventData, DocumentViewedEventData, DocumentSignedEventData, DocumentCompletedEventData, DocumentFailedEventData, DocumentVoidedEventData, DocumentDeclinedEventData, TestEventData, } from '@korala/api-client'; function handleDocument(doc: DocumentDto) { if (doc.status === 'completed') { console.log(`Completed at: ${doc.completedAt}`); } } function handleWebhook(payload: WebhookPayloadDto) { switch (payload.event) { case 'document_signed': { const data = payload.data as DocumentSignedEventData; console.log(`Signer ${data.signerId} signed, all done: ${data.allSigned}`); break; } case 'document_completed': { const data = payload.data as DocumentCompletedEventData; console.log(`Document completed at ${data.completedAt}`); break; } } }

Webhook Verification

The client includes a helper for verifying webhook signatures:

import { verifyWebhookSignature } from '@korala/api-client'; app.post('/webhooks/korala', express.raw({ type: 'application/json' }), (req, res) => { const isValid = verifyWebhookSignature({ secret: process.env.WEBHOOK_SECRET!, signature: req.headers['x-signature'] as string, timestamp: req.headers['x-timestamp'] as string, body: req.body.toString(), }); if (!isValid) { return res.status(401).json({ error: 'Invalid signature' }); } const event = JSON.parse(req.body.toString()); // Process event... res.json({ received: true }); });
Last updated on