Merge and Deliver via Webhook
Purpose
This API is used to deliver the merge documents via Webhook for custom handling by consumers.
Quick Reference
| Property | Value |
|---|---|
| Method | POST |
| Request URL | https://{zohoapis_domain}/writer/api/v1/documents/{document_id}/merge/webhook |
| Scopes | ZohoWriter.documentEditor.ALL, ZohoWriter.merge.ALL, ZohoPC.files.ALL, WorkDrive.files.ALL |
| Rate Limit | See Writer API throttle limits |
Parameters
Path Parameters
| Parameter | Data Type | Description |
|---|---|---|
| document_id | String | Specify a unique id for the writer document. |
Body Parameters
| Parameter | Data Type | Description |
|---|---|---|
| Mandatory Parameters | ||
| output_settings | { "format": "pdf | pdfform | docx", "password": "****", "restricted_access": { "password": "****", "permissions": ["document.copy", "document.print", "document.edit", "document.fill"] } } | format - Specify the format in which you would like to download the merged document.
permissions: Specify the actions that needs to be restricted in merged document. |
| webhook | { " invoke_url ": <url>, " invoke_period": "oneveryrecord/oncomplete" } | Pass the values for invoke_url and invoke_period via this parameter as JSON. Provide the webhook url in which the merged documents needs to be posted in invoke_url and when the merged documents needs to be posted in invoke_period. |
| merge_to | String | Supported merge types are separatedoc and singledoc. Specify in which type you would like to merge the document. separatedoc - If you would like to merge each record as a separate document. singledoc - If you would like to merge all the records as a single document. |
| Merge Data — pass data using any one of the below formats | ||
| merge_data | JSONObject | Pass a String value through 'data' key as JSON Array. |
| merge_data_csv_content | File | Provide the required csv content in your API request body. |
| merge_data_json_content | File | Provide the required json content in your API request body. |
| merge_data_csv_url | url | Provide the required csv url in your API request body. |
| merge_data_json_url | url | Provide the required json url in your API request body. |
| record_id | String | Instead of using merge_data, you can pass the record_id and we will fetch the data internally. Note: This is applicable only for Zoho CRM, Creator and Bigin templates. Maximum length allowed: 25 |
| Optional Parameters | ||
| test_mode | Boolean (true/false) | Using this param, you can test the Merge APIs without consuming any credit points. The output file will contain a watermark as it is used only for testing purpose. Test mode limit: 50 merges/day for an org. |
webhook
| Parameter | Type | Possible Values | Default Value |
|---|---|---|---|
| invoke_url | string | URL | URL |
| invoke_period | string | oncomplete and oneveryrecord. oncomplete - If you would like to post the merged documents after merging all the records. oneveryrecord - If you would like to post the merged document of each record once done. | oncomplete |
permissions
| Permission Key Name | Description |
|---|---|
| document.copy | Copy content from the merged document |
| document.print | Print the merged document |
| document.edit | Edit the merged document |
| document.fill | To fill form fields in the merged document |
Notes
- For possible errors, refer to error codes.
Curl - Sample Request
Copiedcurl -X POST "https://www.zohoapis.com/writer/api/v1/documents/{document_id}/merge/webhook" \
-H "Authorization: Zoho-oauthtoken <ACCESS_TOKEN>" \
-F "output_settings={\"format\":\"pdf\"}" \
-F "webhook={\"invoke_url\":\"https://example.com/webhook\",\"invoke_period\":\"oncomplete\"}" \
-F "merge_to=separatedoc" \
-F "merge_data={\"data\":[{\"name\":\"Amelia\",\"email\":\"Amelia@zylker.com\"},{\"name\":\"Johnson\",\"email\":\"johnson@zylker.com\"}]}"Sample Response
Copied{
"merge_report_data_url": "https://writer.zoho.com/writer/api/v1/merge/job/0tq5n465132106580437abe99b6f56f2b0c85/data",
"merge_report_url": "https://writer.zoho.com/writer/v1/mailmerge/job/0tq5n465132106580437abe99b6f56f2b0c85",
"records": [
{
"data": {
"name": "Amelia",
"email": "amelia@zylker.com"
},
"download_link": "{url}",
"status": "inprogress"
},
{
"data": {
"name": "John",
"email": "john@zylker.com"
},
"download_link": "{url}",
"status": "inprogress"
}
],
}
// When 'merge_report_data_url' is invoked, you will receive the below response;
1. If 'merge_to' = "separatedoc"
{
"records": [
{
"data": {
“name": “Amelia”,
"email": “amelia@zylker.com"
},
"download_link": “{url}“,
"status": "inprogress"
},
{
"data": {
“name": “John”,
"email": “john@zylker.com"
},
"download_link": “{url}“,
"status": "inprogress"
}
],
"status": "inprogress"
}
2. If 'merge_to' = "singledoc"
{
"records": [
{
"download_link": “{url}“,
"data": [
{
“name": “Amelia”,
“email”: “amelia@zylker.com”
},
{
“name": “John”,
“email”: “john@zylker.com”
}
],
"status": "inprogress"
}
],
"status": "inprogress"
}
Deluge Snippet
Copieddata = Map();
data.put("InvoiceNo","12345");
data.put("InvoiceDate","27 May 2022");
data.put("InvoiceAmount","$100");
param = Map();
param.put("output_settings",{"format":docx});
webhook1 = Map();
webhook1.put("invoke_url”,”<https://facebook.com>”);
webhook1.put("invoke_period","oneveryrecord");
param.put("webhook",webhook1);
param.put("merge_to","singledoc");
param.put("merge_data",{"data":data});
info param;
response = invokeurl
[
url :"https://www.zohoapis.com/writer/api/v1/documents/olce2ef69******331f25aaece75dd/merge/webhook"
type :POST
parameters:param
connection:"<connection_name>"
];
info response;Sample Response
Copied{
"merge_report_data_url": "https://writer.zoho.com/writer/api/v1/merge/job/fbsa6360a78f53f564dfa9b4a1e79febed569/data",
"merge_report_url": "https://writer.zoho.com/writer/v1/mailmerge/job/fbsa6360a78f53f564dfa9b4a1e79febed569",
"records": [
{
"download_link": "{url}”,
"data": [
{
"InvoiceNo": "12345",
"InvoiceDate": "27 May 2022",
"InvoiceAmount": "$100",
"id": "0e002287-7c45-4188-af9f-65*****”
}
],
"status": "inprogress"
}
],
"status": "inprogress"
}
Callback Response:
Option 1: oneveryrecord
If the 'invoke_period' key inside the 'webhook' parameter is set to "oneveryrecord", we will process each record individually, generate a merged PDF for each, and trigger the webhook callback immediately with the respective PDF.
Note: For this flow, only the "separatedoc" option is supported for the 'merge_to' parameter, as each record is processed and sent separately. The "singledoc" option is not applicable in this case.
Copieddata:{
"attachment_name": "<file name>.pdf",
"fieldid1": "field value",
"fieldid2": "field value"
}
file: <Multipart file>Option 2: oncomplete
If the 'invoke_period' key under the 'webhook' parameter is set to "oncomplete", we will initiate PDF generation for all records in parallel and trigger the webhook callback only after the PDF generation for all records is complete.
Note: This flow supports the following 'merge_to' options:
- separatedoc – A separate PDF is generated for each record and all files are sent in a single webhook callback. Each file can be identified using the 'attachment_name' field in the response data.
Important: For a large number of input records (more than 10), the response body size can become large. In such cases, we split the output into batches of 10 records and invoke the webhook callback multiple times in a loop until all records are processed. - singledoc – All merged PDFs are combined into a single PDF file, which is then sent via a single webhook callback.
Copieddata:[
{
"attachment_name": "<file name1>.pdf",
"fieldid1": "field value",
"fieldid2": "field value"
},
{
"attachment_name": "<file name2>.pdf",
"fieldid1": "field value",
"fieldid2": "field value"
}...
]
file: <Multipart file - multiple or single PDF file based on merge_to >