Skip to content

Truto doesn't cache vendor data. Every Unified API call is a live call to the vendor API, on the request thread, returning the vendor's response shaped into Truto's unified envelope. That single design choice shapes how you think about rate limits, filtering, and latency.

You share the vendor's rate limit

Because Truto doesn't run a background sync, the rate-limit budget your customer has at the vendor is the budget your app has too. Truto adds nothing on top.

Truto normalizes whatever rate-limit headers the vendor returns into three standard response headers — ratelimit-limit, ratelimit-remaining, ratelimit-reset — so your client can back off the same way regardless of which vendor it just called. The same normalization applies to both /unified/... and /proxy/... calls; /proxy/... is Truto's equivalent of what other Unified-API providers call pass-through.

$ curl -i "https://api.truto.one/unified/crm/contacts?integrated_account_id=$ACCOUNT_ID" \
    -H "Authorization: Bearer $TRUTO_API_TOKEN"
HTTP/2 200
content-type: application/json; charset=utf-8
ratelimit-limit: 110;w=10
ratelimit-remaining: 109
ratelimit-reset: 60
 
{ "result": [ /* ... */ ], "next_cursor": "..." }

ratelimit-limit carries the vendor's window in the ;w=<seconds> parameter when the vendor exposes one (HubSpot does; many don't). If the underlying vendor doesn't return rate-limit information at all, the headers are absent — there's nothing to normalize.

If a call is rate-limited, you get a 429 from Truto with the same three headers — ratelimit-reset tells you how many seconds until the vendor's window opens again.

For the header semantics and a longer worked example, see Rate limits in Truto API.

Filter availability is per integration

The Unified API accepts the same query operators across vendors — created_at[gt], status[in], sort_by, or, and, and so on. What changes per vendor is which operators the underlying API actually supports. If the vendor doesn't support a filter, Truto silently drops it rather than fake it server-side; the cost of doing otherwise is fetching every record and filtering on the request thread, and that loses you the rate-limit budget above.

Before relying on a filter, ask the integration what it supports. The meta endpoint returns the merged JSON schema for one method on one integration mapping — query_schema is the source of truth for which filters that vendor's list accepts:

$ curl "https://api.truto.one/unified/crm/contacts/hubspot/meta/list" \
    -H "Authorization: Bearer $TRUTO_API_TOKEN"
{
  "method": "list",
  "documentation_link": "https://developers.hubspot.com/docs/api/crm/contacts",
  "query_schema": {
    "type": "object",
    "properties": {
      "created_at":   { "type": "string", "format": "date-time" },
      "updated_at":   { "type": "string", "format": "date-time" },
      "first_name":   { "type": "string" },
      "last_name":    { "type": "string" },
      "email_addresses": { "type": "array",  "items": { "type": "string" } },
      "sort_by":      { "type": "object" }
    }
  },
  "default_query": { "limit": 50 }
}

Anything not listed under query_schema.properties is silently dropped at call time — that's how you tell, before you ship a filter to production, whether HubSpot will honor last_name[ilike]=*han or quietly ignore it.

For the full operator grammar see Querying in Truto API.

Latency tracks the vendor

A unified call is a vendor call plus a small Truto hop. Truto's hop is bounded; the vendor's isn't. p99 latency on /unified/... is roughly the vendor's p99 plus a few tens of milliseconds. That's fine for request-time use cases (pulling a contact when a user opens a record), and it's the wrong shape for jobs you'd otherwise run on a schedule against millions of records.

For workloads where you need durable streaming, retries, pagination at scale, or the data landed in your warehouse, use RapidBridge — the same Unified API resources, executed as a background pipeline writing to a webhook, datastore, or SuperQuery destination. For "tell me when something changed at the vendor" use cases, use Webhooks.