Run method (method explorer)
https://api.triport.io/v1/diagnostics/run-methodExecutes a single JSON-RPC method against your default key from the browser-based method explorer, returning a structured envelope for both success and failure.
POST /v1/diagnostics/run-method powers the in-browser method explorer. It
takes a chain, a method name, and a params payload, screens the call against
your account's tier, then forwards it to the live RPC backend using your
default API key — so you can try a method and see its real latency and
result without wiring up a client first.
This endpoint is session-gated, not API-key-gated. It is meant to be called from a logged-in browser tab: the request must carry your session cookie and a matching CSRF token. It is not part of the programmatic RPC surface — for that, call the chain's RPC endpoint directly. The handler never receives or returns a raw API key; it resolves your default key server-side and forwards on your behalf.
The defining trait of this endpoint is its envelope: every response — 2xx
success and 4xx/5xx alike — parses as the same JSON object with an ok boolean.
A non-2xx status is part of the contract, not a transport failure. Callers must
branch on the ok and error fields, never on the HTTP status code alone.
Parameters
Request body (JSON):
chainstringrequiredsol, eth, polygon (the long forms solana, ethereum, poly are also accepted).methodstringrequiredgetBalance, eth_getBlockByNumber. Must be non-empty and known to the classifier for that chain.paramsanyrequiredtransportstringoptional'http' is supported; an empty value defaults to HTTP. Any other value is rejected.Response
A successful call returns HTTP 200 with ok: true:
okbooleantrue on success, false on every error path. Branch on this first.latency_msnumberrate_limited and upstream_failed errors.resultanyresult value, passed through verbatim. Shape depends on the method called.rate_limit_remainingnumber-1 when the upstream did not report a budget.tier_requiredstringfree, basic, pro, business, enterprise).categorystringsol_read_rpc, eth_send_tx.Errors
Every error shares the envelope (ok: false plus an error code). The HTTP
status signals which branch to render but is not the source of truth — read
error.
| Code | HTTP | Meaning | When it happens | Extra fields |
|---|---|---|---|---|
unauthenticated | 401 | No valid session | Missing/expired session cookie, or no user on the request. | — |
invalid_json | 400 | Body did not parse | Malformed JSON, or body over the 64 KiB cap. | — |
invalid_chain | 400 | Unknown chain | chain is not one of sol/eth/polygon (or their aliases). | — |
invalid_method | 400 | Empty method | method was omitted or blank. | — |
transport_not_supported | 400 | Bad transport | transport was set to something other than http. | — |
no_default_key | 500 | No usable key | Your account has no active default API key to forward with. | — |
method_unknown | 403 | Method not classified | The method is not in the tier classifier for that chain. | chain, method |
tier_insufficient | 403 | Tier gate | Your tier does not grant the method's category. | current_tier, required_tier, category, method, upgrade_url |
rate_limited | 429 | Throttled | Either the per-session 5 RPS cap, or the upstream tier RPS budget. | current_tier, category, limit_rps, retry_after_sec (session-cap also sets category: "diagnostics_session") |
upstream_failed | 502 | Forward failed | The upstream RPC returned an error or was unreachable. The message is in detail. | detail, latency_ms |
internal | 500 | Server error | Tier resolution or another internal step failed. | — |
invalid_params | — | Params rejected | The supplied params were rejected for the method. Part of the documented envelope union. | — |
Example tier_insufficient body (HTTP 403):
{
"ok": false,
"error": "tier_insufficient",
"current_tier": "free",
"required_tier": "pro",
"category": "eth_trace_filter",
"method": "trace_filter",
"upgrade_url": "/pricing"
}Example rate_limited body (HTTP 429):
{
"ok": false,
"error": "rate_limited",
"current_tier": "",
"category": "diagnostics_session",
"limit_rps": 5,
"retry_after_sec": 1
}See errors.md for the shared error envelope and conventions.
Examples
JavaScript (fetch)
Reads the nl_csrf cookie and submits it as the CSRF header; credentials: 'include' sends the session cookie. The caller branches on ok, never on the
HTTP status.
function readCookie(name) {
const m = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
return m ? decodeURIComponent(m[1]) : null;
}
async function runMethod(req) {
const headers = { 'Content-Type': 'application/json' };
const csrf = readCookie('nl_csrf');
if (csrf) headers['X-CSRF-Token'] = csrf;
const r = await fetch('https://api.triport.io/v1/diagnostics/run-method', {
method: 'POST',
credentials: 'include',
headers,
body: JSON.stringify(req),
});
// Parse the body for every status — handler always emits the envelope.
return r.json();
}
const res = await runMethod({
chain: 'sol',
method: 'getBalance',
params: ['So11111111111111111111111111111111111111112'],
transport: 'http',
});
if (res.ok) {
console.log(`ok in ${res.latency_ms}ms`, res.result);
} else if (res.error === 'tier_insufficient') {
console.warn(`needs ${res.required_tier}`, res.upgrade_url);
} else if (res.error === 'rate_limited') {
console.warn(`retry in ${res.retry_after_sec}s (limit ${res.limit_rps} rps)`);
} else {
console.error(res.error, res.detail);
}TypeScript SDK (@triport/sdk)
import { Triport } from '@triport/sdk';
// In a browser session the SDK forwards the session cookie and CSRF token.
const client = new Triport();
const res = await client.diagnostics.runMethod({
chain: 'eth',
method: 'eth_getBlockByNumber',
params: ['latest', false],
transport: 'http',
});
if (res.ok) {
console.log(res.category, res.latency_ms, res.result);
} else {
console.error(res.error, res.detail ?? res.required_tier);
}Python (triport-sdk)
from triport import Triport
client = Triport(session=session_cookie, csrf=csrf_token)
res = client.diagnostics.run_method(
chain="polygon",
method="eth_blockNumber",
params=[],
transport="http",
)
if res["ok"]:
print(res["category"], res["latency_ms"], res["result"])
elif res["error"] == "rate_limited":
print("retry after", res["retry_after_sec"], "s")
else:
print("error:", res["error"], res.get("detail"))Notes
- Always branch on
ok/error, not on HTTP status. A403,429, or502carries a fully-formed envelope; treat the status only as a hint for which branch to render. - Two distinct
rate_limitedsources. The per-session 5 RPS cap (this endpoint,category: "diagnostics_session") and the upstream per-category tier budget both surface aserror: "rate_limited". Usecategoryto tell them apart; both carrylimit_rpsandretry_after_sec. - Default key only. The method runs against your account's active default
API key. If none is set you get
no_default_key. - Body cap. Request bodies are limited to 64 KiB — enough for large Solana
simulateTransactionpayloads. Larger bodies fail asinvalid_json. - Browser-first. This is the method explorer's backend; for programmatic access call the chain's RPC endpoint directly with your API key instead.