Data plane
Data-plane commands call third-party services through Truto using credentials on an integrated account. Every call requires an account ID via -a, --account (except capabilities when targeting an integration).
Unified API
Normalized resources across integrations (consistent field names).
# List CRM contacts
truto unified crm contacts -a <account-id>
# Get one record
truto unified crm contacts <contact-id> -m get -a <account-id>
# Create
truto unified crm contacts -m create -a <account-id> -b '{"first_name":"Jane"}'
# Query params (comma-separated key=value, or JSON object)
truto unified crm contacts -a <account-id> -q "limit=10,status=active"
truto unified crm contacts -a <account-id> --query-json '{"limit":10}'
# Stdin body
echo '{"first_name":"Test"}' | truto unified crm contacts -m create -a <account-id> --stdinArguments: <model> (e.g. crm, ats), <resource> (e.g. contacts), optional [id]
A body given with -b or --stdin must be one JSON object (for unified, proxy and custom, which pass it on to the provider, a JSON list too); anything else is refused with exit 1 and nothing is sent. The refusal never quotes the text, which can hold a token.
Use unified when you want Truto's normalized schema across vendors. Use proxy for integration-specific fields or APIs not in the unified model.
Proxy API
Raw integration resources without normalization.
truto proxy tickets -a <account-id>
truto proxy tickets T-42 -m get -a <account-id>
truto proxy tickets -m create -a <account-id> -b '{"subject":"Bug report"}'
# Custom method → POST /proxy/tickets/custom-action
truto proxy tickets -m custom-action -a <account-id> -b '{"key":"value"}'For proxy and unified, -m names a Truto method. list, get, create, update and delete are matched in any case, so -m DELETE is delete. Any other name is a custom method, sent as typed. The resource, the record id and a custom method's name are each sent as one encoded path segment. A name or id that would read as . or .. is refused, and so is an empty id. list, create and custom methods have no id in their route, so an id given to one is refused rather than dropped. A query that names another integrated_account_id than --account is refused.
Custom API
User-defined custom endpoints on Truto:
truto custom /my-endpoint -a <account-id>
truto custom /my-endpoint -m POST -a <account-id> -b '{"key":"value"}'
truto custom /my-endpoint -a <account-id> -H "X-Custom-Header=value"A path with a . or .. segment (also percent-encoded), or one the URL parser would resolve outside /custom, is refused before anything is sent: it would leave /custom for another route. The parser reads \ as / and drops tabs and a trailing space, so /..\integration/x, /%2e%2e\integration/x and '.. ' are refused too.
Batch
Multiple operations in one request (same resource format as sync jobs):
truto batch requests.json
truto batch -b '{"integrated_account_id":"<id>","resources":[
{"resource":"contacts","method":"list"},
{"resource":"companies","method":"list"}
]}'
cat batch.json | truto batch --stdinEach entry: resource, method, optional query, body, id, persist (set persist: true on proxy resources to include results in the response).
Test mapping locally
Evaluate a response_mapping JSONata expression against a sample raw API response — no integrated account or third-party call:
# Inline mapping + sample file
truto unified test-mapping \
--mapping '$map(results, function($r) { $merge([$r, {"id": $string($r.id)}]) })' \
--input sample-response.json
# Fetch mapping from the platform, then evaluate
truto unified test-mapping \
--model crm --resource contacts --integration salesforce \
--method list \
--input sample-response.json
# Overlay environment-specific overrides
truto unified test-mapping \
--model crm --resource contacts --integration salesforce \
--with-overrides <env-unified-model-id> \
--input sample-response.json \
--show-mapping
cat sample-response.json | truto unified test-mapping \
--mapping-file expr.jsonata --stdinPass query context into the mapping as $query / $rawQuery with -q, --query-json, or --query-file (same as live unified calls). Operator-based mappings cannot be evaluated locally yet — the CLI prints the resolved mapping for inspection.
Invalid JSON from --input or --stdin is refused; the refusal names the input (the file path, or --stdin), never its contents, so a stray token in a malformed sample is never echoed back.
Capabilities
Discover proxy and unified methods for an integration or account:
truto capabilities hubspot
truto capabilities <account-id> --methods list,get --resource contacts
truto capabilities hubspot --no-has-description # include methods without descriptionsSee Admin resources — Capabilities for --type, --target, and AI readiness details.
Discovering methods on an account
Before calling unified or proxy, list what an account supports:
truto accounts tools <account-id>
truto accounts tools <account-id> --methods read --tags contactsNext steps
- Power features — bulk
export,diff - Examples — proxy and unified walkthroughs