> For a complete page index, fetch https://docs.conduit.xyz/llms.txt # Make authenticated RPC requests > Send a Conduit Nodes API key and JSON Web Token to an RPC endpoint with TypeScript or Go. After you bind a public key to a Nodes API key, each RPC request must include both credentials: * The Nodes API key in the endpoint URL path. * The signed JSON Web Token (JWT) in the `Authorization: Bearer ` header. Copy the HTTP endpoint URL from the **Endpoints** tab for your Nodes API key. The copied URL includes the API key path. Set the URL and a freshly generated token as environment variables: ```bash export CONDUIT_RPC_URL='https://[YOUR_RPC_URL]/[YOUR_API_KEY]' export JWT='[YOUR_SIGNED_JWT]' ``` If you need a token, [generate a JWT](/rpc-nodes/guides/jwt-authentication/generate-jwts) first. ## Send a request These examples call `eth_blockNumber` and print the JSON-RPC response. Save the example as `request.ts` or `request.go`. **`TypeScript`** ```typescript TypeScript const rpcURL = process.env.CONDUIT_RPC_URL const token = process.env.JWT if (!rpcURL || !token) { throw new Error('Set CONDUIT_RPC_URL and JWT') } const response = await fetch(rpcURL, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [], }), }) if (!response.ok) { throw new Error(`RPC request failed: ${response.status} ${await response.text()}`) } console.log(await response.json()) ``` **`Go`** ```go Go package main import ( "bytes" "fmt" "io" "log" "net/http" "os" ) func main() { rpcURL := os.Getenv("CONDUIT_RPC_URL") token := os.Getenv("JWT") if rpcURL == "" || token == "" { log.Fatal("set CONDUIT_RPC_URL and JWT") } body := []byte(`{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}`) request, err := http.NewRequest(http.MethodPost, rpcURL, bytes.NewReader(body)) if err != nil { log.Fatal(err) } request.Header.Set("Content-Type", "application/json") request.Header.Set("Authorization", "Bearer "+token) response, err := http.DefaultClient.Do(request) if err != nil { log.Fatal(err) } defer response.Body.Close() responseBody, err := io.ReadAll(response.Body) if err != nil { log.Fatal(err) } if response.StatusCode < 200 || response.StatusCode >= 300 { log.Fatalf("RPC request failed: %s: %s", response.Status, responseBody) } fmt.Println(string(responseBody)) } ``` Run the example: **`TypeScript`** ```bash TypeScript npm install --save-dev tsx @types/node npx tsx request.ts ``` **`Go`** ```bash Go go run request.go ``` A successful response contains the latest block number in the `result` field. ## Refresh tokens before they expire Issue short-lived tokens from your backend and replace them before `exp`. Never embed the private key or token-generation code in a browser app. If several clients share a token, refresh it early enough that active requests don't cross the expiration time. ## Troubleshoot authentication errors If Conduit rejects a request, check that: * The endpoint URL contains the correct Nodes API key. * The `Authorization` header uses the `Bearer ` format. * The JWT hasn't expired. * The JWT header's `kid` matches the Key ID shown in Conduit. * The JWT algorithm matches the algorithm selected for the public key. * The public key is enabled and bound to the API key in the endpoint URL. For other HTTP and JSON-RPC failures, use the [RPC error reference](/rpc-nodes/guides/rpc-errors). > Send a Conduit Nodes API key and JSON Web Token to an RPC endpoint with TypeScript or Go.