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:

      RuntimeSupported Categories
      Deluge 1.0Button, Automation, Schedule, Related List, Standalone, Signals, Validation Rule
      Java 8Button, Automation, Schedule, Related List, Standalone
      Java 17Button, Automation, Schedule, Related List, Standalone
      NodeJS 8Button, Automation, Schedule, Related List, Standalone
      NodeJS 22Button, Automation, Schedule, Related List, Standalone
      Python 3.12Button, 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.

      CategoryDescriptionAllowed Return TypesDefault Return Type
      ButtonFunctions that can be associated with a custom button.stringstring
      AutomationFunctions that can be associated with automation features such as workflows, blueprints, approvals, and Command Center.void, stringvoid
      ScheduleFunctions that can be associated with a scheduler.voidvoid
      Related ListFunctions that can be associated with a related list.stringstring
      StandaloneFunctions that can be invoked independently or from other functions.stringstring
      SignalsFunctions that can be associated with CRM Signals.voidvoid
      Validation RuleFunctions that can be associated with a validation rule.mapmap
    • _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.

      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.
  • 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.
  • 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"
        }
    ]
}