Skip to content

Welcome to the Truto Integrations References! This section will help you understand each section in Integrations in Truto. We'll explain everything you need to know, with examples wherever needed and easy-to-understand descriptions.

Authentication

The Authentication section is all about how your integration securely connects to other systems like Salesforce, Shopify, or Keka. Each type of authentication needs different settings. Let’s look at the different authentication methods, their fields, and how to configure them.

1. OAuth 2.0 Authorization

OAuth 2.0 is a popular and secure way to log in using a third-party service. Truto recommends using this method wherever possible.

OAuth 2.0 Fields and Settings

  • Redirect URL:

    • What It Is: The webpage users go to after they log in.
    • Example: https://api.truto.one/connect/salesforce/callback
    • Note: You must register this URL with the service you’re connecting to.
  • Client ID & Client Secret:

    • Client ID Param Name:
      • What It Is: Identifies the OAuth client.
      • Default: client_id
    • Client Secret Param Name:
      • What It Is: Authenticates the OAuth client.
      • Default: client_secret
  • Authorization Host & Path: Check the Authorization Host in the product documentation and enter it here as in the example.

    • Authorization Host:
      • Example:
        https://truto.my.salesforce.com
        
    • Authorization Path:
      • Default: /oauth/authorize
  • Token Host & Path: Check the Token Host in the product documentation and enter it here as in the example.

    • Token Host:
      • Example:
        https://truto.my.salesforce.com
        
    • Token Path:
      • Default: /oauth/token
  • Scopes:

    • What It Is: Permissions you request during login.
    • Format: List one permission per line (e.g., read, write).
    • Scope separator: A space by default.
  • Optional Scopes:

    • What It Is: Scopes the user may grant or decline, sent separately from Scopes. Used by HubSpot.
  • Use OAuth token scope:

    • What It Is: When on, a token refresh asks only for the scopes returned in the token response. Useful for providers like Google, where users can consent to fewer scopes than you asked for.
    • OAuth token scope separator: How to split the scope string in the token response. A space by default.
  • Permissions Text:

    • What It Is: A friendly description of the permissions you’re asking for. You can use HTML or Markdown to make it look nice.
    • Example:
      **Access Required:**  
      - View and manage your Salesforce data.  
      - Send updates to Salesforce on your behalf.
    • Why It’s Important: Helps users understand what they’re agreeing to.
  • OAuth Token Request Authorization Format:

    • Options: Header or Body or Query
  • OAuth Token Request Body Format:

    • Options: Form, JSON, Query. Usually, it’s a form.
  • Token Expiry Duration:

    • What It Is: How long the token lasts, in seconds (e.g., 3600).
  • Add authorize URL params, Add token params, Add refresh token params:

    • What It Is: Extra key-value parameters added to the authorize URL, the token request, and the refresh token request.
  • Connect UI Label and Connect UI Help Text:

    • What It Is: The name and description of this sign-in method on the connect screen.

A few OAuth 2.0 settings are set in the integration's JSON rather than the form:

Key What it does
pkce Turns on PKCE. method must be set to S256 or plain, but Truto always sends an S256 challenge.
auth.refreshPath Path for the refresh token request. Defaults to the token path.
auth.revokePath Path Truto calls to revoke the token when a connection is removed. Defaults to /oauth/revoke.
options.expiresInPropertyName Name of the token response field that holds the token lifetime, when it is not expires_in.
Example: Salesforce OAuth 2.0 Setup
  • Redirect URL: https://api.truto.one/connect/salesforce/callback
  • Authorization Host:
    https://{{subdomain}}.my.salesforce.com
    

OAuth


2. API Key Authentication

API Key Authentication is a simple way to verify by using an API key in every request.

  • Scopes:

    • What It Is: The permissions the API key needs.
    • Format: List one permission per line (e.g., read, write).
  • Permissions Text:

    • What It Is: A friendly description of the permissions you’re asking for. You can use HTML or Markdown to make it look nice.
    • Example:
      **Access Required:**  
      - View and manage your 15five data.  

API Key

API Key Variables and Setup

For API Key Authentication, you need the api_key variable. This will get added automatically in the Variables section.

Required Fields for API Key Variables:
  • Name:

    • Value: api_key (this is how Truto identifies it internally).
  • Label:

    • Value: API Key (the label).
  • Type:

    • Password (hides the key for security).
  • Default Value:

    • Usually left blank. Add any default values.
  • Help Text:

    • Example: "The API Key provided by your service provider. This is required to authenticate your API requests."
  • Transforms:

    • Optional changes you can apply to the key. The values are None, lowercase, UPPERCASE, SHA256
  • Pattern:

    • A regular expression to validate the key.
    • Example: ^AK- (API key must start with AK-).
  • Credential Documentation Link:

    • What It Is: A link to help users find or create their API key.
    • Example: "https://docs.example.com/api-keys"
  • Permissions Text:

    • What It Is: Explains what the API key can do.
    • Example:
      **This API key will grant access to your Shopify store's data and settings.**
Example Usage of API Key

In Cloudflare integration:

  • API Key is used in headers:
    Authorization: Bearer {{api_key}}
    

API Key Variable Example


3. OAuth 2.0 Client Credentials Flow

OAuth 2.0 Client Credentials Flow is another way to use OAuth 2.0. Check the documentation of the product you're integrating to decide on whether to use this.

OAuth 2.0 Client Credentials Fields and Settings

  • Token Host & Path:

    • Token Host:
      • What It Is: The URL where tokens are issued.
      • Example: https://login.salesforce.com
    • Token Path:
      • Required: Yes. Set the path explicitly, for example /oauth/token.
  • OAuth Token Request Authorization Format:

    • Options: Header or Body or Query
    • What It Means: Decides where to send the Client ID and Client Secret.
  • OAuth Token Request Body Format:

    • What It Is: The format of the request body when asking for a token. Usually Form. Other values include JSON, Query.
  • Add Token Params:

    • What It Is: Extra parameters needed by the API.
    • Use: Add as needed by the provider.
  • Permissions Text:

    • What It Is: Explains what access the integration will have.
    • Example:
      **Permissions Required:**  
      - Full read access to your Salesforce accounts.
      - Ability to create and modify records as needed.

OAuth 2.0 Client Credentials

Optional Fields for OAuth 2.0 Client Credentials Variables:
  1. Client ID:

    • Name: client_id
    • Label: Client ID
    • Type: Text
    • Placeholder: "Enter Client ID."
    • Required?: Yes
    • Help Text: "Client ID provided by the service"
  2. Client Secret:

    • Name: client_secret
    • Label: Client Secret
    • Type: Password
    • Placeholder: "Enter Client Secret."
    • Required?: Yes
    • Help Text: "The secret key provided by the service for authenticating requests."

OAuth 2.0 Variables


4. Keka OAuth Authentication

Keka OAuth is specifically for Keka, a platform for HR and payroll services. It needs several pieces of information to work.

Keka OAuth Variables Setup

In the Variables section for Keka OAuth, you need to enter multiple details to authenticate with Keka.

Required Fields for Keka OAuth Variables:
  1. Client ID:

    • Name: client_id
    • Label: Client ID
    • Type: Text
    • Placeholder: "Enter Client ID provided by Keka"
    • Required?: Yes
    • Help Text: "Client ID provided by Keka, used to identify your app."
  2. Client Secret:

    • Name: client_secret
    • Label: Client Secret
    • Type: Password
    • Placeholder: "Enter Client Secret."
    • Required?: Yes
    • Help Text: "The secret key provided by Keka for authenticating requests."
  3. API Key:

    • Name: api_key
    • Label: API Key
    • Type: Password
    • Placeholder: "Enter API key."
    • Required?: Yes
    • Help Text: "API key provided by Keka to authenticate API calls."
  • Permissions Text:
    • What It Is: Explains what access is given when connecting Keka.
    • Example:
      **Permissions Required**: Access to HR and payroll data for your employees to synchronize with other services.
Example Usage in Keka Integration

All three fields are required for Keka OAuth. Users must enter them correctly to connect smoothly.

Keka OAuth Variable Example


5. JWT

JWT is for integrations where authentication uses JSON Web Tokens. Use it when the provider issues or accepts JWTs for API access.

Open the integration’s Authentication tab, choose Edit from the page menu, and select JWT as the authentication format. The fields shown depend on the provider — use their documentation to fill them in.

JWT

If the provider signs in a service account with a key pair, Truto can make the key pair for each connection, so that your end users only install a public key. See Truto-generated key pairs.

JWT fields

Truto signs a JWT with the signing key, then posts it to Token Host + Token Path and keeps the token the provider returns. It reads the token from access_token (or token) in the response, and its expiry from expires_at or expires_in. Leave Token Host and Token Path empty and the signed JWT itself is used as the access token. Either way the token is available as {{oauth.token.access_token}}, so the usual Authorization is Bearer with that value.

Field Config key What it does
Signing ID signing.id The provider's identifier for the credential, such as a GitHub App ID or a Google service account email. Used as the iss claim when the claims don't set one.
Signing algorithm jwt.algorithm Default RS256. Also RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, EdDSA, HS256, HS384, HS512.
Signing key signing.key The private key: PEM text (or upload a .pem file), a JWK as JSON, or an HMAC secret. To sign with a Truto-generated key pair instead, set signing.generated to the key pair's name.
Authorize Host, Authorize Path auth.authorizeHost, auth.authorizePath Optional. When both are set, your end user is redirected here before connecting, for example to install a GitHub App.
Token Host, Token Path auth.tokenHost, auth.tokenPath Where the signed JWT is exchanged for an access token.
Audience jwt.claims.aud The aud claim, often the provider's token URL.
JWT expires in (seconds) jwt.expires_in Required. Truto sets iat to the signing time and exp to iat plus this value. For example 600 for GitHub, 3600 for Google.
Scopes, Scope separator jwt.claims.scope, jwt.scope_separator The scope claim. One scope per line in the form, joined with the separator (a space by default).
Token request authorization format options.authorizationMethod How the JWT goes on the token request: Header (default, as Authorization: Bearer <jwt>), Body, or Query.
Token request body format options.bodyFormat With Body: Form (default) or JSON.
Add authorize URL params, Add token params params, tokenParams Extra parameters for the authorize redirect and the token request.

These keys are set in the integration's JSON rather than the form:

Key What it does
jwt.claims Any other claims, as a template. For example "iss": "{{signing.id}}".
jwt.claims_expression A JSONata expression that returns more claims, merged over jwt.claims. It receives context and signing (id, public).
jwt.header Extra JWT header fields.
options.assertion_field_name The body or query field the JWT goes in. Default assertion.
auth.method The token request method. Default POST.
headers Extra headers for the token request.
{
  "format": "jwt_bearer",
  "config": {
    "fields": [
      { "name": "service_account_email", "label": "Service account email", "type": "text", "required": true },
      { "name": "private_key", "label": "Private key", "type": "password", "required": true }
    ],
    "signing": { "id": "{{service_account_email}}", "key": "{{private_key}}" },
    "jwt": {
      "algorithm": "RS256",
      "expires_in": 3600,
      "claims": {
        "iss": "{{signing.id}}",
        "aud": "https://oauth2.googleapis.com/token",
        "scope": "https://www.googleapis.com/auth/drive.readonly"
      }
    },
    "auth": { "tokenHost": "https://oauth2.googleapis.com", "tokenPath": "/token" },
    "options": { "authorizationMethod": "body" },
    "tokenParams": { "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer" }
  }
}

6. OAuth 1.0

OAuth 1.0 is for integrations that use the OAuth 1.0 signing flow. Use it when the provider requires OAuth 1.0 instead of OAuth 2.0.

Open the integration’s Authentication tab, choose Edit from the page menu, and select OAuth 1.0 as the authentication format. Configure the settings shown according to your provider’s documentation.

OAuth 1.0

OAuth 1.0 fields

Register the Redirect URL shown at the top of the form with the provider, the same way as for OAuth 2.0.

Field Config key What it does
Client ID, Client Secret client.id, client.secret Required. The consumer key and secret from the provider.
Request Token URL auth.requestTokenUrl Required. Where Truto gets the temporary request token.
Authorization URL auth.authorizeUrl Required. Where your end user is sent to approve access.
Token URL auth.tokenUrl Required. Where Truto exchanges the approved request token for an access token.
Scopes scope One scope per line.
OAuth 1.0 Signature Verification Method options.signatureMethod HMAC-SHA1 (default) or PLAINTEXT.
Add authorize URL params params Extra parameters for the authorization redirect.
Add token params tokenParams Extra parameters for the token request.
Add refresh token params refreshParams Extra parameters for the refresh request.

7. AWS STS

AWS STS is for AWS APIs. Your end user creates a role in their AWS account that trusts your AWS account. Truto signs an STS AssumeRole call for that role with a long-lived AWS key, and uses the short-lived key that comes back. One connection can read many AWS accounts, one role per account.

Open the integration’s Authentication tab, choose Edit from the page menu, and select AWS STS as the authentication format.

What Truto does

  • Before a request, Truto calls AssumeRole with Role ARN, Session name, External ID and Duration (seconds), signed with the signing key.
  • It keeps the short-lived key on the connection and mints a new one when it is within one minute of expiry.
  • The integration's Authorization signs each API request with AWS Signature Version 4, using the short-lived key. Don't add connect form fields for an AWS key.
  • With Token key set to a per-request template, the connection keeps one short-lived key per resolved value, so a request for one AWS account never uses another account's key.

AWS STS fields

Field Config key What it does
Access key ID, Secret access key signing.access_key_id, signing.secret_access_key The long-lived AWS key that signs AssumeRole. Leave both empty and each environment supplies its own key (see below); fill them in and every connection uses this key.
Session token (optional) signing.session_token Only needed when the signing key is itself a temporary credential.
Role ARN role.arn Required. The role to assume. {{token_key}} resolves to the current token key, for example arn:aws:iam::{{token_key}}:role/TrutoCloudRead.
Session name role.session_name Optional. Default truto. Characters AWS doesn't allow are replaced with -, and the name is cut to 64 characters.
External ID role.external_id Optional. Usually {{external_id}}, generated by Truto (see below).
Duration (seconds) role.duration_seconds How long the short-lived key lasts. Default 3600. A value under 900 is replaced with 3600. The role's own maximum session duration still applies.
Token host auth.tokenHost Default https://sts.amazonaws.com.
Region auth.region The region AssumeRole is signed for. Default us-east-1.
Token key token_key Leave empty and the connection keeps one key. Set it to a per-request template such as {{query.truto_account_id}} and the connection keeps one key per value. When a request doesn't supply the value, Truto makes no AssumeRole call for it.

The External ID should come from Truto, not from your end user. Declare it as a generated field and reference it in the role:

{
  "format": "aws_sts",
  "config": {
    "fields": [],
    "generated_fields": [{ "name": "external_id", "type": "uuid", "prefix": "truto-" }],
    "signing": { "access_key_id": "dummy", "secret_access_key": "dummy" },
    "role": {
      "arn": "arn:aws:iam::{{token_key}}:role/TrutoCloudRead",
      "external_id": "{{external_id}}"
    },
    "token_key": "{{query.truto_account_id}}"
  }
}

When Token key reads a query parameter, Truto doesn't forward that parameter to AWS on Proxy API calls.

When AssumeRole fails

With a per-request Token key, a failure that blames the role (AccessDenied, AccessDeniedException, NoSuchEntity, MalformedPolicyDocument, PackedPolicyTooLarge) fails that request only. The connection stays active, and the failure is recorded under context.oauth.token_errors.<token key> on the integrated account (code, message, first_failed_at, last_failed_at). A later success for that key clears it. Any other failure that outlasts Truto's retries, such as a revoked signing key, marks the connection as needing reauthorization. Without a per-request Token key, any failure that outlasts the retries does.

Your own signing key, template and AWS account

Each environment can use its own AWS key instead of the integration's. On the integration's settings page, under AWS STS, turn on Use your own signing credentials and fill in:

  • Access Key ID, Secret Access Key and Session token (optional) — the key that signs AssumeRole.
  • CloudFormation template URL (template_url) — the Object URL of your copy of the role template in S3. It must be an https URL on an s3.amazonaws.com host (<bucket>.s3.amazonaws.com or <bucket>.s3.<region>.amazonaws.com) that ends in .yaml or .yml, with no query string. Leave it empty to use Truto's.
  • AWS account ID (provider_account_id) — the 12-digit AWS account that holds your signing key, which your end users' roles trust. Leave it empty to use Truto's.

The connect form can use these values as {{template_url}}, {{template_url_encoded}} (percent-encoded, for a link into the AWS console), {{provider_account_id}} and {{provider_account_id_encoded}}. A value that doesn't match its format is rejected on save, and left out of the connect form.

Variables

Variables help make your integration flexible by allowing you to collect specific information from users, like API keys or subdomains. This makes your integration adaptable for different users and situations. Click Add Variable to create a new field. Note that an option from Authentication section has to be selected to be able to use variables.

Key Points About Variables

  • Reusable: Different users can use the same integration with their own unique information.
  • Customization: Store unique details like API keys, subdomains, or client credentials.

Common Examples of Variables:

  1. Subdomain:

    • Usage: Used in the Base URL.
    • Example:
      https://{{subdomain}}.myshopify.com
      
  2. API Key:

    • Usage: Used in Headers.
    • Example:
      Authorization: Bearer {{api_key}}
      

Fields in Variables Setup:

  • Name: Unique identifier for the variable.

  • Label: What users see.

  • Type: Text, Password, Single Select.

  • Options: For Single Select, the choices the user picks from, each with a label and a value.

  • Default Value: Optional starting value.

  • Placeholder: Hints for users on what to enter.

  • Format: For Text, checks the value is an Email, Number, UUID or URL.

  • Required?: If checked, users must fill it out.

  • Help Text: Explains what the variable is for.

  • Pattern: Regex to validate the input.

  • Credential Documentation Link:

    • What It Is: Link to help users generate or find their credentials.
    • Example: "https://docs.example.com/generate-api-keys"
  • Permissions Text:

    • What It Is: Explains what access the integration is requesting.
    • Format: Markdown or HTML for clarity.

Integration Variables Example

Authorization

The Authorization section sets up how your integration proves it’s allowed to access data every time it makes a request to an external system. This is different from Authentication, which is about logging in initially. Authorization ensures each request has the right permissions.

Authorization Types and How to Set Them Up

This section offers different ways to manage authorized requests to external APIs. Each method has specific settings to configure how your integration behaves.

1. Bearer Auth

Bearer Authentication is a simple way to authorize requests by including a token in the request headers. This token is usually an access token you got during the OAuth login process.

Bearer Auth Fields and Settings

  • Format:

    • Choose Bearer Auth as the authorization method.
  • Bearer Token:

    • What It Is: The token used to authorize the request.
    • Example:
      {{oauth.token.access_token}}
      
      • This dynamically uses the access token from the OAuth flow.
Example Usage:

When integrating with Salesforce, use the Bearer Token for each API request:

  • The Bearer Token is stored as:
    {{oauth.token.access_token}}
    

Bearer authorization

2. Basic Auth

Basic Authentication requires a username and password to access an API. These credentials are sent in the request headers in an encoded format.

Basic Auth Fields and Settings

  • Format:

    • Choose Basic Auth as the authorization method.
  • Username:

    • What It Is: The username for the external system.
    • Usage: Use variables to allow users to input their own username.
  • Password:

    • What It Is: The password for the external system.
    • Usage: Use variables to store the password securely.

Basic authorization

3. Custom Header Authorization

Custom Header Authorization lets you create your own authorization logic, which is useful if the API you’re connecting to doesn’t use standard methods like OAuth or API Keys.

Custom Header Fields and Settings

  • Format:

    • Choose Custom Header as the authorization method.
  • Use JSONata:

    • What It Is: Use JSONata expressions to set custom headers based on the request.
    • How It Works: Write a JSONata expression to define how headers should be set.
  • Custom Header Expression:

    • What It Is: A JSONata expression that sets custom headers.
    • Available Data:
      • url: The full URL of the request.
      • requestOptions: The request details, including headers and body.
      • context: Information stored in the account’s context.
    • What It Must Return: An object with url and requestOptions properties. The returned requestOptions replaces the request's options as a whole, so merge your changes into the incoming requestOptions to keep its method, body and other headers.
Example of JSONata Expression for Custom Header:

If an API needs a special signature in the header based on the URL and a secret key, you can use:

{
  "url": url,
  "requestOptions": $merge([
    requestOptions,
    {
      "headers": $merge([
        requestOptions.headers,
        { "X-Custom-Signature": $digest(url & context.secret, "SHA-256", "hex") }
      ])
    }
  ])
}
  • Explanation:
    • $digest: Hashes the request URL joined with a secret from the context, using SHA-256, as a hex string.
    • $merge: Keeps everything already in requestOptions and its headers, and adds the new header (X-Custom-Signature).

Custom header authorization

Base URL and Headers

The Base URL and Headers section is essential for telling your integration where to send requests and what information to include in those requests.

Base URL

The Base URL is the main address for all API requests. Every API call you make will start with this URL.

  • Base URL:

    • What It Is: The main URL of the external API.
    • Variables Enabled: Use variables to make it dynamic based on user settings.
    • Example:
      https://{{subdomain}}.api.example.com
      
      • subdomain is a variable from the user, allowing different users to connect to their own API endpoints.
  • Use Case: Easily connect to different instances of a service (e.g., different Salesforce accounts with unique subdomains).

Headers

Headers are pieces of information sent with each API request, like content type or authorization tokens. They help the API understand how to process your request.

Fields for Headers
  • Header Name:

    • What It Is: The name of the header (e.g., Authorization, Content-Type).
  • Value:

    • What It Is: The value for the header, which can be static or use variables.
    • Example:
      • Authorization:
        "Bearer {{oauth.token.access_token}}"
        
        • Uses the OAuth token.
      • Content-Type: "application/json"
        • Indicates the data format.
  • Add Header:

    • What It Is: Add multiple headers as needed.
    • Use Case: Include headers like User-Agent or Accept-Language for more customized requests.

Example Usage: Base URL and Headers

If you’re connecting to Salesforce to get customer data, here’s how you might set it up:

  • Base URL:

    https://{{subdomain}}.my.salesforce.com
    
    • subdomain comes from the user, ensuring requests go to the correct Salesforce account.
  • Headers:

    1. Authorization:

      • Value:
      "Bearer {{oauth.token.access_token}}"
      
      • Authorizes each request to Salesforce.
    2. Content-Type:

      • Value: "application/json"
      • Specifies that you’re sending JSON data.
    3. User-Agent:

      • Value: "truto"
      • Identifies your integration for logging or debugging.
    4. Sforce-Query-Options (Optional for Salesforce):

      • Value: "batchSize=200"
      • Optimizes data retrieval by limiting the number of records per request.

Here’s a visual of the Base URL and Headers setup:
Base URL and Headers Example

Query Parameters

Query Parameters are used to refine or filter the data retrieved from external APIs. They are appended to the API request URL and help in specifying exactly what data you need. Understanding how to properly format and add query parameters is essential for effective data retrieval and integration performance.

Query Array Format

When a query parameter holds an array, for example one set in a resource method's query or a Unified API query mapping, the Query Array Format determines how its values are written in the URL. The default is Repeat. A resource method can override it. Truto supports the following array formats:

1. Comma

Description: Elements in the array are separated by commas within a single query parameter.

Example:

https://api.example.com/items?colors=red,green,blue

Usage: Use this format when the external API expects array values to be comma-separated.

2. Brackets

Description: Each element in the array is specified with empty brackets [] after the parameter name.

Example:

https://api.example.com/items?colors[]=red&colors[]=green&colors[]=blue

Usage: Use this format when the external API expects array values to be listed with brackets, allowing the server to recognize them as separate elements.

3. Index

Description: Each element in the array is specified with an index inside the brackets [] after the parameter name.

Example:

https://api.example.com/items?colors[0]=red&colors[1]=green&colors[2]=blue

Usage: Use this format when the external API requires indexed array parameters, which can be useful for maintaining the order of elements.

4. Repeat

Description: The same query parameter name is repeated for each element in the array.

Example:

https://api.example.com/items?colors=red&colors=green&colors=blue

Usage: Use this format when the external API expects multiple instances of the same query parameter to represent array values.

Query array format

Adding Query Parameters

To add query parameters to your integration requests in Truto, follow these guidelines:

  1. Identify Required Parameters: Determine which query parameters are needed based on the external API’s documentation.

  2. Choose the Appropriate Array Format: Select one of the supported Query Array Formats (Comma, Brackets, Index, Repeat) that aligns with the external API’s requirements.

  3. Configure the Parameters:

    • Key: The name of the query parameter (e.g., api_version).
    • Value: A single text value, which can use placeholders (e.g., {{api_version}}).
  4. Add to Query Parameters:

    • Navigate to the Query Parameters section of your integration.
    • Enter the key and value. These parameters are added to every request.
    • Specify the chosen Query Array Format.

Example Scenario:

Suppose you are integrating with an API that retrieves products based on selected colors and expects the colors to be provided using the Brackets format.

  • Desired Colors: red, green, blue
  • API Expectation: colors[]=red&colors[]=green&colors[]=blue

Configuration in Truto:

  • Query Array Format: Brackets

Query value: a resource method's query, or a Unified API query mapping, sets colors to an array:

{ "colors": ["red", "green", "blue"] }

Resulting Query URL:

https://api.example.com/products?colors[]=red&colors[]=green&colors[]=blue

Query Parameters

Pagination

The Pagination section helps your integration handle large amounts of data by breaking it into smaller, manageable chunks. This prevents overwhelming the server and avoids hitting rate limits.

Types of Pagination Methods

Different APIs use different ways to paginate data. Truto supports several methods to match these APIs.

For every format, a page that comes back empty ends pagination. To keep returning the next cursor after an empty page, set allow_empty_page_cursor: true in the pagination config in the integration's JSON.

No Pagination

  • Description: Choose this if the API sends all data at once and doesn’t need pagination.

No pagination

Offset-Based Pagination

Offset-Based Pagination is used when the API sends data in chunks based on a starting point (offset).

Fields and Settings:

  • Format: Offset Based

  • Total Record Path:

    • What It Is: The path in the response where the total number of records is found, written as a plain dot path.
    • Example: total_records, or meta.total for a nested field
  • Offset Key:

    • Default: offset
    • What It Is: The query parameter name for the starting point.
  • Default Offset:

    • What It Is: The starting value for the offset.
  • Limit Key:

    • Default: limit
    • What It Is: The query parameter name for the number of items to fetch.
  • Max Limit:

    • Default: 100
    • What It Is: The maximum number of items per request.
  • Use Content Hashing:

    • Default: On
    • What It Is: Prevents endless loops by comparing content between requests.
  • Add Pagination to Query Parameter:

    • Options: Add pagination details to the request body or as query parameters. Click in Add Pagination Header with their Value.
  • Add Pagination Header:

    • What It Is: Define custom headers for pagination.
Example Use Case for Offset-Based Pagination:

Used when APIs need you to specify where to start (offset) and how many records to get (limit).

Offset Pagination


Cursor-Based Pagination

Cursor-Based Pagination is best for APIs that provide a unique pointer (cursor) to the next set of results.

Fields and Settings:

  • Format: Cursor Based

  • Cursor Path Object:

    • Default: Body
    • What It Is: Where the cursor is found in the response: the Body or the Header.
  • Cursor Path:

    • Required: Yes
    • What It Is: The path to the cursor in the response.
  • Previous Cursor Path:

    • What It Is: The path to the previous page's cursor in the response, if the API returns one.
  • Cursor Key:

    • Default: cursor
    • What It Is: The query parameter name for the cursor.
  • Has Next Path:

    • What It Is: Path in the response that shows if more results are available.
  • Limit Key:

    • Default: limit
  • Max Limit:

    • Default: 100
    • What It Is: The largest page size. The limit is added to the request only when the caller passes limit, and is capped at this value.
  • Is Cursor Link:

    • What It Is: If the cursor is a full URL, its query parameters are used to get the next page.
  • Use the path retrieved from the cursor link:

    • What It Is: With Is Cursor Link on, also use the cursor URL's path for the next page.
  • Cursor is URL-encoded:

    • What It Is: Decode the cursor before sending it, for APIs that return URL-encoded cursors.
  • Ignore Limit in Pagination:

    • What It Is: Don’t add the limit parameter if next_cursor is used.
  • Use Content Hashing:

    • Default: Off
    • Prevents endless loops by comparing content. Applies only when the cursor is read from the body.
  • Add Pagination to Request Body or Query Parameter:

    • Same as Offset-Based.

One cursor setting is set in the integration's JSON rather than the form:

Key What it does
limit_data_type number (default) or string. The type of the limit when pagination is added to the request body.

Cursor Pagination


Page-Based Pagination

Page-Based Pagination splits data into pages, each accessed by a page number.

Fields and Settings:

  • Format: Page Based

  • Page Key:

    • Default: page
    • What It Is: The query parameter name for the page number.
  • Limit Key:

    • Default: limit
    • What It Is: Number of items per page.
  • Starting Page:

    • Default: 1
    • What It Is: The first page number to start from.
  • Max Limit:

    • Default: 100
  • Use Content Hashing:

    • Default: On
    • Prevents endless loops by comparing content.
  • Ignore Limit:

    • What It Is: Don’t add the limit parameter to the request.
  • Add Pagination to Request Body or Query Parameter:

    • Same as Offset-Based.
Example Use Case for Page-Based Pagination:

Used when APIs require a page number and limit to fetch specific pages of data.

Page Pagination


Range-Based Pagination

Range-Based Pagination is useful when you specify a range of records instead of pages or cursors.

Fields and Settings:

  • Format: Range Based

  • Default Start Value:

    • Default: 0
    • What It Is: Starting point for data retrieval.
  • Max Limit:

    • Default: 100
    • What It Is: The largest range per request. The first request asks for start = Default Start Value and end = start plus the page size, which is at most Max Limit.
  • Ignore Limit:

    • What It Is: Don’t add the start and end parameters to the request.
  • Add Pagination to Request Body or Query Parameter:

    • Same as Offset-Based.

The parameter names are set in the integration's JSON: start_key (default start) and end_key (default end).

Example Use Case for Range-Based Pagination:

Used when APIs need a specific range or starting point and the number of records to fetch.

Range Pagination


Link Header-Based Pagination uses links in the response headers to access the next pages.

Fields and Settings:

  • Format: Link Header Based

  • Limit Key:

    • Default: per_page
    • What It Is: Number of items per page.
  • Max Limit:

    • Default: 100
    • What It Is: The largest page size. The limit is added to the request only when the caller passes limit, and is capped at this value.
  • Ignore Limit:

    • What It Is: Don’t add the limit parameter to the request.

Link Header-Based pagination always uses query parameters: the next page's URL comes from the Link header.

Common in APIs that include next, previous, or last page links in the response headers (e.g., Link: <https://api.example.com/items?page=2>; rel="next").

Link Header Pagination


Dynamic Pagination

Dynamic pagination is for APIs none of the formats above fit. You write the pagination yourself as three JSONata expressions. In the console, choose Dynamic pagination as the Format.

Fields and Settings:

  • Format: Dynamic pagination (dynamic in the integration's JSON)

  • Initial Pagination Values Expression (get_initial_pagination_values_expression, optional):

    • When it runs: On the first page, when the request has no next_cursor.
    • Receives: url (the request URL), query (the request's query parameters) and requestOptions (the request's options, including headers).
    • Returns: An object with any of the outputs below.
  • Get Pagination Values Expression (get_pagination_values_expression, required):

    • When it runs: On every later page, when the request has a next_cursor.
    • Receives: The same url, query and requestOptions. query.next_cursor is already decoded, so it holds exactly the cursor your Get Cursor From Response Expression returned.
    • Returns: An object with any of the outputs below.
  • Get Cursor From Response Expression (get_cursor_from_response_expression, required):

    • When it runs: After each response whose body is a JSON object or array.
    • Receives: body (the parsed response), results (the records at the method's response path), headers (the response headers), url, query (next_cursor here is still encoded) and paginationValues.
    • Returns: nextCursor (a string, or null when there are no more pages), optionally prevCursor, and optionally isLooping: true to stop and drop the current page. Return an empty object to stop.

Both values expressions return the same outputs, all optional:

Output What it does
query Query parameters merged into the request URL.
body An object merged into the request body.
requestOptions Request options merged into the request, such as headers or method.
url A URL object that replaces the request URL. Build one with $parseUrl().
paginationValues Values the method's query and body templates can read as {{pagination.<key>}}.

Truto base64-encodes nextCursor before returning it as next_cursor, and decodes it again on the next request. As with other formats, an empty page ends pagination unless allow_empty_page_cursor is true in the pagination config.

Example Use Case for Dynamic Pagination:

An API that takes page_size and page_token and returns the next token as next_page_token in the body:

{
  "format": "dynamic",
  "config": {
    "get_initial_pagination_values_expression": "{ \"query\": { \"page_size\": \"100\" } }",
    "get_pagination_values_expression": "{ \"query\": { \"page_size\": \"100\", \"page_token\": query.next_cursor } }",
    "get_cursor_from_response_expression": "{ \"nextCursor\": body.next_page_token ? body.next_page_token : null }"
  }
}

Adding Pagination Headers

For most pagination methods, you can also add specific headers related to pagination:

  • Add Pagination Header:
    • Header Name: Name of the pagination-related header.
    • Value: The value for the header.
    • Variables Enabled: Use variables for dynamic values.

Pagination Headers

Rate Limiting

The Rate Limiting section helps Truto manage how many API requests your integration makes. This prevents you from exceeding the limits set by the external API, which could cause your integration to stop working temporarily.

Why Rate Limiting Matters

External APIs often limit how many requests you can make in a certain time period (like per minute or hour). If you go over these limits, your integration might get blocked. Rate limiting helps avoid these problems by controlling how often your integration makes requests.

How to Set Up Rate Limiting

In Truto, you use JSONata expressions to set up how rate limiting works. These expressions look at the API’s response to decide if you’ve hit the limit and how to handle it.

Rate Limiting Fields and Settings

  1. Is Rate Limited Expression?

    • What It Is: A JSONata expression that checks if your request was rate-limited.
    • Should Return: true or false.
    • Data Available:
      • headers: API response headers. Header names are lowercase.
      • status: HTTP status code.
    • Default: Checks if the status code is 429 (rate limit exceeded).
    • Example Expression:
      status = 429
  2. Rate Limit Headers Expression

    • What It Is: A JSONata expression to get rate limit details from the response headers.
    • Should Return: An object with limit, remaining, and reset.
    • Data Available:
      • headers: API response headers. Header names are lowercase.
      • status: HTTP status code.
    • Example Expression:
      {
        "limit": headers."x-ratelimit-limit",
        "remaining": headers."x-ratelimit-remaining",
        "reset": headers."x-ratelimit-reset"
      }
  3. Retry After Header Expression

    • What It Is: A JSONata expression to get how long to wait before retrying.
    • Should Return: A number of seconds to wait.
    • Data Available:
      • headers: API response headers. Header names are lowercase.
      • status: HTTP status code.
    • Default: Looks for the Retry-After header.
    • Example Expression:
      $number(headers."retry-after")

Rate limit expressions

Default Rate Limiting in Truto

By default, Truto:

  • Checks if the status code is 429.
  • Looks for a Retry-After header to know how long to wait before trying again.

This setup works well for most APIs, but you can customize it with your own JSONata expressions if needed.

Rate Limiting


Error Expressions

The Error Expressions section helps you handle errors from external APIs, especially when those APIs don’t use standard error codes.

What Are Error Expressions?

Error Expressions are JSONata expressions that convert API error responses into standard HTTP status codes and messages. This makes it easier to manage errors consistently, even if the external API has unusual error formats.

Error Expression Fields and Settings

  1. Error Expression (JSONata)
    • What It Is: A JSONata expression that turns API errors into standard error codes and messages.
    • Data Available:
      • response: The entire API response.
      • status: The HTTP status code.
      • headers: Response headers. Header names are lowercase.
      • data: The response body (usually JSON).
        • For a successful (2xx) response that isn't JSON, XML or multipart/mixed, such as a file download, data is empty. Use status and headers for those.
    • Should Return: An object with:
      • status (number): HTTP status code for the error.
      • message (string): A clear error message.
      • metadata (optional): Extra info about the error.
      • headers (optional): Any related headers.
      • result (required when status is below 400): The body to return instead of an error. Use it to turn an error response from the API into a successful one.
    • When to Use: The expression runs on every response, successful or not. Return an object only when the response is an error. Otherwise return nothing (undefined), and Truto handles the response as usual. Returning a status below 400 without a result fails the request.
    • Example Expression:
      data.errorCode or status >= 400 ? {
        "status": data.errorCode = "INVALID_TOKEN" ? 401 : (status >= 400 ? status : 500),
        "message": data.message ? data.message : "Unknown error occurred",
        "metadata": data,
        "headers": headers
      }
    • Explanation:
      • The object is returned only when the body has an errorCode or the status is 400 or above.
      • If data.errorCode is "INVALID_TOKEN", set status to 401 (Unauthorized). Other errors in a successful response become 500.
      • Use data.message if available; otherwise, use a generic message.
      • Include metadata and headers for more details.

Error expression

Example Use Case: Salesforce Integration Error Handling

Suppose Salesforce sometimes returns custom errors like this:

{
  "errorCode": "INSUFFICIENT_ACCESS",
  "message": "You do not have permission to perform this action"
}

You can handle it with this Error Expression:

data.errorCode or status >= 400 ? {
  "status": data.errorCode = "INSUFFICIENT_ACCESS" ? 403 : (status >= 400 ? status : 500),
  "message": data.message ? data.message : "Unknown error occurred",
  "metadata": data
}
  • Status: "INSUFFICIENT_ACCESS" becomes 403 (Forbidden).
  • Message: Uses the message from Salesforce.
  • Metadata: Includes the whole error response for more info.

Benefits of Using Error Expressions

  1. Consistency: Handle errors the same way, making it easier to manage.
  2. Customization: Tailor error handling to fit the API’s specific needs.
  3. Better User Experience: Provide clear and understandable error messages.

Resources

The Resources section is where you define what data your integration will work with and what actions you can perform on that data. It helps you organize the main functions of your integration.

Truto's CRUD Model

Truto uses the CRUD model (Create, Read, Update, Delete) to define resources. For each type of data, you set up different actions you can do with it. This keeps your integration consistent and complete.

Here are the main parts of Resources:

  1. Resource Name: The type of data, like accounts, contacts, invoices, etc.
  2. Operations (Methods): The actions you can perform on the data, following CRUD:
    • List: Get all items (GET).
    • Get: Get one item by ID (GET).
    • Create: Add a new item (POST).
    • Update: Change an existing item (PATCH or PUT).
    • Delete: Remove an item (DELETE).

Key Elements of Resources Configuration

  1. Resource Name:

    • What It Is: A name that identifies the type of data.
    • Example: accounts, contacts, orders.
    • Use Case: In Salesforce, a resource could be named accounts.
  2. Operations (Methods): Each Resource can have several methods that define what actions you can take:

    • List:

      • Path: The endpoint to get all records.
      • Method: GET
      • Example: /services/data/v57.0/query - Gets a list of accounts.
      • Response Path: Where the data array is in the response.
        • Example: In Salesforce, data might be under records.
        • Use Case: Helps Truto find the list of items in the response.
    • Get:

      • Path: The endpoint to get a specific record.
      • Method: GET
      • Example:
        /services/data/v57.0/sobjects/Account/{{id}}
        
        • Gets a specific account by id.
      • Variables Enabled: Use placeholders like {{id}} to get specific records.
    • Create:

      • Path: The endpoint to add new records.
      • Method: POST
      • Body Format: Usually JSON.
      • Example: /services/data/v57.0/sobjects/Account - Adds a new account.
      • Body: The default data sent when creating a new record.
    • Update:

      • Path: The endpoint to change existing records.
      • Method: PATCH or PUT
      • Example:
        /services/data/v57.0/sobjects/Account/{{id}}
        
        • Updates an existing account by id.
      • Body Format: Usually JSON.
      • Body: The data you want to update.
    • Delete:

      • Path: The endpoint to delete a record.
      • Method: DELETE
      • Example:
        /services/data/v57.0/sobjects/Account/{{id}}
        
        • Deletes a specific account by id.

Response Path and API Response Format

  • Response Path:
    • What It Is: The location in the API response where the actual data is found.
    • Example: In Salesforce, account records might be under records.
    • Use Case: Helps Truto find the list or specific item in the API’s response.

Resource method response path

  • API Response Format:
    • Default: Detect from response
    • What It Is: The expected format of the API response.
    • Example: application/json or text/html.
    • Note: Change it if the API doesn’t set the Content-Type correctly.

Query Parameters

Query Parameters let you filter or refine the data you’re retrieving. These can be dynamic, using placeholders that get replaced when the integration runs.

Resource method query parameters

Headers and Authentication Options

  • Headers:

    • Each operation can have its own headers.
    • Example: The Authorization header is usually needed to make secure requests.
  • No Auth:

    • Allows sending requests without authentication headers.
    • Use Only If: The API is public or doesn’t need authentication.

Resource method headers

Override Options

Sometimes, specific methods need different settings from the rest of the integration:

  1. Override Base URL:

    • Use a different base URL for this method.
  2. Override Pagination:

    • Use a different pagination method for this method.
  3. Override Query Array Format:

    • Change how query arrays are formatted for this method.
  4. Override Error Expression:

    • Use a custom error-handling expression for this method.

Resource method overrides

Actions

The Actions section lets you set up automated tasks that run at set points in a connected account's life. These tasks can gather information, update settings, make requests, or perform specific operations. Actions help make your integrations work smoothly without manual steps.

When Actions Run

Each action is stored under a key in the integration's actions, and the key decides when it runs:

  • post_install (Post-install): Runs right after an account connects. While it runs, the account is connecting. If it fails, the account moves to post_install_error.
  • validation: Runs after post_install succeeds, to check the connection works. If it fails, the account moves to validation_error. You can also run it again on an existing account.
  • post_connect_user_form: A form shown to the user on the connect screen after the account connects, to collect more details.
  • refresh_token (Scheduled action): Runs on a schedule, every set number of seconds (Duration) or on a Cron Expression. Turn on Reactivate auth to make an account active again when the scheduled action succeeds.

Types of Steps

Here’s how actions typically work in Truto:

  1. Get Context: Collect initial information needed for the integration.
  2. Transform: Change or enhance the collected information using JSONata.
  3. Update Context: Save the collected or transformed data for later use.
  4. Set Context: Update specific values in the integration’s context.
  5. Request: Make API requests to get or change data in real time.

Types of Steps in Detail

Action step type picker

1. Get Context

  • What It Is: Collect initial data from the connected account, like subdomains or API keys.
  • Example: Getting the user’s Salesforce subdomain when connecting to Salesforce.

2. Transform

  • What It Is: Modify or enhance the collected data using a JSONata expression.
  • JSONata Example:
    {
      "label": $.subdomain
    }
    • Explanation: Creates a label from the subdomain to make the account easier to recognize.

3. Update Context

  • What It Is: Save the transformed data for future use in the integration.
  • Example: Saving the Salesforce label so users can easily see their connected Salesforce account.

4. Set Context

  • What It Is: Set or update specific key-value pairs in the integration’s context.
  • Use Case: Storing user credentials securely for future API calls.

5. Request

  • What It Is: Make specific API calls to fetch or change data.
  • Use Case: After connecting to Salesforce, verify account details by fetching additional user information.
  • Request Type Fields:
    • Request type: Proxy API calls one of the integration's resources. Unified API calls a Unified API resource, such as crm/contacts.
    • Resource: The resource to act on, like "accounts" or "contacts."
    • Method to Call: The resource method to run, such as list, get, create, update, delete, or a custom method.
    • ID: The record ID, for the get method.
    • Body: The data sent with the request, for methods like create or update.
    • Query: Add query parameters to refine or filter data.
    • Throw error: On by default, so a failed request fails the action. Turn it off to pass the error to the next step, such as a Transform, instead.
    • Run conditionally: Run the step only when a JSONata expression returns true.

Salesforce Example: Setting Up Actions

Here’s how you might set up actions when connecting a Salesforce account:

  1. Step 1: Get Context:

    • Type: Get Context
    • Action: Retrieve the Salesforce subdomain provided by the user.
    • Use Case: Needed to make API requests to the correct Salesforce instance.
  2. Step 2: Transform:

    • Type: Transform
    • JSONata Expression:
      {
        "label": $.subdomain
      }
    • Explanation: Creates a user-friendly label using the subdomain.
  3. Step 3: Update Context:

    • Type: Update Context
    • Action: Save the label so users can easily identify their Salesforce account.

Example of Salesforce Action Setup

Here’s how the Salesforce integration might look after setting up actions:

Salesforce Actions

After connecting the account, the label appears like this, making it easy to recognize:

Salesforce Integrated Account Label

Webhooks

Webhooks let you receive real-time notifications from other systems when certain events happen. This section explains how to set up and handle incoming webhook events and any necessary verification.

Incoming webhooks are verified by the integration's webhook config, not by Actions. Truto applies its three keys to each incoming request in this order:

  • payload_transform — a JSONata expression that reshapes the incoming request (body, raw_body, headers, query_params, context) before anything else runs.
  • handle_verification — a JSONata expression that returns an object with type. Return verify to answer a vendor's verification handshake, or payload (or meta) to process the request as an event.
  • signature_verification — checks that an event came from the vendor. format is hmac, basic, bearer or jwt, and config holds the secret, algorithm and the parts of the request to sign or compare. A request that fails the check is rejected with a 400.

For more details, check out the Webhooks Documentation.

RapidForm

RapidForm helps you create customizable forms to collect user input during the integration process. You can use it to gather required credentials or other information needed to set up your integration successfully. Learn more in the RapidForm Documentation.