List integrated accounts
/integrated-account
Query Parameters
The ID of the tenant you want to filter the integrated accounts by.
acme-1Filter by the environment integration (installed integration) ID.
b179ad55-db02-4bd4-b7a4-d2c173eee9aeWhether the integrated account is in sandbox mode or not. Sandbox integrated accounts do not allow any "write" operations.
falseThe name of the integration you want to filter the integrated accounts by.
zendeskFilter the integrated accounts by the ones using SuperQuery. The value will be the SuperQuery region.
apacapacwnam
Filter the integrated accounts by status.
activeactiveconnectingpost_install_errorvalidation_errorneeds_reauth
Filter the integrated accounts by the date and time when they were created.
2021-08-10T10:00:00.000ZFilter the integrated accounts by the date and time when they were last updated.
2021-08-10T10:00:00.000ZResponse Body
Type of authentication used.
oauth2api_keyoauth2_client_credentialskeka_oauth
The context of the integrated account. You can find these in the Variables section of an integrated account in the Truto UI.
{"zendesk_subdomain":"truto"}The date and time when the integrated account was created.
2021-08-10T10:00:00.000ZThe ID of the environment this integrated account belongs to.
8a2b104d-74a6-47f2-b93e-c6b611e82391The ID of the environment integration (installed integration).
b179ad55-db02-4bd4-b7a4-d2c173eee9aeThe ID of the integrated account.
1ba1f401-7183-47c5-9e39-e8e257e3c7959 properties
The configuration object defining the underlying API of the integration.
{
"base_url": "https://api.example.com",
"label": "Example API Integration",
"logo": "https://example.com/logo.png",
"icon": "https://example.com/icon.png",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "truto"
},
"query": {
"search": "{{search_query}}",
"filter": "{{filter_criteria}}"
},
"query_array_format": "comma",
"actions": {
"sync_users": {
"type": "request",
"config": {
"method": "post",
"path": "/sync/users",
"headers": {
"Authorization": "Bearer {{oauth.token.access_token}}"
},
"body": {
"users": "{{context.users}}"
}
}
}
},
"credentials": {
"oauth2": {
"format": "oauth2",
"config": {
"client": {
"id": "your-client-id",
"secret": "your-client-secret"
},
"auth": {
"tokenHost": "https://auth.example.com",
"tokenPath": "/oauth/token",
"refreshPath": "/oauth/refresh"
},
"options": {
"scopeSeparator": " ",
"authorizationMethod": "header",
"bodyFormat": "form"
},
"fields": [
{
"name": "client_id",
"label": "Client ID",
"type": "text",
"required": true
},
{
"name": "client_secret",
"label": "Client Secret",
"type": "password",
"required": true
}
],
"tokenParams": {
"grant_type": "client_credentials"
},
"refreshParams": {
"grant_type": "refresh_token"
},
"tokenExpiryDuration": "3600"
}
}
},
"authorization": {
"format": "bearer",
"config": {
"token": "{{oauth.token.access_token}}"
}
},
"pagination": {
"format": "page",
"config": {
"page_key": "page",
"limit_key": "per_page"
}
},
"rate_limit": {
"is_rate_limited": true,
"retry_after_header_expression": "Retry-After",
"rate_limit_header_expression": "X-RateLimit-Remaining"
},
"resources": {
"users": {
"list": {
"method": "get",
"path": "/users",
"response_path": "data.users",
"headers": {
"Authorization": "Bearer {{oauth.token.access_token}}"
},
"query": {
"page": "{{pagination.page}}",
"per_page": "{{pagination.per_page}}"
},
"pagination": {
"format": "page",
"config": {
"page_key": "page",
"limit_key": "per_page"
}
},
"authorization": {
"format": "bearer",
"config": {
"token": "{{oauth.token.access_token}}"
}
},
"rate_limit": {
"is_rate_limited": true,
"retry_after_header_expression": "Retry-After",
"rate_limit_header_expression": "X-RateLimit-Remaining"
},
"examples": {
"response": "{\n \"data\": {\n \"users\": [\n {\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"name\": \"John Doe\",\n \"email\": \"john.doe@example.com\"\n }\n ]\n }\n}\n"
}
}
},
"orders": {
"create": {
"method": "post",
"path": "/orders",
"body": {
"user_id": "{{context.user_id}}",
"items": "{{context.items}}"
},
"response_path": "data.order",
"headers": {
"Authorization": "Bearer {{oauth.token.access_token}}"
},
"authorization": {
"format": "bearer",
"config": {
"value": "{{oauth.token.access_token}}"
}
}
}
}
},
"webhook": {
"signature_verification": {
"format": "hmac",
"config": {
"secret": "{{environment_variables.WEBHOOK_SECRET}}",
"algorithm": "sha256",
"string_type": "hex",
"compare_with": "{{headers.x-signature}}",
"parts": [
"raw_body"
]
}
},
"handle_verification": "{ 'type': webhook_type = 'verify' ? 'verify' : 'payload', 'verification_response': webhook_type = 'verify' ? { 'body': { 'challenge': body.challenge } } }"
},
"error_expression": "status >= 400 ? { 'status': status, 'message': data.error.message }"
}16 properties
Named integration actions. Reserved keys (post_install, post_connect_user_form, refresh_token, validation) hook into specific platform lifecycle events; custom names are callable from the proxy/sync runtime.
How Truto applies the resolved credential to outbound HTTP requests. The format discriminator selects which config shape applies.
All string values support Truto placeholders ({{path}}) resolved against the runtime context. Common placeholder roots: {{api_key}} for fields collected at connect time, {{oauth.token.access_token}} for OAuth2 access tokens, {{environment_variables.MY_KEY}} for env-vars set at the environment-integration level.
bearer · 2 properties
1 property
The bearer token. Almost always a placeholder like {{oauth.token.access_token}} (OAuth2) or {{api_key}} (api-key fields).
{{oauth.token.access_token}}bearer
basic · 2 properties
2 properties
Password, supports placeholders.
{{client_secret}}Username, supports placeholders (e.g. {{api_key}} for vendors that pass the API key as the username).
{{client_id}}basic
header · 2 properties
2 properties
JSONata expression that fully constructs the outgoing request. Use for advanced cases (request signing, dynamic URL rewrites).
Input: IntegrationHeaderAuthorizationContext. Output: IntegrationHeaderAuthorizationResult (must contain url and requestOptions).
Map of header name → value. Values support placeholders (e.g. { "X-API-Key": "{{api_key}}" }).
{"X-API-Key":"{{api_key}}","X-Account-Id":"{{account_id}}"}header
Default base URL prepended to every resource method's path.
https://api.example.comEither a single credential definition (when the integration only supports one auth format) or a map keyed by auth format (when an integration supports multiple, e.g. api_key and oauth2). For multi-format integrations, the customer picks one in the Connect UI. Each credential's config.label and config.help_text customize the auth-method card shown in the Connect UI.
Integration-wide JSONata expression evaluated on every response. Use to detect errors in successful (2xx) responses, normalize error messages, or transform "errors" with < 400 status into successful responses. Overridden by per-method IntegrationResourceMethod.error_expression when set.
Input: IntegrationErrorExpressionContext. Output: IntegrationErrorExpressionResult — return null/undefined to indicate "no error", or a { status, message?, headers?, metadata?, result? } object.
Default HTTP headers merged into every outbound request. Values may be templated with JSONata placeholders.
URL to a smaller monochrome icon used in catalog listings.
Human-readable name shown in the Truto Dashboard and Link UI.
Example APIURL to the integration logo (square, recommended 256x256).
Pagination strategy for an integration or a single resource method. The format discriminator selects which config shape applies.
page · 2 properties
Page-number pagination options. All fields optional; defaults shown.
9 properties
Add pagination keys to the request body instead of the query string.
Add pagination keys to the query string. Defaults to true when add_to_body is false.
Static or templated headers added to every paginated request. Templated against the request query plus a synthetic limit.
Drop the limit_key from the URL after pagination is applied (for APIs that 400 on it).
Query/body key that holds the page size.
Maximum page size Truto will request, regardless of the caller's limit.
Query/body key that holds the page number.
Page number used for the first page (some APIs are 0-indexed).
Stop paginating when consecutive pages return identical results (loop detection). Defaults to true.
page
cursor · 2 properties
Cursor pagination options.
17 properties
Send the cursor in the request body instead of the URL.
Add the cursor to the query string.
Don't treat an empty cursor as the end of pagination.
Query/body key Truto uses to send the cursor on the next request.
Dotted-path accessor into the response body (or headers, when cursor_path_object: header) that yields the next cursor.
data.meta.next_cursorWhere to read cursor_path from.
bodyheader
Optional accessor that returns a truthy/"true"/"false" value indicating whether more pages exist.
Static or templated headers added to every paginated request. Templated against the request query plus a synthetic limit.
Don't re-send limit_key after the first page (for APIs that reject it on subsequent calls).
When is_link is true, also overwrite the request path with the link's path (not just the query string).
URL-decode the cursor before sending (some upstreams double-encode).
Treat the value at cursor_path as a fully-qualified URL (or path) rather than an opaque token.
Cast the limit value when sending it in the body.
numberstring
Query/body key that holds the page size.
Maximum page size Truto will request.
Optional accessor that yields the previous-page cursor.
Detect loops by hashing each page's results. Only effective when cursor_path_object is body.
cursor
link_header · 2 properties
5 properties
Static or templated headers added to every paginated request.
Don't send limit_key even when the caller sets limit.
Query key that holds the page size when the caller sets limit.
Maximum page size Truto will request.
Informational only; the actual cursor comes from the Link header.
link_header
offset · 2 properties
10 properties
Send pagination params in the request body instead of the query string.
Send pagination params in the query string.
Offset used for the first request (some APIs are 1-indexed).
Static or templated headers added to every paginated request.
Drop limit_key from the URL after pagination is applied.
Query/body key that holds the page size.
Maximum page size Truto will request.
Query/body key that holds the offset.
Optional dotted-path accessor into the response body that yields the total result count, used to stop paginating early.
Detect loops by hashing each page's results.
offset
range · 2 properties
9 properties
Send pagination params in the request body instead of the query string.
Send pagination params in the query string.
Start value used for the first request.
Query/body key that holds the end of the range (exclusive).
Static or templated headers added to every paginated request.
Drop start_key, end_key, and limit from the URL after pagination is applied.
Maximum range size Truto will request.
Query/body key that holds the start of the range.
Optional dotted-path accessor into the response body that yields the total result count, used to stop paginating early.
range
dynamic · 2 properties
3 properties
JSONata expression evaluated after each response. Returns the next cursor (Truto then base64-encodes it) and optional loop-detection flags.
Input: IntegrationDynamicPaginationResponseContext. Output: IntegrationDynamicPaginationResponseResult.
Optional JSONata expression evaluated before the first request. Use to seed pagination values (e.g. compute a default since window).
Input: IntegrationDynamicPaginationRequestContext. Output: IntegrationDynamicPaginationRequestResult.
JSONata expression evaluated before each subsequent request (when query.next_cursor is set). Mutates the URL/body/headers/query for the next page.
Input: IntegrationDynamicPaginationRequestContext with query.next_cursor decoded from base64. Output: IntegrationDynamicPaginationRequestResult.
dynamic
Default query-string params merged into every outbound request.
commabracketsindicesrepeat
How Truto detects and reacts to upstream rate-limiting. All fields are JSONata expressions evaluated against the upstream response.
3 properties
JSONata expression returning a truthy value when the response should be treated as rate-limited. When omitted, Truto falls back to status === 429.
Input: IntegrationRateLimitExpressionContext. Output: boolean.
status = 429JSONata expression returning the current rate-limit window state. Truto forwards this as RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset headers in the proxy response.
Input: IntegrationRateLimitExpressionContext. Output: IntegrationRateLimitHeaderValues.
{ "limit": headers.`x-ratelimit-limit`, "remaining": headers.`x-ratelimit-remaining`, "reset": headers.`x-ratelimit-reset` }
JSONata expression returning the seconds to wait before retrying. When omitted, Truto reads the standard Retry-After header.
Input: IntegrationRateLimitExpressionContext. Output: number (seconds).
$number(headers.`retry-after`)Resource → method tree (e.g. resources.users.list). The inner key is one of the canonical methods (list, get, create, update, delete) or a custom method name. Each method definition matches IntegrationResourceMethod.
Optional tag arrays keyed by resource name (contacts) or
resource.method (contacts.delete). Method-level tags are unioned
with resource-level tags when building MCP tools and filtering by
MCP token config.tags.
How Truto receives and verifies inbound webhooks for this integration. Not to be confused with WebhookSchema elsewhere in this spec, which describes Truto's outbound webhook delivered to your application.
3 properties
JSONata expression evaluated on every inbound webhook before signature verification. Use to:
- Respond to handshake pings (return
{ type: 'verify', verification_response: { status_code, body, headers } }). - Surface meta-events that should not fan out (return
{ type: 'meta' }). - Update the integrated account context (return
{ type: 'verify' \| 'payload' \| 'meta', update_context: { ... } }). - Pass through to fan-out (return
{ type: 'payload' }or omit entirely — defaults topayload).
Input: IntegrationWebhookPayloadContext. Output: IntegrationWebhookHandleVerificationResult.
JSONata expression that transforms the raw inbound payload before handle_verification and signature_verification see it. Use to normalize vendor-specific envelopes (e.g. unwrap a Salesforce payloads[] array, decode a base64 body).
Input: IntegrationWebhookPayloadContext. Output: IntegrationWebhookPayloadContext (the same shape — what you return becomes the new payload).
Strategy used to verify the webhook signature before accepting it. Runs after payload_transform and after handle_verification returns { type: 'payload' }.
hmac · 2 properties
HMAC signature verification. Truto computes hmac(algorithm, secret, signed_string) and compares it (constant-time) with compare_with.
6 properties
Hashing algorithm.
sha256The signature value from the request to compare against. Usually a placeholder like {{headers.x-signature}}.
Ordered list of IntegrationWebhookPayloadContext field names to concatenate as the signed string (e.g. ["raw_body"] or ["timestamp", "raw_body"]). Mutually exclusive with verification_content.
Shared HMAC secret. Typically a placeholder like {{context.webhook_secret}} or {{environment_variables.WEBHOOK_SECRET_secret}}.
Output encoding for the computed digest.
hexOrdered list of placeholders to concatenate as the signed string (e.g. ["{{headers.x-timestamp}}", ".", "{{raw_body}}"]). Mutually exclusive with parts.
hmac
basic · 2 properties
HTTP Basic signature verification. Truto base64-encodes username:password and compares it with the second word of compare_with (i.e. Authorization: Basic <token>).
3 properties
The full Authorization header value, e.g. {{headers.authorization}}.
Expected password. Supports placeholders.
Expected username. Supports placeholders.
basic
bearer · 2 properties
Bearer-token signature verification. Truto compares secret (constant-time) with the second word of compare_with (i.e. Authorization: Bearer <token>).
2 properties
The full Authorization header value, e.g. {{headers.authorization}}.
Expected bearer token. Supports placeholders.
bearer
jwt · 2 properties
JWT signature verification. Truto verifies compare_with is a valid JWT signed with secret (HS256 by default).
2 properties
The JWT to verify, typically a placeholder like {{headers.authorization}} or {{body.token}}.
Shared signing secret. Supports placeholders.
jwt
The category of the integration.
helpdeskThe date and time when the integration was created.
2021-08-10T10:00:00.000ZThe ID of the integration.
4a4de828-f4db-4c9e-adfd-434e0864c3c7Whether the integration is in beta or not. Beta integrations might not have been tested completely and are not recommended for production environments.
falseThe name of the integration.
zendeskThe sharing policy of the integration.
allowallowaskdeny
The ID of the team that owns this integration.
05daecaf-4365-42e8-8370-8127de5dd717The date and time when the integration was last updated.
2021-08-10T10:00:00.000ZWhether the integrated account is in sandbox mode or not. Sandbox integrated accounts do not allow any "write" operations.
falseThe results of the post install and validation steps that ran on the integrated account.
The last error that occurred while running the post install or validation steps.
Details of the most recent 403 Forbidden returned by the third-party API for this
account, or null if the most recent call succeeded. Cleared automatically on the next
successful call.
11 properties
The sentence the live 403 carried, recorded so this row reads the same as the call did.
Access forbidden. This operation requires a role or privilege granted in the provider's own admin console, not an OAuth scope — reconnecting will not change it.The method that was attempted on that resource.
listScopes of which the operation needs any one, where the grant holds none. Kept
apart from missing_scopes so alternatives are never reported as though all were
required.
["Chat.Read.All","Chat.ReadWrite.All"]The scopes required by this resource and method that the provider did not confirm as granted.
Present only when both halves of that comparison are known: the provider echoed the
scopes it granted, and this resource and method declares required scopes. It is
absent — not empty — otherwise, which includes api_key and OAuth1 connections
(no scope grant exists), OAuth2 and jwt_bearer connections where the provider
omits scope from its token response, resources and methods that declare no
required scopes, and requirements that are not OAuth scopes at all
(refusal_basis: non_scope_requirement — see permission_vocabulary), where no
diff is run and required_permissions carries the answer instead.
An empty array therefore means "no all-of scope is missing", while an absent
field means "cannot be determined" — two different statements. Read refusal_basis
for the one question this field cannot answer on its own, "was anything missing at
all": an empty array sits beside a populated missing_any_of_scopes whenever the
whole shortfall is an unmet any-of requirement, so on
refusal_basis: scopes_missing an empty array does not mean every permission
was granted. It means that on refusal_basis: scopes_satisfied, and only there. Do
not default an absent missing_scopes to [] either: that reads back as "nothing
is missing" about a request that was refused.
Truto's comparison is an inference over integration configuration. The provider's
own account of the refusal is the authoritative one, and Truto relays it without
interpreting it: raw_response (the error body verbatim) and message (its human
text) on the 403 itself, and a capped copy of the body on this record as
raw_response_excerpt. message is not persisted, so re-run the call to see it.
Truto deliberately does not lift a "code" or a "documentation link" out of that body. Which key in an arbitrary provider's error shape is the important one has no correct general answer, and a confidently wrong one placed above a correct body is the same failure as reporting a scope missing that was never checked.
["crm.objects.contacts.read"]When the forbidden response was recorded.
2021-08-10T10:00:00.000ZWhich vocabulary required_permissions is written in, and therefore what the
remedy is. Only oauth_scope is fixed by reconnecting: api_key_permission is
granted to the API key in the provider, and role_label in the provider's own
admin console.
x-extensible-enum for the same reason as refusal_basis above: this is a stored
value, and a rollback can serve one written by a build that knew a fourth
vocabulary. Keep a default branch.
role_labelA capped copy of the integration's own error body, so this record shows what the
provider said and not only what Truto inferred about it. Truncated with a trailing
… truncated marker past 2,048 bytes of UTF-8, because this record is
deserialized on every proxy and unified call that resolves the account and that cost
is what the bound exists to control. Bytes, not characters: 2,048 characters of CJK
is about 6 KB stored, so a character bound would charge one language three times
what it charges another. Expect fewer characters than 2,048 for any non-ASCII body.
The 2,048 covers the marker as well, so the stored value never exceeds it.
A truncated excerpt is not parseable. It is a byte prefix of a serialized body
with a marker on the end, so JSON.parse on this field throws whenever truncation
happened — which the trailing … truncated is how you detect. Render it as text.
An untruncated excerpt of a JSON body does parse, but nothing guarantees this field
is JSON at all: a plain-text or HTML error body is stored exactly as it arrived.
Absent when the refusal carried no body. Not forwarded to the connections widget:
it is a raw provider string, which is what connections.show_error_details exists
to keep away from an end user.
Note that "every remote 403 carries an insight" and "every remote 403 leaves a
record here" are different statements. A Proxy API custom method and a Custom
API both carry the live insight, but a Custom API names no resource or method, and
writing {resource: "", method: ""} would replace a record naming a real call with
one naming none — so no record is written for those. Read the insight on the
response for them.
{"error":"insufficient_scope","error_description":"Token does not have crm.objects.contacts.write scope"}Which of the states below produced this record, so a reader never has to infer it
from the presence or emptiness of missing_scopes. Absent on rows recorded before
Truto stored it — and on such a row an empty missing_scopes cannot be read as
"compared, nothing missing", because it was also written when nothing had been
compared at all.
An open set, and x-extensible-enum rather than enum says so to a code
generator as well as to a reader. Prose asking for a default branch is not
something a generator reads, and a closed union here can be violated by design:
the read path deliberately accepts an unrecognised value so a row written by a
newer build stays readable after a rollback, and the older build then serves that
value straight back on this field. The values below are what Truto writes today.
Keep a default branch.
The live truto_error_insight.forbidden_error.value.refusal_basis keeps a closed
enum, and the asymmetry is the point: a running build always emits its own
documented set, while a stored row can carry a value the build reading it never
wrote.
non_scope_requirementPermissions of which the operation needs any one, kept apart from required_permissions for the same reason.
["Chat.Read.All"]What this operation requires, whether or not a comparison was possible. Always
paired with permission_vocabulary, since the same string means "reconnect and
grant this", "add this to your API key" or "ask an admin for this role" depending
on which vocabulary it is written in.
["Agent","Customers Read"]The third-party resource that was forbidden.
contactsThe list of context fields that are stored in the object store.
The region where the integrated account is placed.
wnamwnamenamapaceu
Status of the integrated account.
active- Everything is fine and the account should workconnecting- Post install and validation steps are being runpost_install_error- There was an error while running post install stepsvalidation_error- There was an error while running validation stepsneeds_reauth- There was an error while refreshing the credentials in case of OAuth authentication or the credentials are no longer valid in other authentication methods. The integrated account needs to be reauthorized.
activeconnectingpost_install_errorvalidation_errorneeds_reauth
The ID of the tenant.
acme-1The date and time when the integrated account was last updated.
2021-08-10T10:00:00.000Ztruto accounts list -o jsonimport Truto from '@truto/truto-ts-sdk';
const truto = new Truto({
token: '<your_api_token>',
});
for await (const item of truto.integratedAccount.list()) {
console.log(item);
}import asyncio
from truto_python_sdk import TrutoApi
truto_api = TrutoApi(token="<your_api_token>")
async def main():
async for item in truto_api.integrated_accounts.list():
print(item)
asyncio.run(main())curl -X GET 'https://api.truto.one/integrated-account' \
-H 'Authorization: Bearer <your_api_token>' \
-H 'Content-Type: application/json'const response = await fetch('https://api.truto.one/integrated-account', {
method: 'GET',
headers: {
'Authorization': 'Bearer <your_api_token>',
'Content-Type': 'application/json',
},
});
const data = await response.json();
console.log(data);import requests
url = "https://api.truto.one/integrated-account"
headers = {
"Authorization": "Bearer <your_api_token>",
"Content-Type": "application/json",
}
params = {
}
response = requests.get(url, headers=headers, params=params)
print(response.json())