Skip to content

TypeScript SDK

The TypeScript SDK provides a type-safe client for integrating with Subnoto’s API. It handles Oak tunnel encryption, HTTP signature authentication, and provides helper functions for common operations.

Terminal window
npm install @subnoto/api-client
# or
pnpm add @subnoto/api-client
# or
yarn add @subnoto/api-client
import { SubnotoClient } from "@subnoto/api-client";
const client = new SubnotoClient({
apiBaseUrl: "https://enclave.subnoto.com",
accessKey: process.env.API_ACCESS_KEY,
secretKey: process.env.API_SECRET_KEY,
unattested: false
});
// Use openapi-fetch syntax
const { data, error } = await client.POST("/public/utils/whoami", { body: {} });
console.log("User info:", data);
const { data: workspaces } = await client.POST("/public/workspace/list", { body: {} });
console.log("Workspaces:", workspaces);
OptionTypeRequiredDescription
apiBaseUrlstringYesAPI base URL
accessKeystringYesAPI access key
secretKeystringYesAPI secret key
unattestedbooleanNoUse unattested mode (default: false)
attesterKeyBufferNoPublic key for attestation
const { data, error } = await client.POST("/public/workspace/list", { body: {} });
if (error) {
console.error("Failed to list workspaces:", error);
} else {
data.workspaces.forEach(workspace => {
console.log(`Workspace: ${workspace.name} (${workspace.uuid})`);
});
}
const { data, error } = await client.POST("/public/envelope/list", {
body: {
workspaceUuid: "your-workspace-uuid",
page: 1
}
});
if (data) {
data.envelopes.forEach(envelope => {
console.log(`Envelope: ${envelope.title} - Status: ${envelope.status}`);
});
}
// Create envelope from a pre-configured template
// Recipients must include labels that match the template's recipient labels
const { data, error } = await client.POST("/public/envelope/create-from-template", {
body: {
workspaceUuid: "your-workspace-uuid",
templateUuid: "your-template-uuid",
recipients: [
{
type: "manual",
label: "customer",
firstname: "John",
lastname: "Doe"
},
{
type: "manual",
label: "manager",
firstname: "Jane",
lastname: "Smith"
}
]
}
});
if (data) {
console.log(`Created envelope: ${data.envelopeUuid}`);
}
const { error } = await client.POST("/public/envelope/send", {
body: {
workspaceUuid: "your-workspace-uuid",
envelopeUuid: "your-envelope-uuid",
customInvitationMessage: "Please review and sign this document."
}
});
if (!error) {
console.log("Envelope sent successfully!");
}
const { data, error } = await client.POST("/public/template/list", {
body: { page: 1 }
});
if (data) {
data.templates.forEach(template => {
console.log(`Template: ${template.name} (${template.uuid})`);
});
}
const { data, error } = await client.POST("/public/contact/list", {
body: { workspaceUuid: "your-workspace-uuid" }
});
if (data) {
data.contacts.forEach(contact => {
console.log(`Contact: ${contact.firstname} ${contact.lastname} (${contact.email})`);
});
}

The SDK includes a helper function for uploading documents. This handles encryption and S3 upload automatically:

import { SubnotoClient } from "@subnoto/api-client";
import { readFileSync } from "fs";
const client = new SubnotoClient({
apiBaseUrl: "https://enclave.subnoto.com",
accessKey: process.env.API_ACCESS_KEY,
secretKey: process.env.API_SECRET_KEY
});
const fileBuffer = readFileSync("path/to/document.pdf");
const { envelopeUuid, documentUuid } = await client.uploadDocument({
workspaceUuid: "your-workspace-uuid",
fileBuffer: fileBuffer,
envelopeTitle: "My Document"
});
console.log("Document uploaded:", envelopeUuid, documentUuid);
import { SubnotoClient } from "@subnoto/api-client";
async function createAndSendEnvelope() {
const client = new SubnotoClient({
apiBaseUrl: "https://enclave.subnoto.com",
accessKey: process.env.API_ACCESS_KEY,
secretKey: process.env.API_SECRET_KEY
});
// 1. Get workspace
const { data: workspaceData } = await client.POST("/public/workspace/list", { body: {} });
const workspaceUuid = workspaceData.workspaces[0].uuid;
// 2. Get template
const { data: templateData } = await client.POST("/public/template/list", {
body: { page: 1 }
});
const templateUuid = templateData.templates[0].uuid;
// 3. Create envelope from template
const { data: envelopeData } = await client.POST("/public/envelope/create-from-template", {
body: {
workspaceUuid,
templateUuid,
recipients: [
{
type: "manual",
label: "signer",
firstname: "John",
lastname: "Doe"
}
]
}
});
// 4. Send the envelope
await client.POST("/public/envelope/send", {
body: {
workspaceUuid,
envelopeUuid: envelopeData.envelopeUuid,
customInvitationMessage: "Please review and sign this document."
}
});
console.log(`Envelope ${envelopeData.envelopeUuid} created and sent!`);
}
createAndSendEnvelope().catch(console.error);

The SDK supports attestation verification to ensure you’re communicating with a genuine Subnoto enclave:

const client = new SubnotoClient({
apiBaseUrl: "https://enclave.subnoto.com",
accessKey: process.env.API_ACCESS_KEY,
secretKey: process.env.API_SECRET_KEY,
attesterKey: Buffer.from(process.env.ATTESTATION_PUBLIC_KEYS, "base64"),
unattested: false // Enable attestation (default)
});
// After making a request, check attestation status
const attestationStatus = client.getAttestationStatus();
console.log("Attestation status:", attestationStatus);
const attestationResults = client.getAttestationResults();
console.log("Attestation results:", attestationResults);

The SDK uses openapi-fetch syntax for all API calls. All endpoints are type-safe and match the OpenAPI specification.

For complete API documentation, see the OpenAPI specifications.