Passthrough
Rutter offers two passthrough features to extend your integration capabilities:
- Field-Level Passthrough - Inject platform-specific fields into Rutter API requests
- 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:
- Passthrough Object - A request body field that contains platform-specific fields to inject
- 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.
1POST 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
- Design your request with standard Rutter fields and any platform-specific fields in the
passthrough
object - Test with preview mode by adding
preview=true
to inspect the generated platform request - Verify against platform docs to ensure the request structure matches the platform's API requirements
- 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
andPATCH
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
1GET 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"
.
1. SuiteQL Queries (Recommended)
Use NetSuite's SQL-like query language to retrieve data from standard tables.
Endpoint:
1POST https://{{account_id}}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql?offset=0&limit=1000
Headers:
1Prefer: transient
2Content-Type: application/json
3Authorization: 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:
1curl --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 recordsvendor
- Vendor recordsitem
- Inventory and service itemsaccount
- Chart of accountsemployee
- 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:
1https://{{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:
1GET 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 typeid
- The internal ID of the record
Example:
1GET 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 typeids
- Comma-separated list of internal IDs
Example:
1GET 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 Type | Description |
---|---|
classification | Class records |
creditcardcharge | Credit card charges |
creditcardrefund | Credit card refunds |
creditmemo | Invoice credit memos |
currency | Currency records |
customer | Customer records |
customerpayment | Customer payments |
department | Department records |
inventoryitem | Inventory items |
invoice | Sales invoices |
item | All item records |
journalentry | Journal entries |
location | Location records |
othername | Other name records |
purchaseorder | Purchase orders |
salestaxitem | Sales tax items |
subsidiary | Subsidiary records |
vendor | Vendor records |
vendorbill | Bills |
vendorcredit | Bill credit memos |
vendorpayment | Bill payments |
3. File Operations
Download Files
Endpoint:
1GET 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:
1POST 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
- Use SuiteQL when possible - It's more efficient and follows NetSuite's modern API patterns
- Implement proper error handling - NetSuite APIs can return various error types
- Respect rate limits - NetSuite has governance limits on API calls
- Use pagination - Always paginate large result sets to avoid timeouts
- Filter by date - Use date filters to reduce data transfer and improve performance
Error Handling
Common NetSuite error responses include:
INVALID_LOGIN_CREDENTIALS
- Authentication failedEXCEEDED_REQUEST_LIMIT
- Rate limit exceededINVALID_RECORD_TYPE
- Unsupported record typeRECORD_NOT_FOUND
- Record doesn't exist
Additional Resources
For additional platform-specific passthrough guidance, please contact Rutter Support.