Tray.ai (Tray.io) Integration Capabilities for Complex ERP Orchestration

Type: ERP Integration System: Tray.ai Universal Automation Cloud (UAC 2025) Confidence: 0.83 Sources: 7 Verified: 2026-03-03 Freshness: 2026-03-03

TL;DR

System Profile

Tray.ai (rebranded from Tray.io in 2024) is a cloud-native iPaaS built on the Universal Automation Cloud (UAC) architecture. It targets technical teams that need full control over integration logic while also enabling business technologists through low-code and AI-assisted build experiences. Unlike MuleSoft's API-led connectivity model or Workato's recipe-centric approach, Tray takes a workflow-first approach with deep support for branching, looping, conditional logic, and parallel execution.

The platform operates across three tiers: Pro (entry-level), Team (mid-market), and Enterprise (full governance). All tiers share the same runtime engine but differ in task credits, workspace count, log retention, and governance controls. Tray does NOT offer an on-premise deployment option — it is cloud-only, hosted on AWS.

PropertyValue
VendorTray.ai (formerly Tray.io)
SystemUniversal Automation Cloud (UAC) 2025
API SurfaceREST, GraphQL (Embedded API), Webhook triggers, Connector SDK (TypeScript)
Current Platform VersionUAC 2025 (continuous release)
Editions CoveredPro, Team, Enterprise
DeploymentCloud (AWS-hosted, multi-tenant)
API DocsTray.ai Documentation
StatusGA

API Surfaces & Capabilities

Tray.ai exposes multiple API surfaces for building integrations, managing workflows programmatically, and embedding integration capabilities into external products.

API SurfaceProtocolBest ForKey CapabilityRate LimitReal-time?Bulk?
Workflow REST TriggersHTTPS/JSON WebhookInbound event-driven integrationsTrigger workflows from external systems429 at high volumeYesNo
Tray Code APIs (Connectivity, Trigger, Auth)HTTPS/JSONProgrammatic connector accessSingle interface to 700+ apps30 req/sYesNo
GraphQL Embedded APIHTTPS/GraphQLWhite-label integration UXManage workflows, auth, users programmatically30 req/sYesNo
Call Connector APIHTTPS/JSONDirect connector operation callsExecute connector ops from external code1,000 concurrentYesNo
HTTP Client (Universal)HTTPS/JSON/XMLAny REST/SOAP API without native connector15-min timeout, custom authPer-target limitsYesYes
Connector Builder (CDK)TypeScript SDKCustom connectors for unsupported systemsImport OpenAPI specs or build from scratchN/A (build-time)N/AN/A
CSV/File ConnectorsHTTPS/CSV/XMLBulk file-based data movementUp to 1 GB CSV processing60-min timeoutNoYes

Rate Limits & Quotas

Per-Request Limits

Limit TypeValueApplies ToNotes
Data between workflow steps6 MBAll connectorsChunk larger payloads using Data Storage or file connectors
Webhook trigger payload1 MBInbound webhooks10 MB for multipart file uploads
Trigger event reply body1 MBSynchronous webhook responsesResponse to calling system
Webhook response size2 MBOutbound responsesApplies to "await workflow and respond" mode
CSV row size8 KBCSV EditorPer-row limit within CSV processing
CSV max columns4,096CSV EditorPer-file column limit
Data Storage single key400 KBKey-value data storage32 levels max nesting depth

Rolling / Daily Limits

Limit TypeValueWindowEdition Differences
API rate limit30 req/s (1,800/min)Per second, rollingAll editions; burst to 50 req/s momentarily
Call Connector concurrency1,000 concurrent requestsConcurrentConcurrency-limited, not rate-limited
Task credits (Pro)250,000 starter creditsMonthlyOverage charged per credit
Task credits (Team)500,000 starter creditsMonthlyOverage charged per credit
Task credits (Enterprise)750,000 starter creditsMonthlyCustom negotiation available
Workspaces (Pro)3Per account--
Workspaces (Team)20Per account--
Workspaces (Enterprise)UnlimitedPer account--

Timeout Limits

ComponentTimeoutNotes
Standard connectors45 seconds120 seconds for CDK-built connectors
HTTP Client (universal)15 minutesResponse wait time for custom API calls
CSV/Redshift connectors60 minutesException for bulk data operations
Webhook trigger (sync)5 minutesWhen using trigger event reply
Callable workflow responseNo timeoutCan run indefinitely
Authentication refreshImmediate 1st retry2nd-3rd retries wait ~20 seconds

Authentication

Tray.ai provides a centralized authentication store that manages credentials for all connected services. Workflows reference stored auth objects rather than embedding credentials directly.

FlowUse WhenToken LifetimeRefresh?Notes
OAuth 2.0 Authorization CodeUser-context operations, most SaaS appsPer-service defaultYes (automatic)Default and preferred flow; supports PKCE
OAuth 2.0 Client CredentialsServer-to-server, machine-to-machinePer-service defaultYes (automatic)For APIs that don't need user context
API KeySimple service auth (Stripe, SendGrid, etc.)Until revokedN/AStored encrypted in Tray vault
Basic AuthLegacy systems, on-premise APIsPer-sessionN/AUsername/password stored encrypted
Custom Service AuthNon-standard auth flowsVariableConfigurableBuild custom auth via Connector Builder

Authentication Gotchas

Constraints

Integration Pattern Decision Tree

START -- User needs to integrate ERP systems using Tray.ai
|-- What's the integration pattern?
|   |-- Real-time (individual records, <1s latency)
|   |   |-- Target system has native Tray connector?
|   |   |   |-- YES --> Use native connector in workflow with webhook trigger
|   |   |   |-- NO --> Use HTTP Client connector with custom auth
|   |   |-- Data payload < 6 MB per step?
|   |   |   |-- YES --> Direct step-to-step data passing
|   |   |   |-- NO --> Use Data Storage or file intermediary
|   |   |-- Need synchronous response?
|   |       |-- YES --> Webhook with "Await workflow and respond" (5-min timeout)
|   |       |-- NO --> Webhook with "Auto respond 200" + async processing
|   |-- Batch/Bulk (scheduled, high volume)
|   |   |-- Data volume < 1,000 records?
|   |   |   |-- YES --> Loop connector with native connector steps
|   |   |   |-- NO --> CSV connector (up to 1 GB) + callable workflow for parallel
|   |   |-- Need to stay within task credit budget?
|   |       |-- YES --> Minimize loop iterations; use bulk API calls
|   |       |-- NO --> Standard loop + individual record operations
|   |-- Event-driven (webhook, CDC)
|   |   |-- Source system can push webhooks?
|   |   |   |-- YES --> Webhook trigger on Tray workflow
|   |   |   |-- NO --> Scheduled polling workflow
|   |   |-- Need guaranteed delivery?
|   |       |-- YES --> Add Data Storage queue + dead letter workflow
|   |       |-- NO --> Direct webhook trigger processing
|   |-- File-based (CSV/XML import/export)
|       |-- File size < 1 GB?
|       |   |-- YES --> CSV/File connector with 60-min timeout
|       |   |-- NO --> Split files externally before ingestion
|       |-- Need transformation?
|           |-- YES --> CSV Editor step (8 KB/row, 4,096 col max)
|           |-- NO --> Direct file pass-through
|-- Which direction?
|   |-- Inbound --> Check target system rate limits + Tray 30 req/s limit
|   |-- Outbound --> Check source system pagination + 6 MB step limit
|   |-- Bidirectional --> Design conflict resolution in workflow logic FIRST
|-- Error tolerance?
    |-- Zero-loss required --> Data Storage queue + callable retry + error workflow
    |-- Best-effort --> Standard retry policy (3 retries, 40s interval)

Quick Reference

Platform Capability Comparison

CapabilityTray.aiWorkatoMuleSoftCeligo
ApproachWorkflow-first, visual + codeRecipe-based, low-codeAPI-led connectivityERP-centric templates
Connectors700+1,000+400+ (Exchange)200+ (ERP-focused)
AI AssistantMerlin AI (NLP to workflow)Workato CopilotEinstein AIAuto-mapping
Code AccessTray Code (3 APIs), JS in stepsLimited custom codeFull Java/Mule DSLJavaScript transforms
ERP DepthMedium -- strong NetSuite, weak SAPStrong -- broad ERP coverageDeep -- Salesforce-nativeDeep -- NetSuite/Salesforce-native
Pricing ModelTask credits (per step)Recipes + connectionsvCores + API callsFlows + connections
Starting Price~$600/mo (Pro)~$10K/year~$15K/year~$500/mo
DeploymentCloud-onlyCloud-onlyCloud + on-premiseCloud-only
Embedded/OEMYes (GraphQL Embedded API)Yes (Embedded platform)Limited (API Manager)No
SecuritySOC 2 Type 2, HIPAA, GDPRSOC 2 Type 2, HIPAASOC 2, ISO 27001SOC 2 Type 2

Step-by-Step Integration Guide

1. Create a Tray.ai Workflow with Webhook Trigger

Set up the workflow entry point that will receive events from an ERP system. [src3]

// In Tray Build: Create new workflow
// 1. Click "Create Workflow"
// 2. Select "Webhook" trigger
// 3. Choose "Auto respond with status 200" for high-volume
//    or "Await workflow and respond" for sync responses
// 4. Copy the generated webhook URL

const webhookUrl = "https://YOUR_TRAY_WEBHOOK_URL";

const response = await fetch(webhookUrl, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    event: "order_created",
    order_id: "ORD-12345",
    customer: { name: "Acme Corp", erp_id: "CUST-001" },
    line_items: [
      { sku: "WIDGET-A", qty: 100, unit_price: 25.00 }
    ]
  })
});

Verify: Check Tray workflow logs for the incoming event --> expected: trigger received with payload visible in step output.

2. Add Connector Steps for ERP Read/Write Operations

Configure the target ERP connector (e.g., NetSuite, Salesforce) to process the incoming data. [src5]

// In Tray Build: Add connector step after trigger
// 1. Search connector library for target system (e.g., "NetSuite")
// 2. Select operation (e.g., "Create Record" or "Search Records")
// 3. Map input fields from trigger payload using JSONPath:
//    $.steps.trigger.body.customer.erp_id --> NetSuite Customer Internal ID
//    $.steps.trigger.body.line_items --> Loop connector input

// For systems without native connector (e.g., SAP):
// Use HTTP Client connector:
// - Method: POST
// - URL: https://your-sap-instance.com/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder
// - Headers: { "Authorization": "Bearer {auth.token}" }
// - Body: Map from trigger payload with Data Mapper

Verify: Step output shows the created/updated record ID from the target ERP system.

3. Implement Error Handling with Boolean and Branch Steps

Add conditional logic to handle partial failures and route errors. [src1]

// In Tray Build: Add error handling
// 1. After each connector step, add a "Boolean" step
//    Condition: $.steps.previous.error IS NOT NULL
// 2. TRUE branch: Route to error handler
//    - Log error to Data Storage (for dead letter queue)
//    - Send alert via Slack/email connector
// 3. FALSE branch: Continue to next step

// For retry logic:
// - Use "Callable Workflow" trigger for the retry workflow
// - Store failed records in Data Storage with key = record_id
// - Scheduled workflow polls Data Storage every 15 min for retries
// - Max 3 retries before routing to manual review queue

Verify: Trigger a test failure (invalid record ID) --> expected: error branch executes, record stored in Data Storage.

4. Handle High-Volume Data with Loop and Chunking

Process bulk records while staying within Tray platform limits. [src1]

// In Tray Build: Bulk processing pattern
// 1. Use "List Helpers - Chunk" step to split large arrays
//    Input: $.steps.trigger.body.records (e.g., 5,000 items)
//    Chunk size: 200 (to stay well under 6 MB step limit)
//
// 2. Use "Loop" connector over chunks
//    For each chunk:
//      a. Call target ERP connector with batch operation
//      b. Collect results
//      c. Add "Delay" step (1-2 seconds) to avoid target system rate limits
//
// 3. Alternatively: Use "Callable Workflow" for parallel processing
//    Main workflow: chunks data, calls child workflow per chunk
//    Child workflow: processes single chunk, returns results

// IMPORTANT: Each loop iteration = 1 task credit per step inside the loop
// 5,000 records / 200 per chunk = 25 chunks
// 5 steps per chunk = 125 task credits

Verify: Monitor workflow execution logs --> expected: all chunks processed, total task credits match estimate.

Code Examples

Python: Trigger a Tray Workflow via Webhook

# Input:  Webhook URL from Tray workflow, ERP event payload
# Output: HTTP 200 (async) or workflow result (sync)

import requests
import json

TRAY_WEBHOOK_URL = "https://YOUR_TRAY_WEBHOOK_URL"

def trigger_tray_workflow(event_type: str, payload: dict) -> dict:
    """Trigger a Tray.ai workflow via webhook with ERP event data."""
    headers = {"Content-Type": "application/json"}
    response = requests.post(
        TRAY_WEBHOOK_URL,
        headers=headers,
        json={"event": event_type, "data": payload},
        timeout=30
    )
    if response.status_code == 429:
        import time
        time.sleep(2)
        return trigger_tray_workflow(event_type, payload)
    response.raise_for_status()
    return response.json() if response.text else {"status": "accepted"}

result = trigger_tray_workflow("order_created", {
    "order_id": "ORD-12345",
    "customer_id": "CUST-001",
    "total": 2500.00,
    "currency": "USD"
})

JavaScript/Node.js: Use Tray Embedded API (GraphQL)

// Input:  Tray user token, workflow ID
// Output: Workflow list and management

import { GraphQLClient, gql } from "graphql-request"; // v6.x

const client = new GraphQLClient("https://tray.io/graphql", {
  headers: { Authorization: `Bearer ${process.env.TRAY_USER_TOKEN}` },
});

const LIST_WORKFLOWS = gql`
  query {
    viewer {
      workflows {
        edges {
          node { id name enabled triggerUrl }
        }
      }
    }
  }
`;

async function listWorkflows() {
  const data = await client.request(LIST_WORKFLOWS);
  return data.viewer.workflows.edges.map((e) => e.node);
}

const workflows = await listWorkflows();
console.log(`Found ${workflows.length} workflows`);

cURL: Test Webhook Trigger

# Input:  Tray webhook URL
# Output: HTTP 200 + workflow trigger confirmation

# Trigger a workflow via webhook
curl -X POST "https://YOUR_TRAY_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"event": "invoice_created", "invoice_id": "INV-2026-001", "amount": 5000.00}'

# List workflows via GraphQL API
curl -X POST "https://tray.io/graphql" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TRAY_USER_TOKEN" \
  -d '{"query": "{ viewer { workflows { edges { node { id name enabled } } } } }"}'

Data Mapping

When connecting ERP systems through Tray.ai, field mapping happens in the Data Mapper step, which supports JSONPath expressions, JavaScript transforms, and lookup tables.

Field Mapping Reference

Source FieldTarget FieldTypeTransformGotcha
Salesforce: Account.NameNetSuite: customer.companyNameStringDirect mappingNetSuite max 83 chars vs Salesforce 255
Salesforce: Opportunity.AmountNetSuite: salesOrder.totalCurrencyCurrency conversion if multi-currencyMust set exchange rate subsidiary
SAP: VBAK-NETWRSalesforce: Opportunity.AmountDecimalDivide by 100 (SAP minor currency units)SAP CURR fields store in minor units
NetSuite: transaction.tranDateSalesforce: Opportunity.CloseDateDateTimeISO 8601 to YYYY-MM-DDNetSuite timezone = subsidiary timezone
Any: Multi-value fieldTray: JSON arrayArraySplit/join with List HelpersStep payload limit 6 MB for large arrays

Data Type Gotchas

Error Handling & Failure Points

Common Error Codes

CodeMeaningCauseResolution
HTTP 429Rate limit exceeded>30 req/s to Tray API or high-volume webhooksExponential backoff; use "Auto respond 200" for webhooks
STEP_TIMEOUTConnector operation timed outStandard connector exceeded 45s timeoutSwitch to HTTP Client (15-min timeout)
PAYLOAD_TOO_LARGEStep data exceeds 6 MBLarge dataset between workflow stepsUse CSV connector, Data Storage, or chunk payloads
AUTH_REFRESH_FAILEDOAuth token refresh failed after 3 retriesExpired refresh token or revoked accessRe-authenticate connector in Tray UI
CONNECTOR_ERRORTarget system returned errorInvalid data, missing fields, permission deniedCheck step input mapping and auth permissions
WORKFLOW_DISABLEDWorkflow triggered but not enabledWorkflow was disabled manually or via APIEnable workflow in Tray UI or via GraphQL

Failure Points in Production

Anti-Patterns

Wrong: Processing large datasets record-by-record in a single loop

// BAD -- each record = N steps = N task credits
// 10K records * 5 steps = 50K credits; likely hits 6 MB payload limit
// Loop over 10,000 items with 4 connector steps per iteration
// Total: 40,000 task credits, likely hits payload limit

Correct: Chunk data and use callable workflows for parallel batch processing

// GOOD -- chunk into 200-record batches, process in parallel callable workflows
// Main: List Helpers Chunk (200) --> 50 chunks --> Loop --> Call child workflow
// Child: Bulk Create/Update (single API call) --> Return results
// Total: ~250 credits (160x more efficient)

Wrong: Synchronous webhook mode for high-volume event streams

// BAD -- "Await workflow and respond" rate-limits at high volume
// Hundreds of events/second triggers 429 errors, dropped events

Correct: Async webhook with queue pattern

// GOOD -- "Auto respond with status 200" (no rate limit) + async queue
// Webhook: Auto-respond 200 --> Data Storage queue --> Done
// Separate scheduled workflow: Read queue --> Process batch --> Cleanup

Wrong: Hardcoding field mappings without null/type checks

// BAD -- assumes all fields exist and have expected types
// target.amount = $.steps.salesforce.Amount  (fails if null)
// target.name = $.steps.salesforce.Account.Name (fails if deleted ref)

Correct: Defensive mapping with Boolean checks and type conversion

// GOOD -- null checks + type conversion + fallback values
// Boolean: Amount not null? --> Type Converter (to Number) : default 0.00
// Boolean: Account not null? --> Map Name : "Unknown Customer" + flag
// Script: const d = steps.sf.CloseDate; return d ? new Date(d).toISOString() : now;

Common Pitfalls

Diagnostic Commands

# Check Tray API rate limit status (look for 429 responses)
curl -X POST "https://tray.io/graphql" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TRAY_USER_TOKEN" \
  -d '{"query": "{ viewer { name } }"}' \
  -w "\nHTTP Status: %{http_code}\n"

# List all workflows and their status
curl -X POST "https://tray.io/graphql" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TRAY_USER_TOKEN" \
  -d '{"query": "{ viewer { workflows { edges { node { id name enabled triggerUrl } } } } }"}'

# Test a webhook trigger endpoint
curl -X POST "$TRAY_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"test": true, "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}'

# Monitor task credit usage: Settings > Usage > Task Credits in Tray UI
# No API endpoint for credit balance (UI-only as of 2026)

Version History & Compatibility

Platform VersionRelease DateStatusBreaking ChangesMigration Notes
UAC 2025 (Tray Code/Build/Chat)2024-09CurrentRebrand to Tray.ai; 3 new APIsExisting workflows unaffected; new APIs are additive
Merlin AI Integration2023-05CurrentNoneNLP workflow generation added; optional feature
Enterprise Core Refresh2023-01CurrentSSO configuration changesRequires SSO re-setup for existing Enterprise
Embedded Platform v22022-06SupportedGraphQL schema changesUpdate GraphQL queries; old mutations deprecated
Classic PlatformPre-2022Deprecated--Migrate to UAC; classic workflows remain functional

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Complex multi-system orchestration with branching, loops, and conditional logicSimple point-to-point data sync between 2 systemsCeligo or Zapier
Need embedded/white-label integration UX for your SaaS productNeed deep SAP-native integration with IDoc/BAPI/RFCSAP Integration Suite or MuleSoft
Development team comfortable with JavaScript and API conceptsTeam needs purely no-code drag-and-drop with minimal trainingWorkato
Need AI-assisted workflow generation for rapid prototypingNeed full API lifecycle management (design, mock, test, version)MuleSoft Anypoint Platform
Budget is $500-$5K/month and need enterprise-grade securityBudget is <$500/month or need free tiern8n (self-hosted) or Make.com
High-volume webhook-driven event processing (async pattern)Need sub-100ms latency for real-time API proxyingMuleSoft or AWS API Gateway

Cross-System Comparison

CapabilityTray.aiWorkatoMuleSoftCeligo
ArchitectureWorkflow-first, visual + codeRecipe-based, low-codeAPI-led connectivityERP template-first
Connectors700+1,000+400+ (Exchange)200+ (ERP-focused)
AI CopilotMerlin AI (NLP to full workflow)Workato CopilotEinstein AIAuto-mapping
Developer APIGraphQL + 3 REST APIsREST Admin APIAnypoint CLI + RESTREST Admin API
Connector SDKCDK (TypeScript)SDK (Ruby)Custom Connector SDK (Java)JavaScript transforms
SAP SupportNo native connector (HTTP only)Native SAP connectorDeep SAP connectorNative SAP connector
NetSuite SupportNative connector (strong)Native connector (strong)Via connectorNative connector (deep)
Bulk ProcessingCSV connector (1 GB), 60-min timeoutBatch recipes, 200 records/batchBatch processing, DataWeaveSmart Map bulk sync
Embedded/OEMYes (Embedded API, white-label)Yes (Embedded platform)Limited (API Manager)No
Max Payload/Step6 MB (between steps)100 MB (recipe data)No hard limit (JVM-dependent)5 MB (default)
DeploymentCloud-only (AWS)Cloud-onlyCloud + on-premiseCloud-only
ComplianceSOC 2 Type 2, HIPAA, GDPRSOC 2 Type 2, HIPAASOC 2, ISO 27001, PCISOC 2 Type 2

Important Caveats

Related Units