Authentication
https://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.
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:
| Environment | Base URL |
|---|---|
| Production | https://api.triport.io |
| Staging | https://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 thex-tokenheader. 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"errorstringunauthorized on missing or invalid credentials.Obtaining a key
-
Sign in to the Triport portal at
https://api.triport.io. -
Create a project and generate an API key. Production keys are issued with the
nl_live_prefix (e.g.nl_live_1a2b3c4d…). -
Assign the chains the key may call. Each chain grants the corresponding scope (see the mapping below).
-
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:
| # | Form | Where | Example | Notes |
|---|---|---|---|---|
| 1 | x-token header | Request header | x-token: $TRIPORT_API_KEY | SDK default and preferred. |
| 2 | Authorization: Bearer header | Request header | Authorization: Bearer $TRIPORT_API_KEY | Standard Bearer scheme. |
| 3 | ?api-key= query parameter | URL query | ?api-key=$TRIPORT_API_KEY | Legacy form. |
| 4 | Path-form /<chain>/<key> | URL path | POST /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 segment | Chain | Scope required |
|---|---|---|
sol | Solana | solana:rpc |
eth | Ethereum | eth:rpc |
poly | Polygon | polygon:rpc |
op | Optimism | op:rpc |
bsc | BSC | bsc: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:
| Chain | Path segment | Scope |
|---|---|---|
| Solana | sol | solana:rpc |
| Ethereum | eth | eth:rpc |
| Polygon | poly | polygon:rpc |
| Optimism | op | op:rpc |
| BSC | bsc | bsc:rpc |
A key holding * satisfies every scope check.
Errors
| Code | HTTP | Meaning | When it happens |
|---|---|---|---|
unauthorized | 401 | Missing or invalid credentials | No token in any of the four forms, or the token is unknown. Response includes WWW-Authenticate: Bearer realm="proxy". |
trial_expired | 401 | Free trial ended | The key was on the free trial and its 7-day window has passed. |
subscription_expired | 401 | Subscription lapsed | A paid subscription is no longer active. |
tier_insufficient | 403 | Tier too low for method | The key's tier does not include the requested method's category. |
method_unknown | 403 | Method not in product | The method is not part of the product for that chain. |
rate_limited | 429 | Sustained RPS exceeded | Too 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-token→Authorization: Bearer→?api-key=→ path-form); sending more than one means the lower-priority forms are ignored. - Path-form is
nl_live_*only. Keys without thenl_live_prefix cannot authenticate through/<chain>/<key>— use a header form instead. - Auth headers stop at Triport. The
x-tokenandAuthorizationheaders 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 thex-tokenheader. - Related: Rate limits · Errors · Getting started