Look Ma, No Code! Why Truto’s Zero-Code Architecture Wins
Truto's architecture uses zero integration-specific code. Discover how the Interpreter Pattern and JSONata enable infinite extensibility without the maintenance nightmare.
You are likely reading this because you are skeptical of unified APIs. You should be.
Most unified API platforms are "black boxes." They promise to abstract away the complexity of 50 different integrations, but under the hood, they solve the problem with brute force. They maintain 50 separate code paths—one for Salesforce, one for HubSpot, one for NetSuite. When an API changes, their engineers have to rewrite code, redeploy, and hope they didn't break the other 49 integrations.
This architectural rigidity is why you wait months for a new endpoint. It’s why you can’t map that one custom field your enterprise customer needs right now. It is the hidden cost of the Adapter Pattern at scale.
Truto is different. We don't write integration code. Our entire platform—runtime, database, proxy, and sync engine—contains zero integration-specific logic.
We built a programmable unified API based on the Interpreter Pattern. This isn't just an implementation detail; it is the reason we can ship new integrations in hours and why you can customize them without waiting on our roadmap.
The "If-This-Then-That" Trap of Traditional Unified APIs
To understand why Truto’s architecture is radical, you have to look at how the rest of the industry builds integrations.
The standard approach is the Strategy Pattern (or Adapter Pattern). The platform defines a common interface (e.g., UnifiedContact), and then writes a specific adapter class for each provider.
It looks something like this in their codebase:
// The "Brute Force" Approach
if (provider === 'hubspot') {
return hubspotAdapter.getContacts(params);
} else if (provider === 'salesforce') {
return salesforceAdapter.getContacts(params);
}This scales linearly with pain.
- Maintenance Hell: Every new integration adds more code to maintain. A bug in the Salesforce pagination logic doesn't get fixed for HubSpot.
- Rigid Schemas: Because the logic is hardcoded, your unified APIs are lying to you about flexibility. If the vendor didn't code a mapping for a specific field, you can't access it.
- Slow Velocity: Adding a new integration requires a full engineering cycle: code, review, test, deploy.
We realized early on that schema normalization is the hardest problem in SaaS integrations, and solving it with if/else statements is a losing battle.
The Architecture of Zero: 38 Tables, No Integration Columns
Truto’s architecture is built on a single, provocative constraint: No integration-specific code, column, or UI.
If you inspect our database schema, you will find 38 tables. You will find tables for users, teams, and integrated_accounts. But you will not find a hubspot_token column. You won't find a salesforce_instance_url field. You won't find a zendesk_subdomain.
Instead, everything is generic.
- The Integration Table: Contains a
configJSON blob. This blob describes the API's base URL, authentication scheme (OAuth2, API Key), and pagination rules. - The Integrated Account Table: Contains a
contextJSON blob. This holds the actual credentials and tokens for a specific customer's connection. - The Mapping Table: Contains
configJSON blobs with JSONata expressions that define how to transform data.
This means adding a new integration is purely a data operation. We insert a row into the integration table describing the API, and rows into the unified_model_resource_method table describing the mappings.
We do not deploy code to add an integration. The runtime engine that processes a Salesforce request is the exact same binary that processes a Notion request. It just reads a different configuration. This means bug fixes and improvements are instant. As soon as you click Save, the behavior changes immediately for every connected account—no build pipeline, no CI/CD wait time, and no deployment window required.
JSONata: The Secret Weapon for Declarative Mapping
If we don't write code to map data, how do we handle the massive differences between APIs?
HubSpot uses filterGroups arrays with specific operators. Salesforce uses SOQL (Salesforce Object Query Language). NetSuite uses XML.
We use JSONata, a declarative query and transformation language for JSON. Instead of writing imperative code to loop through arrays and rename fields, we store transformation logic as data strings.
Example: The "List Contacts" Problem
Here is how the exact same generic code path handles two completely different API paradigms using stored JSONata expressions.
1. HubSpot (The REST + Filter Array approach)
HubSpot requires constructing a complex JSON payload for filtering. Our stored mapping looks like this:
# Stored in the database, not code
request_body_mapping: >-
rawQuery.{
"filterGroups": [{
"filters": [
first_name ? { "propertyName": "firstname", "operator": "CONTAINS_TOKEN", "value": first_name },
email ? { "propertyName": "email", "operator": "EQ", "value": email }
]
}]
}2. Salesforce (The SOQL approach)
Salesforce requires a SQL-like string. Our stored mapping handles this by constructing the query dynamically:
# Stored in the database, not code
query_mapping: >-
{
"q": "SELECT Id, FirstName, LastName, Email FROM Contact WHERE " &
(email ? "Email = '" & email & "'" : "Id != null")
}When a request comes in, our generic execution engine loads the configuration, evaluates the JSONata expression, and dispatches the request. It doesn't know it's talking to Salesforce. It just knows it needs to send the string result of that expression to the URL defined in the config.
This approach extends to multi-step API orchestration as well. We can define before and after steps in the configuration to chain multiple API calls together (e.g., "fetch the Company ID first, then create the Contact") without writing a single line of TypeScript.
The Interpreter Pattern: Why We Don't Deploy Code
Truto implements the Interpreter Pattern.
- The Language: Our integration configuration schema (JSON) and mapping expressions (JSONata) form a Domain Specific Language (DSL) for integrations.
- The Interpreter: Our runtime engine is a generic machine that executes this DSL.
This is why our architecture is superior to the "code-first" platforms like Nango or the "managed black box" platforms like Merge.
With a code-first platform, you inherit the maintenance burden. You write the scripts. You debug the edge cases.
With a black-box platform, they own the code, but you are held hostage by their release cycle. If their Salesforce adapter has a bug, you wait for them to deploy a fix.
With Truto's Interpreter pattern, the "code" is just configuration. This leads to our most powerful feature: Overrides.
The Ultimate Flex: Customer-Defined Overrides
Because integration logic is data, it can be patched at runtime. Truto implements a 3-level override hierarchy that allows you to customize the unified API without waiting for us.
- Platform Level: The default mapping we provide (e.g., standard Salesforce contacts).
- Environment Level: You can override mappings for your specific application. Need to map a custom
tierfield from Salesforce topriorityin your app? You just patch the JSONata mapping in your environment config. - Account Level: You can even override mappings for a single specific customer. If one of your enterprise clients has a wildly customized HubSpot instance, you can apply a mapping patch just for them.
Why this matters: You are no longer blocked by your unified API vendor. You can fix bugs, add fields, or change endpoint logic instantly by updating the configuration, not deploying code.
Look Ma, No Maintenance Burden
This architecture cascades benefits into every part of the platform:
- Reliability: When we improve the pagination engine, every integration gets better instantly. There is no "legacy code" rotting in an old integration adapter.
- MCP Support: Because our integrations are defined as structured data, we auto-generate MCP (Model Context Protocol) tool definitions. Every integration is immediately AI-ready.
- Speed: We can add new integrations in hours, not weeks.
We didn't just build a unified API. We built a programmable integration engine. The difference isn't just academic—it's the difference between a tool that accelerates you and a tool that eventually blocks you.
FAQ
- How does Truto's Interpreter Pattern differ from the Adapter Pattern used by platforms like Merge?
- Platforms like Merge use the Adapter Pattern, maintaining separate codebases for each integration, which creates a "black box" you can't modify. Truto uses the Interpreter Pattern, where a generic engine executes integrations defined entirely as data. This allows for instant updates, infinite extensibility, and the ability to patch or override any integration logic without waiting for a vendor deployment.
- What does "zero integration-specific code" mean for my engineering team?
- It means you never have to wait for a code deployment to fix an integration bug or map a new field. Because Truto defines integrations as data (JSON/JSONata) rather than code, changes are instant. You can override mappings in your environment or for specific accounts immediately, eliminating the maintenance burden typical of unified APIs.
- Can I customize integrations for specific customers?
- Yes. Truto’s architecture supports a 3-level override hierarchy (Platform, Environment, Account). You can patch the JSONata mapping for a single customer’s Salesforce integration to handle custom fields or unique logic, without affecting any other customer or requiring a code change.
- How does Truto handle custom fields?
- Truto supports a 3-level override hierarchy. You can map custom fields globally for your app, or even for a specific connected account, by simply patching the JSONata mapping configuration.
- Do I need to write code to add an integration?
- No. Adding an integration in Truto is a configuration task, not a coding one. You define the API structure and data mappings in JSON, and our generic engine handles the execution.
- What is JSONata used for in Truto?
- JSONata is a declarative transformation language we use to map data between your unified schema and third-party APIs. It handles complex logic like filtering, conditional mapping, and data reshaping without imperative code.