Integrations Object
Properties
The category of the integration.
helpdeskThe 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 }"
}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 Link 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 per resource, surfaced via the Truto MCP tools listing.
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 date and time when the integration was created.
2021-08-10T10:00:00.000ZThe ID of the integration.
4a4de828-f4db-4c9e-adfd-434e0864c3c7A list of environment IDs where this integration is installed.
Whether 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
Whether the team allows impersonation.
falseThe date and time when the team was created.
2021-08-10T10:00:00.000ZThe domain of the team.
example.comThe ID of the team.
05daecaf-4365-42e8-8370-8127de5dd717Whether the team is verified or not.
trueWhether the team is white-labeled or not.
falseThe URL of the team's logo.
https://example.com/logo.pngThe name of the team.
My Awesome TeamA link to the team's Terms of Service, if available.
https://example.com/tosThe date and time when the team was last updated.
2021-08-10T10:00:00.000ZThe 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.000Z