POST to /services/data/vXX.0/composite with a body containing a 'compositeRequest' array; each sub-request has a 'method', 'url', 'referenceId', and optionally 'body'.
Reference earlier sub-request results in subsequent sub-requests using @{referenceId.field} syntax — for example, use @{newAccount.id} to pass a just-created Account ID into a Contact insert.
Set 'allOrNone': true at the top level if you want the entire batch to roll back on any single sub-request failure; otherwise partial failures proceed and you must inspect each result.
Inspect the 'compositeResponse' array; each element mirrors the sub-request's referenceId, HTTP status code, and body — a 201 means created, a 4xx means that sub-request failed.
Keep the total sub-request count at or below 25 per call; each sub-request still consumes API limits separately.
Validate that SOQL sub-requests use the /query endpoint, not a DML endpoint, and that relationship references resolve within the same composite batch.
Known gotchas
allOrNone interacts with external IDs in upsert sub-requests: a 'matched, no update needed' 204 result is still counted as success, but check that downstream references still resolve.
You cannot mix Composite sub-requests that span different API versions within the same call; the version in the outer URL governs all sub-requests.
If a sub-request makes a callout to an external service, Salesforce will reject the entire composite request — external callouts are not permitted inside composite batches.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp