Installation
Get the Chaindoc SDKs into your project. There are two packages: the Server SDK for backend work (documents, signatures, verification) and the Embed SDK for dropping a signing UI into your frontend.
Before you start
If you don't have an account yet, start with the quick start guide to get one set up.
Server SDK
The Server SDK handles everything on the backend: creating documents, sending signature requests, managing teams, and triggering blockchain verification. It's a thin wrapper around the REST API, so if you've read the API docs, the method names will feel familiar.
Install the package
npm install @chaindoc_io/server-sdkSet up environment variables
Create a `.env` file in your project root. You'll need your secret key here.
# Production keys
CHAINDOC_SECRET_KEY=sk_live_xxxxxxxxxxxxx
# Staging/Testing keys
# CHAINDOC_SECRET_KEY=sk_test_xxxxxxxxxxxxx
# Optional: Custom API endpoint
# CHAINDOC_API_URL=https://api.chaindoc.ioInitialize the SDK
import { Chaindoc } from '@chaindoc_io/server-sdk';
// Basic initialization
export const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
// Advanced configuration
export const chaindocAdvanced = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
baseUrl: process.env.CHAINDOC_API_URL, // Optional
timeout: 60000, // 60 seconds
retry: {
maxRetries: 5,
baseDelayMs: 1000,
maxDelayMs: 10000,
},
headers: {
'X-Custom-Header': 'value',
},
});The basic config is enough for most projects. The retry settings are worth tuning if you're processing lots of documents in batch, since the API has rate limits.
Verify your connection
// Test API connection
const health = await chaindoc.healthCheck();
if (health.status === 'ok' && health.apiKeyValid) {
console.log('Connected to Chaindoc API');
console.log('User ID:', health.userId);
} else {
console.error('Connection failed');
}If this fails, double-check that your secret key starts with `sk_live_` (production) or `sk_test_` (sandbox). The most common issue is using a public key by accident.
Embed SDK
The Embed SDK lets you show the Chaindoc signing interface inside your web app. Your users sign documents without leaving your site. It works with React, Vue, Angular, or plain JavaScript.
Install the package
npm install @chaindoc_io/embed-sdkThe CDN option is handy for quick prototypes or sites without a build step. For production, use the npm package so you get tree-shaking and proper version control.
Set up environment variables
The Embed SDK uses your public key (`pk_`), which is safe to include in client-side code.
# .env.local
REACT_APP_CHAINDOC_PUBLIC_KEY=pk_live_xxxxx
# or for Next.js
NEXT_PUBLIC_CHAINDOC_PUBLIC_KEY=pk_live_xxxxxInitialize in your app
// hooks/useChaindoc.ts
import { useRef, useEffect } from 'react';
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
export function useChaindoc() {
const sdkRef = useRef<ChaindocEmbed | null>(null);
useEffect(() => {
sdkRef.current = new ChaindocEmbed({
publicKey: process.env.REACT_APP_CHAINDOC_PUBLIC_KEY!,
environment: 'production',
});
return () => {
sdkRef.current?.destroy();
};
}, []);
return sdkRef.current;
}Framework-specific setup
These examples show how to wire up the Embed SDK as a provider or service in each framework. If you're using the Server SDK on the backend, you don't need a provider; just import it where you need it.
Next.js (App Router)
'use client';
import { createContext, useContext, useEffect, useRef } from 'react';
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
const ChaindocContext = createContext<ChaindocEmbed | null>(null);
export function ChaindocProvider({ children }: { children: React.ReactNode }) {
const sdkRef = useRef<ChaindocEmbed | null>(null);
useEffect(() => {
if (!sdkRef.current) {
sdkRef.current = new ChaindocEmbed({
publicKey: process.env.NEXT_PUBLIC_CHAINDOC_PUBLIC_KEY!,
});
}
return () => {
sdkRef.current?.destroy();
};
}, []);
return (
<ChaindocContext.Provider value={sdkRef.current}>
{children}
</ChaindocContext.Provider>
);
}
export const useChaindoc = () => useContext(ChaindocContext);Next.js (Pages Router)
import type { AppProps } from 'next/app';
import { useEffect, useRef } from 'react';
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
export default function App({ Component, pageProps }: AppProps) {
const sdkRef = useRef<ChaindocEmbed | null>(null);
useEffect(() => {
sdkRef.current = new ChaindocEmbed({
publicKey: process.env.NEXT_PUBLIC_CHAINDOC_PUBLIC_KEY!,
});
return () => {
sdkRef.current?.destroy();
};
}, []);
return <Component {...pageProps} />;
}Nuxt 3
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig();
const chaindoc = new ChaindocEmbed({
publicKey: config.public.chaindocPublicKey,
});
return {
provide: {
chaindoc,
},
};
});Angular
import { Injectable, OnDestroy } from '@angular/core';
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
import { environment } from '../environments/environment';
@Injectable({
providedIn: 'root'
})
export class ChaindocService implements OnDestroy {
private sdk: ChaindocEmbed;
constructor() {
this.sdk = new ChaindocEmbed({
publicKey: environment.chaindocPublicKey,
});
}
getSdk(): ChaindocEmbed {
return this.sdk;
}
ngOnDestroy(): void {
this.sdk.destroy();
}
}TypeScript configuration
Both SDKs ship with full TypeScript definitions. You don't need any extra `@types` packages.
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"types": ["node"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}If you're on an older TypeScript setup (< 5.0), use `"moduleResolution": "node"` instead of `"bundler"`.
Development vs. production
Use test keys during development so you don't accidentally create real documents or send signature emails to actual recipients.
Development setup
// Use test keys for development
const chaindoc = new Chaindoc({
secretKey: 'sk_test_xxxxx',
baseUrl: 'https://api.chaindoc.io',
});
const embed = new ChaindocEmbed({
publicKey: 'pk_test_xxxxx',
environment: 'staging',
debug: true, // Enable detailed logs
});The `debug: true` flag prints request/response details to the console. It's noisy, but useful when you're figuring out why something isn't working.
Production setup
// Use live keys for production
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!, // sk_live_xxxxx
});
const embed = new ChaindocEmbed({
publicKey: process.env.NEXT_PUBLIC_CHAINDOC_PUBLIC_KEY!, // pk_live_xxxxx
environment: 'production',
});Verify your installation
Run through these checks to make sure everything's wired up correctly:
1Check the SDK versionRun `console.log(ChaindocEmbed.version)` in your app. If it prints a version number, the package installed correctly.
2Test the API connectionCall `chaindoc.healthCheck()` from your backend. A successful response means your secret key is valid and the API is reachable.
3Try a file uploadUpload a small test PDF using `chaindoc.media.upload()`. This confirms that auth, networking, and file handling all work.
4Open the signing UIInitialize the Embed SDK and call `openSignatureFlow()` with a test session. If the modal appears, you're good to go.
Troubleshooting
"Module not found" error
This usually means the package didn't install properly or there's a cached version conflict. Clear everything and reinstall:
# npm
rm -rf node_modules package-lock.json
npm install
# yarn
rm -rf node_modules yarn.lock
yarn installTypeScript type errors
Make sure you have Node.js types installed and your `tsconfig.json` uses the right module resolution. Most issues come from mismatched `moduleResolution` settings.
npm install --save-dev @types/nodeAPI key errors
If you're getting 401 or 403 responses, here's what to check:
- 401 Unauthorized means the key is invalid or expired. Regenerate it in your dashboard.
- 403 Forbidden means your plan doesn't include API access. You need a Business plan.
- Make sure you're using the right key type: `pk_` keys are for the Embed SDK (frontend), `sk_` keys are for the Server SDK (backend). Mixing them up is the most common mistake.
- Test keys (`_test_`) only work against the sandbox. Live keys (`_live_`) hit production.
What to do next
Now that the SDKs are installed, pick your next step:
- Quick start — send your first signature request in 10 minutes
- API documentation — full endpoint reference with examples
- SDKs — advanced SDK features and per-framework guides
- Webhooks — set up real-time event notifications
- Security best practices — what to configure before going live