Download Bulk Read Result

Purpose

To download the bulk read job as a CSV or an ICS file (only for the Events module). The file would be in .zip format. Extract it to get the CSV or ICS file.

Request Details

Request URL

https://www.zohoapis.com/crm/bulk/v2/read/{job_id}/result
where job_id is the unique ID of the bulk read job.

Header

Authorization: Zoho-oauthtoken d92d4xxxxxxxxxxxxx15f52

Scope

scope=ZohoCRM.bulk.read
(and)
scope=ZohoCRM.modules.{module_name}.{operation_type}

Possible module names

leads, accounts, contacts, deals, campaigns, tasks, cases, events, calls, solutions, products, vendors, pricebooks, quotes, salesorders, purchaseorders, invoices, and custom

Possible operation types

ALL - Full access to related records
READ - Get bulk read job

Note

  • Only 10 requests for download are allowed for one-minute interval. Crossing the limit will result in an error (HTTP code :429) returned to the user as response.

  • To know more about the Bulk API limits, go here.

  • The value of the fields with sensitive health data will be retrieved only when Restrict Data access through API option in the compliance settings is disabled. If the option is enabled, the value will be empty in the result.

Sample Result

CSV

csv result

ICS

ics result

For CSV type export,
  • If the "fields" attribute in the query JSON is left empty, all the fields available in CRM are listed in the CSV file. In case you need only specific fields, like in the above image, please specify the fields for export.

  • The "id" column is added by default in the CSV file, and it contains the id of the exported records.

  • The "Data/Time" fields in the CSV file are given in the ISO8601 format.

  • You can export a maximum of 200,000 records in a single API call.

For ICS type export,
  • The "fields" attribute is not supported when you want to export the events as an ICS file.

  • If you do not specify "file_type" as "ics", the records will be exported in the CSV format, by default.

  • You can export a maximum of 20,000 records in a single API call.

  • To know more about the Bulk API limits on ICS file, go here.

Possible Errors

  • INVALID_URL_PATTERNHTTP 404

    Please check if the URL trying to access is a correct one
    Resolution: The request URL specified is incorrect. Specify a valid request URL. Refer to request URL section above.

  • OAUTH_SCOPE_MISMATCHHTTP 401

    Unauthorized
    Resolution: Client does not have ZohoCRM.bulk.read or ZohoCRM.modules.{module_name}.READ. Create a new client with valid scope. Refer to scope section above.

  • NO_PERMISSIONHTTP 403

    Permission denied to read
    Resolution: The user does not have permission to read records. Contact your system administrator.

  • INTERNAL_ERRORHTTP 500

    Internal Server Error
    Resolution: Unexpected and unhandled exception in Server. Contact support team.

  • INVALID_REQUEST_METHODHTTP 400

    The http request method type is not a valid one
    Resolution: You have specified an invalid HTTP method to access the API URL. Specify a valid request method. Refer to endpoints section above.

  • AUTHORIZATION_FAILEDHTTP 400

    User does not have sufficient privilege to read.
    Resolution: The user does not have the permission to read records. Contact your system administrator.

  • RESOURCE_NOT_FOUNDHTTP 404

    The requested resource doesn't exist.
    Resolution: The job ID specified is invalid. Specify a valid job ID.

Sample Request

Copiedcurl "https://www.zohoapis.com/crm/bulk/v2/read/554023000000568002/result"
-X GET
-H "Authorization: Zoho-oauthtoken 1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf"
3.0.08.0
CopiedLong jobId = 3477061000005177002L;
String destinationFolder = "/Users/user_name/Documents";

//Get instance of BulkReadOperations Class
BulkReadOperations bulkReadOperations = new BulkReadOperations();

//Call downloadResult method that takes jobId as parameters
APIResponse < ResponseHandler > response = bulkReadOperations.downloadResult(jobId);
Copiedimport java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
public class DownloadBulkReadResult 
{	
	public static void main(String[] args) 
	{
		try
		{
			HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
			SSLContext sslContext = SSLContext.getDefault();
			SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
			CloseableHttpClient httpclient = httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory).build();
			URIBuilder uriBuilder = new URIBuilder("https://www.zohoapis.com/crm/bulk/v2/read/34770617772019/result");
			HttpUriRequest requestObj = new HttpGet(uriBuilder.build());
			requestObj.addHeader("Authorization", "Zoho-oauthtoken 1000.xxxxxxx.xxxxxxx");
			HttpResponse response = httpclient.execute(requestObj);
			HttpEntity responseEntity = response.getEntity();
			System.out.println("HTTP Status Code : " + response.getStatusLine().getStatusCode());
			if(responseEntity != null)
			{
				if(response.containsHeader("Content-Disposition"))
				{
					String contentDisposition = response.getFirstHeader("Content-Disposition").getValue();
					String fileName = contentDisposition.split("=")[1];
					if(fileName.contains("''"))
			        {
			            fileName = fileName.split("''")[1];
			        }
					if(fileName.contains("\""))
			        {
			        	fileName = fileName.replace("\"", "");
			        }
					//Create a file instance with the absolute_file_path
					File file = new File("/Users/username/Desktop" + File.separatorChar + fileName);
					//Get InputStream from the response
					InputStream is = responseEntity.getContent();
					//Create an OutputStream for the destination file
					OutputStream os = new FileOutputStream(file);
					byte[] buffer = new byte[1024];
			        int bytesRead;
			        //read the InputStream till the end
			        while((bytesRead = is.read(buffer)) != -1)
			        {
			        	//write data to OutputStream
			        	os.write(buffer, 0, bytesRead);
			        }
			        //Close the InputStream
			        is.close();
			        //Flush and close the OutputStream
			        os.flush();
			        os.close();
				}
				else
				{
					Object responseObject = EntityUtils.toString(responseEntity);
					String responseString = responseObject.toString();
					System.out.println(responseString);
				}
			}
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
}
3.0.07.x
Copied//Get instance of BulkReadOperations Class
$bulkReadOperations = new BulkReadOperations();
//Call downloadResult method that takes jobId as parameters
$response = $bulkReadOperations->downloadResult($jobId);
Copied<?php
class DownloadBulkReadResult 
{
    public function execute(){
        $curl_pointer = curl_init();
        
        $curl_options = array();
        $curl_options[CURLOPT_URL] = "https://www.zohoapis.com/crm/bulk/v2/read/35240335999005/result";
        $curl_options[CURLOPT_RETURNTRANSFER] = true;
        $curl_options[CURLOPT_HEADER] = 1;
        $curl_options[CURLOPT_CUSTOMREQUEST] = "GET";
        $headersArray = array();
        
        $headersArray[] = "Authorization". ":" . "Zoho-oauthtoken " . "1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf";
        
        $curl_options[CURLOPT_HTTPHEADER]=$headersArray;
        
        curl_setopt_array($curl_pointer, $curl_options);
        
        $result = curl_exec($curl_pointer);
        $responseInfo = curl_getinfo($curl_pointer);
        curl_close($curl_pointer);
        list ($headers, $content) = explode("\r\n\r\n", $result, 2);
        if(strpos($headers," 100 Continue")!==false){
            list( $headers, $content) = explode( "\r\n\r\n", $content , 2);
        }
        $headerArray = (explode("\r\n", $headers, 50));
        $headerMap = array();
        foreach ($headerArray as $key) {
            if (strpos($key, ":") != false) {
                $firstHalf = substr($key, 0, strpos($key, ":"));
                $secondHalf = substr($key, strpos($key, ":") + 1);
                $headerMap[$firstHalf] = trim($secondHalf);
            }
        }
        $response = $content;
        if ($response == null && $responseInfo['http_code'] != 204) {
            list ($headers, $content) = explode("\r\n\r\n", $content, 2);
            $response = json_decode($content, true);
        }
        $contentDisp = $headerMap['Content-Disposition'];
        $fileName = substr($contentDisp, strrpos($contentDisp, "'") + 1, strlen($contentDisp));
        
        if (strpos($fileName, "=") !== false)
        {
            $fileName = substr($fileName, strrpos($fileName, "=") + 1, strlen($fileName));
            
            $fileName = str_replace(array(
                '\'',
                '"'
            ), '', $fileName);
        }
        $filePath = "/Users/test/PHP/PHPNativeSampleCode/";
        $fp = fopen($filePath . $fileName, "w"); // $filePath - absolute path where downloaded file has to be stored.
        $stream = $response;
        fputs($fp, $stream);
        fclose($fp);   
    }
}
(new DownloadBulkReadResult())->execute();
3.0.08.x
Copied//Get instance of BulkReadOperations Class
BulkReadOperations bulkReadOperations = new BulkReadOperations();
//Call DownloadResult method that takes jobId as parameters
APIResponse<API.BulkRead.ResponseHandler> response = bulkReadOperations.DownloadResult(jobId);
Copiedusing System;
using System.IO;
using System.Net;
namespace Com.Zoho.Crm.API.Sample.RestAPI.BulkRead
{
    public class DownloadBulkReadResult
    {
        public static void DownloadBulkRead()
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.zohoapis.com/crm/bulk/v2/read/34770617772019/result");
            request.Method = "GET";
            request.Headers["Authorization"] = "Zoho-oauthtoken 1000.abfeXXXXXXXXXXX2asw.XXXXXXXXXXXXXXXXXXsdc2";
            request.KeepAlive = true;
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                if (e.Response == null) { throw; }
                response = (HttpWebResponse)e.Response;
            }
            HttpWebResponse responseEntity = response;
            Console.WriteLine("HTTP Status Code : " + (int)response.StatusCode);
            WebHeaderCollection collection = responseEntity.Headers;
            string contentDisposition = collection["Content-Disposition"];
            if (contentDisposition != null)
            {
                string fileName = contentDisposition.Split(new string[] { "=" }, StringSplitOptions.None)[1];
                if (fileName.Contains("''"))
                {
                    fileName = fileName.Split(new string[] { "''" }, StringSplitOptions.None)[1];
                }
                fileName = fileName.Trim('\"');
                string fullFilePath = Path.Combine("/Users/abc-123/Desktop", fileName);
                using (FileStream outputFileStream = new FileStream(fullFilePath, FileMode.Create))
                {
                    responseEntity.GetResponseStream().CopyTo(outputFileStream);
                }
                responseEntity.Close();
            }
            else
            {
                string responsestring = new StreamReader(responseEntity.GetResponseStream()).ReadToEnd();
                responseEntity.Close();
                Console.WriteLine(responsestring);
            }
        }
    }
}
3.0.03.x.x
Copied# Get instance of BulkReadOperations Class
bulk_read_operations = BulkReadOperations()
# Call download_result method that takes job_id as parameter
response = bulk_read_operations.download_result(job_id)
Copieddef download_bulk_read_result():
    import requests
    import os

    url = 'https://www.zohoapis.com/crm/bulk/v2/read/3409643000002461001/result'

    headers = {
        'Authorization': 'Zoho-oauthtoken 1000.04be928e4a96XXXXXXXXXXXXX68.0b9eXXXXXXXXXXXX60396e268',
    }

    response = requests.get(url=url, headers=headers)

    if response is not None:
        print("HTTP Status Code : " + str(response.status_code))

        if 'Content-Type' in response.headers:
            content_type = response.headers['Content-Type'].split(';')[0]

            if content_type == 'application/json':
                print(response.json())
            else:
                if 'Content-Disposition' in response.headers:
                    file_name = ''
                    content_disposition = response.headers['Content-Disposition']

                    if "'" in content_disposition:
                        start_index = content_disposition.rindex("'")
                        file_name = content_disposition[start_index + 1:]

                    elif '"' in content_disposition:
                        start_index = content_disposition.rindex('=')
                        file_name = content_disposition[start_index + 1:].replace('"', '')

                    destination_file = os.path.join('/Users/abc-123/Documents', file_name)

                    with open(destination_file, 'wb') as f:
                        for chunk in response:
                            f.write(chunk)

download_bulk_read_result()
1.0.010.x
Copied//Get instance of BulkReadOperations Class
let bulkReadOperations = new BulkReadOperations();
//Call downloadResult method that takes jobId as parameter
let response = await bulkReadOperations.downloadResult(jobId);
Copiedasync function downloadBulkReadResult() {
    const got = require("got");
    const fs = require("fs");
    const path = require("path");

    let url = 'https://www.zohoapis.com/crm/bulk/v2/read/3409643000002461001/result'

    let headers = {
        Authorization : "Zoho-oauthtoken 1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf"
    }

    let requestDetails = {
        method : "GET",
        headers : headers,
        throwHttpErrors : false
    }
    
    let response = await got(url, requestDetails)
    
    if(response != null) {
        console.log(response.statusCode);
        
        if(response.headers.hasOwnProperty('content-type')) {
            let contentType = response.headers['content-type'].split(";")[0];

            if(contentType == 'application/json') {
                console.log(response.body);
            }
            else {
                let fileName = "";

                let contentDisposition = (response.headers['content-disposition']);

                if(contentDisposition.includes("'")){
                    let startIndex = contentDisposition.lastIndexOf("'");

                    fileName = contentDisposition.substring(startIndex + 1);
                }
                else if(contentDisposition.includes("\"")){
                    let startIndex = contentDisposition.lastIndexOf("=");

                    fileName = contentDisposition.substring(startIndex + 1).replace(/"/g, "");
                }

                fileName = path.join("/Users/abc-123/Documents/SDK/latest/nodejs/zohocrm-nodejs-sdk", fileName);

                fs.writeFileSync(fileName, response.rawBody);
            }
        }
    }
}
downloadBulkReadResult()
2.02.x.x
Copied# Get instance of BulkReadOperations Class
bro = BulkRead::BulkReadOperations.new
# Call download_result method that takes job_id as parameter
response = bro.download_result(job_id)
Copiedclass DownloadBulkWriteResult 

    def execute
      
        url = "https://www.zohoapis.com/crm/bulk/v2/read/3524033000006012040/result"
        url = URI(url)
        req = Net::HTTP::Get.new(url.request_uri)
        http = Net::HTTP.new(url.host, url.port)
        http.use_ssl = true
        headers={}
        headers["Authorization"]="Zoho-oauthtoken 1000.50XXXXXXXXX&77e3a.44XXXXXXXXX8353"
        headers&.each { |key, value| req.add_field(key, value) }   
        
        response=http.request(req)
        file_name = response.to_hash["content-disposition"][0].split('=')[1]

        file_name = file_name.split("''")[1] if file_name.include? "''"

        file_name = file_name.gsub('"', '') if file_name.include? '"'

        status_code = response.code.to_i
        headers = response.each_header.to_h
        print status_code
        print headers
        unless response.body.nil?
            File.open("/Users/test/RUBY/RUBYNativeSampleCode/"+file_name, 'w') { |file| file.write(response.body) }
        end
    end
end
DownloadBulkWriteResult.new.execute
1.0.0ES6
Copied//Get instance of BulkReadOperations Class
let bulkReadOperations = new ZCRM.BulkRead.Operations();
//Call downloadResult method that takes jobId as parameter
let response = await bulkReadOperations.downloadResult(jobId);
Copiedvar listener = 0;
class DownloadBulkReadResult {

	async downloadBulkReadResult()	{
		var url = "https://www.zohoapis.com/crm/bulk/v2/read/34770619080469/result"
        var parameters = new Map()
        var headers = new Map()
        var token = {
            clientId:"1000.NPY9M1V0XXXXXXXXXXXXXXXXXXXF7H",
            redirectUrl:"http://127.0.0.1:5500/redirect.html",
            scope:"ZohoCRM.users.ALL,ZohoCRM.bulk.read,ZohoCRM.modules.ALL,ZohoCRM.settings.ALL,Aaaserver.profile.Read,ZohoCRM.org.ALL,profile.userphoto.READ,ZohoFiles.files.ALL,ZohoCRM.bulk.ALL,ZohoCRM.settings.variable_groups.ALL"
        }
        var accesstoken = await new DownloadBulkReadResult().getToken(token)
        headers.set("Authorization", "Zoho-oauthtoken " + accesstoken)
        var requestMethod = "GET"
        var reqBody = null
        var params = "";
        parameters.forEach(function(value, key) {
            if (parameters.has(key)) {
                if (params) {
                    params = params + key + '=' + value + '&';
                }
                else {
                    params = key + '=' + value + '&';
                }
            }
        });
        var apiHeaders = {};
        if(headers) {
            headers.forEach(function(value, key) {
                apiHeaders[key] = value;
            });
        }
        if (params.length > 0){
            url = url + '?' + params.substring(0, params.length - 1);
        }
        var requestObj = {
            uri : url,
            method : requestMethod,
            headers : apiHeaders,
            body : JSON.stringify(reqBody),
            encoding: "utf8",
            allowGetBody : true,
			throwHttpErrors : false
        };
        var result = await new DownloadBulkReadResult().makeAPICall(requestObj);
        console.log(result.status)

        var filename;

        var disposition = result.getResponseHeader('content-disposition');//No I18N

        if (disposition && disposition.indexOf('attachment') !== -1) {

            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;

            var matches = filenameRegex.exec(disposition);

            if (matches != null && matches[1]) {

                filename = matches[1].replace(/['"]/g, '');

                filename = filename.replace('UTF-8','');
            }
        }

        let readStream = result.response;

        var url = URL.createObjectURL(readStream);

        var ttt = document.createElement('a');

        ttt.href = url;

        ttt.download = filename;

        ttt.click();

    }

    async getToken(token) {

        if(listener == 0) {

            window.addEventListener("storage", function(reponse) {
                if(reponse.key === "access_token" && (reponse.oldValue != reponse.newValue || reponse.oldValue == null)){
                    location.reload();
                }
                if(reponse.key === "access_token"){

                    sessionStorage.removeItem("__auth_process");
                }
            }, false);
            listener = 1;
            if(sessionStorage.getItem("__auth_process")) {
                sessionStorage.removeItem("__auth_process");
            }
        }
        ["granted_for_session", "access_token","expires_in","expires_in_sec","location","api_domain","state","__token_init","__auth_process"].forEach(function (k) {
            var isKeyExists = localStorage.hasOwnProperty(k);
            if(isKeyExists) {
                sessionStorage.setItem(k, localStorage[k]);
            }
            localStorage.removeItem(k);
        });
        var valueInStore = sessionStorage.getItem("access_token");
        var tokenInit = sessionStorage.getItem("__token_init");
        if(tokenInit != null && valueInStore != null && Date.now() >= parseInt(tokenInit) + 59 * 60 * 1000){ // check after 59th minute
            valueInStore = null;
            sessionStorage.removeItem("access_token");
        }

        var auth_process = sessionStorage.getItem("__auth_process");
        if ((valueInStore == null && auth_process == null) || (valueInStore == 'undefined' && (auth_process == null || auth_process == "true"))) {
            var accountsUrl = "https://accounts.zoho.com/oauth/v2/auth"
            var clientId;
            var scope;
            var redirectUrl;
            if(token != null) {
                clientId = token.clientId;
                scope = token.scope;
                redirectUrl = token.redirectUrl;
            }

            var fullGrant = sessionStorage.getItem("full_grant");
            var grantedForSession = sessionStorage.getItem("granted_for_session");
            if(sessionStorage.getItem("__token_init") != null && ((fullGrant != null && "true" == full_grant) || (grantedForSession != null && "true" == grantedForSession))) {
                accountsUrl += '/refresh';
            }
            if (clientId && scope) {
                sessionStorage.setItem("__token_init", Date.now());
                sessionStorage.removeItem("access_token");
                sessionStorage.setItem("__auth_process", "true");
                window.open(accountsUrl + "?" + "scope" + "=" + scope + "&"+ "client_id" +"=" + clientId + "&response_type=token&state=zohocrmclient&redirect_uri=" + redirectUrl);
                ["granted_for_session", "access_token","expires_in","expires_in_sec","location","api_domain","state","__token_init","__auth_process"].forEach(function (k) {
                    var isKeyExists = localStorage.hasOwnProperty(k);
                    if(isKeyExists){
                        sessionStorage.setItem(k, localStorage[k]);
                    }
                    localStorage.removeItem(k);
                });
                valueInStore = sessionStorage.getItem("access_token");
            }
        }
        if(token != null && valueInStore != 'undefined'){
            token.accessToken = valueInStore;
        }
        return token.accessToken;
    }

    async makeAPICall(requestDetails) {
        return new Promise(function (resolve, reject) {
            var body, xhr, i;
            body = requestDetails.body || null;
            xhr = new XMLHttpRequest();
            xhr.withCredentials = true;
            xhr.open(requestDetails.method, requestDetails.uri, true);
            for (i in requestDetails.headers) {
                xhr.setRequestHeader(i, requestDetails.headers[i]);
            }
            xhr.responseType = "blob";//No I18N
            xhr.send(body);
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4) {
                    resolve(xhr);
                }
            }
        })
    }
}
1.0.14.x.x
CopiedString jobId = 34096432461001n;
String destinationFolder = "/Users/user_name/Documents";

//Get instance of BulkReadOperations Class
let bulkReadOperations: BulkReadOperations = new BulkReadOperations();

//Call downloadResult method that takes jobId as parameter
let response: APIResponse < ResponseHandler > = await bulkReadOperations.downloadResult(jobId);
Copiedimport got from 'got';
import { createWriteStream } from "fs";
class DownloadBulkReadResult {
	public async main()  {
		var apiHeaders: {[key: string]: string} = {};
		var apiParameters: {[key: string]: string} = {};
		var modifiedRequestBody: any;
		apiHeaders["Authorization"] = "Zoho-oauthtoken 1000.xxxxxxx.xxxxxx"
		var requestDetails: {[key: string]: any} = {
			method : "GET",
			headers : apiHeaders,
			searchParams : apiParameters,
			body : modifiedRequestBody,
 			encoding: "utf8",
			allowGetBody : true,
			throwHttpErrors : false
		};
		var response = await got("https://www.zohoapis.com/crm/bulk/v2/read/34770619338001/result", requestDetails);
		console.log(response.statusCode)
		var filepath :string="/User/Downloads"
		var contentDispo :string = response.headers["content-disposition"]
		var filename :string= contentDispo.split( "=")[1]

		if (filename.includes( "''")) {

			filename = filename.split( "''")[1]
		}

		if(filename.includes("\"")){
			let start_index = filename.lastIndexOf("=");
			filename = filename.substring(start_index + 1).replace(/"/g, "");
		}
		filepath = filepath +"/"+filename
		var writeStream = createWriteStream(filepath);
		writeStream.write(response.rawBody)
	}
}
var v = new DownloadBulkReadResult()

v.main()