---
title: "The Developer's Guide to Passthrough APIs: Raw Access Without the Boilerplate"
slug: the-developers-guide-to-passthrough-apis-raw-access-without-the-boilerplate
date: 2026-04-20
author: Uday Gajavalli
categories: [Guides, Engineering]
excerpt: 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.
tldr: "Passthrough APIs (or Proxy APIs) provide raw, unmapped access to third-party endpoints while offloading OAuth token management and rate limit normalization to your integration platform. Use them to unblock enterprise deals requiring custom objects."
canonical: https://truto.one/blog/the-developers-guide-to-passthrough-apis-raw-access-without-the-boilerplate/
---

# 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](https://truto.one/why-unified-api-data-models-break-on-custom-salesforce-objects-and-how-to-fix-it/). 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](https://truto.one/the-unified-api-that-doesnt-use-standardized-data-models-for-custom-objects/) 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.

```mermaid
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](https://truto.one/what-is-a-proxy-api-2026-saas-architecture-guide/).

## 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:

```bash
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.

```bash
# 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.

```bash
# 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.

```typescript
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](https://truto.one/best-practices-for-handling-api-rate-limits-and-retries-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.

```bash
# 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](https://truto.one/how-do-unified-apis-handle-pagination-differences-across-rest-apis/).

## 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](https://truto.one/3-level-api-mapping-per-customer-data-model-overrides-without-code/) 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](https://truto.one/stop-waiting-on-missing-endpoints-why-trutos-custom-resources-are-the-ultimate-saas-integration-hack/).

## 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](https://truto.one/per-customer-api-mappings-3-level-overrides-for-enterprise-saas/).
- **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.

## 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.

> Ready to ship integrations without the schema constraints? See how Truto gives you a unified API and a proxy API on the same platform—with managed auth, normalized rate limits, and the ability to promote raw endpoints to custom resources without code deploys.
>
> [Talk to us](https://cal.com/truto/partner-with-truto)
