Create Function
Purpose
Use this API to create a function in your Zoho CRM account.
You can create Deluge, Java, Node.js, or Python functions by specifying the required function metadata and code. Deluge functions can be specified as JSON-embedded code (_code) or uploaded as a .ds file, while Java, Node.js, and Python functions require a ZIP code package.
Endpoints
- POST /settings/functions
Request Details
Request URL
{api-domain}/crm/{version}/settings/functions
Header
Authorization: Zoho-oauthtoken d92d4xxxxxxxxxxxxx15f52
Scope
ZohoCRM.settings.functions.ALL
(or)
ZohoCRM.settings.functions.CREATE
(or)
ZohoCRM.settings.CREATE
Request Body
This API accepts a multipart/form-data request with the following form-data parameters:
- metadatatext, mandatory
Specify the function metadata in JSON format. Refer to the Input JSON section for the complete schema.
- codefile, optional
Upload the function implementation. For Deluge functions, upload a Deluge script (.ds) file. For Java, Node.js, and Python runtimes, upload the function package as a ZIP file. If you do not specify the code parameter, the function will be created without an implementation.
The maximum supported file size for the code form-data parameter is 25 MB. For the ZIP package requirements and runtime-specific package structure, refer to the ZIP Package Requirements and ZIP Package Structure sections.
Note
- You can create up to 20,000 functions per organization.
- For Deluge functions, you can specify the function implementation using the _code key or upload it as a Deluge script (.ds) file using the code form-data parameter.
- If both code and _code are specified, the code file takes precedence and the _code value will be ignored.
- If neither _code nor code is specified for a Deluge function, the function is created in the active state with a default implementation based on the function name, category, and default return type.
For example, if the function name is Cleanup Duplicates and the category is Standalone, the default implementation is:
string standalone.cleanup_duplicates()
{
return "";
}
Sample Request
Copiedcurl "https://www.zohoapis.com/crm/v8/settings/functions"
-X POST
-H "Authorization: Zoho-oauthtoken 1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf"
-F "metadata=@function.json;type=application/json"Input JSON
The metadata form-data parameter accepts the following JSON object:
- functionsJSON array, mandatory
Specify the details of the function. The functions array must contain exactly one object with the following keys:
- namestring, mandatory
Specify the display name of the function. The name must start with a letter and can contain only letters, digits, spaces, hyphens (-), and underscores (_). The name must be between 3 and 100 characters long.
- api_namestring, mandatory
Specify the unique API name of the function. It must start with a letter and can contain only letters, digits, hyphens (-), and underscores (_). The api_name must be between 3 and 100 characters long.
- descriptionstring, optional
Specify a description for the function. The description can be up to 3000 characters long.
- runtimestring, mandatory
Specify the runtime used to execute the function. The following table lists the possible runtime values and the categories supported by each runtime:
Runtime Supported Categories Deluge 1.0 Button, Automation, Schedule, Related List, Standalone, Signals, Validation Rule Java 8 Button, Automation, Schedule, Related List, Standalone Java 17 Button, Automation, Schedule, Related List, Standalone NodeJS 8 Button, Automation, Schedule, Related List, Standalone NodeJS 22 Button, Automation, Schedule, Related List, Standalone Python 3.12 Button, Automation, Schedule, Related List, Standalone - categorystring, mandatory
Specify the category based on how you want to use the function in CRM. Each category determines the CRM feature or context in which the function can be associated or invoked.
Possible values: Button, Automation, Schedule, Related List, Standalone, Signals, Validation Rule
Refer to the Categories and Return Types table for the category descriptions and supported return types.Category Description Allowed Return Types Default Return Type Button Functions that can be associated with a custom button. string string Automation Functions that can be associated with automation features such as workflows, blueprints, approvals, and Command Center. void, string void Schedule Functions that can be associated with a scheduler. void void Related List Functions that can be associated with a related list. string string Standalone Functions that can be invoked independently or from other functions. string string Signals Functions that can be associated with CRM Signals. void void Validation Rule Functions that can be associated with a validation rule. map map - _codestring, optional
Specify the complete Deluge function definition as a JSON string. This key is applicable only when the runtime is Deluge 1.0. You can either specify the implementation using this key or upload a Deluge script (.ds) file using the code form-data parameter. When the implementation is provided using either method, the function is automatically published.
The function declaration in the code must use the function's name in lowercase, with spaces replaced by underscores, followed by the category name in lowercase, with spaces replaced by underscores. The maximum possible length of the _code key value is 2097152 characters.
Paste your Deluge function below to convert it to a JSON string that you can use as the value of the _code key.
Note: This tool converts the code to a JSON string. Do not apply URL encoding or form URL encoding to the converted value.For Java, NodeJS, and Python functions, you must upload the function package as a ZIP file using the code form-data parameter.
- publishJSON object, optional
Specify the publish configuration for the function.
For Deluge functions, specifying this object records the changelog for the published revision. Deluge functions are published automatically regardless of whether this object is specified or not.
For Java, Node.js, and Python functions, specifying this object attempts to publish the function after it is created. If this object is omitted, the function is created in the unpublished state. In that case, you can use the Publish Function API to publish the function later.- changelogstring, optional
Specify the changelog message to associate with the published version of the function.
Sample Input
Copied{
"functions": [
{
"name": "restoreDealByNameTest",
"description": "To clean up duplicate groups",
"category": "Standalone",
"api_name": "restoreDealByNameTest",
"runtime": "Deluge 1.0",
"_code": "string standalone.restoreDealByNameTest(String deal_name,Int days)\n{\n// Step 1: Query the Recycle Bin\nresponse = invokeurl\n[\n\turl :\"https://www.zohoapis.com/crm/v8/settings/recycle_bin\"\n\ttype :GET\n\tconnection:\"crm_oauth_connection\"\n];\nrecycleBinRecords = response.get(\"recycle_bin\");\nif(recycleBinRecords == null || recycleBinRecords.size() == 0)\n{\n\treturn \"No records found in Recycle Bin.\";\n}\n// Step 2: Calculate the lookback date\nlookbackDate = zoho.currentdate.subDay(days);\n// Step 3: Find the Deal matching name and deleted within the last X days\nmatchedRecordId = \"\";\nmatchedDisplayName = \"\";\ntrimmedName = deal_name.trim().toLowerCase();\nfor each record in recycleBinRecords\n{\n\tdisplayName = record.get(\"display_name\");\n\tmoduleApiName = record.get(\"module\").get(\"api_name\");\n\tdeletedTimeStr = record.get(\"deleted_time\");\n\t// Convert deleted_time string to date\n\t// Format from API: \"2026-03-16T17:03:06+05:30\"\n\t// Extract just the date part for comparison\n\tdeletedDateStr = deletedTimeStr.subString(0,10);\n\tdeletedDate = deletedDateStr.toDate(\"yyyy-MM-dd\");\n\tif(moduleApiName == \"Deals\" && displayName.trim().toLowerCase().contains(trimmedName) && deletedDate >= lookbackDate)\n\t{\n\t\tmatchedRecordId = record.get(\"id\");\n\t\tmatchedDisplayName = displayName;\n\t\tbreak;\n\t}\n}\nif(matchedRecordId == \"\")\n{\n\treturn \"No Deal found in Recycle Bin matching name: \" + deal_name + \" within the last \" + days + \" days.\";\n}\n// Step 4: Restore the matched Deal\nrestoreUrl = \"https://www.zohoapis.com/crm/v8/settings/recycle_bin/\" + matchedRecordId + \"/actions/restore\";\nrestoreResponse = invokeurl\n[\n\turl :restoreUrl\n\ttype :POST\n\tconnection:\"crm_oauth_connection\"\n];\n// Step 5: Parse and return the result\nrestoreResult = restoreResponse.get(\"recycle_bin\");\nif(restoreResult != null)\n{\n\tfirstResult = restoreResult.get(0);\n\tstatus = firstResult.get(\"status\");\n\tcode = firstResult.get(\"code\");\n\tif(status == \"success\" && code == \"SUCCESS\")\n\t{\n\t\treturn \"Deal '\" + matchedDisplayName + \"' successfully restored. Record ID: \" + matchedRecordId;\n\t}\n\telse if(code == \"SCHEDULED\")\n\t{\n\t\treturn \"Deal '\" + matchedDisplayName + \"' restoration scheduled as background job. Record ID: \" + matchedRecordId;\n\t}\n\telse\n\t{\n\t\treturn \"Restore failed. Response: \" + restoreResponse.toString();\n\t}\n}\nreturn \"Unexpected response: \" + restoreResponse.toString();\n}"
}
]
}Note
- For Deluge functions:
- The function declaration in the code must use the function's name in lowercase, with spaces replaced by underscores, followed by the category name in lowercase, with spaces replaced by underscores. For example, a function named Restore Deal By Name in the Standalone category must use the declaration string standalone.restore_deal_by_name(...).
- The return type in the function declaration must match the default return type for the selected category. Refer to the Categories and Return Types table for the allowed and default return types.
- For Java, Node.js, and Python functions:
- Upload the function implementation as a ZIP file using the code form-data parameter.
- If publishing fails due to compilation errors, the function is saved as a draft and the API returns a 207 Partial Success response.
ZIP Package Requirements
The following requirements apply when uploading a ZIP package using the code form-data parameter:
- The file must be in .zip format and must not exceed 25 MB.
- The ZIP file can contain a maximum of 10,000 entries, and the maximum size of an individual extracted file is 25 MB.
- The filename must be unique.
- The filename can contain only letters and numbers and must not exceed 255 characters.
- The function ZIP package must follow the runtime-specific folder structure described in the ZIP Package Structure section.
ZIP Package Structure
The Function ZIP package must follow the runtime-specific folder structure described below.
Java and Python
<function-folder>/
├── <function-name>.java
├── lib/
└── config.json
Node.js
<function-folder>/
├── <function-name>.js
├── node_modules/
└── config.json
For more details, please refer to our Functions help guide here.
Possible Errors
- COMPILATION_ERRORHTTP 400
Function have compilation errors
Resolution: Resolve the compilation errors returned in the response, and then retry the request. - API_NOT_SUPPORTEDHTTP 400
API not supported for client portal user
Resolution: This API is not supported for Client Portal users. Use a supported CRM user account to access this API. - REQUIRED_PARAM_MISSINGHTTP 400
Mandatory param missing
Resolution: Specify the mandatory metadata form-data parameter, and then retry the request. - DUPLICATE_DATAHTTP 400
- Duplicate name
Resolution: Specify a unique value for the name key and retry the request. - Duplicate API name
Resolution: Specify a unique value for the api_name key and retry the request. - Code package with the same file name already exists
Resolution: Ensure that the uploaded ZIP file has a unique filename, and then retry the request.
- Duplicate name
- FEATURE_NOT_ENABLEDHTTP 400
Feature is not enabled yet
Resolution: Enable the required feature for your organization, and then retry the request. - NOT_ALLOWEDHTTP 400
_code not allowed
Resolution: The _code key is supported only for Deluge functions. For Java, Node.js, and Python functions, upload the function package using the code form-data parameter. - LIMIT_EXCEEDEDHTTP 400
Function creation limit reached
Resolution: Your organization has reached the limit of 20,000 functions. Reduce the number of functions in your CRM account, and then retry the request. - DUPLICATE_DATAHTTP 400
A code package with the same file name already exists.
Resolution: Rename the code package file and retry the request. - CANNOT_PROCESSHTTP 400
- Unable to process your request
Resolution: Retry the request after some time. If the issue persists, contact Zoho Support. - Initial function creation is restricted to administrators
Resolution: Create the first function using an administrator account, and then retry the request.
- Unable to process your request
- INVALID_DATAHTTP 400
Invalid data
Resolutions:Refer to the message in the response for details about the invalid data, and resolve the issue accordingly. Here are a few possible resolutions:
- Verify that the metadata form-data parameter contains a valid JSON object, and then retry the request.
- Specify a valid value for the category key. Supported values are Button, Automation, Schedule, Related List, Standalone, Signals, and Validation Rule.
- Specify a valid value for the runtime key. Supported values are Deluge 1.0, Java 8, Java 17, NodeJS 8, NodeJS 22, and Python 3.12.
- Verify that the uploaded ZIP package is valid and not corrupted, and then retry the request.
- INVALID_REQUEST_METHODHTTP 400
The http request method type is not a valid one
Resolution: This API supports only the POST method. Retry the request using the POST method. - OAUTH_SCOPE_MISMATCHHTTP 401
Unauthorized
Resolution: Client does not have the required OAUTH SCOPE. Create a new token with valid scopes. Refer to the Scope section for more details. - NO_PERMISSIONHTTP 403
Permission denied
Resolution: Ensure that the user making the API call has the Manage Automation permission enabled in their CRM profile, and then retry the request. - 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 the Request URL section for more details. - FILE_SIZE_EXCEEDSHTTP 413
File size exceeds
Resolution: Reduce the size of the uploaded function package or Deluge script and retry the request. - INTERNAL_ERRORHTTP 500
Internal Server Error
Resolution: Unexpected and unhandled exception in Server. Contact support team.
Sample Response
Copied{
"functions": [
{
"code": "SUCCESS",
"details": {
"id": "4876876000025052002"
},
"message": "function created successfully",
"status": "success"
}
]
}