Skip to content

Zoho: Process multiple API requests in a single call

Zoho compositeRequests.createCompositeRequest: arguments, response, policy and SDK examples.

← Composite requests operations · Get started

Operation zoho.createcompositerequest

Provider route: POST /crm/v8/__composite_requests. Alter supplies the connection’s credentials and routing.

Install @alter-ai/sdk @alter-ai/zoho with npm, or alter-sdk-zoho with pip. Supply your connected customer’s grant ID and the arguments described below.

import { App } from "@alter-ai/sdk";
import { ZohoIntegration } from "@alter-ai/zoho";
async function execute(input: Parameters<ZohoIntegration["compositeRequests"]["createCompositeRequest"]>[0]) {
const app = new App({ apiKey: process.env.ALTER_API_KEY! });
try {
const provider = new ZohoIntegration(app, { grantId: process.env.PROVIDER_GRANT_ID! });
const call = await provider.compositeRequests.createCompositeRequest(input);
const result = await call.wait();
return result.bodyJson();
} finally {
await app.close();
}
}
import os
from alter_sdk import App
from alter_sdk_zoho import ZohoIntegration
async def execute(arguments):
async with App(api_key=os.environ["ALTER_API_KEY"]) as app:
provider = ZohoIntegration(app, {"grant_id": os.environ["PROVIDER_GRANT_ID"]})
call = await provider.composite_requests.create_composite_request(arguments)
result = await call.wait()
return result.body_json()
FieldTypePresenceDescription and constraints
$objectRootAdditional keys: not allowed
bodyobjectRequired within parentSpecify the composite request configuration, including execution options and the array of sub-requests to process.
Additional keys: not allowed
body.__composite_requestsarrayRequired within parentSpecify the API requests to execute as sub-requests within the composite call.
Maximum items: 5
body.__composite_requests[]objectEach itemEach object represents an individual API sub-request, including the HTTP method, URI, and optional headers, parameters, and body.
Additional keys: not allowed
body.__composite_requests[].bodyobjectOptionalSpecify the request body for the sub-request.

> Note
> - Using References in Composite API Requests: You can reference the output of one sub-request in another within the same API call.
> - Reference Structure: `@{sub_request_id:JSONPath}`
> Where,
> - `sub_request_id` is the ID of the sub-request whose response you want to reference.
> - `JSONPath` is the path to the specific field in that response.
> For example, if you create a Lead in one sub-request (sub_request_id : 1) and need to update it in another, you can use `@{1:$.data[0].details.id}` to dynamically fetch the Lead ID from sub-request 1 and use it in sub-request 2 to modify the same record.
> - The `rollback_on_fail` and `parallel_execution` keys cannot both be set to `true`. If both are enabled, the API returns the `AMBIGUITY_DURING_PROCESSING` error.
> - All Delete APIs (except Notification APIs) support only record IDs in the URL. Bulk delete operations are not supported.
> - When `rollback_on_fail` is `false`:
> - Workflows, approvals, and other automation actions are triggered as intended.
> - The Composite API consumes one API credit.
> - When `rollback_on_fail` is `true`:
> - Workflows
> - Automation actions execute only after all sub-requests complete successfully and no rollback occurs. If one or more sub-requests fail and a rollback happens, the automation actions are not triggered.
> - For example, consider the case where a workflow is triggered every time a lead is created with the company name starting with ‘S’. In sub-request 1, a lead is created, whose Company name starts with ‘S’, and sub-request 2 edits the newly created record’s company name so that it does not start with ‘S’. Only after executing both the sub-requests the workflow will be executed. But in this case, the workflow will not be triggered because the newly created Lead’s company name is already updated in sub-request 2, and the criterion for the workflow is not met. Consider another case, where in sub-request 1, a lead is created, whose Company name is ‘Silicon Solutions’, and sub-request 2 edits this newly created record’s website. If none of the other sub-requests change the company name of this newly created record, after executing all the sub-requests successfully, the workflow will be triggered.
> - When a rollback occurs, the Composite API consumes one API credit.
> - When all sub-requests succeed, the Composite API consumes two API credits.
> - Each Composite API request consumes five concurrency credits, regardless of the number of sub-requests.
> - Each composite API reduces the sub-concurrency by one, while the sub-requests consume their respective sub-concurrencies.

### Allowed APIs
The following table gives the list of APIs allowed in a composite request. For these APIs, there are restrictions on the number of records that you can create, update, or delete in a composite request.

| API | No. of records allowed |
| --- | --- |
| Get Org, Get Metadata, Convert a Lead, Get Layout Rules, Get Validation Rules, Get Custom Links, Get/Add/Update Roles, Get Profiles, Get Records’ Count, Get/Update Blueprint, Get Variables/Variable Groups, Get Tags, Add/Remove Tags for a record, Get List of Attachments, Delete Photo, Get Currencies, Get Shared Record Details, Get Assignment Rules, Get/Add/Update Pipeline, Get Wizards, Get List of From Addresses, Delete Notifications | No Restriction |
| Add/Update/Delete Users, Update/Delink Related Records, Add/Delete Variables, Create/Update/Delete Notes, Create/Update/Merge Tags, Add/Update Currency, Add/Update/PATCH Notifications, Create/Update/Upsert/Delete Records | 1 |
| Get Territories, Get Notes, Get Email/Inventory Templates, Get Notifications, Get/Search Records, Get Related Records, Get records through a COQL query, Get Deleted Records, Get Users | 25 |

Additional keys: allowed
body.__composite_requests[].headersobjectOptionalSpecify the HTTP headers for the sub-request. The authorization and x-crm-org headers are restricted and cannot be used.
Additional keys: allowed
body.__composite_requests[].methodstringRequired within parentSpecify the HTTP method for the corresponding sub-request.
Possible values:
GET - Retrieve data from the API.
POST - Create a new resource.
PUT - Update an existing resource.
DELETE - Remove a resource.
PATCH - Partially update a resource.

One of: GET, POST, PUT, DELETE, PATCH
body.__composite_requests[].paramsobjectOptionalSpecify the parameters for the sub-request.
Additional keys: allowed
body.__composite_requests[].sub_request_idstringOptionalSpecify a unique identifier for the sub-request. Use this ID to reference the output of this sub-request. The accepted regex is `[a-zA-Z0-9][a-zA-Z0-9_]`.
Maximum length: 100
Pattern: [a-zA-Z0-9][a-zA-Z0-9_]
body.__composite_requests[].uristringRequired within parentSpecify the URI path of the corresponding sub-request. The URI must follow the pattern /crm/{version}/{endpoint} with the regex `/crm(/.)?/v[0-9]+([.][0-9]+)?/.`.
Maximum length: 2048
Pattern: /crm(/.)?/v[0-9]+([.][0-9]+)?/.
body.parallel_executionbooleanOptionalSpecify whether to process all independent sub-requests (sub-requests with no dependencies/references) in parallel. The default value is true. If “rollback_on_fail” is true, then the default value of this key is false.
Possible values:
true - Execute independent sub-requests in parallel.
false - Execute sub-requests sequentially.
This key cannot be true when rollback_on_fail is true.

Default: true
body.rollback_on_failbooleanOptionalSpecify whether to rollback the composite API request if any of the sub-requests fail. The default value is false.
Possible values:
true - Rollback all operations if any sub-request fails. Workflow automation actions execute only after all sub-requests succeed.
false - Process each sub-request independently without rollback.
This key cannot be true when parallel_execution is true.

Default: false

Response media type: application/json. The table describes the pinned successful response. Referenced models link to their complete fields.

FieldTypePresenceDescription and constraints
$JSONRoot
$ (anyOf 1)objectAlternativeContains the successful response for a composite request where all sub-requests were executed successfully.
Additional keys: not allowed
$ (anyOf 1).__composite_requestsarrayRequired within parentContains the response for each sub-request in the composite call.
Maximum items: 5
$ (anyOf 1).__composite_requests[]objectEach itemEach object represents the response details for an individual sub-request, including the status code, headers, and body from the wrapped API call.
Additional keys: not allowed
$ (anyOf 1).__composite_requests[].codestringRequired within parentRepresents the response code for the sub-request.
Possible values:
SUCCESS - The sub-request was executed successfully.

Known values: SUCCESS
$ (anyOf 1).__composite_requests[].detailsobjectRequired within parentContains the detailed response information for the sub-request, including the HTTP response from the wrapped API call.
Additional keys: not allowed
$ (anyOf 1).__composite_requests[].details.responseobjectRequired within parentContains the response details from the wrapped API call, including the status code, headers, and body.
Additional keys: not allowed
$ (anyOf 1).__composite_requests[].details.response.bodyobjectRequired within parentContains the response body from the wrapped API call.
Additional keys: allowed
$ (anyOf 1).__composite_requests[].details.response.headersobjectRequired within parentContains the response headers from the wrapped API call.
Additional keys: allowed
$ (anyOf 1).__composite_requests[].details.response.status_codeJSONRequired within parent
$ (anyOf 1).__composite_requests[].details.response.status_code (anyOf 1)integerAlternativeRepresents the status code from the wrapped API call.
Format: int32
$ (anyOf 1).__composite_requests[].details.response.status_code (anyOf 2)stringAlternativePattern: ^-?[0-9]+(?:.[0-9]+)?(?:[eE][+-]?[0-9]+)?$
$ (anyOf 1).__composite_requests[].messagestringRequired within parentRepresents the response message for the sub-request.
Maximum length: 1000
$ (anyOf 1).__composite_requests[].statusstringRequired within parentRepresents the status of the sub-request execution.
Possible values:
success - The sub-request was processed successfully.

Known values: success
$ (anyOf 2)objectAlternativeContains the partial success response when some sub-requests succeed and others fail in the composite call.
Additional keys: not allowed
$ (anyOf 2).__composite_requestsarrayRequired within parentContains the mixed success and error responses for individual sub-requests. Each item corresponds to a sub-request and indicates whether it succeeded or failed.
Maximum items: 5
$ (anyOf 2).__composite_requests[]objectEach itemEach object represents the response for an individual sub-request, which may indicate either success or error based on the execution result.
Additional keys: allowed

SDK function policy ID: zoho.createcompositerequest. Catalog operation: createCompositeRequest. Rules can name either ID; function rules distinguish managed calls and conservatively cover raw calls sharing the route. Existing grant permissions and policy rules apply. wait() returns an immediate result or waits for a required approval; it never approves the request itself. Persist the approval ID to resume after a restart.

Refused by default. This operation leaves the caller holding a credential (Marked: a sub-request can be GET /settings/variables, GET /settings/automation/webhooks/{id} or GET /actions/watch, each of which reads a stored credential, and the refusal matches the outer route only.), so Alter refuses it on every connection with credential_minting_refused unless an organization admin allows it: a credential_minting rule naming provider zoho and operation zoho.createcompositerequest (or createCompositeRequest). See Allow an operation that hands over a credential.

Provider errors retain their response; JSON decoding raises ProviderAPIError for provider failures. ManagedOperationError identifies contract/input/retention errors. See error handling and provider-specific behavior. Sensitive input may be refused before approval storage. A decoding error never resubmits a write.

Official provider source

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.