Managing vendor agreements across procurement and finance systems often requires manually downloading executed contracts and attaching them to vendor records. This can become time-consuming and difficult to manage when dealing with a large number of contracts.
In this post, we’ll share a simple automation built using Zoho Flow, Zoho Contracts APIs, and Zoho Books that connects procurement, legal, and finance workflows.
This integration automatically:
- Creates counterparties and contracts in Zoho Contracts when a vendor is added in Zoho Books
- Detects when a contract is executed in Zoho Contracts
- Downloads the executed contract
- Attaches the signed contract to the vendor record in Zoho Books
This enables a seamless Procure-to-Pay vendor contract workflow and demonstrates how Zoho Contracts can be integrated with finance systems to streamline vendor agreement management.
Business Use Case – Procure to Pay
A typical vendor agreement lifecycle involves:
- Vendor onboarding in Zoho Books
- Contract creation, negotiation, and execution in Zoho Contracts
- Executed agreement available for the finance team’s reference
Without automation, finance teams must manually download the executed agreement and attach it to the vendor record.
Prerequisites
Before implementing this automation, ensure the following setup is completed:
- Zoho Books and Zoho Contracts are configured in your organization
- Zoho Flow is enabled and connected to both Zoho Books and Zoho Contracts
- API connections are configured for Zoho Books and Zoho Contracts in Zoho Flow
- Appropriate permissions are available to create counterparties and contracts in Zoho Contracts
- Additionally, create a custom field in Zoho Books (Vendor module) to store the Zoho Contracts Counterparty API Name.
Example:
- Field Name: Contracts Counterparty ID
- Field Type: Text
- Module: Vendors
This field helps map vendors in Zoho Books with their corresponding counterparties in Zoho Contracts.
Solution Overview
Zoho applications involved:
- Zoho Contracts
- Zoho Books
- Zoho Flow
The automation is implemented using two flows.
Flow 1 – Vendor Creation → Contract Creation
Trigger: A new vendor is created in Zoho Books.
Actions:
- Zoho Flow detects the new vendor.
- A custom function checks whether a corresponding counterparty exists in Zoho Contracts
- If the counterparty does not exist, a new counterparty is created in Zoho Contracts
- The counterparty API name is stored in Zoho Books
- A contract is automatically created in Zoho Contracts for that vendor
Custom Function Snippet (Create Counterparty and Contract):
Note: The custom functions shared below are working reference implementations. However, depending on your environment, you may need to update certain values before using them in your setup.
Please review and update the following as applicable:
- Connection names used in the invokeurl statements
- Organization ID used for Zoho Books API calls
- Custom field API names used to store the Counterparty reference in Zoho Books
- Contract type API names configured in Zoho Contracts
Ensure these values are updated according to your configuration before deploying the automation
.
- map createContract1(string vendorName, string vendorID, string counterpartyID)
- {
- result = Map();
- createdCounterPartyAPIName = "";
- if(counterpartyID != null && counterpartyID != "")
- {
- existingCounterpartyResponse = invokeurl
- [
- url :"https://contracts.zoho.in/api/v1/counterparties/" + counterpartyID
- type :GET
- connection:"zcontractsconn"
- ];
- if(existingCounterpartyResponse.get("counterparty") != null)
- {
- createdCounterPartyAPIName = existingCounterpartyResponse.get("counterparty").get("apiName");
- }
- }
- if(createdCounterPartyAPIName == "")
- {
- counterpartyMap = Map();
- counterpartyMap.put("name",vendorName);
- counterpartyMap.put("counterPartyType","vendor");
- createResponse = invokeurl
- [
- url :"https://contracts.zoho.in/api/v1/counterparties"
- type :POST
- parameters:counterpartyMap.toString()
- connection:"zcontractsconn"
- ];
- counterpartyDetail = createResponse.getJSON("counterparties").get(0);
- createdCounterPartyAPIName = counterpartyDetail.get("organizationApiName");
- customFields = List();
- cf = Map();
- cf.put("api_name","cf_contracts_counterparty_id");
- cf.put("value",createdCounterPartyAPIName);
- customFields.add(cf);
- updateMap = Map();
- updateMap.put("custom_fields",customFields);
- updateVendor = invokeurl
- [
- url :"https://books.zoho.in/api/v3/vendors/" + vendorID + "?organization_id=60047651581"
- type :PUT
- parameters:updateMap
- connection:"zbooks"
- ];
- }
- info "STEP 4 STARTED - Preparing Contract Variables";
- newContractType = "master-subscription-agreement-pro-plus";
- newContractName = "Agreement with " + vendorName;
- isNewContractTermIsDefinite = false;
- isNewContractRenewable = false;
- contractEffectiveDate = 1;
- info "Contract Type: " + newContractType;
- info "Contract Name: " + newContractName;
- info "Counterparty API Name: " + createdCounterPartyAPIName;
- newContractDetail = {"externalSource":true,"inputfields":{{"metaApiName":"contract-type","inputs":{{"inputApiName":"contract-type","inputValue":newContractType}}},{"metaApiName":"contract-term","inputs":{{"inputApiName":"contract-term","inputValue":isNewContractTermIsDefinite}}},{"metaApiName":"is-renewable","inputs":{{"inputApiName":"is-renewable","inputValue":isNewContractRenewable}}},{"metaApiName":"title","inputs":{{"inputApiName":"title","inputValue":newContractName}}},{"metaApiName":"party-b-name","inputs":{{"inputApiName":"party-b-name","inputValue":createdCounterPartyAPIName}}},{"metaApiName":"contract-effective-date","inputs":{{"inputApiName":"contract-effective-date","inputValue":contractEffectiveDate}}}}};
- createContractResponse = invokeurl
- [
- url :"https://contracts.zoho.in/api/v1/createcontract"
- type :POST
- body:newContractDetail.toString()
- headers:{"Content-Type":"application/json"}
- connection:"zcontractsconn"
- ];
- info createContractResponse;
- result.put("counterpartyApiName",createdCounterPartyAPIName);
- result.put("contractResponse",createContractResponse);
- return result;
- }
Flow 2 – Contract Execution → Attach Signed Agreement
Trigger: Contract signing is completed in Zoho Contracts
Actions:
- Zoho Flow detects the contract execution event
- A custom function calls the Zoho Contracts API to download the executed contract document.
- The function identifies the corresponding vendor in Zoho Books.
- The executed agreement is automatically attached to the vendor record in Zoho Books.
Custom Function Snippet (Retrieve and Attach Signed Contract):
- map attachSignedContractToVendor(string contractApiName, string contractTitle)
- {
- result = Map();
- orgID = "60047651581";
- info "FLOW 2 STARTED";
- info contractApiName;
- info contractTitle;
- if(contractApiName.startsWith("contract/"))
- {
- contractApiName = contractApiName.replaceAll("contract/","");
- }
- info "Clean Contract API Name: " + contractApiName;
- if(contractTitle.startsWith("Agreement with "))
- {
- vendorName = contractTitle.subString(15);
- }
- else
- {
- vendorName = contractTitle;
- }
- info "Vendor Extracted: " + vendorName;
- vendorSearch = invokeurl
- [
- url :"https://books.zoho.in/api/v3/contacts?contact_name=" + vendorName + "&organization_id=" + orgID
- type :GET
- connection:"zbooks"
- ];
- info vendorSearch;
- contactsList = vendorSearch.get("contacts");
- if(contactsList == null || contactsList.size() == 0)
- {
- info "Vendor not found";
- result.put("status","vendor_not_found");
- return result;
- }
- vendorID = contactsList.get(0).get("contact_id");
- info "Vendor ID: " + vendorID;
- info "Downloading signed contract";
- signedFile = invokeurl
- [
- url :"https://contracts.zoho.in/api/v1/download/contracts/" + contractApiName + "/signed/document"
- type :GET
- connection:"zcontractsconn"
- ];
- info signedFile;
- fileMap = Map();
- fileMap.put("attachment",signedFile);
- fileMap.put("organization_id",orgID);
- info "Uploading attachment to Zoho Books";
- uploadResponse = invokeurl
- [
- url :"https://books.zoho.in/api/v3/contacts/" + vendorID + "/attachment?organization_id=" + orgID
- type :POST
- parameters:fileMap
- connection:"zbooks"
- content-type:"multipart/form-data"
- ];
- info uploadResponse;
- result.put("uploadResponse",uploadResponse);
- info "FLOW 2 COMPLETED";
- return result;
- }
Benefits
- This automation provides several advantages:
- Eliminates manual document handling
- Ensures finance teams always have access to executed agreements
- Connects legal and finance workflows
- Improves compliance and audit readiness
- Reduces operational friction
Closing
If you're implementing Procure-to-Pay contract workflows, this approach can help streamline the connection between Zoho Contracts and finance systems like Zoho Books.
We’d be happy to discuss variations of this implementation or answer any questions.
If you're planning to implement a similar workflow and need guidance, feel free to reach out to the Zoho Contracts support team at
support@zohocontracts.com.
.
Stay tuned for more tips, tricks, and automation ideas around Zoho Contracts.
Cheers,
Sathyakeerthi
Zoho Contracts Team
Recent Topics
Picklist values out-of-date in Campaigns
Hi I use a CRM (Global) picklist set of values for my field "Connection Strength" (see screenshot 1). . I use Campaigns to follow-up and change the Connection Strength value depending on their stage. The picklist values that appear in the dropdown for
Refering cell from other sheet
Hi, If we want to refer any cell in the same sheet its very easy, like suppose if I want to refer cell A2 in P7 I just need to type =A2 in P7, similarly how can I refer a cell present in different sheet ( I mean refer cell A2 from Sheet1 into Sheet2) Thanks
How to keep track of bags, cans, drums of inventory?
We buy and sell products that are packaged in bags 🛍️, cans🥫, drums🛢️, etc. with batch numbers. When we get a shipment of one of the products, how do we track we received (say) 10 cans each of 5L of a product and maybe we received 10 cans of another
Global/Overall Reports & Dashboards in Zoho Sprints
Hi, Do we have an option to refer Global Level Reports & Dashboards in Zoho Sprints? We could see that we have Project specific Reports & Dashboards inside every Project. However, for a management level we want Reports & Dashboards visibility at a Global
Important Update: New Fields Addition in Zoho Sprints Integration
We'd like to inform you of an upcoming update to the 'Timesheets' module in the Zoho Sprints integration from June 3, 2026. To enhance time tracking and reporting accuracy for the Zoho Sprints integration, three new fields - Log Type, Meeting ID, Release
Custom Buttons & Links Now Supported in Portals
We’ve just made portals in Zoho Recruit more powerful and customizable than ever! You can now bring the power of Custom Buttons and Links to your Candidate, Client, Vendor, and Custom Portals, enabling portal users to take direct action without recruiter
Packaged Weight And Dimensions
Hello, we have item weight and dimensions, please add packaged weight and dimensions. Thank you
Nome do Agente não aparece nas conversas do whatsapp para o nosso cliente
Nome do Agente não aparece nas conversas do whatsapp para o nosso cliente! Isso é ruim pois so,os em 5 agentes e o cliente fica sem saber com quem ele está falando, pois tentei procurar configurações que pudessem ter esta opção, mas até então não encontrei.
Marketing Plus : quatre ans à réinventer la simplicité des opérations marketing
Pourquoi et comment ? Il y a exactement quatre ans, nous avons démarré simplement, avec une seule vision: unifier et simplifier les opérations marketing pour les équipes marketing de tous les secteurs. Chez Zoho, nous proposons des outils dédiés à chaque
hide resolution from help centre
to my surprise, i just found out that the resolution text is public in the helpcenter, even if 'notify customer' is off. is there a workaround to that? how do others deal with this? How zoho support does this and I don't think its used by Zoho in the first place. the resolution is meant to be private, not public
Zoho Desk - Event Calendar View
Hi Desk team, Are there any plans to introduce a calendar or timeline view for Events in Zoho Desk? It would be very helpful if we could see Events visually in a calendar and/or timeline. This is very helpful when desk side support activities need to
Pasting Images in Zoho Desk ignores cursor location
My team has reported an issue which started recently where when we paste an image into a new or existing reply or comment, the pasted image seems to ignore the current cursor location instead paste itself at the last character present in the reply/comment,
Enrich your contact and company details automatically using the Data Enrichment topping
Greetings, I hope you're all doing well. We're happy to announce the latest topping we've added to Bigin: The Data Enrichment topping, powered by WebAmigo. This topping helps you automatically enhance your contact and company records in Bigin. By leveraging
Financial manger
why is transaction locking for zoho I Can't closing period
API usage
My application has bad implementation and code that is resulting in very high API usage. This is my first time experiencing something like this. Does anyone know how I can troubleshoot and fix this?
Disabled page
Hello, When I try to to run Inventory Valuation Summary and FIFO Cost Lot Tracking reports, I get This page is disabled error. I tried everything in settings, cant find the settings to enable. Help me.
Setting defaults for "Find and Merge Duplicate for..."
To remove some of the extreme tedium from Zoho's poorly implemented merge function, I would like to set defaults. Currently I am defaulted to match "ANY" when I would never do that, so I always have to click "ALL". Then it makes me click on several totally irrelevant drop boxes to turn off phone, mobile and other useless match criteria. Is there a way I can set: Match to default as "ALL" Firstname to default to "IS" Lastname to default to "IS" every other match field default to "-NONE-" This will
Linux agent 2026_M05 release notes
Agent Version: 3.6.5.3 Release date: 28 April, 2026 Major Enhancement: Quick Support feature release. Security improvements and enhancement to in session features.
Automated Sales Order Fulfillment Based on Inventory Availability (Allocation / Commitment Modes)
Hi everyone, I recently reached out to Zoho Inventory support regarding a workflow challenge and wanted to share both the issue and their response here for visibility. Zoho confirmed: “Zoho Inventory does not currently support automatic notifications
Linux agent 2026_M04 release notes
Agent Version: 3.6.5.2 Release date: 30 April, 2026 Code refactoring and improvements to function efficiently in minimal hardware environments.
Simple Totals on all pages?
Hi there. I'm surprised this isn't implemented yet (since most other software has this by default). Can you display a simple total at the bottom of all invoice lists? ie: I click in SALES tab, select INVOICES and on that page please show us a simple total? Yes, I realize I can go the long way around and generate reports and select my date options and select the type of invoices etc...but honestly that shouldn't be necessary when just viewing a list of unpaid invoices and how much total is outstanding.
Linux agent 2026_M03 release notes
Agent Version: 3.6.5.1 Release date: 27 February, 2026 Bug fixes and performance improvements for optimised session experience.
Linux agent 2026_M02 release notes
Agent Version: 3.6.5.0 Release date: 26 February, 2026 Major enhancement: File Manager feature release Issue fixing of idle session timing interfering with backend activities.
Linux agent 2026_M01 release notes
Agent Version: 3.6.4.8 Release date: 13 February, 2026 Optimised the unattended agent uninstallation process to properly cleanup residual files and complete uninstallation process. Fixed issues with CTRL+ALT+DEL command not functioning properly in some
Using API for multiple organizations
I am busy building an app to load data from a retailer into Zoho Books. We are planning on selling the app to multiple organizations that use this retailer. Is there a way to get a single oauth app to access multiple organizations? From what I can find
MacOS agent 2026_M04 release notes
Agent Version: 3.120.0 Release date: 23 April, 2026 Retry mechanism for end users to enable Accessibility and Screen Share permissions to successfully join remote sessions. Agent stickiness on multiple desktops to avoid confusion. Improvements to audio
MacOS agent 2026_M03 release notes
Agent Version: 3.117.0 Release date: 02 March, 2026 Bug fixes and performance improvements for optimised session experience.
MacOS agent 2026_M02 release notes
Agent Version: 3.116.0 Release date: 23 February, 2026 Major enhancement: File Manager feature release Minor enhancement: Improved peer to peer connectivity across various network conditions. Minor enhancement: Improvements to Elevate to Admin mode
MacOS agent 2026_M01 release notes
Agent Version: 3.111.0 Release date: 11 February, 2026 Major Enhancement: Quick Support feature release. Upgrades to monitoring protocols for analysing performance. Issue fixing of idle session timing interfering with backend activities.
Account Unblock Request
Dear Sir/Madam, I hope you are doing well. I noticed that my account has been blocked for violation of the usage policy which I believe comes from it being associated with sending spam. I have since then removed the old keys which were compromised in
Kaizen #242 Enabling In-Context Order Creation from Deals Using SlyteUI
Hello everyone! Welcome to another interesting Kaizen post. Today’s spotlight is on SlyteUI, the new UI builder designed to create powerful, intuitive user interfaces in minutes. Built for speed and simplicity, SlyteUI empowers teams to deliver high-impact
Auto-sync field of lookup value
This feature has been requested many times in the discussion Field of Lookup Announcement and this post aims to track it separately. At the moment the value of a 'field of lookup' is a snapshot but once the parent lookup field is updated the values diverge.
CRM gets location smart with the all new Map View: visualize records, locate records within any radius, and more
Hello all, We've introduced a new way to work with location data in Zoho CRM: the Map View. Instead of scrolling through endless lists, your records now appear as pins on a map. Built on top of the all-new address field and powered by Mappls (MapMyIndia),
Can't access google from toppings menu
So... When I click the manage button in toppings, nothing happens. it won't let me access the settings.
Best sales insights for target accounts?
Question for all the sales power-users out there: I would like to gain insights from Zoho CRM for a rotating list of target accounts. Each Outside Salesperson has 5 target accounts, and they can change these targets quarterly with management approval.
Emails Disappearing From Inbox
I am experiencing the unnerving problem of having some of the messages in my inbox just disappear. It seems to happen to messages that have been in there for longer than a certain amount of time (not sure how long exactly). They are usually messages that I have flagged and know I need to act on, but have not gotten around to doing so yet. I leave them in my inbox so I will see them and be reminded that I still need to do something about them, but at least twice now I have opened my inbox and found
Cadence not stopping on reply (in some cases) – anyone else?
Hi everyone, we’ve noticed that in a few cases, Cadences don’t stop even though the contact replied (setting “stop on reply” is active). It works fine most of the time, but occasionally the reply is visible in CRM without stopping the Cadence. Our assumption
Issue with Resume Parsing and Storage Limit in Zoho Recruit
Hello Team, We are currently facing an issue with resume parsing in Zoho Recruit. While parsing resumes, we are receiving a message indicating that the storage is full. We would like to delete multiple old resumes from the system to free up storage space.
BUG: Related List Buttons with Client Script action now erroring
There appears to have been a bug introduced over the last few days with Related List buttons that invoke a Client Script action. Button configuration: Configured Client Script: Results: The default loader is presented at the top of the page, and an error
SalesIQ Email Delivery Issues to Microsoft
Is anyone else having delivery issues to Hotmail, Outlook, and Live inboxes when sending transcripts and replies via email from SalesIQ? We’ve detected that emails sent from SalesIQ to these accounts aren't arriving—they don’t even bounce back; they simply
Next Page