TriportRPC

Rate Limits and Tiers

How Triport meters traffic: five subscription tiers, per-category sustained RPS, a 2× burst allowance, and the headers and errors you'll see when you hit a limit.

Method / Endpointn/a — rate-limit reference
NetworkSolana, Ethereum, Polygon
Authenticationx-token header (SDK-preferred); see Authentication
Required scope
Tier / rate limitApplies to every method on every chain

Description

Triport meters requests by sustained requests-per-second (RPS), scoped to the combination of your tier and the category a method belongs to (for example sol_read_rpc, eth_send_tx, polygon_read_rpc). Every chain splits its methods into roughly eight category buckets, and each tier has its own sustained RPS budget per bucket. A burst above the sustained rate is tolerated up to 2× sustained (the global burst multiplier); beyond that you receive a 429 rate_limited with Retry-After: 1.

There is no daily cap. Triport does not enforce a per-day request quota, and there is no X-Daily-Quota-Remaining header — the only limit you need to plan around is sustained RPS per category. A 429 is normal backpressure, not a fatal error: back off one second and retry.

Higher tiers unlock more categories, more regions, more tokens, and higher RPS. When a method requires a tier above yours, you get 403 tier_insufficient instead of a rate-limit error.

Tiers

TierPriceDurationRegionsMax tokensMulti-regionNotes
Free$07-day trialEU only1Trial; limited category access
Basic$99/momonthlyEU1
Pro$499/momonthlyEU + US1Includes a staging token
Business$1499/momonthlyEU + US5active-active
EnterpriseCustom (from $5000+/mo)min. 365 daysEU + US + custom PoPsunlimitedactive-activeUnlimited RPS, custom domain, white-label
  • Free is a 7-day trial limited to the EU region with a single token. When the trial period ends you receive 401 trial_expired.
  • Pro adds the US region and ships with a dedicated staging token for https://staging.api.triport.io.
  • Business enables multi-region active-active routing across EU + US and allows up to 5 tokens.
  • Enterprise has unlimited RPS (rps_unlimited), custom Points of Presence, a custom domain, and white-labeling. Pricing and limits are negotiated per contract.

Sustained RPS per tier

The table below lists the sustained RPS for the core read/write categories on each chain. Burst capacity is these numbers (see below). enterprise is unlimited across all categories unless a contract overrides it.

CategoryFreeBasicProBusinessEnterprise
sol_read_rpc2060200600unlimited
sol_read_rpc_heavy252080unlimited
sol_send_tx51050150unlimited
eth_read_rpc1020100250unlimited
eth_send_tx353080unlimited
polygon_read_rpc1520100250unlimited
polygon_send_tx353080unlimited

Additional specialized categories (e.g. tracing, bundles, mempool streams, DAS, websocket pub/sub) are gated by tier and have their own budgets; consult the relevant method's reference page for the category it charges against.

Burst capacity

A short spike above your sustained RPS is allowed. The global burst multiplier is 2, so your effective ceiling at any instant is:

burst_capacity = 2 × sustained_rps

For example, a Free-tier key on sol_read_rpc has a sustained budget of 20 RPS and a burst capacity of 40. Stay below sustained on average and you can absorb brief spikes up to the burst ceiling without a 429.

Rate-limit response headers

On metered responses Triport returns the following headers describing your current window. They let you implement client-side pacing without trial and error.

HeaderTypeDescription
X-RateLimit-LimitintegerTotal allowed RPS for the matching tier + category.
X-RateLimit-RemainingintegerRemaining capacity in the current 1-second window.
X-RateLimit-ResetintegerUNIX timestamp when the window resets.
X-RateLimit-CategorystringThe tier-matrix category bucket charged for this request.
Retry-AfterintegerOn 429, seconds to wait before retrying (always 1).

There is no X-Daily-Quota-Remaining header. Triport does not track a daily quota.

Errors

When you exceed sustained + burst, or call a method above your tier, you get one of these. The full error envelope is documented in Errors.

Code (JSON-RPC)HTTPMeaningWhen it happens
-32003429rate_limitedSustained + burst RPS exceeded for your tier on that category. Back off Retry-After seconds and retry.
-32002403tier_insufficientThe method requires a higher tier than your key has.
-32601403method_unknownThe method is not part of the product for that chain.

429 rate_limited

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32003,
    "message": "Rate limit exceeded: 20 RPS sustained on sol_read_rpc (free tier)",
    "data": {
      "current_tier": "free",
      "category": "sol_read_rpc",
      "limit_rps": 20,
      "burst_capacity": 40,
      "retry_after_sec": 1
    }
  }
}

Response headers on this error:

HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Reset: 1746950412
FieldTypeDescription
current_tierstringTier of the key that triggered the limit (freeenterprise).
categorystringTier-matrix category the offending request belongs to.
limit_rpsintegerSustained RPS budget for that tier + category.
burst_capacityintegerInstantaneous ceiling = 2 × limit_rps.
retry_after_secintegerSeconds to wait before retrying (≥ 1).

403 tier_insufficient

Returned when a method needs a higher tier. The X-Required-Tier header carries the minimum tier, and the body includes current_tier, required_tier, the gating category, and an upgrade_url.

Examples

JavaScript (fetch) — honor Retry-After

async function callWithBackoff(body) {
  for (;;) {
    const res = await fetch("https://api.triport.io/sol", {
      method: "POST",
      headers: {
        "x-token": process.env.TRIPORT_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });


    if (res.status === 429) {
      const wait = Number(res.headers.get("Retry-After") ?? 1);
      await new Promise((r) => setTimeout(r, wait * 1000));
      continue; // back off and retry — 429 is normal backpressure
    }
    return res.json();
  }
}

TypeScript SDK (@triport/sdk)

import { Triport, RateLimitedError } from "@triport/sdk";


// The SDK sends your key via the x-token header and retries 429s automatically.
const client = new Triport({ token: process.env.TRIPORT_API_KEY! });


try {
  const balance = await client.sol.getBalance(
    "So11111111111111111111111111111111111111112",
  );
} catch (err) {
  if (err instanceof RateLimitedError) {
    console.warn(
      `rate limited on ${err.category}: ${err.limitRps} RPS (tier ${err.currentTier})`,
    );
  }
}

Python (triport-sdk)

import os
from triport import Triport
from triport.errors import RateLimitedError


client = Triport(token=os.environ["TRIPORT_API_KEY"])


try:
    balance = client.sol.get_balance(
        "So11111111111111111111111111111111111111112"
    )
except RateLimitedError as e:
    # e.retry_after_sec is always 1; the SDK already backed off and retried
    print(f"rate limited on {e.category}: {e.limit_rps} RPS (tier {e.current_tier})")

Notes

  • Pace to sustained, not burst. The burst multiplier (2×) absorbs spikes, but sustaining above your tier's sustained RPS will produce a steady stream of 429s. Use X-RateLimit-Remaining to throttle proactively.
  • 429 is recoverable. Always retry after Retry-After seconds (currently 1). It is backpressure, not a hard failure.
  • No daily quota. Plan only around per-category RPS — there is no daily cap and no daily-quota header.
  • Need more headroom or regions? Compare tiers above and upgrade; Business adds multi-region active-active and up to 5 tokens, Enterprise removes RPS limits entirely.
  • See also: Authentication for how to pass your token, Errors for the full error envelope, and Getting Started.