6. Signature Templates
Signature Templates
This scenario demonstrates how to create and use signature templates in Circularo. Signature templates allow you to save predefined signature field configurations for repeated use, streamlining the signature request process and ensuring consistency across your organization's signing workflows.
Key features:
Create reusable signature templates with predefined signature fields
Retrieve template information when needed
Create new documents based on signature templates
Request signatures using the template's predefined signature fields
Prerequisites
Before working with signature templates, you need:
A valid authentication token (see the "Authentication & Security" section for details)
A PDF file to upload as the template's content
Knowledge of the metadata definition and workflow you want to use
Understanding of signature field positioning and requirements
Signature templates are particularly useful when you frequently request signatures on documents with the same layout. They help maintain consistency in signature positioning and reduce the effort needed to configure signature fields for each document.
Step 1 - Upload a PDF file
The first step in creating a signature template is to upload the PDF file that will serve as the template's content. This file will be the base document for all documents created from this template.
The file is uploaded as a multipart/form-data request
The response includes the file ID that will be used in the template creation step
The file should represent the standard document structure with areas designated for signatures
Choose a file that represents your standard document format with clear areas where signatures should be placed. This could be a contract, agreement, or any document that requires consistent signature placement.
Endpoint
POST /files/saveFile
Request
POST /files/saveFile?token=SrBSJ0AXTPsHuNoFzl2YezLLdEmdawaH0DzHSvC9gIkijgafx9R3Sneai3QPkamx
Content-Type: multipart/form-data
{
"file": "blob",
"fileName": "Contract Template"
}
Response
The response contains the following important properties:
fileHash - Located at
file.idin the response.Example value:
dbmhgtKT7gYQkyxDvhJiLd7u64jpBHcBBrR0ru2nAIGWXDjbbNV3V3j1eHRU4GBk
The PDF file has been successfully uploaded and stored in the system. The response includes the file ID that will be used to create the signature template.
The file.id is the unique identifier for the uploaded file
This ID will be referenced when creating the template in the next step
The storage information shows your current usage and available quota
Step 2 - Create a signature template
This endpoint creates a new signature template using the previously uploaded PDF file. The template will store the file reference, metadata definition, and signature field configurations that can be reused when creating documents and requesting signatures.
The name parameter defines a descriptive name for the template
The documentType parameter specifies which metadata definition to use
The definitionType parameter is set to "ext" for external file-based documents
The file parameter references the file ID from the previous step
The signEntities array defines the roles of signers
The signFields array defines the exact positions and properties of signature fields
The type parameter is set to "sign" to indicate a signature template
Endpoint
POST /templates
Request
POST /templates?token=SrBSJ0AXTPsHuNoFzl2YezLLdEmdawaH0DzHSvC9gIkijgafx9R3Sneai3QPkamx
Content-Type: application/json
{
"data": {
"name": "Contract Template",
"documentType": "d_default",
"definitionType": "ext",
"file": "dbmhgtKT7gYQkyxDvhJiLd7u64jpBHcBBrR0ru2nAIGWXDjbbNV3V3j1eHRU4GBk",
"sequential": false, //Whether signatures should be collected sequentially or in parallel
"signEntities": [ //Defines the roles of signers in the template
{
"userRoleId": 0,
"userRoleName": "Recipient 1",
"type": "user",
"shareType": "sign"
}
],
"signFields": [ //Defines the exact positions and properties of signature fields
{
"userRoleId": 0,
"userRoleName": "Recipient 1",
"timestamp": false,
"required": true,
"type": "signature",
"pages": [
1
],
"position": {
"percentX": 0.2,
"percentY": 0.6,
"percentWidth": 0.4,
"percentHeight": 0.1
}
}
],
"type": "sign"
}
}
Response
The response contains the following important properties:
templateId - Located at
idin the response.Example value:
71b2366b-1f79-4d84-ae42-1b77a23b7931
The signature template has been successfully created and is now available for use.
The response includes the template ID which will be used to reference this template
The template stores the file reference, metadata definition, and signature field configurations
This template can now be used to create multiple documents with consistent signature field positioning
Step 3 - Retrieve signature template information
When you need to use a signature template, you can retrieve its details using this endpoint. This allows you to examine the template's signature field configurations before using it to create a document.
The templateId parameter specifies which template to retrieve
The response includes all template details including the file reference and signature field configurations
Endpoint
GET /templates/:templateId
Request
GET /templates/71b2366b-1f79-4d84-ae42-1b77a23b7931?token=SrBSJ0AXTPsHuNoFzl2YezLLdEmdawaH0DzHSvC9gIkijgafx9R3Sneai3QPkamx
Response
{
"definitionType": "ext",
"documentType": "d_default",
"file": "dbmhgtKT7gYQkyxDvhJiLd7u64jpBHcBBrR0ru2nAIGWXDjbbNV3V3j1eHRU4GBk",
"name": "Contract Template",
"__id": "71b2366b-1f79-4d84-ae42-1b77a23b7931",
"__addedBy": "mary.griffin@circularo.com",
"__addedOn": "2023-07-11T13:38:36.909Z",
"__owner": "mary.griffin@circularo.com",
"__users": [],
"__groups": [],
"signEntities": [
{
"userRoleId": 0,
"userRoleName": "Recipient 1",
"type": "user",
"shareType": "sign"
}
],
"signFields": [
{
"userRoleId": 0,
"userRoleName": "Recipient 1",
"timestamp": false,
"required": true,
"type": "signature",
"pages": [
1
],
"position": {
"percentX": 0.2,
"percentY": 0.6,
"percentWidth": 0.4,
"percentHeight": 0.1
}
}
],
"sequential": false,
...
}
The response includes detailed information about the requested signature template.
The name field contains the template's descriptive name
The file field contains the file ID of the template's content
The signEntities array defines the roles of signers in the template
The signFields array contains the exact positions and properties of signature fields
The sequential field indicates whether signatures should be collected sequentially or in parallel
Step 4 - Create a document from signature template
This endpoint creates a new document based on the previously created signature template. The template provides both the document content and signature field configurations.
The customTemplate parameter references the template ID to use
The documentTitle and other metadata fields must be explicitly provided for this document
The cloneMainFile option is crucial as it creates a copy of the template's file for this document
The workflow parameter defines which workflow to apply to the new document
Important: The template ID (customTemplate) only serves as a reference - it does NOT automatically populate the document with template data. You must explicitly provide all required document data in the request.
The cloneMainFile: true option is essential when creating documents from templates. It ensures that each document has its own independent file.
Endpoint
POST /documents
Request
POST /documents?token=SrBSJ0AXTPsHuNoFzl2YezLLdEmdawaH0DzHSvC9gIkijgafx9R3Sneai3QPkamx
Content-Type: application/json
{
"body": {
"documentType": "d_default",
"documentTitle": "Company memo from template",
"customTemplate": "71b2366b-1f79-4d84-ae42-1b77a23b7931", //ID of the signature template to use
"pdfFile": {
"content": "dbmhgtKT7gYQkyxDvhJiLd7u64jpBHcBBrR0ru2nAIGWXDjbbNV3V3j1eHRU4GBk" //Reference to the template's file that will be cloned
}
},
"optionalData": {
"cloneMainFile": true //Creates a copy of the template's file for this document
},
"definitionType": "ext",
"workflow": "wf_archive"
}
Response
The response contains the following important properties:
documentId - Located at
results[0].documentIdin the response.Example value:
84de4c38-a972-40a8-a6b2-64f06eb469a9
The document has been successfully created based on the signature template.
The response includes the document ID of the newly created document
The document uses a copy of the template's file, not the original file
The document is ready to be shared for signature using the template's predefined signature field configurations
The document starts in the initial state of the specified workflow
The signature fields from the template are not automatically applied to the document. They will be applied manually when you share the document for signature in the next step.
Step 5 - Request signature using template fields
This endpoint demonstrates how to share a document for signature using the signature field configurations from the template.
The document is shared with a recipient for signing
The signature fields are positioned according to the template's configuration
The recipient will be notified and can sign the document at the designated positions
The signing process is tracked in the document history
Important: When using signature templates, you need to manually specify all the signature data based on the template data.
Endpoint
POST /share
Request
POST /share?token=SrBSJ0AXTPsHuNoFzl2YezLLdEmdawaH0DzHSvC9gIkijgafx9R3Sneai3QPkamx
Content-Type: application/json
{
"id": "84de4c38-a972-40a8-a6b2-64f06eb469a9",
"type": "d_default",
"objectType": "document",
"data": [
{
"sharePurpose": "sign", //Purpose of the share - in this case, requesting a signature
"shareTo": "derek.trotter@circularo.com" //Email or username of the recipient who should sign
}
],
"signatureFields": [
{
"user": [ //User who should sign at this position
"derek.trotter@circularo.com"
],
"userRoleId": 0, //Role and other data defined in the template
"userRoleName": "Recipient 1",
"timestamp": false,
"required": true,
"type": "signature",
"pages": [
1
],
"position": {
"percentX": 0.2,
"percentY": 0.6,
"percentWidth": 0.4,
"percentHeight": 0.1
}
}
]
}
Response
[
{
"shareId": "h2HaA9NJaSRrx3JRODXo",
"isActive": true,
"isPermanentViewToken": false,
"shareDate": "2023-07-20T14:04:36.186Z",
"shareType": "sign",
"sharedBy": "mary.griffin@circularo.com",
"sharedObjectEsId": "84de4c38-a972-40a8-a6b2-64f06eb469a9",
"sharedObjectEsType": "d_default",
"sharedObjectType": "document",
"sharedWith": [
"derek.trotter@circularo.com"
],
...
}
]
The document has been successfully shared for signature. The recipient will receive a notification and can sign the document at the positions defined in the template.
The signature fields are manually positioned according to the template's configuration
The recipient will be notified about the signature request
The signing process is tracked in the document history
Signature Templates Summary
You have successfully learned how to create and use signature templates in the Circularo system.
Key Concepts
Signature Templates: Reusable configurations that store file references, metadata definitions, and signature field positions
Signature Entities: Define the roles of signers in the template
Signature Fields: Define the exact positions and properties of signature fields on the document
Manual Data Entry: All document data must be explicitly provided in the request - no data is automatically fetched from templates
Example Implementation
See our OpenAPI documentation to learn about the full set of API endpoints and parameters.
Please use proper exception handling and function decomposition in your own code. The code is provided for illustrative purposes only and is not intended for production use.
// Signature template usage example
const URL = "https://sandbox.circularo.com";
const API_PATH = "/api/v1";
const TOKEN = "YOUR_AUTH_TOKEN"; // Obtained from login or API key
try {
// Step 1: Upload a PDF file for the template
const formData = new FormData();
formData.append('fileName', 'Contract Template');
formData.append('file', fs.createReadStream('path/to/template.pdf')); // Using Node.js fs module
const uploadResponse = await fetch(`${URL}${API_PATH}/files/saveFile?token=${TOKEN}`, {
method: 'POST',
body: formData
});
if (!uploadResponse.ok) {
throw new Error(`File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`);
}
const uploadData = await uploadResponse.json();
const fileId = uploadData.file.id;
// Step 2: Create a signature template
const createTemplateResponse = await fetch(`${URL}${API_PATH}/templates?token=${TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
data: {
name: "Contract Signature Template",
documentType: "d_default",
definitionType: "ext",
file: fileId,
sequential: false,
signEntities: [{
userRoleId: 0,
userRoleName: "Recipient 1",
type: "user",
shareType: "sign"
}],
signFields: [{
userRoleId: 0,
userRoleName: "Recipient 1",
timestamp: false,
required: true,
type: "signature",
pages: [1],
position: {
percentX: 0.2,
percentY: 0.6,
percentWidth: 0.4,
percentHeight: 0.1
}
}],
type: "sign"
}
})
});
if (!createTemplateResponse.ok) {
throw new Error(`Template creation failed: ${createTemplateResponse.status} ${createTemplateResponse.statusText}`);
}
const templateData = await createTemplateResponse.json();
const templateId = templateData.id;
console.log(`Signature template created with ID: ${templateId}`);
// Later, when you need to use the template...
// Step 3: Retrieve template information
const templateResponse = await fetch(`${URL}${API_PATH}/templates/${templateId}?token=${TOKEN}`);
if (!templateResponse.ok) {
throw new Error(`Failed to retrieve template: ${templateResponse.status} ${templateResponse.statusText}`);
}
const template = await templateResponse.json();
console.log(`Using signature template: ${template.name}`);
// Step 4: Create a document from the signature template
const createDocumentResponse = await fetch(`${URL}${API_PATH}/documents?token=${TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
body: {
documentType: template.documentType,
documentTitle: "Client Contract - ABC Corporation",
customTemplate: templateId,
pdfFile: {
content: template.file
}
},
optionalData: {
cloneMainFile: true // Important: creates a copy of the template's file
},
definitionType: template.definitionType,
workflow: "wf_archive"
})
});
if (!createDocumentResponse.ok) {
throw new Error(`Document creation failed: ${createDocumentResponse.status} ${createDocumentResponse.statusText}`);
}
const documentData = await createDocumentResponse.json();
const documentId = documentData.results[0].documentId;
console.log(`Document created from signature template with ID: ${documentId}`);
// Step 5: Request signature using the template's signature field configuration
const shareResponse = await fetch(`${URL}${API_PATH}/share?token=${TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: documentId,
type: template.documentType,
objectType: "document",
data: [
{
sharePurpose: "sign",
shareTo: "recipient@example.com"
}
],
signatureFields: [
{
user: ["recipient@example.com"],
userRoleId: 0,
userRoleName: "Recipient 1",
timestamp: false,
required: true,
type: "signature",
pages: [1],
position: {
percentX: 0.2,
percentY: 0.6,
percentWidth: 0.4,
percentHeight: 0.1
}
}
]
})
});
if (!shareResponse.ok) {
throw new Error(`Signature request failed: ${shareResponse.status} ${shareResponse.statusText}`);
}
const shareData = await shareResponse.json();
console.log(`Document shared for signature with recipient@example.com`);
console.log(`Share ID: ${shareData[0].shareId}`);
} catch (error) {
console.error('Error working with signature templates:', error.message);
}