Create and send your first envelope
Ce contenu n’est pas encore disponible dans votre langue.
This tutorial walks you through creating and sending an envelope via the API. You’ll learn how to:
- Upload a document and create an envelope
- Add recipients
- Add blocks (signatures, text, images)
- Send the envelope
Prerequisites
Section titled “Prerequisites”- A Subnoto workspace with API credentials — see Create API keys
- A programming language with HTTP client support (examples shown in Node.js)
API Base URL: The examples below use two different base URLs depending on the method:
curlandfetchrequire the Encryption Proxy — replacehttp://your-proxy:8080with your proxy’s address.@subnoto/api-clientSDK connects directly tohttps://enclave.subnoto.com— it handles secure communication internally.
Note: This tutorial presents examples in Node.js, but the Subnoto API can be used from any programming language. The API is language-agnostic and uses standard HTTP requests and JSON payloads. You can adapt these examples to Python, Go, Ruby, PHP, or any other language that supports HTTP requests.
-
Upload Document and Create Envelope
Upload your document using the
create-from-fileendpoint. This endpoint accepts multipart/form-data and handles encryption, upload, and document processing automatically.Using curl:
Terminal window curl -X POST http://your-proxy:8080/public/envelope/create-from-file \-H "Authorization: Bearer $ACCESS_KEY:$SECRET_KEY" \-F "workspaceUuid=your-workspace-uuid" \-F "envelopeTitle=My First Envelope" \-F "file=@/path/to/document.pdf"Using Node.js with fetch:
import FormData from "form-data";import { createReadStream } from "fs";const API_BASE_URL = "http://your-proxy:8080";const ACCESS_KEY = "your-access-key";const SECRET_KEY = "your-secret-key";const WORKSPACE_UUID = "your-workspace-uuid";const formData = new FormData();formData.append("workspaceUuid", WORKSPACE_UUID);formData.append("envelopeTitle", "My First Envelope");formData.append("file", createReadStream("path/to/document.pdf"));const createResponse = await fetch(`${API_BASE_URL}/public/envelope/create-from-file`, {method: "POST",headers: {Authorization: `Bearer ${ACCESS_KEY}:${SECRET_KEY}`,...formData.getHeaders()},body: formData});if (!createResponse.ok) {throw new Error(`Failed to create envelope: ${createResponse.status}`);}const createResult = await createResponse.json();const { envelopeUuid, documentUuid } = createResult;console.log("Envelope UUID:", envelopeUuid);console.log("Document UUID:", documentUuid);Using Node.js with the
@subnoto/api-clientSDK:import { SubnotoClient } from "@subnoto/api-client";import FormData from "form-data";import { createReadStream } from "fs";const client = new SubnotoClient({apiBaseUrl: "https://enclave.subnoto.com",accessKey: process.env.API_ACCESS_KEY,secretKey: process.env.API_SECRET_KEY});const formData = new FormData();formData.append("workspaceUuid", "your-workspace-uuid");formData.append("envelopeTitle", "My First Envelope");formData.append("file", createReadStream("path/to/document.pdf"));const { data, error } = await client.POST("/public/envelope/create-from-file", {body: formData,headers: {...formData.getHeaders()}});if (error) {throw new Error(`Failed to create envelope: ${error}`);}const { envelopeUuid, documentUuid } = data;console.log("Envelope UUID:", envelopeUuid);console.log("Document UUID:", documentUuid);Response:
The endpoint returns a JSON object with:
envelopeUuid(string): The unique identifier for your envelopedocumentUuid(string): The unique identifier for the document
What happens automatically:
- Document encryption
- File upload to storage
- PDF validation and preview generation
- Setting envelope status to
draft
Supported file types:
- PDF files (
.pdf) - MIME type:application/pdf - Word documents (
.docx,.doc) - MIME types:application/vnd.openxmlformats-officedocument.wordprocessingml.documentorapplication/msword- automatically converted to PDF
File size limits:
- Maximum file size: 50 MB
Required dependencies:
For Node.js examples, install the required dependency for multipart form data:
Terminal window npm install form-data -
Add Recipients
Add recipients to your envelope. Recipients can be added as manual entries, contacts, or workspace members:
const addRecipientsResponse = await fetch(`${API_BASE_URL}/public/envelope/add-recipients`, {method: "POST",headers: {Authorization: `Bearer ${ACCESS_KEY}:${SECRET_KEY}`,"Content-Type": "application/json"},body: JSON.stringify({workspaceUuid: WORKSPACE_UUID,envelopeUuid,recipients: [{type: "manual",firstname: "John",lastname: "Doe"}]})});const recipientsResult = await addRecipientsResponse.json();You can add multiple recipients (up to 50) at once. Each recipient can be:
type: 'manual'- Manual entry with email, firstname, lastnametype: 'contact'- Existing contact usingcontactUuidtype: 'member'- Workspace member usinguserUuid
-
Add Blocks
Add blocks to your document. Blocks can be signatures, text, or images:
Tip: Use the Block Preview Tool to visually place blocks on your PDF and get the exact coordinates (page, x, y, width, height) before making API calls. This tool helps you preview block placement and copy the JSON format directly for your API requests.
const addBlocksResponse = await fetch(`${API_BASE_URL}/public/envelope/add-blocks`, {method: "POST",headers: {Authorization: `Bearer ${ACCESS_KEY}:${SECRET_KEY}`,"Content-Type": "application/json"},body: JSON.stringify({workspaceUuid: WORKSPACE_UUID,envelopeUuid,documentUuid,blocks: [{type: "signature",page: "1",x: 100,y: 200,},{type: "text",page: "1",x: 100,y: 250,text: "Please sign here",width: 200,height: 30}]})});const blocksResult = await addBlocksResponse.json();Block Types
{type: 'signature',page: '1', // Page number as stringx: 100, // X position in pointsy: 200, // Y position in points}{type: 'text',page: '1',x: 100,y: 200,text: 'Your text here',width: 200, // Optionalheight: 30, // OptionaltemplatedText: 'fullname', // Optional: 'email', 'fullname', or 'phone'}Templated text: When
templatedTextis set, thetextfield is automatically populated from the recipient’s data at creation time:'fullname'— recipient’s first and last name (e.g. “John Doe”)'email'— recipient’s email address'phone'— recipient’s phone number
recipientEmailmust match an existing recipient on the envelope. You can passtext: ''— it will be resolved automatically.{type: 'image',page: '1',x: 100,y: 200,src: 'data:image/png;base64,iVBORw0KGgo...', // Base64 encoded (max 256KB)fileType: 'image/png',width: 100, // Optionalheight: 100 // Optional} -
Send the Envelope
Finally, send the envelope to all recipients:
const sendResponse = await fetch(`${API_BASE_URL}/public/envelope/send`, {method: "POST",headers: {Authorization: `Bearer ${ACCESS_KEY}:${SECRET_KEY}`,"Content-Type": "application/json"},body: JSON.stringify({workspaceUuid: WORKSPACE_UUID,envelopeUuid,useUserAsSenderName: false, // Optional: use user name instead of company namecustomInvitationMessage: "Please review and sign this document" // Optional: custom message})});if (!sendResponse.ok) {throw new Error(`Failed to send envelope: ${sendResponse.status}`);} -
Track Envelope Events with Webhooks
After sending an envelope, you can track signing events and completion using webhooks. Create a webhook in your workspace and subscribe to envelope events (e.g.
ENVELOPE_SIGNEDandENVELOPE_COMPLETED). See Setting up webhooks for the full steps.Available Events
- ENVELOPE_SIGNED: Triggered each time a recipient signs the document. Use this to track individual signing events.
- ENVELOPE_COMPLETED: Triggered when the envelope is fully completed and all required signatures have been collected. Use this to know when the envelope process is complete.
Webhook Payload Example
When a recipient signs the document, you’ll receive an
ENVELOPE_SIGNEDevent:{"eventUuid": "0f29a0a2-3a6f-44a4-b2a2-5d7b3f1b1f9b","eventType": "ENVELOPE_SIGNED","eventTime": 1704067200000,"webhookUuid": "webhook-uuid","teamUuid": "team-uuid","data": {"workspaceUuid": "workspace-uuid","envelopeUuid": "envelope-uuid","recipientName": "John Doe"}}When the envelope is completed, you’ll receive an
ENVELOPE_COMPLETEDevent:{"eventUuid": "f5a6c2d3-2e1b-4c7a-92ab-5e8f2d1c0b9a","eventType": "ENVELOPE_COMPLETED","eventTime": 1704067200000,"webhookUuid": "webhook-uuid","teamUuid": "team-uuid","data": {"workspaceUuid": "workspace-uuid","envelopeUuid": "envelope-uuid","documentUuid": "document-uuid","finalRevisionVersion": 1}}
Important Notes
Section titled “Important Notes”- Envelope Status: Envelopes must be in
draftstatus to add recipients, blocks, or make modifications. Once sent, the status changes and modifications are restricted. - Block Positioning: Block coordinates (x, y) are in PDF points (1/72 inch). Make sure to position blocks correctly on your pages.
- Signature Blocks: Signature blocks always require a
recipientEmailthat must match one of the recipients added to the envelope. - Recipient Emails: When adding blocks with
recipientEmail, the email must match one of the recipients added to the envelope.
Error Handling
Section titled “Error Handling”The API may return various error codes. Common ones include:
When creating envelopes:
WORKSPACE_NOT_FOUND: Invalid workspace UUIDINVALID_FILE_DATA: The uploaded file data is invalid or corruptedFILE_SIZE_EXCEEDED: File size exceeds the 50 MB limitINVALID_PDF: The uploaded file is not a valid PDFINVALID_REQUEST: The request format is invalid (e.g., missing required fields)DOCUMENT_INVALID: The document failed validationDOCUMENT_CONVERSION_UNAVAILABLE: Document conversion service is unavailableDOCUMENT_CONVERSION_FAILED: Failed to convert Word document to PDF
When managing envelopes:
ENVELOPE_NOT_FOUND: Invalid envelope UUIDENVELOPE_NOT_IN_DRAFT: Envelope has already been sentNO_RECIPIENTS: Attempting to send without recipientsDOCUMENT_NOT_FOUND: Invalid document UUIDINVALID_RECIPIENT_EMAIL: Recipient email doesn’t match any added recipients
Always check response status codes and handle errors appropriately in your application.
Related
Section titled “Related”- Working with the API — High-level API flow and next steps
- Setting up webhooks — Configure webhooks for envelope events
- Download signed document and proof — Get the signed PDF and audit proof after completion