- Introduction
- OAuth
- API Endpoint
- Quick start with Zoho Sign's API
- Postman collection
- SwaggerHub
- Basic concepts
- Getting started with Zoho Sign's API under 2 minutes
- Signer groups
- Document Management
- POSTCreate document
- PUTUpdate document
- POSTSend document for signature
- POSTCorrect document
- GETGet details of a particular document
- GETGet documents list
- GETDownload PDF
- GETDownload particular PDF file
- GETDownload completion certificate
- GETGet document form data
- POSTRecall Document
- POSTRemind Recipient
- PUTDelete Document
- PUTExtend document
- POSTCreate new Folder
- GETGet folder list
- GETRetrieve field type
- GETGet document type
- POSTCreate new document type
- POSTUpdate document type
- Template Management
- Embedded Signing
- Embedded Sending
- Use Cases
- How-to guides
- Sending a signing request via SMS
- Enforce authentication
- Add fields to your document
- In-Person signing
- Sign documents with digital signature providers
- Sending documents in bulk
- eStamping
- Collecting payments from my recipients
- Adding witness to your envelope
- Manages recipients
- Sending an envelope to a signer group
- Replace signer group with normal recipients
- API error codes
- API limitation
- Security
- Contact details for technical assistance
Sending a document using a template
- The id of the template must be known in order to use the template for sending documents.
- If the details of the template are known, then the API call can be made. If not, then you will need to make the get template details call whose response will give all the details of the template including the recipients, their action ids and the pre fill field details.
- Make the create document call along with the details for the recipients associated with the templates and the pre fill fields of the template if they exist.
<?php
//Create Template
$templateJSON=new stdClass();
$templates=new stdClass();
$templates->template_name="<Template-Name>";
$templates->is_sequential="true";
$templateJSON->templates=$templates;
$templatesData=json_encode($templateJSON);
$POST_DATA = array(
'data' => $templatesData,
'file' => new CURLfile("<File-Path>")
);
$curl = curl_init("https://sign.zoho.com/api/v1/templates");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization:Zoho-oauthtoken <Oauth-Token>',
"Content-Type:multipart/form-data"
));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
$response = curl_exec($curl);
$jsonbody = json_decode($response); // contain filed tyes response
if ($jsonbody->status == "success") {
$templateId = $jsonbody->templates->template_id;
//Save the ID from the response to update later
$createdTemplate=new stdClass();
$createdTemplate = $jsonbody->templates;
}
else //Error check for error
{
echo $jsonbody->message;
}
curl_close($curl);
//Add recipient for template
$actionsJson= new stdClass();
$actionsJson->recipient_name = "<Recipient-Name>";
$actionsJson->recipient_email = "<Recipient-Email>";
$actionsJson->action_type = "SIGN";
$actionsJson->private_notes = "Please get back to us for further queries";
$actionsJson->signing_order = 0;
$actionsJson->verify_recipient = true;
$actionsJson->verification_type = "EMAIL";
$actionsJson->role="<Role>";
$documentJson= new stdClass();
$documentJson->template_name = "<Template-Name>";
$documentJson->expiration_days = 1;
$documentJson->is_sequential = true;
$documentJson->email_reminders = true;
$documentJson->reminder_period = 8;
$documentJson->actions = array($actionsJson);
$templateJSON= new stdClass();
$templateJSON->templates = $documentJson;
$templatesData=json_encode($templateJSON);
$POST_DATA = array(
'data' => $templatesData
);
$curl = curl_init("https://sign.zoho.com/api/v1/templates/".$templateId);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization:Zoho-oauthtoken <Oauth-Token>',
"Content-Type:multipart/form-data"
));
curl_setopt($curl,CURLOPT_CUSTOMREQUEST,"PUT");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
$response = curl_exec($curl);
$jsonbody = json_decode($response); // contain filed tyes response
if ($jsonbody->status == "success") {
$templateId = $jsonbody->templates->template_id;
//Save the ID from the response to update later
$createdTemplate=new stdClass();
$createdTemplate = $jsonbody->templates;
}
else //Error check for error
{
echo $jsonbody->message;
}
curl_close($curl);
//Add Field for recipient
$actionsJson=new stdClass();
$actionsJson->action_id = $createdTemplate->actions[0]->action_id;
$actionsJson->recipient_name = $createdTemplate->actions[0]->recipient_name;
$actionsJson->recipient_email = $createdTemplate->actions[0]->recipient_email;
$actionsJson->action_type = $createdTemplate->actions[0]->action_type;
$fieldJson=new stdClass();
$fieldJson->document_id = $createdTemplate->document_ids[0]->document_id;
$fieldJson->field_name = "TextField";
$fieldJson->field_type_name = "Textfield";
$fieldJson->field_label = "Text - 1";
$fieldJson->field_category = "Textfield";
$fieldJson->abs_width = "200";
$fieldJson->abs_height = "18";
$fieldJson->is_mandatory = true;
$fieldJson->x_coord = "30";
$fieldJson->y_coord = "30";
$fieldJson->page_no = 0;
$actionsJson->fields = array($fieldJson);
$templates=new stdClass();
$templates->actions = array($actionsJson);
$templateJSON= new stdClass();
$templateJSON->templates = $templates;
$templatesData=json_encode($templateJSON);
$POST_DATA = array(
'data' => $templatesData
);
$curl = curl_init("https://sign.zoho.com/api/v1/templates/".$templateId);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization:Zoho-oauthtoken <Oauth-Token>',
"Content-Type:multipart/form-data"
));
curl_setopt($curl,CURLOPT_CUSTOMREQUEST,"PUT");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
$response = curl_exec($curl);
$jsonbody = json_decode($response); // contain filed tyes response
if ($jsonbody->status == "success") {
$templateId = $jsonbody->templates->template_id;
//Save the ID from the response to update later
$createdTemplate=new stdClass();
$createdTemplate = $jsonbody->templates;
}
else //Error check for error
{
echo $jsonbody->message;
}
curl_close($curl);
// Send template for signing
$actionsJson=new stdClass();
$actionsJson->action_id = $createdTemplate->actions[0]->action_id;
$actionsJson->recipient_name = $createdTemplate->actions[0]->recipient_name;
$actionsJson->recipient_email = $createdTemplate->actions[0]->recipient_email;
$actionsJson->action_type = $createdTemplate->actions[0]->action_type;
$templates=new stdClass();
$templates->actions = array($actionsJson);
$templateJSON= new stdClass();
$templateJSON->templates = $templates;
$templatesData=json_encode($templateJSON);
$POST_DATA = array(
'data' => $templatesData,
"is_quicksend"=>"true"
);
$curl = curl_init("https://sign.zoho.com/api/v1/templates/".$templateId."/createdocument");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization:Zoho-oauthtoken <Oauth-Token>',
"Content-Type:multipart/form-data"
));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
$response = curl_exec($curl);
$jsonbody = json_decode($response); // contain filed tyes response
if ($jsonbody->status == "success") {
$templateId = $jsonbody->templates->template_id;
//Save the ID from the response to update later
$createdTemplate=new stdClass();
$createdTemplate = $jsonbody->templates;
}
else //Error check for error
{
echo $jsonbody->message;
}
curl_close($curl);
?>
const express = require('express');
const FormData = require('form-data');
const fetch = require('node-fetch');
const app = express();
const port = 4000;
app.get('/sendTemplate', async (req, res) => {
let HEADERS = {};
HEADERS['Authorization'] = 'Zoho-oauthtoken <Oauth Token>';
let URL = 'https://sign.zoho.com/api/v1/templates/<Template-Id>';
let method = 'GET';
let requestOptions = {
method: method,
headers: HEADERS
};
let response = await fetch(URL, requestOptions)
.then((_res) => {
console.log(`Return code is ${_res.status}`);
return _res.json().then((responseJson) => {
return responseJson['templates'];
});
})
.catch((error) => {
let errorResponse = {};
errorResponse['message'] = 'call failed to initiate'; //check internet connection or proper DC type
errorResponse['status'] = 'failure';
res.send(errorResponse);
});
let template_id = response.template_id;
let actionsJson = {};
actionsJson['action_id'] = response.actions[0].action_id;
actionsJson['recipient_name'] = response.actions[0].recipient_name;
actionsJson['recipient_email'] = response.actions[0].recipient_email;
actionsJson['action_type'] = response.actions[0].action_type;
let templates = {};
templates['actions'] = new Array(actionsJson);
let data = {};
data['templates'] = templates;
var payload = new FormData();
payload.append('data', JSON.stringify(data));
payload.append('is_quicksend', 'true');
let requestOptions1 = {
method: 'POST',
headers: HEADERS,
body: payload
};
let URL1 = 'https://sign.zoho.com/api/v1/templates/' + template_id + '/createdocument';
let response1 = await fetch(URL1, requestOptions1)
.then((_res) => {
console.log(`Return code is ${_res.status}`);
return _res.json().then((responseJson) => {
res.send(responseJson);
return responseJson['templates'];
});
})
.catch((error) => {
let errorResponse = {};
errorResponse['message'] = 'call failed to initiate'; //check internet connection or proper DC type
errorResponse['status'] = 'failure';
res.send(errorResponse);
});
});
app.listen(port, () => {
console.log(`Example app listening on port {port}`);
});
actionMap = Map();
fieldTextData = Map();
fieldTextData.put("TextField_1", "Document to Review");
actionMap.put("field_data",{"field_text_data":fieldTextData});
eachActionMap1 = Map();
eachActionMap1.put("recipient_name","<recipient name>");
eachActionMap1.put("recipient_email","<recipient email>");
eachActionMap1.put("action_type","SIGN");
eachActionMap1.put("action_id","<ActionId>");
eachActionMap1.put("role","Reviewer");
eachActionMap1.put("verify_recipient","false");
eachActionMap2 = Map();
eachActionMap2.put("recipient_name","<recipient name>");
eachActionMap2.put("recipient_email","<recipient email>");
eachActionMap2.put("action_type","SIGN");
eachActionMap2.put("action_id","<ActionId>");
eachActionMap2.put("role","Manager");
eachActionMap2.put("verify_recipient","false");
fieldList = List();
fieldList.add(eachActionMap1);
fieldList.add(eachActionMap2);
actionMap.put("actions",fieldList);
submitMap = Map();
submitMap.put("templates",actionMap);
parameters = Map();
parameters.put("is_quicksend","true");
parameters.put("data",submitMap);
response = zoho.sign.createUsingTemplate(<TemplateId>, parameters);
JSONObject documentJson = temp.getJSONObject("requests");
String docStatus = documentJson.getString("request_status");
if(docStatus.equals("completed"))
{
//Check if single or multiple documents
JSONArray documentIds = documentJson.getJSONArray("document_ids");
if(documentIds.length() == 1)
{
//Download single document directly
getMethod = new HttpGet("https://sign.zoho.com/api/v1/requests/"+requestId+"/pdf");
response = client.execute(getMethod);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
String filePath = "C:\\Users\\windowsUserName\\Downloads\\"+documentJson.getString("request_name");
FileOutputStream fos = new FileOutputStream(new File(filePath));
byte[] buffer = new byte[5600];
int inByte;
while((inByte = is.read(buffer)) > 0)
fos.write(buffer,0,inByte);
is.close();
fos.close();
}
else
{
for(int i=0; i< documentIds.length(); i++)
{
String documentId = documentIds.getJSONObject(i).getString("document_id");
getMethod = new HttpGet("https://sign.zoho.com/api/v1/requests/"+requestId+"/documents/"+documentId+"/pdf");
response = client.execute(getMethod);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
String filePath = "C:\\Users\\windowsUserName\\Downloads\\"+documentIds.getJSONObject(i).getString("document_name");
FileOutputStream fos = new FileOutputStream(new File(filePath));
byte[] buffer = new byte[5600];
int inByte;
while((inByte = is.read(buffer)) > 0)
fos.write(buffer,0,inByte);
is.close();
fos.close();
}
}
//Download Completion certificate
getMethod = new HttpGet("https://sign.zoho.com/api/v1/requests/"+requestId+"/completioncertificate");
response = client.execute(getMethod);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
String filePath = "C:\\Users\\windowsUserName\\Downloads\\"+documentJson.getString("request_name")+"_completioncertificate.pdf";
FileOutputStream fos = new FileOutputStream(new File(filePath));
byte[] buffer = new byte[5600];
int inByte;
while((inByte = is.read(buffer)) > 0)
fos.write(buffer,0,inByte);
is.close();
fos.close();
}
def getTemplateDetailsUsingTemplateID(template_id,Oauthtoken):
headers = {'Authorization':'Zoho-oauthtoken '+Oauthtoken}
r = requests.get(domainName + '/api/v1/templates/'+template_id,headers=headers)
return r.json()
def sendDocumentUsingTemplate(template_id,respjson,Oauthtoken):
headers = {'Authorization':'Zoho-oauthtoken '+Oauthtoken}
temp_data={}
prefillfieldsJsonArray = respjson['document_fields']
actionsJsonArray = respjson['actions']
#Adding recipient to the template
newActionArray = []
for i in actionsJsonArray:
newAction={}
newAction['recipient_email']="<recipient_email>"
newAction['recipient_name']="<recipient_name>"
newAction['action_id']=i['action_id']
newAction['action_type']=i['action_type']
newAction['private_notes']=""
newAction['signing_order']=i['signing_order']
newActionArray.append(newAction)
temp_data['actions']=newActionArray
#Addding data to PreFill Fields
text_data={}
date_data={}
boolean_data={}
for i in prefillfieldsJsonArray:
if 'fields' in i:
fieldsArr = i['fields']
for j in fieldsArr:
if j['field_category'] == 'datefield':
date_data[j['field_label']] = "04 November 2019" # Adding date field data in this format dd MMMM yyyy
if j['field_category'] == 'textfield':
text_data[j['field_label']] = "Some Value"
if j['field_category'] == 'dropdown':
text_data[j['field_label']] = j['dropdown_values'][0]['dropdown_value']
if j['field_category'] == 'checkbox':
boolean_data[j['field_label']] = True # Value should be True/False
prefill_data = {}
prefill_data['field_text_data'] = text_data
prefill_data['field_date_data'] = date_data
prefill_data['field_boolean_data'] = boolean_data
temp_data['field_data'] = prefill_data
data={}
data['templates']=temp_data
data_json={}
data_json['data'] = json.dumps(data)
data_json['is_quicksend'] = True
url = domainName + '/api/v1/templates/'+template_id+'/createdocument'
r = requests.post(url, data=data_json, headers=headers)
return r.json()
respjson = getTemplateDetailsUsingTemplateID('<Template ID>',Oauthtoken)
respjson=respjson['templates']
print sendDocumentUsingTemplate('<Template ID>',respjson,Oauthtoken)
var Client = new RestClient("https://sign.zoho.com/api/v1/templates/" + <<templateId>>);
var getRequest = new RestRequest();
getRequest.AddHeader("Authorization", "Zoho-oauthtoken " + <<accessToken>>);
var getResponse = Client.Get(getRequest);
string responseString = getResponse.Content;
JObject responseObj = JObject.Parse(responseString);
JObject templateObj = (JObject)responseObj.GetValue("templates");
JArray actions = (JArray)templateObj.GetValue("actions");
JArray document_fields = (JArray)templateObj.GetValue("document_fields");
JObject field_text_data = new JObject();
JObject field_boolean_data = new JObject();
JObject field_date_data = new JObject();
JObject field_data = new JObject();
foreach (JObject document in document_fields)
{
JArray fields = (JArray)document.GetValue("fields");
foreach(JObject field in fields)
{
string field_category = (string)field.GetValue("field_category");
string field_label = (string)field.GetValue("field_label");
if (field_category.Equals("datefield"))
{
field_date_data.Add(field_label, "25 October 2019"); // DD MMMM YYYY
}else if (field_category.Equals("checkbox"))
{
field_boolean_data.Add(field_label, true);
}
else if (field_category.Equals("textfield") || field_category.Equals("dropdown"))
{
field_text_data.Add(field_label, "text");
}
}
}
field_data.Add("field_date_data", field_date_data);
field_data.Add("field_text_data", field_text_data);
field_data.Add("field_boolean_data", field_boolean_data);
foreach (JObject action in actions)
{
action["recipient_name"] = <<Recipient Name>>;
action["recipient_email"] = <<Recipient Email>>;
action["verify_recipient"] = false;
action.Remove("fields");
}
JObject templates = new JObject();
templates.Add("actions", actions);
templates.Add("field_data", field_data);
templates.Add("request_name",<<Request Name>>);
JObject dataJson = new JObject();
dataJson.Add("templates", templates);
string dataString = Newtonsoft.Json.JsonConvert.SerializeObject(dataJson);
Client = new RestClient("https://sign.zoho.com/api/v1/templates/"+ <<templateId>> +"/createdocument");
var postRequest = new RestRequest();
postRequest.AddHeader("Authorization", "Zoho-oauthtoken " + accessToken);
postRequest.AddParameter("data", dataString);
postRequest.AddParameter("is_quicksend", true);
var postResponse = Client.Post(postRequest);
string requestResponse = postResponse.Content;
Show full
Show less
© 2025, Zoho Corporation Pvt. Ltd. All Rights Reserved.