Passthrough

Rutter offers two passthrough features to extend your integration capabilities:

  1. Field-Level Passthrough - Inject platform-specific fields into Rutter API requests
  2. Connection Credentials Passthrough - Fetch underlying API keys and tokens to make direct API calls to platforms

Field-Level Passthrough

Field-level passthrough allows you to bypass Rutter's standard field mapping and inject specific fields into requests sent to accounting platforms like Xero or QuickBooks Online. This gives you precise control over platform-specific functionality that may not be available through Rutter's unified API.

Overview

This feature works through two key components:

  1. Passthrough Object - A request body field that contains platform-specific fields to inject
  2. Preview Mode - A query parameter that lets you inspect the exact request body before sending it to the platform

Passthrough Object

Include a passthrough object at the root level of your request body to specify platform-specific fields. These fields are merged directly into the request sent to the accounting platform.

Basic Example

Creating a Xero account with custom tax type:

1
{
2
"account": {
3
"account_type": "bank",
4
"currency_code": "USD",
5
"name": "Bowlable Inc",
6
"nominal_code": "200",
7
"additional_fields": {
8
"bank_account_number": "17837937892"
9
}
10
},
11
"passthrough": {
12
"TaxType": "OUTPUT2",
13
"BankAccountNumber": "1"
14
}
15
}

Platform Request Body:

1
{
2
"Name": "Bowlable Inc",
3
"Code": "200",
4
"Type": "BANK",
5
"BankAccountNumber": "1",
6
"CurrencyCode": "USD",
7
"TaxType": "OUTPUT2"
8
}

Array Handling

For endpoints that work with arrays (like invoice line items), use array positioning to target specific items. Empty objects ({}) act as placeholders for items you don't want to modify.

Example: Adding a discount to the second line item only:

1
{
2
"invoice": {
3
"line_items": [
4
{
5
"account_id": "7720610c-b84e-429f-96fe-75f0592ca60e",
6
"total_amount": 12.34,
7
"description": "A Rutter Shirt"
8
},
9
{
10
"account_id": "7720610c-b84e-429f-96fe-75f0592ca60e",
11
"total_amount": 12.34,
12
"description": "A Rutter Shirt"
13
}
14
]
15
},
16
"passthrough": {
17
"LineItems": [
18
{},
19
{
20
"DiscountAmount": 4
21
}
22
]
23
}
24
}

Platform Request Body:

1
{
2
"Contact": {},
3
"LineItems": [
4
{
5
"Description": "A Rutter Shirt",
6
"Quantity": "1",
7
"UnitAmount": 12.34,
8
"AccountCode": "12355"
9
},
10
{
11
"Description": "A Rutter Shirt",
12
"Quantity": "1",
13
"UnitAmount": 12.34,
14
"DiscountAmount": 4,
15
"AccountCode": "12355"
16
}
17
],
18
"InvoiceID": "f2117612-94c0-49b5-aca7-eaebb9244b13"
19
}

Preview Mode

Use the preview=true query parameter to see the exact JSON payload that will be sent to the accounting platform without actually executing the request.

1
POST https://production.rutterapi.com/accounting/invoices?preview=true

Response:

1
{
2
"platform_request_body": {
3
// ... the actual JSON payload sent to Xero/QuickBooks Online ...
4
}
5
}

This lets you verify the request structure against the platform's API documentation before committing to the operation.

Workflow

  1. Design your request with standard Rutter fields and any platform-specific fields in the passthrough object
  2. Test with preview mode by adding preview=true to inspect the generated platform request
  3. Verify against platform docs to ensure the request structure matches the platform's API requirements
  4. Execute the request by removing the preview parameter to perform the actual operation

Platform Support

Field-level passthrough is available for:

  • Platforms: All accounting platforms except Sage Intacct
  • Endpoints: All accounting POST and PATCH endpoints

Important Considerations

Platform-Specific Fields: Fields in the passthrough object must adhere to the target platform's API requirements. Consult the platform's documentation for correct field names, data types, and validation rules.

Field Overwrites: Passthrough fields can overwrite fields generated by Rutter's standard mapping. Use carefully to avoid unintended data conflicts.

No Validation: Rutter does not perform any validation on passthrough fields. You're responsible for ensuring field validity for the target platform.

Error Handling: Invalid passthrough fields will generate errors from the accounting platform, which Rutter will relay in the response.

For platform-specific field references, consult the platform's API documentation. For example:

Connection Credentials Passthrough

This feature allows you to fetch the underlying API keys and tokens that are used to make authenticated requests for each platform. Depending on the type of authentication used in the underlying platform, different fields may be returned. You should view the platform-specific API pages to properly format your request.

Fetch Connection Credentials

1
GET https://production.rutterapi.com/versioned/connections/credentials

This endpoint is available on the following platforms:

  • Accounting: Dynamics 365, FreeAgent, FreshBooks, NetSuite, QuickBooks, Sage Business Cloud, Sage Intacct, Wave, Xero, Zoho Books
  • Ads: Facebook, Google, TikTok
  • Commerce: Amazon, BigCommerce, Chargebee, Chargify, eBay, Etsy, Lazada, Magento, MercadoLibre, PayPal, Recurly, Shopify, Shopee, Shoper, Squarespace, Stripe, Walmart, Wix, WooCommerce

OAuth

If the credential type is oauth, then an access_token property will be included along with any other required pieces of information to make a direct API call. This can be used to make authenticated requests to the platform directly.

Note: Refresh Tokens are not returned, to prevent loss of access.

1
{
2
"credential": {
3
"type": "oauth",
4
"access_token": "ACCESS_TOKEN",
5
"store_url": "test.myshopify.com"
6
},
7
"connection": {
8
"id": "0f801665-5caa-4717-8ff0-9bfdb351ce11",
9
"platform": "SHOPIFY"
10
}
11
}

OAuth 1.0a

If the credential type is oauth1.0a, then the four fields necessary to generate an authenticated request are returned. A sample response is below:

1
{
2
"credential": {
3
"type": "oauth1.0a",
4
"oauth_consumer_key": "CONSUMER_KEY",
5
"oauth_consumer_secret": "CONSUMER_SECRET",
6
"oauth_token": "OAUTH_TOKEN",
7
"oauth_token_secret": "OAUTH_TOKEN_SECRET"
8
},
9
"connection": {
10
"id": "0f801665-5caa-4717-8ff0-9bfdb351ce02",
11
"platform": "ETSY"
12
}
13
}

Basic

If the credential type is basic, then the platform API uses Basic Access authentication.

1
{
2
"credential": {
3
"type": "basic",
4
"username": "USERNAME",
5
"password": "PASSWORD"
6
},
7
"connection": {
8
"id": "0f801665-5caa-4717-8ff0-9bfdb351ce02",
9
"platform": "SHOPIFY"
10
}
11
}

Query Params

access_token string

The access token of the connection.

Response Body

A sample response body can be found below.

1
{
2
"credential": {
3
"type": "oauth1.0a",
4
"oauth_consumer_key": "CONSUMER_KEY",
5
"oauth_consumer_secret": "CONSUMER_SECRET",
6
"oauth_token": "OAUTH_TOKEN",
7
"oauth_token_secret": "OAUTH_TOKEN_SECRET"
8
},
9
"connection": {
10
"id": "0f801665-5caa-4717-8ff0-9bfdb351ce02",
11
"platform": "ETSY"
12
}
13
}

Once you have the underlying credentials of the Rutter connection, you will now be able to call the underlying platform APIs to take actions that are not available in Rutter's built-in endpoints.

NetSuite

NetSuite offers multiple passthrough methods for accessing data and functionality beyond Rutter's built-in endpoints. Start by getting your platform credentials using the GET /connections/credentials endpoint described above.

Authentication Setup

All NetSuite passthrough requests require OAuth 1.0a authentication. The credentials response will include:

  • oauth_consumer_key
  • oauth_consumer_secret
  • oauth_token
  • oauth_token_secret
  • realm (your NetSuite account ID)

You'll need to generate the OAuth signature for each request following the OAuth 1.0a specification.

Additionally, the oauth_signature_method must be set to "HMAC-SHA256".

Use NetSuite's SQL-like query language to retrieve data from standard tables.

Endpoint:

1
POST https://{{account_id}}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql?offset=0&limit=1000

Headers:

1
Prefer: transient
2
Content-Type: application/json
3
Authorization: OAuth realm="{{realm}}",oauth_consumer_key="{{oauth_consumer_key}}",oauth_token="{{oauth_token}}",oauth_signature_method="HMAC-SHA256",oauth_timestamp="{{timestamp}}",oauth_nonce="{{nonce}}",oauth_version="1.0",oauth_signature="{{signature}}"

Request Body:

1
{
2
"q": "SELECT id, tranid, entity FROM transaction WHERE type = 'Invoice'"
3
}

Example cURL:

1
curl --location 'https://{{account_id}}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql?offset=0&limit=1000' \
2
--header 'Prefer: transient' \
3
--header 'Content-Type: application/json' \
4
--header 'Authorization: OAuth realm="{{realm}}",oauth_consumer_key="{{oauth_consumer_key}}",oauth_token="{{oauth_token}}",oauth_signature_method="HMAC-SHA256",oauth_timestamp="{{timestamp}}",oauth_nonce="{{nonce}}",oauth_version="1.0",oauth_signature="{{signature}}"' \
5
--data '{
6
"q": "SELECT id, tranid, entity FROM transaction WHERE type = '\''Invoice'\''"
7
}'

Common SuiteQL Tables:

  • transaction - All transaction records (invoices, bills, payments, etc.)
  • customer - Customer records
  • vendor - Vendor records
  • item - Inventory and service items
  • account - Chart of accounts
  • employee - Employee records

See NetSuite's SuiteQL documentation for complete table reference.

2. Rutter's Custom RESTlet

Rutter provides a custom SuiteScript RESTlet to support specific use cases.

Base Endpoint:

1
https://{{account_id}}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=customscript_accountlink&deploy=customdeploy_accountlink

Get Paginated Records

Parameters:

  • function=getRecordPagedData
  • recordType - The NetSuite record type (required)
  • pageSize - Number of records per page (default: 20, max: 1000)
  • pageIndex - Page number (starts at 0)
  • lastModifiedDate - Filter for records modified after this date (ISO format)
  • beforeLastModifiedDate - Filter for records modified before this date (ISO format)

Example:

1
GET https://{{account_id}}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=customscript_accountlink&deploy=customdeploy_accountlink&function=getRecordPagedData&recordType=invoice&lastModifiedDate=2024-01-01T00:00:00.000Z&pageSize=100&pageIndex=0

Get Single Record

Parameters:

  • function=getRecordById
  • recordType - The NetSuite record type
  • id - The internal ID of the record

Example:

1
GET https://{{account_id}}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=customscript_accountlink&deploy=customdeploy_accountlink&function=getRecordById&recordType=invoice&id=12345

Get Multiple Specific Records

Parameters:

  • function=getRecordsOfIds
  • recordType - The NetSuite record type
  • ids - Comma-separated list of internal IDs

Example:

1
GET https://{{account_id}}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=customscript_accountlink&deploy=customdeploy_accountlink&function=getRecordsOfIds&recordType=invoice&ids=123,456,789

Supported Record Types

Record TypeDescription
classificationClass records
creditcardchargeCredit card charges
creditcardrefundCredit card refunds
creditmemoInvoice credit memos
currencyCurrency records
customerCustomer records
customerpaymentCustomer payments
departmentDepartment records
inventoryitemInventory items
invoiceSales invoices
itemAll item records
journalentryJournal entries
locationLocation records
othernameOther name records
purchaseorderPurchase orders
salestaxitemSales tax items
subsidiarySubsidiary records
vendorVendor records
vendorbillBills
vendorcreditBill credit memos
vendorpaymentBill payments

3. File Operations

Download Files

Endpoint:

1
GET https://{{account_id}}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=customscript_accountlink&deploy=customdeploy_accountlink&function=getFile&id={{file_id}}

Parameters:

  • id - The NetSuite file ID

4. Custom Operations

For create, update, or delete operations, use the POST method with the RESTlet:

Endpoint:

1
POST https://{{account_id}}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=customscript_accountlink&deploy=customdeploy_accountlink

Request Body: Include the operation details and data in the request body as JSON. For example payloads, head to the NetSuite Request Logs in your Rutter Dashboard and expand the "Rutter -> Platform Request Body" toggle.

Best Practices

  1. Use SuiteQL when possible - It's more efficient and follows NetSuite's modern API patterns
  2. Implement proper error handling - NetSuite APIs can return various error types
  3. Respect rate limits - NetSuite has governance limits on API calls
  4. Use pagination - Always paginate large result sets to avoid timeouts
  5. Filter by date - Use date filters to reduce data transfer and improve performance

Error Handling

Common NetSuite error responses include:

  • INVALID_LOGIN_CREDENTIALS - Authentication failed
  • EXCEEDED_REQUEST_LIMIT - Rate limit exceeded
  • INVALID_RECORD_TYPE - Unsupported record type
  • RECORD_NOT_FOUND - Record doesn't exist

Additional Resources

For additional platform-specific passthrough guidance, please contact Rutter Support.