PerformanceBlog
Tempo MCP serverGive agents search and read tools for Tempo docs
Skip to content
LogoLogo

Tempo API Typed Client

Use the Tempo API Typed Client for endpoint autocomplete and full end-to-end type-safety across API parameters, response bodies, statuses, and errors.

Install Tempo API package

Install the tapimo package with your package manager.

Create typed Tempo API client

Create a Tempo API client with Client.create.

client.ts
import {  } from 'tapimo'
 
const  = .({
  // API key sugar for the canonical `tempo-api-key` header.
  : 'tempo_api_key',
  // Override the API URL. Defaults to `Client.defaultUrl`.
  : 'https://api.tempo.xyz',
  // Or pass custom headers directly.
  : { : 'Bearer tempo_api_key' },
})

Client.create() also accepts Hono client options such as a custom fetch implementation. If you pass apiKey, the client merges it into the request headers as tempo-api-key.

Make type-safe Tempo API requests

Requests are end-to-end type-safe across parameters, response bodies, statuses, and errors. For example, GET /v1/tokens/:token narrows the response body from the HTTP status:

tokens.ts
import {  } from 'tapimo'
 
const  = .()
 
const  = await ..[':token'].({
  : { : '0x20c0000000000000000000000000000000000000' },
})
 
// Narrow responses by status.
if (. !== 200) {
  .statusArrow
// status is now typed to non-200 series
if (. === 404) { // Handle 404 status specifically const jsonArrow
= await .()
..codeArrow
// which narrows to "token_not_found"
} else if (. === 402) { // Handle the payment challenge from `WWW-Authenticate` const challengeArrow
= await .()
} else { // Handle validation, auth, rate-limit, or upstream errors const jsonArrow
= await .()
} throw new ('Request failed') } // Request is successfull .statusArrow
// Response is narrowed to 200
// Get typed response body const tokenArrow
= await .()
.symbolArrow

Tempo API endpoint autocomplete

Routes autocomplete directly on the client, so you can discover endpoints without leaving your editor:

endpoints.ts
import {  } from 'tapimo'
 
const  = .()
 
const  = await ..|
  • addresses
  • blocks
  • exchange
  • indexer
  • tokenlist
  • tokens
  • transactions
  • transfers
  • webhooks
const = await ...|
  • $get
  • $path
  • $url
  • receipts

Call Tempo JSON-RPC through Typed Client

The Typed Client exposes the raw JSON-RPC passthrough as a typed route under client.rpc. The route key includes Hono's path pattern because the chain selector is optional:

rpc.ts
import {  } from 'tapimo'
 
const  = .()
 
const  = await .[':chain{mainnet|testnet|[0-9]+}?'].({
  // Use `undefined` for `/rpc`, or pass `mainnet`, `testnet`, or a numeric chain id.
  : { : 'testnet' },
  : {
    : '2.0',
    : 1,
    : 'eth_blockNumber',
    : [],
  },
})
 
if (. !== 200) {
  const  = await .()
  throw new (..)
}
 
const  = await .()
if (!.() && .)
  throw new (..)
 
const  = .() ? [0]?. : .

Chain selectors map to these hosted endpoints:

chain valueHosted RPC path
undefinedhttps://api.tempo.xyz/rpc
'mainnet'https://api.tempo.xyz/rpc/mainnet
'testnet'https://api.tempo.xyz/rpc/testnet
'4217'https://api.tempo.xyz/rpc/4217

Send batch JSON-RPC requests

The JSON-RPC body type accepts one request or an array of requests. The client narrows the success body to the same single-or-batch response union:

batch-rpc.ts
import {  } from 'tapimo'
 
const  = .()
 
const  = await .[':chain{mainnet|testnet|[0-9]+}?'].({
  : { :  },
  : [
    { : '2.0', : 1, : 'eth_chainId', : [] },
    { : '2.0', : 2, : 'eth_blockNumber', : [] },
  ],
})
 
if (. === 200) {
  const  = await .()
  // results is typed as one JSON-RPC response or an array of JSON-RPC responses.
}