Tired of the manual invoice process? Printing, signing, scanning, and emailing can be a significant time drain. What if you could automate the signature process directly within your JavaScript applications?
Docstudio offers an API for exactly this. In this straightforward guide, we'll walk through how to integrate Docstudio's e-signature capabilities into your JavaScript workflow, focusing on sending invoices for signature.
The result? No more paper, instant notifications upon signing, and a digital record of your documents. Let's see step by step guide.
Before proceeding, ensure you have the following:
The methods below illustrates how to upload a PDF invoice and specify one or more signatories.
I recommend using NVM (Node Version Manager) so you can juggle multiple Node versions effortlessly:
Install (if you don’t already have it)
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
Load nvm (you may need to restart your shell or source your profile)
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Grab the latest LTS (should be v22.x)
nvm install --lts, nvm use --lts
Verify if you have
node -v # → v22.x.x; npm -v # → 10.x.x or newer
package.json
— or, if there’s already one there, just update it to fit your needs:
{
"name": "quick-send-cli",
"version": "1.0.0",
"description": "CLI to upload PDF via DocStudio quick-send API",
"type": "module",
"main": "cli.js",
"scripts": {
"start": "node cli.js"
},
"engines": {
"node": ">=14"
},
"dependencies": {
"form-data": "^4.0.0",
"mime": "^3.0.0",
"node-fetch": "^3.3.1"
},
"license": "MIT"
}
npm i
fileUploader.js
. Define const variables you will need and make sure you have all required deps installed:
// fileUploader.js
import { promises as fs, createReadStream } from 'fs';
import path from 'path';
import mime from 'mime';
import FormData from 'form-data';
import fetch from 'node-fetch';
const MAX_SIZE = 10 * 1024 * 1024; // 10 MiB
const ACCEPTED_EXT = '.pdf';
const ACCEPTED_MIME = 'application/pdf';
const QUICK_SEND_URL = 'https://api.docstudio.com/api/v1/envelope/quick-send';
uploadFile()
method.Here you can see that by default, file type and size are validated at 10 MB, and PDFs are the only file type that can be sent for signing. After all required checks we send file to DocStudio using /api/v1/envelope/quick-send.
// fileUploader.js
export async function uploadFile(filePath, mailboxUuid, token, recipientEmail) {
// 1) Extension check
if (path.extname(filePath).toLowerCase() !== ACCEPTED_EXT) {
throw new Error('File must end with .pdf');
}
// 2) Size check
let stat;
try {
stat = await fs.stat(filePath);
} catch (err) {
throw new Error(`Cannot access file: ${err.message}`);
}
if (stat.size > MAX_SIZE) {
const sizeMB = (stat.size / (1024 * 1024)).toFixed(2);
throw new Error(`File too large (${sizeMB} MB > 10 MB)`);
}
// 3) MIME check
const detected = mime.getType(filePath) || '';
if (detected !== ACCEPTED_MIME) {
throw new Error(`File is not a PDF (detected "${detected}")`);
}
// 4) Send it
return await sendQuickSend({
mailboxUuid,
token,
filePath,
fileName: path.basename(filePath, ACCEPTED_EXT),
recipientEmail
});
}
sendQuickSend()
method handles file send request:
// fileUploader.js
async function sendQuickSend({ mailboxUuid, token, filePath, fileName, recipientEmail }) {
const form = new FormData();
form.append('files', createReadStream(filePath), {
filename: fileName + ACCEPTED_EXT,
contentType: ACCEPTED_MIME
});
const payload = {
subject: fileName,
message: fileName,
recipients: [
{
recipient: recipientEmail,
signer: true,
eInkSignature: true
}
]
};
form.append('data', JSON.stringify(payload), { contentType: 'application/json' });
const res = await fetch(QUICK_SEND_URL, {
method: 'POST',
headers: {
'Mailbox': mailboxUuid,
'Authorization': `Bearer ${token}`,
...form.getHeaders()
},
body: form
});
const text = await res.text();
if (!res.ok) {
throw new Error(`Quick-send failed ${res.status}: ${text}`);
}
return JSON.parse(text);
}
On the root level add cli.js
file and ensure both cli.js
and fileUploader.js
are in your project folder.
Just quick check:
ls quick-send/
# should list: package.json cli.js fileUploader.js
Now place next code to your cli.js
#!/usr/bin/env node
// cli.js
import { uploadFile } from './fileUploader.js';
async function main() {
const [,, filePath, mailboxUuid, token, recipientEmail] = process.argv;
if (!filePath || !mailboxUuid || !token || !recipientEmail) {
console.error('Usage: node cli.js <file.pdf> <mailboxUuid> <token> <recipientEmail>');
process.exit(1);
}
try {
const result = await uploadFile(filePath, mailboxUuid, token, recipientEmail);
console.log('Upload & send successful:', result);
} catch (err) {
console.error('Error:', err.message);
process.exit(2);
}
}
main();
Make it executable:
chmod +x cli.js
And run:
node cli.js \
~/Documents/proxies.pdf \
mailboxUuid \
token \
recipient@example.com
When the request goes through, you’ll see a confirmation message right in your terminal:
Upload & send successful: { uuid: 'b05c122e-4b38-466f-a15a-b5ed05bc251c' }
The signer will get an email with a link to the document and will be able to sign it or reject it.
As a mailbox owner owner, you’ll receive an email notification when the document will be ready and signed.
Wish you the best, with DocStudio!