TriportRPC

Authentication

POSThttps://api.triport.io/

How to obtain a Triport API key and present it on every request — across the four accepted token forms, in priority order.

Solana | Ethereum | Polygon | Optimism | BSCper-chain (solana:rpc, eth:rpc, polygon:rpc, op:rpc, bsc:rpc)tier resolved from the key — see [Rate limits](./rate-limits.md)

Every request to the Triport API must carry a valid API key. There is no anonymous access. The platform accepts the key in four different forms so that existing clients, SDKs, and copy-pasted endpoint URLs all keep working — but they are tried in a fixed priority order, and the first one present wins.

Authenticate against one of two base URLs:

EnvironmentBase URL
Productionhttps://api.triport.io
Staginghttps://staging.api.triport.io

A key is scoped to one or more chains. When you call a chain-specific endpoint, the key must hold the matching scope (or the wildcard *); otherwise the request is rejected with 403 Forbidden. Missing or invalid credentials are rejected with 401 Unauthorized and a WWW-Authenticate: Bearer challenge.

The SDKs (@triport/sdk, triport-sdk) default to the x-token header. Use it for new integrations; the other forms exist for compatibility.

Response

A successful, authenticated request returns the normal method result. When authentication fails, the body is a minimal JSON envelope and the response carries a WWW-Authenticate challenge header:

HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Bearer realm="proxy"
errorstring
Machine-readable error code. unauthorized on missing or invalid credentials.

Obtaining a key

  1. Sign in to the Triport portal at https://api.triport.io.

  2. Create a project and generate an API key. Production keys are issued with the nl_live_ prefix (e.g. nl_live_1a2b3c4d…).

  3. Assign the chains the key may call. Each chain grants the corresponding scope (see the mapping below).

  4. Store the key as an environment variable — never commit it to source:

    export TRIPORT_API_KEY="nl_live_1a2b3c4d5e6f7890abcdef"

Token forms (priority order)

The server checks for a token in the following order and uses the first one it finds:

#FormWhereExampleNotes
1x-token headerRequest headerx-token: $TRIPORT_API_KEYSDK default and preferred.
2Authorization: Bearer headerRequest headerAuthorization: Bearer $TRIPORT_API_KEYStandard Bearer scheme.
3?api-key= query parameterURL query?api-key=$TRIPORT_API_KEYLegacy form.
4Path-form /<chain>/<key>URL pathPOST /eth/nl_live_…Restricted to nl_live_* keys only.

Because the order is fixed, sending both an x-token header and an ?api-key= query parameter means the header is used and the query value is ignored.

Path-form details

The path-form POST /<chain>/<key> is accepted only for keys with the nl_live_ prefix. The chain URL segment must be one of:

URL segmentChainScope required
solSolanasolana:rpc
ethEthereumeth:rpc
polyPolygonpolygon:rpc
opOptimismop:rpc
bscBSCbsc:rpc

A trailing slash is permitted (/eth/nl_live_…/). When you use the path-form, the chain segment also drives the scope check: the key must hold the scope shown above (or *), or the request returns 403 Forbidden.

Chain-to-scope mapping

A key carries one scope per chain it may call. The chain segment used in the path-form maps to the full scope stored on the key:

ChainPath segmentScope
Solanasolsolana:rpc
Ethereumetheth:rpc
Polygonpolypolygon:rpc
Optimismopop:rpc
BSCbscbsc:rpc

A key holding * satisfies every scope check.

Errors

CodeHTTPMeaningWhen it happens
unauthorized401Missing or invalid credentialsNo token in any of the four forms, or the token is unknown. Response includes WWW-Authenticate: Bearer realm="proxy".
trial_expired401Free trial endedThe key was on the free trial and its 7-day window has passed.
subscription_expired401Subscription lapsedA paid subscription is no longer active.
tier_insufficient403Tier too low for methodThe key's tier does not include the requested method's category.
method_unknown403Method not in productThe method is not part of the product for that chain.
rate_limited429Sustained RPS exceededToo many requests; retry after Retry-After seconds.

See Errors for the full error envelope and the typed fields on each error code.

Examples

JavaScript (fetch)

const res = await fetch("https://api.triport.io/", {
  method: "POST",
  headers: {
    "x-token": process.env.TRIPORT_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "getSlot",
    params: [],
  }),
});


if (res.status === 401) {
  throw new Error("Authentication failed — check TRIPORT_API_KEY");
}
const { result } = await res.json();

TypeScript SDK (@triport/sdk)

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


// The SDK sends the key via the x-token header by default.
const client = new Triport({
  apiKey: process.env.TRIPORT_API_KEY!,
  // baseUrl defaults to https://api.triport.io
  // baseUrl: "https://staging.api.triport.io", // for testing
});


const slot = await client.solana.getSlot();

Python (triport-sdk)

import os
from triport import Triport


# Authenticates with the x-token header.
client = Triport(api_key=os.environ["TRIPORT_API_KEY"])


slot = client.solana.get_slot()

Notes

  • Pick one form. Forms are tried in priority order (x-tokenAuthorization: Bearer?api-key= → path-form); sending more than one means the lower-priority forms are ignored.
  • Path-form is nl_live_* only. Keys without the nl_live_ prefix cannot authenticate through /<chain>/<key> — use a header form instead.
  • Auth headers stop at Triport. The x-token and Authorization headers are stripped before any request is forwarded downstream; your key is never echoed to the response or onward.
  • Keep keys out of URLs where you can. The ?api-key= query and path-form place the key in the URL, where it may be captured by proxy and access logs. Prefer the x-token header.
  • Related: Rate limits · Errors · Getting started