API Playground
Interactive API testing environment for FortiBlox RPC methods
API Playground
Test FortiBlox API methods directly in your browser with our interactive playground. Execute real API calls, see responses in real-time, and generate cURL commands for your applications.
Browser Limitations
CORS Restrictions: The playground makes requests directly from your browser, which may be blocked by CORS policies. For production use, make API calls from your backend server. If you experience connection issues in the browser:
- Use curl or Postman for testing without CORS restrictions
- Copy the cURL command from the playground and run it in your terminal
- Implement API calls in your backend code (recommended for production)
- See authentication documentation for server-side implementation examples
Features
The playground provides a complete testing environment with:
RPC/REST Features
- Method Explorer - Browse all available RPC methods organized by category
- Smart Parameters - Dynamic parameter inputs that adapt to each method
- Real-time Execution - Execute API calls and see responses instantly
- Response Timing - Monitor request performance with millisecond precision
- Error Handling - Clear error messages with actionable solutions
- cURL Generator - Copy ready-to-use cURL commands for any request
- Header Inspection - View request and response headers for debugging
- Local Storage - API keys stored securely in your browser only
gRPC Streaming Features
- Real-time Streams - Subscribe to transactions, blocks, and account updates
- High Performance - 10x lower latency (< 10ms) compared to REST polling
- Advanced Filtering - Filter by accounts, programs, vote transactions
- WebSocket Fallback - Browser-compatible streaming when native gRPC unavailable
- Production Ready - Complete examples with error handling and auto-reconnect
- Multi-language Support - JavaScript, Python, Rust, Go examples
Security & Privacy
Security Best Practices
This playground runs entirely in your browser. Your API key is only sent when making API calls to FortiBlox endpoints.
Important:
- Use testnet keys for testing
- Never use production mainnet keys with real funds
- API keys are stored locally in your browser
- Clear your browser data to remove stored keys
Getting Started
1. Get Your API Key
If you don't have an API key yet:
- Visit the FortiBlox Developer Portal
- Create a new project
- Generate an API key
- Copy your key to the playground
2. Select Network
Choose between:
- Testnet - Safe testing environment (recommended)
- Mainnet - Production blockchain (use with caution)
3. Choose a Method
Select from available RPC methods organized by category:
- Account Methods - Query account balances and information
- Transaction Methods - Fetch and submit transactions
- Block Methods - Access blockchain blocks and slots
- Token Methods - Work with SPL tokens
4. Fill Parameters
The playground automatically shows required parameters for each method. Click "Load Example" to populate with sample values.
5. Execute
Click "Execute Request" to run the API call. View the response, timing, and headers.
When to Use Each API
Choose the right API for your use case:
| Use Case | RPC/REST | gRPC Streaming |
|---|---|---|
| Query account balance | ✓ Best | - |
| Get transaction details | ✓ Best | - |
| Fetch historical blocks | ✓ Best | ✓ Good |
| Monitor wallet activity | Limited | ✓ Best |
| Real-time DEX tracking | Limited | ✓ Best |
| NFT marketplace indexing | Limited | ✓ Best |
| Block explorer updates | Polling required | ✓ Best |
| Simple one-off queries | ✓ Best | - |
| Browser applications | ✓ Best | WebSocket only |
| Server-side streaming | - | ✓ Best |
Use RPC/REST when:
- Making one-off queries or occasional requests
- Fetching specific data (balance, transaction, block)
- Building browser-based applications
- Simplicity is more important than real-time updates
Use gRPC Streaming when:
- Need real-time blockchain data updates
- Monitoring specific accounts or programs continuously
- Building DeFi protocols, NFT indexers, or analytics platforms
- Server-side applications where performance is critical
- Processing high-volume blockchain events
Interactive Playground
Security Notice
This playground runs entirely in your browser. Your API key is never sent to our servers except when making API calls. For production apps, use test keys only. Avoid using mainnet keys with real funds.
API Playground
Test FortiBlox API methods directly in your browser
Stored locally in your browser
Returns the lamport balance of the account
Pubkey of account to query
cURL Command
curl -X POST "https://nexus-testnet.fortiblox.com/rpc" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": [
"vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
]
}'Browser Limitations
Native gRPC not supported in browsers: Standard gRPC uses HTTP/2 which requires special handling in browsers. For browser-based applications, use:
- gRPC-Web - HTTP/1.1 compatible proxy
- WebSocket fallback - Available at
wss://nexus.fortiblox.com/ws - Server-side gRPC - Recommended for production (Node.js, Python, Rust, Go)
The examples below are for server-side implementations. See gRPC documentation for full setup.
gRPC Endpoint
Connect to FortiBlox gRPC streaming:
| Network | Endpoint | Port |
|---|---|---|
| Mainnet | grpc.fortiblox.com:10002 | 10002 (HTTP/2) |
Authentication
All gRPC requests require the x-api-key metadata header:
const metadata = new grpc.Metadata();
metadata.add('x-api-key', 'YOUR_API_KEY');Stream Transactions
Subscribe to real-time transaction updates:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
// Load proto definition
const packageDefinition = protoLoader.loadSync('geyser.proto');
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;
// Create client with TLS
const client = new geyserProto.Geyser(
'grpc.fortiblox.com:10002',
grpc.credentials.createSsl()
);
// Add API key to metadata
const metadata = new grpc.Metadata();
metadata.add('x-api-key', process.env.FORTIBLOX_API_KEY);
// Subscribe to transactions
const stream = client.SubscribeTransactions({
account_include: ['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
filter_votes: true,
commitment: 'CONFIRMED'
}, metadata);
stream.on('data', (tx) => {
console.log(`Transaction: ${tx.signature}`);
console.log(` Slot: ${tx.slot}`);
console.log(` Success: ${tx.success}`);
console.log(` Fee: ${tx.fee} lamports`);
});
stream.on('error', (err) => {
console.error('Stream error:', err.message);
});
stream.on('end', () => {
console.log('Stream ended');
});import grpc
import geyser_pb2
import geyser_pb2_grpc
import os
# Create secure channel with TLS
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel(
'grpc.fortiblox.com:10002',
credentials
)
# Create stub
stub = geyser_pb2_grpc.GeyserStub(channel)
# Add API key to metadata
metadata = [('x-api-key', os.getenv('FORTIBLOX_API_KEY'))]
# Subscribe to transactions
request = geyser_pb2.SubscribeTransactionsRequest(
account_include=['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
filter_votes=True,
commitment=geyser_pb2.CONFIRMED
)
try:
for tx in stub.SubscribeTransactions(request, metadata=metadata):
print(f"Transaction: {tx.signature}")
print(f" Slot: {tx.slot}")
print(f" Success: {tx.success}")
print(f" Fee: {tx.fee} lamports")
except grpc.RpcError as e:
print(f"Error: {e.code()} - {e.details()}")# WebSocket fallback for browser/testing
wscat -c wss://nexus.fortiblox.com/ws \
-H "X-API-Key: $FORTIBLOX_API_KEY"
# Send subscription request
{
"jsonrpc": "2.0",
"id": 1,
"method": "transactionSubscribe",
"params": [{
"accountInclude": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
"vote": false,
"commitment": "confirmed"
}]
}Stream Blocks
Subscribe to real-time block updates:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
// Setup client (same as above)
const packageDefinition = protoLoader.loadSync('geyser.proto');
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;
const client = new geyserProto.Geyser(
'grpc.fortiblox.com:10002',
grpc.credentials.createSsl()
);
const metadata = new grpc.Metadata();
metadata.add('x-api-key', process.env.FORTIBLOX_API_KEY);
// Subscribe to blocks
const stream = client.SubscribeBlocks({
commitment: 'FINALIZED'
}, metadata);
stream.on('data', (block) => {
console.log(`Block ${block.slot}`);
console.log(` Hash: ${block.blockhash}`);
console.log(` Transactions: ${block.transaction_count}`);
console.log(` Parent Slot: ${block.parent_slot}`);
console.log(` Timestamp: ${new Date(block.block_time * 1000)}`);
});
stream.on('error', (err) => {
console.error('Stream error:', err.message);
});import grpc
import geyser_pb2
import geyser_pb2_grpc
import os
from datetime import datetime
# Setup (same as above)
credentials = grpc.ssl_channel_credentials()
channel = grpc.insecure_channel('grpc.fortiblox.com:10002', credentials)
stub = geyser_pb2_grpc.GeyserStub(channel)
metadata = [('x-api-key', os.getenv('FORTIBLOX_API_KEY'))]
# Subscribe to blocks
request = geyser_pb2.SubscribeBlocksRequest(
commitment=geyser_pb2.FINALIZED
)
try:
for block in stub.SubscribeBlocks(request, metadata=metadata):
print(f"Block {block.slot}")
print(f" Hash: {block.blockhash}")
print(f" Transactions: {block.transaction_count}")
print(f" Parent Slot: {block.parent_slot}")
print(f" Timestamp: {datetime.fromtimestamp(block.block_time)}")
except grpc.RpcError as e:
print(f"Error: {e.code()} - {e.details()}")Account Updates (via Transaction Monitoring)
Monitor specific account activity:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
// Setup client
const packageDefinition = protoLoader.loadSync('geyser.proto');
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;
const client = new geyserProto.Geyser(
'grpc.fortiblox.com:10002',
grpc.credentials.createSsl()
);
const metadata = new grpc.Metadata();
metadata.add('x-api-key', process.env.FORTIBLOX_API_KEY);
// Monitor account updates via transactions
const WALLET_ADDRESS = 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg';
const stream = client.SubscribeTransactions({
account_include: [WALLET_ADDRESS],
filter_votes: true,
commitment: 'CONFIRMED'
}, metadata);
stream.on('data', (tx) => {
console.log(`Account ${WALLET_ADDRESS} activity detected:`);
console.log(` Transaction: ${tx.signature}`);
console.log(` Slot: ${tx.slot}`);
console.log(` Success: ${tx.success}`);
console.log(` Accounts involved: ${tx.account_keys.length}`);
});import grpc
import geyser_pb2
import geyser_pb2_grpc
import os
# Setup
credentials = grpc.ssl_channel_credentials()
channel = grpc.insecure_channel('grpc.fortiblox.com:10002', credentials)
stub = geyser_pb2_grpc.GeyserStub(channel)
metadata = [('x-api-key', os.getenv('FORTIBLOX_API_KEY'))]
# Monitor account updates via transactions
WALLET_ADDRESS = 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg'
request = geyser_pb2.SubscribeTransactionsRequest(
account_include=[WALLET_ADDRESS],
filter_votes=True,
commitment=geyser_pb2.CONFIRMED
)
try:
for tx in stub.SubscribeTransactions(request, metadata=metadata):
print(f"Account {WALLET_ADDRESS} activity detected:")
print(f" Transaction: {tx.signature}")
print(f" Slot: {tx.slot}")
print(f" Success: {tx.success}")
print(f" Accounts involved: {len(tx.account_keys)}")
except grpc.RpcError as e:
print(f"Error: {e.code()} - {e.details()}")WebSocket Fallback for Browsers
When native gRPC is not supported, use WebSocket subscriptions:
// Browser-compatible WebSocket streaming
const ws = new WebSocket('wss://nexus.fortiblox.com/ws');
ws.onopen = () => {
// Subscribe to transactions
ws.send(JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'transactionSubscribe',
params: [{
accountInclude: ['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
vote: false,
commitment: 'confirmed'
}]
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.method === 'transactionNotification') {
const tx = data.params.result;
console.log('Transaction:', tx.signature);
console.log(' Slot:', tx.slot);
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
// Authentication via query parameter
const wsWithAuth = new WebSocket(
`wss://nexus.fortiblox.com/ws?api_key=${YOUR_API_KEY}`
);Complete Working Example
Full production-ready example with error handling and reconnection:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
class GrpcStreamClient {
constructor(endpoint, apiKey) {
this.endpoint = endpoint;
this.apiKey = apiKey;
this.reconnectDelay = 1000;
this.maxReconnectDelay = 30000;
this.currentDelay = this.reconnectDelay;
}
connect() {
// Load proto
const packageDefinition = protoLoader.loadSync('geyser.proto');
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;
// Create client
this.client = new geyserProto.Geyser(
this.endpoint,
grpc.credentials.createSsl()
);
// Setup metadata
this.metadata = new grpc.Metadata();
this.metadata.add('x-api-key', this.apiKey);
}
subscribeTransactions(filters, onData, onError) {
const stream = this.client.SubscribeTransactions(filters, this.metadata);
stream.on('data', (tx) => {
this.currentDelay = this.reconnectDelay; // Reset delay on success
onData(tx);
});
stream.on('error', (err) => {
console.error('Stream error:', err.message);
onError(err);
// Auto-reconnect with exponential backoff
setTimeout(() => {
console.log(`Reconnecting in ${this.currentDelay}ms...`);
this.subscribeTransactions(filters, onData, onError);
this.currentDelay = Math.min(
this.currentDelay * 2,
this.maxReconnectDelay
);
}, this.currentDelay);
});
stream.on('end', () => {
console.log('Stream ended, reconnecting...');
setTimeout(() => {
this.subscribeTransactions(filters, onData, onError);
}, this.reconnectDelay);
});
return stream;
}
}
// Usage
const client = new GrpcStreamClient(
'grpc.fortiblox.com:10002',
process.env.FORTIBLOX_API_KEY
);
client.connect();
const stream = client.subscribeTransactions(
{
account_include: ['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
filter_votes: true,
commitment: 'CONFIRMED'
},
(tx) => {
console.log(`Transaction: ${tx.signature}`);
console.log(` Slot: ${tx.slot}`);
console.log(` Success: ${tx.success}`);
},
(err) => {
console.error('Error handler:', err.message);
}
);
// Graceful shutdown
process.on('SIGINT', () => {
stream.cancel();
process.exit(0);
});Health Check
Test your gRPC connection:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync('geyser.proto');
const geyserProto = grpc.loadPackageDefinition(packageDefinition).geyser;
const client = new geyserProto.Geyser(
'grpc.fortiblox.com:10002',
grpc.credentials.createSsl()
);
const metadata = new grpc.Metadata();
metadata.add('x-api-key', process.env.FORTIBLOX_API_KEY);
client.Ping({ count: 1 }, metadata, (err, response) => {
if (err) {
console.error('Connection failed:', err.message);
return;
}
console.log('Connected to FortiBlox gRPC!');
console.log(` Version: ${response.version}`);
console.log(` Latest Slot: ${response.latest_slot}`);
console.log(` Network: ${response.network}`);
});import grpc
import geyser_pb2
import geyser_pb2_grpc
import os
credentials = grpc.ssl_channel_credentials()
channel = grpc.insecure_channel('grpc.fortiblox.com:10002', credentials)
stub = geyser_pb2_grpc.GeyserStub(channel)
metadata = [('x-api-key', os.getenv('FORTIBLOX_API_KEY'))]
try:
response = stub.Ping(
geyser_pb2.PingRequest(count=1),
metadata=metadata
)
print('Connected to FortiBlox gRPC!')
print(f' Version: {response.version}')
print(f' Latest Slot: {response.latest_slot}')
print(f' Network: {response.network}')
except grpc.RpcError as e:
print(f'Connection failed: {e.code()} - {e.details()}')Next Steps for gRPC
- Get Proto Files - Download from GitHub
- Install Dependencies - Follow Getting Started Guide
- Explore Advanced Filtering - See Transaction Streaming
- Learn Historical Replay - Check Historical Replay
Popular Methods
getBalance
Check the SOL balance of any wallet address. Returns the balance in lamports (1 SOL = 1,000,000,000 lamports).
Use Case: Verify wallet balances before transactions, build portfolio dashboards
Parameters:
address- Wallet public key (required)
Example Response:
{
"jsonrpc": "2.0",
"result": {
"context": { "slot": 123456789 },
"value": 1500000000
},
"id": 1
}getAccountInfo
Retrieve detailed information about any account including owner, data, and lamports.
Use Case: Inspect program accounts, verify account ownership
Parameters:
address- Account public key (required)encoding- Data encoding format (optional, default: "base64")
getTransaction
Fetch complete transaction details including signatures, accounts, and instructions.
Use Case: Transaction verification, blockchain explorers, audit trails
Parameters:
signature- Transaction signature (required)maxSupportedTransactionVersion- Set to 0 for versioned transactions (optional)
Important: Transactions must be confirmed before they can be retrieved.
getBlock
Get all transactions and metadata for a specific block.
Use Case: Block explorers, analytics platforms, data indexing
Parameters:
slot- Block slot number (required)maxSupportedTransactionVersion- Set to 0 for versioned transactions (optional)
getSignaturesForAddress
List all transaction signatures for an account in chronological order.
Use Case: Transaction history, activity monitoring, audit logs
Parameters:
address- Account address (required)limit- Maximum signatures to return (optional, max 1000)
sendTransaction
Submit a signed transaction to the blockchain for processing.
Use Case: Wallet applications, DeFi protocols, NFT marketplaces
Parameters:
transaction- Base64 encoded signed transaction (required)
Mainnet Warning
Using sendTransaction on mainnet will execute real blockchain transactions that cannot be reversed. Always test on testnet first!
Tips & Best Practices
Performance Optimization
- Use Commitment Levels - Specify commitment levels for faster or more reliable responses
- Batch Requests - Group multiple calls to reduce latency
- Cache Responses - Store frequently accessed data locally
- Monitor Rate Limits - Check response headers for rate limit status
Error Handling
Common errors and solutions:
| Error | Cause | Solution |
|---|---|---|
Invalid API Key | Wrong or expired key | Verify key in developer portal |
Rate Limit Exceeded | Too many requests | Wait and retry with exponential backoff |
Invalid Params | Wrong parameter format | Check parameter types and values |
Account Not Found | Account doesn't exist | Verify address on blockchain explorer |
Transaction Not Found | Transaction not confirmed | Wait for confirmation or check signature |
Testing Workflow
Recommended testing approach:
- Start with Simple Methods - Try
getSlotorgetBlockHeightto verify connectivity - Test with Known Data - Use public addresses from blockchain explorers
- Validate Responses - Check response structure matches documentation
- Test Error Cases - Try invalid inputs to see error handling
- Generate cURL - Copy working requests to your codebase
Code Examples
Once you've tested in the playground, use these patterns in your applications:
// JavaScript/Node.js with fetch
async function callRPC(method, params) {
const response = await fetch('https://nexus.fortiblox.com/rpc', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.FORTIBLOX_API_KEY
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: method,
params: params
})
});
const data = await response.json();
if (data.error) {
throw new Error(`RPC Error: ${data.error.message}`);
}
return data.result;
}
// Usage
const balance = await callRPC('getBalance', [
'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg'
]);
console.log(`Balance: ${balance.value / 1e9} SOL`);# Python with requests
import requests
import os
def call_rpc(method, params):
response = requests.post(
'https://nexus.fortiblox.com/rpc',
json={
'jsonrpc': '2.0',
'id': 1,
'method': method,
'params': params
},
headers={
'X-API-Key': os.getenv('FORTIBLOX_API_KEY')
}
)
data = response.json()
if 'error' in data:
raise Exception(f"RPC Error: {data['error']['message']}")
return data['result']
# Usage
balance = call_rpc('getBalance', [
'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg'
])
print(f"Balance: {balance['value'] / 1e9} SOL")# cURL with environment variable
curl -X POST "https://nexus.fortiblox.com/rpc" \
-H "Content-Type: application/json" \
-H "X-API-Key: $FORTIBLOX_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": ["vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"]
}'Advanced Features
Batch Requests
Send multiple RPC calls in a single HTTP request:
[
{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": ["address1"]
},
{
"jsonrpc": "2.0",
"id": 2,
"method": "getBalance",
"params": ["address2"]
}
]WebSocket Subscriptions
For real-time updates, use WebSocket subscriptions instead of polling:
const ws = new WebSocket('wss://nexus.fortiblox.com/ws');
ws.on('open', () => {
ws.send(JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'accountSubscribe',
params: ['address', { encoding: 'jsonParsed' }]
}));
});
ws.on('message', (data) => {
console.log('Account updated:', JSON.parse(data));
});Rate Limits & Quotas
The playground shares the same rate limits as regular API calls:
| Tier | Requests/Second | Daily Quota |
|---|---|---|
| Free | 10 | 100,000 |
| Developer | 50 | 1,000,000 |
| Business | 200 | 10,000,000 |
| Enterprise | Custom | Custom |
Monitor your usage in the Developer Portal.
Quick Reference
gRPC Endpoints
| Network | Endpoint | Port | TLS | Authentication |
|---|---|---|---|---|
| Devnet | grpc-devnet.fortiblox.com | 5691 | Yes | x-api-key metadata |
| Mainnet | grpc.fortiblox.com:10002 | 10002 | Yes | x-api-key metadata |
gRPC Methods
| Method | Description | Parameters |
|---|---|---|
SubscribeTransactions | Stream transaction updates | account_include, filter_votes, commitment |
SubscribeBlocks | Stream block updates | commitment, start_slot, end_slot |
SubscribeSlots | Stream slot updates | None |
Ping | Health check | count |
Connection Examples
JavaScript (Node.js)
const client = new geyserProto.Geyser(
'grpc.fortiblox.com:10002',
grpc.credentials.createSsl()
);Python
credentials = grpc.ssl_channel_credentials()
channel = grpc.insecure_channel('grpc.fortiblox.com:10002', credentials)
stub = geyser_pb2_grpc.GeyserStub(channel)WebSocket (Browser)
const ws = new WebSocket('wss://nexus.fortiblox.com/ws');Next Steps
Now that you've tested the API:
- Build Your Application - Use the code examples to integrate FortiBlox
- Explore Enhanced APIs - Try Enhanced APIs for parsed data
- Set Up Webhooks - Get real-time notifications for blockchain events
- Read gRPC Documentation - See gRPC Streaming Guide for advanced usage
- Read RPC Documentation - Explore complete method reference
Troubleshooting
Playground Issues
CORS or network errors
- This is a browser security restriction, not an API issue
- Use the "Copy cURL" button and test in your terminal instead
- Try Postman, Insomnia, or other API testing tools
- For production, always make API calls from your backend server
- CORS errors cannot be fixed in the browser playground
API key not saving
- Check browser localStorage is enabled
- Try incognito mode to test without extensions
Requests failing
- Verify API key is valid in developer portal
- Check network endpoint is correct
- Review error messages for specific guidance
- Check request timing - some methods require confirmed blocks
Slow responses
- Try testnet instead of mainnet
- Check your network connection
- Verify method parameters are correct
- Some methods (like getBlock) can be slower for recent blocks
gRPC-Specific Issues
gRPC not working in browser
- gRPC requires HTTP/2 which browsers don't support directly
- Use the WebSocket fallback:
wss://nexus.fortiblox.com/ws - Or use gRPC-Web proxy for browser compatibility
- Server-side gRPC (Node.js, Python) works without issues
Authentication errors
- Ensure API key is added to metadata:
metadata.add('x-api-key', key) - Verify API key is valid in developer portal
- Check Professional tier required for mainnet gRPC
Connection timeouts
- Verify TLS/SSL is enabled in client configuration
- Check firewall allows port 5691
- Test with Ping method to verify connectivity
- Ensure using correct endpoint (devnet vs mainnet)
Stream disconnections
- Implement auto-reconnect with exponential backoff (see examples)
- Monitor network stability
- Use proper error handling on stream events
- Check rate limits haven't been exceeded
Proto file issues
- Download latest proto from GitHub
- Regenerate client code after proto updates
- Verify proto compiler version compatibility
Getting Help
- Documentation - Search our comprehensive docs
- Discord Community - Join our developer community
- Support Portal - Submit a ticket for technical support
- GitHub - Report bugs and request features
- gRPC Examples - Check GitHub examples
Feedback Welcome
Found a bug or have a feature request for the playground? Let us know in our Discord community or GitHub repository.