Zoho Sign API Use cases
Sending a document for signature
There are three steps to send a document for signature::
- Getting the field types
- Uploading the document
- Adding the recipients and the fields associated with the recipients
Get the field types associated with the current Zoho Sign account using the Field types API.
Store the field types for adding the fields to the actions. If your app will only need to work for one Zoho Sign account, you can hard code the field type IDs.
Upload the files to create the document using the create document API.
The file contents must be sent in the body as multipart form data. Multiple files can be sent in a single call. The recipient information can also be added by sending actions with this call.
Add any additional actions or associated fields as required using the update document API call.
Every action except action_type VIEW actions must have at least one field associated with it. Otherwise, you will not be able to send the document. Send the document for signature using the submit document API call.
<?php
//Create document and add recipients
$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";
$requestJSON = new stdClass();
$requestJSON->request_name = "<Request-Name>";
$requestJSON->expiration_days = 1;
$requestJSON->is_sequential = true;
$requestJSON->email_reminders = true;
$requestJSON->reminder_period = 8;
$requestJSON->actions = array($actionsJson);
$request = new stdClass();
$request->requests = $requestJSON;
$data = json_encode($request);
$POST_DATA = array(
'data' => $data,
'file' => new CURLfile("<File-Path>")
);
$curl = curl_init("https://sign.zoho.com/api/v1/requests");
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") {
$createdRequestId = $jsonbody->requests->request_id;
//Save the ID from the response to update later
$createdRequest = new stdClass();
$createdRequest = $jsonbody->requests;
} else //Error check for error
{
echo $jsonbody->message;
}
curl_close($curl);
//Add fields and send out document
$actionsJson = new stdClass();
$actionsJson->action_id = $createdRequest->actions[0]->action_id;
$actionsJson->recipient_name = $createdRequest->actions[0]->recipient_name;
$actionsJson->recipient_email = $createdRequest->actions[0]->recipient_email;
$actionsJson->action_type = $createdRequest->actions[0]->action_type;
$fieldJson = new stdClass();
$fieldJson->document_id = $createdRequest->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);
$requestJSON = new stdClass();
$requestJSON->actions = array($actionsJson);
$request = new stdClass();
$request->requests = $requestJSON;
$data = json_encode($request);
$POST_DATA = array(
'data' => $data
);
$curl = curl_init("https://sign.zoho.com/api/v1/requests/" . $createdRequestId . "/submit");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization:Zoho-oauthtoken <Oauth-Token>',
));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
$response = curl_exec($curl);
echo $response;
$jsonbody = json_decode($response); // contain filed tyes response
if ($jsonbody->status == "success") {
$created_request_id = $jsonbody->requests->request_id; //Save the ID from the response to update later
$status = $jsonbody->requests->request_status;
echo $status;
} else //Error check for error
{
echo $jsonbody->message;
}
curl_close($curl);
?>
const express = require('express');
const fs = require('fs');
const FormData = require('form-data');
const fetch = require('node-fetch');
const path = require('path');
const app = express();
const port = 4000;
app.get('/sendForSignature', async (req, res) => {
let actionsJson = {};
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';
let documentJson = {};
documentJson['request_name'] = '<Request-Name>';
documentJson['expiration_days'] = 1;
documentJson['is_sequential'] = true;
documentJson['email_reminders'] = true;
documentJson['reminder_period'] = 8;
documentJson['actions'] = new Array(actionsJson);
let data = {};
data['requests'] = documentJson;
let files = ['<File-Path>', '<File-Path>'];
var payload = new FormData();
if (fs.existsSync(files[0])) {
let value = fs.createReadStream(files[0]);
payload.append('file', value);
} else {
return 'unable to read file';
}
payload.append('data', JSON.stringify(data));
let HEADERS = {};
HEADERS['Authorization'] = 'Zoho-oauthtoken <Oauth-Token>';
let URL = 'https://sign.zoho.com/api/v1/requests';
let method = 'POST';
let requestOptions = {
method: method,
headers: HEADERS,
body: payload
};
let response = await fetch(URL, requestOptions)
.then((_res) => {
console.log(`Return code is ${_res.status}`);
return _res.json().then((responseJson) => {
return responseJson['requests'];
});
})
.catch((error) => {
let errorResponse = {};
errorResponse['message'] = 'call failed to initiate'; //check internet connection or proper DC type
errorResponse['status'] = 'failure';
res.send(errorResponse);
});
var request_id = response.request_id;
let actionsJson1 = {};
actionsJson1['action_id'] = response.actions[0].action_id;
actionsJson1['recipient_name'] = response.actions[0].recipient_name;
actionsJson1['recipient_email'] = response.actions[0].recipient_email;
actionsJson1['action_type'] = response.actions[0].action_type;
let fieldJson = {};
fieldJson['document_id'] = response.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;
actionsJson1['fields'] = new Array(fieldJson);
let documentJson1 = {};
documentJson1['actions'] = new Array(actionsJson1);
let data1 = {};
data1['requests'] = documentJson1;
var payload1 = new FormData();
payload1.append('data', JSON.stringify(data1));
let URL1 = 'https://sign.zoho.com/api/v1/requests/' + request_id + '/submit';
let requestOptions1 = {
method: 'POST',
headers: HEADERS,
body: payload1
};
return fetch(URL1, requestOptions1)
.then((_res1) => {
console.log(`Return code is ${_res1.status}`);
return _res1.json().then((responseJson1) => {
res.send(responseJson1);
});
})
.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}`);
});
//Get field types list
JSONArray fieldTypes = null;
HttpClient client = new DefaultHttpClient();
//Create document
File firstFile = new File("/home/documents/Test1.pdf"); //First file to be uploaded
File secondFile = new File("/home/documents/Test2.pdf"); //Second file to be uploaded
//Documents json object with details about the document and recipients
JSONObject docJson = new JSONObject();
docJson.put("request_name","testDoc");
docJson.put("expiration_days",10);
docJson.put("is_sequential", true);
docJson.put("note","Sign this test sign");
JSONObject actionJson = new JSONObject();
actionJson.put("action_type","SIGN");
actionJson.put("recipient_email","<recipient email id>");
actionJson.put("recipient_name","<recipient name>");
actionJson.put("verify_recipient", false);
actionJson.put("signing_order", 0);
docJson.put("actions", new JSONArray().put(actionJson));
JSONObject dataJson =new JSONObject();
dataJson.put("requests", docJson);
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.addBinaryBody("file",firstFile, ContentType.APPLICATION_OCTET_STREAM, "Test1.pdf");
reqEntity.addBinaryBody("file", secondFile, ContentType.APPLICATION_OCTET_STREAM, "Test2.pdf");
reqEntity.addTextBody("data",dataJson.toString());
HttpEntity multipart = reqEntity.build();
HttpPost postMethod = new HttpPost("https://sign.zoho.com/api/v1/requests");
postMethod.setHeader("Authorization","Zoho-oauthtoken "+ "<access-token>");
postMethod.setEntity(multipart);
response = client.execute(postMethod);
responseJSON = EntityUtils.toString(response.getEntity(), "UTF-8");
JSONObject documentJson = new JSONObject(responseJSON);
if(documentJson.getString("status").equals("success"))
{
String requestId = documentJson.getString("request_id");
JSONArray actions = documentJson.getJSONArray("actions");
//Add fields to recipient
for(int i=0;i< actions.length() ;i++)
{
JSONObject action = actions.getJSONObject(i);
if(action.getString("action_type").equals("SIGN"))
{
JSONArray fields = new JSONArray();
JSONArray documents = documentJson.getJSONArray("document_ids");
for(int j=0; j< documents.length(); j++)
{
String document_id = documents.getJSONObject(j).getString("document_id");
JSONObject fieldJson = new JSONObject();
//Add a signature field
fieldJson.put("field_name","Signature");
fieldJson.put("field_label","Signature");
fieldJson.put("field_type_name","Signature");
fieldJson.put("page_no",0);
fieldJson.put("x_coord",0+i*100);
fieldJson.put("y_coord",0+i*100);
fieldJson.put("document_id",document_id);
fields.put(fieldJson);
//Add a date field
fieldJson = new JSONObject();
fieldJson.put("field_name","Sign Date");
fieldJson.put("field_label","Sign Date");
fieldJson.put("field_type_name","Date");
fieldJson.put("page_no",0);
fieldJson.put("x_coord",20+i*100);
fieldJson.put("y_coord",20+i*100);
fieldJson.put("document_id",document_id);
fields.put(fieldJson);
action.put("fields",fields);
}
}
}
documentJson.put("actions",actions);
dataJson = new JSONObject();
dataJson.put("requests", documentJson);
reqEntity = MultipartEntityBuilder.create();
reqEntity.addTextBody("data",dataJson.toString());
postMethod = new HttpPost("https://sign.zoho.com/api/v1/requests/"+ requestId+"/submit");
postMethod.setHeader("Authorization","Zoho-oauthtoken "+ "<access-token>");
postMethod.setEntity(multipart);
response = client.execute(postMethod);
responseJSON = EntityUtils.toString(response.getEntity(), "UTF-8");
JSONObject submitResponse = new JSONObject(responseJSON);
if(submitResponse.has("status") && submitResponse.getString("status").equals("success"))
{
System.out.println("Document sent successfully");
}
else
{
System.out.println("Error : "+submitResponse.getString("message"));
}
}
else
{
System.out.println("Error with creating document : "+documentJson.getString("message"));
}
file_object1 = invokeurl
[
url :"<url>"
type :GET
];
file_object1.setparamname("file");
q = List();
//can add multiple files
q.add(file_object1);
res = zoho.sign.createDocument(q);
req_id = res.get('requests').get('request_id');
doc_id = res.get('requests').get('document_ids').get(0).get('document_id');
reciMap = Map();
reciMap.put("recipient_name","<recipient name>");
reciMap.put("recipient_email","<recipient email>");
reciMap.put("action_type","SIGN");
reciMap.put("signing_order",0);
fieldList = List();
textField1 = Map();
textField1.put("field_name", "Company");
textField1.put("is_mandatory", "true");
textField1.put("field_type_name", "Company");
textField1.put("document_id", doc_id);
textField1.put("x_coord",10);
textField1.put("y_coord",30);
textField1.put("abs_width",100);
textField1.put("abs_height",15);
textField1.put("page_no",0);
fieldList.add(textField1);
reciMap.put("fields",fieldList);
reciList = List();
reciList.add(reciMap);
request = Map();
request.put("actions",reciList);
data = Map();
data.put("requests",request);
updateMap = Map();
updateMap.put("data",data);
res = zoho.sign.submitRequest(req_id.toLong(), updateMap);
def createDocument(fileList,Oauthtoken):
headers = {'Authorization':'Zoho-oauthtoken '+Oauthtoken}
files =[]
for i in fileList:
files.append(('file', (i[0],open(i[1],'rb'),i[2])))
req_data={}
req_data['request_name']="Python Test"
req_data["expiration_days"]= 10
req_data["is_sequential"]=True
req_data["email_reminders"]=True
req_data["reminder_period"]= 5
actions_list=[]
actions_list.append({"recipient_name":"<recipient_name>","recipient_email":"<recipient_email>","action_type":"SIGN","private_notes":"Please get back to us for further queries","signing_order":0})
req_data['actions']=actions_list
data={}
data['requests']=req_data
data_json={}
data_json['data'] = json.dumps(data)
r = requests.post('https://sign.zoho.com/api/v1/requests', files=files, data=data_json,headers=headers)
return r.json()
def submitDocument(request_id,respjson,Oauthtoken):
headers = {'Authorization':'Zoho-oauthtoken '+Oauthtoken}
req_data={}
req_data['request_name']=respjson['request_name']
docIdsJsonArray = respjson['document_ids']
actionsJsonArray = respjson['actions']
for i in docIdsJsonArray:
docId=i["document_id"]
for j in actionsJsonArray:
fields=[]
sigField={}
sigField["field_type_name"]= "Signature"
sigField["is_mandatory"]= True
sigField["field_name"]= "Signature"
sigField["page_no"]= 0
sigField["y_coord"]= 700
sigField["abs_width"]= 150
sigField["description_tooltip"]= ""
sigField["x_coord"]= 225
sigField["abs_height"]= 20
sigField["document_id"]= docId
fields.append(sigField)
emailField={}
emailField["field_type_name"]= "Email"
emailField["text_property"]={}
emailField["text_property"]["is_italic"]= False
emailField["text_property"]["is_underline"]= False
emailField["text_property"]["font_color"]= "000000"
emailField["text_property"]["font_size"]= 11
emailField["text_property"]["is_read_only"]= False
emailField["text_property"]["is_bold"]= False
emailField["text_property"]["font"]= "Arial"
emailField["is_mandatory"]= True
emailField["page_no"]= 0
emailField["document_id"]= docId
emailField["field_name"]= "Email"
emailField["y_coord"]= 750
emailField["abs_width"]= 250
emailField["description_tooltip"]= ""
emailField["x_coord"]=225
emailField["abs_height"]= 20
fields.append(emailField)
if 'fields' in j:
j['fields']=j['fields']+fields
else:
j["fields"]=fields
j.pop('is_bulk',None)
j.pop('allow_signing',None)
j.pop('action_status',None)
req_data['actions']=actionsJsonArray
data={}
data['requests']=req_data
data_json={}
data_json['data'] = json.dumps(data)
url = 'https://sign.zoho.com/api/v1/requests/'+request_id+'/submit'
r = requests.post(url, files=[],data=data_json, headers=headers)
return r.json()
file_list=[["<FileName1>","<FilePath>","application/pdf"],["<FileName2>","<FilePath>","application/pdf"]]
respjson= createDocument(file_list,Oauthtoken)
respjson=respjson['requests']
request_id=respjson['request_id']
submitrespjson=submitDocument(request_id,respjson,Oauthtoken)
//Create Document
string[] files = new string[] { "./test.pdf" }; //PDF to be uploaded
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://sign.zoho.com/api/v1/requests");
request.Headers["Authorization"] = "Zoho-oauthtoken " + accessToken;
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
Stream memStream = new System.IO.MemoryStream();
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/pdf\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "file", files[i]);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
}
JObject requestObj = new JObject();
using (HttpWebResponse requestResp = (HttpWebResponse)request.GetResponse())
{
Stream stream = requestResp.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string requestResponse = reader.ReadToEnd();
JObject ResponseString = JObject.Parse(requestResponse);
requestObj = (JObject)ResponseString.GetValue("requests");
}
string requestId = (string)requestObj["request_id"];
JArray actions = (JArray)requestObj["actions"];
//Add Recipients
JObject recipient = new JObject();
recipient.Add("recipient_name", <Recipient Name>);
recipient.Add("recipient_email", <Recipient email>);
recipient.Add("action_type", <Recipient action type - SIGN/VIEW>);
recipient.Add("verify_recipient", false);
actions.Add(recipient);
// Add Fields to Recipient
JArray recipientActions = new JArray();
for (int i = 0; i < actions.Count; i++)
{
JObject action = (JObject)actions[i];
if (((string)action.GetValue("action_type")).Equals("SIGN"))
{
JArray image_fields = new JArray();
JArray date_fields = new JArray();
JObject fields = new JObject();
JArray documents = (JArray)requestObj["document_ids"];
for (int j = 0; j < documents.Count; j++)
{
JObject document = (JObject)documents[j];
string document_id = (string)document.GetValue("document_id");
JObject fieldJson = new JObject();
//Add a signature field
fieldJson.Add("field_name", "Signature");
fieldJson.Add("field_label", "Signature");
fieldJson.Add("field_type_name", "Signature");
fieldJson.Add("page_no", 0);
fieldJson.Add("abs_width", "200");
fieldJson.Add("abs_height", "18");
fieldJson.Add("x_coord", 0 + i * 100);
fieldJson.Add("y_coord", 0 + i * 100);
fieldJson.Add("document_id", document_id);
image_fields.Add(fieldJson);
//Add a date field
fieldJson = new JObject();
fieldJson.Add("field_name", "Sign Date");
fieldJson.Add("field_label", "Sign Date");
fieldJson.Add("field_type_name", "Date");
fieldJson.Add("page_no", 0);
fieldJson.Add("abs_width", "200");
fieldJson.Add("abs_height", "18");
fieldJson.Add("x_coord", 20 + i * 100);
fieldJson.Add("y_coord", 20 + i * 100);
fieldJson.Add("document_id", document_id);
date_fields.Add(fieldJson);
fields.Add("image_fields", image_fields);
fields.Add("date_fields", date_fields);
action.Add("fields", fields);
recipientActions.Add(action);
}
}
}
requestObj = new JObject();
requestObj.Add("actions", recipientActions);
JObject dataJson = new JObject();
dataJson.Add("requests", requestObj);
string dataStr = Newtonsoft.Json.JsonConvert.SerializeObject(dataJson);
// Send Document for Signature
Client = new RestClient("https://sign.zoho.com/api/v1/requests/" + requestId + "/submit");
var submitRequest = new RestRequest();
submitRequest.AddHeader("Authorization", "Zoho-oauthtoken " + accessToken);
submitRequest.AddParameter("data", dataStr);
var response = Client.Post(submitRequest);
var content = response.Content;
string responseString = content.ToString();
Show full
Show less