@korala/api-client
TypeScript API client for the Korala document signing platform.
Installation
npm install @korala/api-client
Authentication
Korala uses HMAC signature authentication. You'll need an API key ID and secret from your Korala dashboard.
import { KoralaClient } from '@korala/api-client';
const client = new KoralaClient({
apiKeyId: 'your-api-key-id',
apiSecret: 'your-api-secret',
baseUrl: 'https://api.korala.ai/api/v1',
});
OAuth access token
An AI assistant connection (or anything else that holds a Korala OAuth access
token) authenticates with the token instead of an API key. The token's scopes
and mode decide what it may do.
const client = new KoralaClient({ accessToken: 'token-from-the-oauth-flow' });
Both forms accept fetch to replace the global fetch, for example to add
tracing or to dispatch requests in-process.
Usage
Create and send a document
const { documentId, uploadUrl } = await client.documents.createUploadUrl({
fileName: 'contract.pdf',
contentType: 'application/pdf',
});
await fetch(uploadUrl, { method: 'PUT', body: pdfBuffer });
await client.documents.confirmUpload(documentId);
const signer = await client.signers.create(documentId, {
name: 'John Doe',
email: 'john@example.com',
});
await client.fields.create(documentId, {
signerId: signer.id,
fieldType: 'signature',
pageNumber: 1,
xPosition: 100,
yPosition: 500,
width: 200,
height: 50,
});
await client.documents.send(documentId);
Create a document from a template
const document = await client.templates.createDocument(templateId, {
name: 'Sales Agreement - Acme Corp',
signers: {
buyer: { name: 'Jane Smith', email: 'jane@acme.com' },
},
variables: {
company_name: 'Acme Corporation',
contract_date: '2026-03-16',
},
});
Markdown templates
Use Markdown and Liquid to create a reusable source template, then pass explicit JSON when generating a document. Preview before saving:
const preview = await client.templates.previewMarkdown({ source, sampleData });
const template = await client.templates.createMarkdown({
name: 'Services agreement', source, sampleData, pageSize: 'A4',
});
const pdf = await client.templates.generate(template.id, { templateData: customerData });
preview.pdfBase64 contains the PDF. Edit with templates.updateMarkdown(id, { name, source, sampleData, revision }); use the revision returned by templates.get(id). See the Markdown template guide for conditions, loops and signature roles.
Bulk sign (countersign)
Sign multiple documents at once using a saved signature:
await client.signatures.create({
email: 'ceo@company.com',
name: 'Jane Smith',
signatureImageUrl: 'https://example.com/signature.png',
isDefault: true,
});
const result = await client.documents.bulkSign({
documentIds: ['doc-1', 'doc-2', 'doc-3'],
signerEmail: 'ceo@company.com',
});
console.log(`${result.signed} signed, ${result.failed} failed`);
Create a signing packet
Use the authenticated management API to give one recipient a Korala-hosted
flow for up to 50 documents. The API key prepares and sends the packet; the
recipient verifies their email and authorizes the signatures in Korala.
const packet = await client.signingPackets.create({
name: 'Series A closing',
recipient: { name: 'Alex Manager', email: 'alex@example.com' },
items: [
{
documentId: subscription.id,
signerId: subscriptionSigner.id,
fieldValues: [{ fieldId: approvedAmountField.id, value: '18500.00' }],
},
{ documentId: sideLetter.id, signerId: sideLetterSigner.id },
],
redirectUrl: 'https://fund.example.com/closing/complete',
});
const sent = await client.signingPackets.send(packet.id, {
delivery: 'email',
});
console.log(sent.signingUrl);
Webhooks
const webhook = await client.webhooks.create({
url: 'https://your-app.com/webhooks/korala',
events: ['document.completed', 'document.signed'],
});
API Reference
client.documents | createUploadUrl, confirmUpload, list, get, send, void, getAuditTrail, bulkSign |
client.signers | list, create |
client.fields | list, create, update, delete |
client.signatures | list, get, create, delete |
client.signingPackets | create, get, update, send, remind, void, audit |
client.templates | list, get, createDocument, generate, previewMarkdown, createMarkdown, updateMarkdown |
client.webhooks | list, get, create, update, delete |
License
MIT
Collections
Use collections to group documents and templates within your organization
and mode. Supply collectionIds when creating a resource. Choose destinations
for each generated document; template memberships do not carry over. The public exports include collection, membership,
pagination, and query types. See the collections guide
for limits and the full workflow.
const collection = await client.collections.create({
name: 'Acme', externalId: 'crm:acme',
});
await client.collections.addDocuments(collection.id, [documentId]);
const page = await client.documents.listPage({ collectionId: collection.id });
const combined = await client.documents.listPage({
collectionIds: [collection.id, anotherCollection.id],
});
documents.listPage() returns the pagination envelope. Deprecated
documents.list() returns only the first page’s items, matching its array
contract; earlier releases incorrectly returned the envelope at runtime.
templates.list() continues returning an envelope; listPage() is an alias.