---
title: Send a document for signature from JavaScript
description: Send a document for signature from JavaScript, with a program that was run against Docustay before it was put here.
---

# Send a document for signature from JavaScript

npm install @docustay/sdk

The package has no dependencies and needs Node 18 or newer. It makes one Idempotency-Key for each call and reuses it on every retry, so a network retry never sends the document twice. It is an ES module, so use import, or a .mjs file.

```js
import { Docustay } from "@docustay/sdk";

const docustay = new Docustay(process.env.DOCUSTAY_API_KEY, process.env.DOCUSTAY_URL ? { baseUrl: process.env.DOCUSTAY_URL } : {});
const doc = await docustay.sendDocument({
  templateId: process.env.DOCUSTAY_TEMPLATE_ID,
  parties: [{ seat: "signer_1", name: "Pat Example", email: "pat@example.com" }],
});
console.log(doc.id, doc.state);
```

It reads DOCUSTAY_API_KEY and DOCUSTAY_TEMPLATE_ID from the environment. Use a test key first: it sends nothing real and bills nothing.

## What you need installed

Node 18 or newer, and the Docustay package from npm. Node 18 has fetch built in, so the package adds only the typed helpers and the webhook check. The program is an ES module: save it as send.mjs, or set the package type to module, and run it with node. The key and the template id come from DOCUSTAY_KEY and TEMPLATE_ID in the shell, so neither is ever written into the file.

## How the send behaves

The call returns a promise that resolves to the new document, with its id and its state. A repeat with the same idempotency key resolves to the same document instead of making a second one, so a retry after a dropped connection cannot double-send. If the key is wrong or lacks the permission, the promise rejects with an error whose message names the request id; paste that id into the API log to find the call.

## Reading the result

Await getDocument with the id and read its state: sent, partially signed, executed, declined, expired or voided. In a server you will rarely poll. Register a webhook, verify each delivery with the package's verifyWebhook, and react to documents.document.executed by downloading the sealed PDF.

## Questions people ask

**Does a test key send real email?**

No. A test key emails only you, stamps the document TEST and is never counted against your plan.

**Can I use require instead of import?**

Yes. The package ships both module formats, so a CommonJS file can require it.

**Where do I see the result?**

In Documents in the app, and in the API log under Developers.

## Keep reading

- [Quick start](/docs/quickstart)
- [API reference](/docs/api-reference)
- [Webhooks](/docs/webhooks)
- [SDKs](/developers/sdks)
- [Test mode](/docs/test-mode)
- [Sending](/product/sending)
