Skip to content

The Developer's Guide to Passthrough APIs: Raw Access Without the Boilerplate

Standard unified APIs break down when you need custom objects or niche endpoints. Learn how passthrough APIs give you raw access without the OAuth boilerplate.

Uday Gajavalli Uday Gajavalli · · 20 min read
The Developer's Guide to Passthrough APIs: Raw Access Without the Boilerplate

If you are building B2B SaaS integrations, you will eventually hit a wall where a standard unified API schema does not cover the exact endpoint, custom object, or proprietary field your enterprise customer needs. You are sitting in a deployment review, and a major client asks why their custom industry code field is missing from the data sync. You check your unified API provider's documentation and realize the field is stripped out because it does not fit their "common model."

Integrations are no longer a backlog item; they are a primary business driver. Recent industry data shows that 83% of organizations view product integrations as one of their biggest priorities. Furthermore, 77% of buyers prioritize integration capabilities, and solutions that fail to integrate seamlessly with existing workflows are often deprioritized regardless of features or price.

But the sheer volume of SaaS applications creates a massive long-tail of custom endpoints that standard unified APIs simply cannot cover. On average, large enterprises manage between 125 and 200 SaaS applications. Each of those apps has its own custom objects, proprietary endpoints, and tenant-specific configurations.

When standard schemas fail, you need an escape hatch. You need raw API access, but you do not want to go back to building custom auth flows from scratch.

This is exactly what a passthrough API (or proxy API) solves. This guide covers the architectural pattern, when to use it, and how to go from zero to a working raw API request in minutes.

The Problem with "Lowest Common Denominator" Unified APIs

Unified APIs are incredible for standardizing common entities like CRM contacts or HRIS employees. They abstract away the painful differences in field names, pagination styles, and authentication methods. You write one integration, and it works across Salesforce, HubSpot, BambooHR, and the rest. That is genuinely useful for 70% of integration use cases.

The other 30% is where things fall apart. The trade-off for this standardization is rigidity.

When a unified API provider creates a common data model, they have to make opinionated decisions about which fields to include. They look at Salesforce, HubSpot, and Pipedrive, and they map the overlapping fields: first_name, last_name, email, phone.

Here is the real-world scenario that kills deals: your prospect runs a heavily customized Salesforce instance. They need you to read from Territory__c, a custom object with fields that power their entire GTM motion. Or perhaps they have spent six months heavily customizing their instance with proprietary objects like FleetVehicle__c or PatientEncounter__c.

Your unified API covers standard Contacts and Deals. It simply does not know what to do with custom objects. It drops the data entirely. Now what?

The "Integration Debt" Trap

When developers hit this wall, they usually resort to one of three painful workarounds:

  1. Tell the prospect to wait while you file a feature request with your integration vendor and hope they prioritize adding the missing field to their schema. The deal goes cold.
  2. Build a manual workaround, maintaining a completely separate, custom-built direct integration from scratch—managing OAuth yourself, writing SOQL queries, handling pagination and rate limits—just for this one customer's custom object.
  3. Use a passthrough API that lets you hit the REST endpoint directly, using the OAuth token your platform already manages.

Option 3 is the only one that ships this week. Modern integration architectures that allow flexible data modeling drastically reduce time-to-market. In fact, 63% of teams can ship a new API connection in under a week when using platforms that support custom fields and flexible data models. You cannot achieve that speed if you are waiting on a third-party vendor's roadmap.

What is a Passthrough API (Proxy API)?

A passthrough API is an outbound proxy layer that routes raw HTTP requests to a third-party service while automatically handling authentication, base URL resolution, credential management, and token lifecycles on your behalf.

Think of it as raw API access with managed plumbing. It allows you to bypass the unified schema entirely and talk directly to the underlying integration, using the exact payload and endpoint path the third-party API expects.

In the context of B2B SaaS integrations, a proxy API is not a reverse proxy sitting in front of your own services. It is an outbound proxy that your application calls to reach someone else's API. Instead of building custom infrastructure to handle the quirks of 50 different vendor APIs, your application makes a standard REST request to the proxy. The proxy handles the heavy lifting—injecting the correct credentials, managing the connection, normalizing errors—before forwarding the request to the destination.

sequenceDiagram
    participant App as Your Application
    participant Proxy as Proxy API Layer
    participant SaaS as Third-Party API<br>(e.g. Salesforce / Zendesk)
    
    App->>Proxy: GET /proxy/custom_objects<br>+ integrated_account_id
    Proxy->>Proxy: Resolve credentials<br>Refresh OAuth token if needed
    Proxy->>SaaS: GET /services/data/v59.0/sobjects/Territory__c<br>Authorization: Bearer {token}
    SaaS-->>Proxy: Raw JSON response
    Proxy-->>App: Raw JSON response<br>+ normalized rate limit headers

The key distinction from a unified API: no schema mapping happens. What the third-party returns is what you get. This means you get full access to every endpoint the provider exposes—standard objects, custom objects, admin endpoints, reporting APIs, everything—without waiting for someone to build a normalized model for it.

For a deeper architecture breakdown, see our guide to proxy APIs.

How Pass-Through Requests Handle Data in Real Time

A common question from engineering and security teams evaluating integration platforms: does my customers' data get cached or stored on intermediate infrastructure? With a pass-through architecture, the answer is no. Customer payloads are fetched live from the source system, processed in memory, and returned directly to your application. Nothing is written to disk, cached, or indexed.

Here is the exact sequence of operations, end to end:

sequenceDiagram
    participant App as Your Application
    participant Platform as Integration Platform
    participant DB as Credential Store<br>(encrypted tokens only)
    participant SaaS as Third-Party API<br>(e.g. Zendesk)
    
    App->>Platform: GET /proxy/contacts<br>+ integrated_account_id
    Platform->>DB: Look up stored credentials
    DB-->>Platform: Encrypted OAuth token
    Platform->>Platform: Decrypt token, check expiry,<br>refresh if needed
    Platform->>SaaS: GET /api/v2/contacts.json<br>Authorization: Bearer {token}
    SaaS-->>Platform: Raw JSON (in memory only)
    Platform-->>App: JSON response forwarded<br>(nothing written to disk)
    Note over Platform: Response payload<br>garbage collected

Step 1: Authenticate Your Request

Your application sends a request to the proxy endpoint with your platform API key and an integrated_account_id. The platform validates your key and identifies which connected account to use. No customer data is involved yet - only authentication metadata.

Step 2: Resolve and Refresh Credentials

The platform retrieves the customer's stored OAuth token (or API key) from its credential store. Tokens are encrypted at rest. If the OAuth access token has expired, the platform automatically runs the refresh flow against the third-party's token endpoint and updates the stored credentials - all before the upstream request is made.

Step 3: Make the Live API Call

The platform constructs the upstream HTTP request - resolving the correct base URL, injecting the authorization header, and forwarding your query parameters. This is a real-time call. There is no cache layer between the platform and the third-party API.

# What you send to the proxy
curl -X GET "https://api.truto.one/proxy/contacts?integrated_account_id=acc_12345&limit=10" \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY"
# What the platform sends upstream (constructed from stored config)
GET /api/v2/contacts.json?page[size]=10 HTTP/1.1
Host: acme-corp.zendesk.com
Authorization: Bearer eyJhbGciOi...zendesk_access_token

Step 4: Return the Response (Nothing Persisted)

The third-party's response is held in memory, normalized rate limit headers are attached, and the payload is returned to your application. Once the HTTP response completes, the customer data is garbage collected. No record of the response body exists on the platform.

{
  "result": [
    {
      "id": 12345,
      "name": "Jane Smith",
      "email": "jane@acme.com",
      "custom_fields": { "territory_code": "EMEA-North" }
    }
  ],
  "next_cursor": "eyJpZCI6MTIz..."
}

If you use the Unified API instead of the Proxy API, one additional step happens in memory: the platform evaluates a JSONata expression to map the third-party's native field names into the unified schema. This transformation runs entirely in memory - no intermediate storage, no disk writes. The normalized response is returned and the raw data is discarded.

What Gets Persisted vs. What Never Touches Disk

This is the question that matters for compliance and security reviews. Here is the concrete breakdown:

Data Category Stored? Details
OAuth tokens and API keys ✅ Encrypted at rest Required to authenticate upstream API calls. Refreshed automatically before expiry.
Connection metadata ✅ Yes Account ID, integration type, environment ID, tenant association.
Integration configuration ✅ Yes API endpoint definitions, pagination strategies, field mappings. Contains no customer data.
Customer API request payloads ❌ Never stored Exist only in memory for the duration of the HTTP request.
Customer API response payloads ❌ Never stored Processed in memory and returned. Never written to disk, cache, or object storage.
Customer records (contacts, employees, tickets) ❌ Never stored The platform has no database table, cache, or index for customer business data.
Request metadata (timestamps, status codes) ⚠️ Transient logs Used for debugging and rate limit tracking. Contains no response body data.

The architectural implication: the platform is not a data processor of your customers' business records under GDPR or CCPA. It processes credentials (which are covered under your existing DPA with the platform) but never stores, replicates, or indexes the actual data flowing through it. This keeps your SOC 2 audit scope narrow and avoids the compliance overhead of managing a secondary copy of customer data on third-party infrastructure.

This stands in contrast to sync-and-cache architectures, where the integration platform polls upstream APIs on a schedule, normalizes the data, and stores a copy on its own infrastructure. That copy becomes a secondary database containing sensitive customer information - and if that data is breached, your customers' records are exposed.

Why Developers Need Raw API Access

Raw API access is a critical requirement for enterprise operations. Standard batch transfers and pre-built schemas often fail to support live, operational data needs. The business case for passthrough APIs comes down to these forces:

1. Unblocking Enterprise Sales Deals

Enterprise buyers do not care about your internal engineering constraints. Organizations have spent years customizing their CRMs, ERPs, and marketing tools to match their exact workflows. When they evaluate your product, they do not want to compromise. They expect you to work with their data model, not the other way around. Slightly over half (51%) of B2B buyers cited poor integration with their existing tech stack as a reason to explore new vendors. A passthrough API turns "we don't support that endpoint yet" into "give us a day."

2. Supporting Complex Multi-Step Orchestration

Some integration workflows require multiple interdependent API calls. For example, creating a ticket in Jira might require first querying for the correct project ID, then fetching the allowed issue types, and finally submitting the payload. Unified models often abstract this into a single "create ticket" action, which might fail if the customer's Jira instance has strict validation rules. Raw access lets you orchestrate the exact sequence of calls required.

3. Accessing Beta or Undocumented Endpoints

SaaS platforms frequently release new features via beta endpoints that are not yet officially supported by unified API providers. If your product relies on being on the cutting edge of an ecosystem (like accessing a new AI feature in Notion or Slack), you need raw access to hit those beta endpoints the day they launch.

4. The Long Tail of SaaS Endpoints is Massive

In 2024, organizations used an average of 106 SaaS apps. Each one has dozens or hundreds of API endpoints. No unified schema will ever cover them all. The passthrough pattern gives you an escape hatch that does not require abandoning your integration platform.

Developer Quick-Start: Making Your First Passthrough Request

Let us look at how this works in practice using a Proxy API. The goal here is to make a raw request to a specific integration without worrying about the authentication headers. Your code never touches an OAuth token. You never write a token refresh handler. You never parse a WWW-Authenticate header.

Example 1: Querying a Niche Zendesk Endpoint

Assume you have a customer who has connected their Zendesk account, and you want to hit a specific, non-standard endpoint: GET /api/v2/macros.json. All you need is the integrated_account_id.

Instead of finding the customer's Zendesk subdomain and looking up their current OAuth token, you send the request to the proxy route:

curl --request GET \
  --url 'https://api.truto.one/proxy/macros?integrated_account_id=acc_12345abcde' \
  --header 'Authorization: Bearer YOUR_TRUTO_API_KEY'

Under the hood, the proxy layer:

  1. Looks up the integrated account (acc_12345abcde).
  2. Checks if the Zendesk OAuth token is expired.
  3. If expired, automatically runs the refresh flow to get a new token.
  4. Resolves the correct base URL for that specific customer's Zendesk instance.
  5. Injects the Authorization: Bearer <zendesk_token> header.
  6. Forwards the request to GET /api/v2/macros.json.
  7. Returns the exact, unmapped JSON response from Zendesk.

Example 2: Creating and Updating Salesforce Custom Objects

The proxy supports the full CRUD surface. Suppose you need to interact with that Territory__c custom object in Salesforce.

# Create a new record
curl -X POST "https://api.truto.one/proxy/territories?integrated_account_id=sf_abc123" \
  -H "Authorization: Bearer YOUR_TRUTO_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"Name": "West Coast", "Region_Code__c": "WC-01"}'
 
# Update an existing record
curl -X PATCH "https://api.truto.one/proxy/territories/001xx000003DGbYAAW?integrated_account_id=sf_abc123" \
  -H "Authorization: Bearer YOUR_TRUTO_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"Region_Code__c": "WC-02"}'
 
# Delete a record
curl -X DELETE "https://api.truto.one/proxy/territories/001xx000003DGbYAAW?integrated_account_id=sf_abc123" \
  -H "Authorization: Bearer YOUR_TRUTO_API_TOKEN"

The REST-to-method mapping is consistent across platforms:

HTTP Method Proxy Route Operation
GET /proxy/:resource List resources (paginated)
GET /proxy/:resource/:id Get a single resource
POST /proxy/:resource Create a resource
PATCH /proxy/:resource/:id Update a resource
DELETE /proxy/:resource/:id Delete a resource

Using the CLI

If you are debugging locally, you can use the Truto CLI to test passthrough endpoints rapidly. This is invaluable when you are reading through terrible vendor API docs and just want to see what the payload actually looks like.

# Fetch raw records from the proxy API
truto proxy territories -a sf_abc123
 
# Create a raw record with integration-specific fields
truto proxy territories -m create -a sf_abc123 -b '{"Name": "East Coast"}'

Notice that you are passing the exact nested JSON structure the provider expects, not a normalized schema.

Handling GraphQL via REST Proxies

One of the most painful aspects of raw API access is dealing with GraphQL-only integrations (like Linear or GitHub). Building GraphQL query strings dynamically in your application code is error-prone and messy.

Advanced proxy architectures can solve this by mapping RESTful CRUD requests to underlying GraphQL mutations. Instead of forcing you to write a massive GraphQL query just to list issues, the integration configuration defines a template with placeholders.

When you make a standard GET /proxy/issues request, the proxy layer injects your query parameters into the GraphQL variables and extracts the relevant slice from the response envelope. From your application's perspective, you are making a simple REST call. From the provider's perspective, they receive a perfectly formatted GraphQL POST. This keeps your application code clean while still giving you access to the raw underlying data.

Handling Rate Limits and Pagination on Raw Endpoints

When you bypass the unified schema, you are taking on more responsibility. You are no longer protected from the idiosyncrasies of the underlying API. Raw access sounds simple until you hit the operational edges. The two biggest challenges you will face are rate limits and pagination. Both behave differently across every SaaS vendor, and both will break your integration in production if you do not handle them.

The Reality of Rate Limits

Every SaaS API handles rate limiting differently. HubSpot returns X-HubSpot-RateLimit-Daily-Remaining. Salesforce uses Sforce-Limit-Info. Jira has X-RateLimit-Remaining. Some use a leaky bucket algorithm. Some return a Retry-After header in seconds, others in HTTP dates. A major interoperability issue in throttling is the lack of standard headers, because each implementation associates different semantics to the same header field names.

A robust proxy layer normalizes this chaos. It detects when an upstream API is rate-limiting the request, standardizes the response status to 429 Too Many Requests, and normalizes the upstream rate limit information into standard IETF headers on every response:

  • ratelimit-limit: The maximum number of requests permitted.
  • ratelimit-remaining: The number of requests remaining in the current window.
  • ratelimit-reset: The time at which the rate limit window resets (in UTC epoch seconds).
Warning

Important: When an upstream API returns HTTP 429, the proxy layer passes that status code and the original error directly back to your application. It does not magically absorb rate limits for you. Your code is responsible for implementing exponential backoff. This is intentional—silent retries inside a proxy layer hide quota consumption and can cause unpredictable latency spikes.

Because the headers are normalized, you can write a single, generic exponential backoff utility in your application that works across every single integration, instead of writing custom retry logic for Salesforce, another for HubSpot, and another for Zendesk.

async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);
    
    if (response.status === 429) {
      // Read the normalized IETF headers provided by the proxy layer
      const resetTime = response.headers.get('ratelimit-reset');
      
      let waitTimeMs = 2000; // Default fallback
      
      if (resetTime) {
        const resetEpochMs = parseInt(resetTime, 10) * 1000;
        const now = Date.now();
        // Calculate time to wait, adding a 1-second buffer
        waitTimeMs = Math.max(0, resetEpochMs - now) + 1000;
      }
      
      console.warn(`Rate limited. Retrying in ${waitTimeMs}ms...`);
      await new Promise(resolve => setTimeout(resolve, waitTimeMs));
      continue;
    }
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    return response.json();
  }
  throw new Error('Max retries exceeded');
}

For a deeper dive into retry strategies, see our guide on handling API rate limits across multiple third-party APIs.

Standardizing Pagination

Pagination is equally chaotic. Salesforce uses cursor-based pagination with nextRecordsUrl. HubSpot uses after cursors. Some legacy APIs use page numbers. Others use offset/limit. A few return Link headers.

When using a well-architected proxy API, the underlying configuration handles the pagination strategy for list operations, abstracting all of these into a single interface. You can simply pass limit=50 and next_cursor=abc in your REST query string.

# First page
GET /proxy/territories?integrated_account_id=sf_abc123&limit=50
 
# Next page (using cursor from previous response)
GET /proxy/territories?integrated_account_id=sf_abc123&limit=50&next_cursor=eyJpZCI...

The proxy layer translates that into the correct upstream format (whether that is ?page=2, ?offset=50, or a GraphQL after variable) and extracts the next cursor from the raw response to send back to you.

For the full breakdown of how pagination normalization works across different strategies, check out how unified APIs handle pagination differences.

When to Use Passthrough vs. Unified API

The passthrough API and the unified API are not competitors—they are complements. Here is the decision framework:

Scenario Use Unified API Use Passthrough API
Standard CRUD on common objects (contacts, tickets, employees) ✅ Normalized schema saves time ❌ Overkill
Custom objects or proprietary endpoints ❌ Not covered by the schema ✅ Full access
Cross-provider reporting (same query, many integrations) ✅ Consistent field names ❌ Response shapes differ
Niche features (bulk exports, admin APIs, webhooks setup) ❌ Rarely modeled ✅ Direct access
Rapid prototyping before a mapping exists ❌ Mapping takes time to build ✅ Immediate access

The best integration architecture uses both. Start with the unified API for the 80% case, and drop to the passthrough when you hit the edges.

Promoting Raw Endpoints to Custom APIs

The ultimate goal of a passthrough API is not to leave your code littered with raw HTTP requests. It is a testing ground. Once you have validated that a raw endpoint works and returns the data your enterprise customer needs, you want to make it a permanent, reusable part of your integration architecture.

This is the "Test and Promote" workflow:

  1. Discover the gap. A customer needs data from an endpoint your unified schema does not cover.
  2. Test it via passthrough. Use the proxy API to hit the endpoint directly against a connected account. See the real response shape.
  3. Validate the response. Confirm the data is what you expected. Check for pagination behavior, required query parameters, and field types.
  4. Promote to a custom method. Define the endpoint as a reusable custom resource in your integration config—specifying the path, HTTP method, default query parameters, and use JSONata expressions to transform the raw response into a clean, predictable shape that matches your internal data models (or apply per-customer data model overrides for specific tenants).
  5. Ship it. The new endpoint is instantly available to all connected accounts for that integration. No code deploy. No waiting on a vendor roadmap.
Tip

Architectural Best Practice: Use the Proxy API for rapid prototyping and debugging. Once the integration logic is proven, wrap it in a Custom API definition. This moves the integration-specific logic out of your application codebase and into the declarative configuration layer, keeping your core system clean.

By promoting raw endpoints to custom methods, you eliminate "Integration Debt." Your application code goes back to calling a clean, standardized interface, but you retain the exact custom functionality that the enterprise deal required. For a step-by-step walkthrough of this workflow, see how to stop waiting on missing endpoints.

Architectural Trade-Offs to Consider

Passthrough APIs are not magic. Be honest about what you are giving up:

  • No schema normalization. You get the raw provider response. If you are querying the same logical resource across Salesforce and HubSpot, your application code has to handle two different response shapes, unless you implement per-customer API mappings.
  • Provider-specific error formats. A 400 from Salesforce looks different from a 400 from Jira. Your error handling needs to account for this.
  • You own the data contract. If Salesforce changes a field name on their Territory__c object, your code breaks. There is no mapping layer to absorb the change.
  • No before/after orchestration steps. Unified APIs can chain multiple API calls. Passthrough requests are single-shot.

These trade-offs are acceptable—often desirable—for custom endpoints, niche features, and rapid prototyping. They become painful if you try to build your entire integration strategy on raw passthrough alone.

Operational Trade-Offs: Latency, Availability, and Compliance

Beyond the schema-level trade-offs above, a pass-through architecture has operational consequences that affect how you build and run your integration in production. Be clear-eyed about what you gain and what you give up.

What You Gain

Compliance simplicity. When your integration platform never stores customer records, it does not become an additional data processor for those records. Your SOC 2 audit scope stays contained. GDPR Article 5(1)(e) requires data to be kept "no longer than necessary" - with pass-through, the data is not kept at all. The average cost of a data breach reached $4.44 million in 2025, and compliance failure adds $1.22M to the average breach cost. Minimizing the data you store is one of the most direct ways to reduce both exposure and cost.

Data freshness. Every response is live from the source system. There is no stale cache, no sync lag, no eventual consistency. If a record was updated in Salesforce 30 seconds ago, your next API call returns the updated version. For use cases like real-time customer support dashboards or live inventory checks, this is non-negotiable.

Smaller attack surface. If the integration platform is breached, there are no customer records to exfiltrate. The attacker gets encrypted OAuth tokens (which can be revoked) and integration config (which contains no business data). According to multiple global studies, 45-50% of breaches now involve cloud or SaaS environments. A pass-through architecture removes one potential breach target entirely.

What You Give Up

Latency is bound to the upstream API. Every request is a live round-trip. If Salesforce's API responds in 800ms, your pass-through request takes at least 800ms plus the proxy overhead (typically 20-80ms). High-performing APIs typically keep average response times between 0.1 and 1 second. Some enterprise APIs are slower, especially for complex queries or large result sets. There is no cache to absorb the hit.

Availability is coupled to the upstream API. If HubSpot's API goes down, your integration is down. There is no local cache to serve stale-but-available data during an outage. Your application needs to handle upstream failures gracefully with circuit breakers and fallback logic.

Rate limit consumption is higher. Every read costs you an API call against the third-party's rate limit quota. If you read the same 50 contacts ten times in an hour, that is 10 API calls. A cache-first architecture would make one call and serve the rest from cache. For high-read-frequency use cases, this adds up fast.

Decision Checklist: Pass-Through vs. Sync-and-Cache

Use this checklist to decide which pattern fits your use case. Most production systems end up using both.

Choose pass-through when:

  • ✅ You operate in regulated industries (healthcare, finance, government) where data minimization is a compliance requirement
  • ✅ You need guaranteed data freshness - stale data is worse than slower data
  • ✅ You are accessing custom objects, niche endpoints, or admin APIs that change frequently
  • ✅ You are prototyping or debugging integrations and need to see real responses
  • ✅ Your enterprise customers' security teams require that no third-party vendor stores their data
  • ✅ Write operations (create, update, delete) that must hit the live API regardless

Choose sync-and-cache when:

  • ✅ You need sub-100ms response times for dashboards or autocomplete
  • ✅ You query the same dataset repeatedly (e.g., rendering a contact list multiple times per session)
  • ✅ The upstream API has aggressive rate limits and you cannot afford to burn quota on repeat reads
  • ✅ You need to run complex queries, joins, or aggregations that the source API does not natively support
  • ✅ You need offline access or guaranteed availability independent of upstream API health
  • ✅ You are building cross-provider analytics where consistent local data is more valuable than real-time freshness
Tip

The hybrid approach: Use the unified API with pass-through for real-time CRUD operations and webhooks. Use sync jobs to maintain a local cache for analytics, search, and high-frequency reads. This gives you data freshness for operational workflows and query performance for analytical ones.

What to Look for in a Proxy Layer

Not all passthrough implementations are equal. When evaluating platforms, look for:

  • Automatic credential injection: The platform should handle the full OAuth lifecycle: initial token exchange, proactive refresh before expiry, and needs_reauth detection when refresh fails.
  • Normalized rate limit headers: You want consistent ratelimit-limit, ratelimit-remaining, ratelimit-reset headers regardless of the upstream provider.
  • Pagination abstraction: Standard limit and next_cursor parameters that work across cursor-based, page-based, offset-based, and link-header pagination strategies.
  • Support for multiple auth types: OAuth 2.0, OAuth 1.0, API key, basic auth, and custom header expressions.
  • GraphQL translation: If the provider exposes a GraphQL API, the proxy should translate your REST calls into the correct queries/mutations via config.
  • Path to custom resources: The ability to save, name, and reuse raw endpoints so they become permanent integration surface area.

Stop Waiting. Start Shipping.

The passthrough API pattern resolves a fundamental tension in integration architecture: you want the speed and consistency of a unified API, but your enterprise customers need access to data that no standard schema covers. Instead of choosing between the two, use both.

You cannot predict every edge case your customers will demand. The SaaS landscape is too fragmented, and enterprise instances are too customized. If you rely entirely on strict, unified schemas, you will eventually hit a wall that costs you revenue. Passthrough APIs provide the architectural flexibility to handle any endpoint, any custom object, and any proprietary field, without forcing your engineering team to take on the burden of authentication and infrastructure management.

Start with the unified API for normalized CRUD on common resources. Drop to the proxy when a customer needs a custom Salesforce object, a niche HRIS report, or a proprietary bulk export endpoint. When that raw request proves valuable, promote it to a documented custom resource. That is how you go from "it's on the roadmap" to "it's live" in a matter of days.

FAQ

What is a passthrough API?
A passthrough API (or proxy API) acts as an outbound proxy layer that routes raw HTTP requests to a third-party service while automatically injecting the correct authentication credentials, refreshing OAuth tokens, and resolving base URLs on your behalf.
What is the difference between a passthrough API and a unified API?
A unified API normalizes third-party data into a common schema (e.g., all CRM contacts look the same). A passthrough API forwards your request directly to the provider's native endpoint with no data transformation, returning the raw response. Use unified APIs for standard objects and passthrough APIs for custom endpoints.
How do passthrough APIs handle rate limits?
A well-designed passthrough API normalizes upstream rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) and passes HTTP 429 errors directly back to the client so your application can implement a single, generic exponential backoff strategy.
Can I use a passthrough API to access custom Salesforce objects?
Yes. This is a primary use case. You call the proxy with the custom object's resource path, and the platform routes the request to Salesforce using the connected account's credentials, giving you full access to proprietary fields without building a separate integration.
Can I use a passthrough API for GraphQL endpoints?
Yes. Advanced proxy architectures can map RESTful CRUD requests to underlying GraphQL mutations and queries, handling the payload transformation automatically so your application code only needs to make standard REST calls.

More from our Blog