Frequently Asked Questions
General Questions
What is Link Quote?
Link Quote is a digital asset pricing and rate aggregation microservice for the LedgerLink platform. It provides real-time market rates for cryptocurrencies and other digital assets by aggregating data from multiple trusted providers.
Technology Stack:
- NestJS backend with TypeScript
- PostgreSQL database with TypeORM
- CoinMarketCap and Pyth Network integrations
- ActiveMQ for real-time event streaming
- RESTful API with Swagger documentation
What providers does Link Quote support?
Currently, Link Quote integrates with:
- CoinMarketCap: Professional cryptocurrency market data with extensive coverage
- Pyth Network (Hermes): Decentralized oracle network with sub-second updates
Provider selection is configurable per asset or category, with automatic failover support.
How accurate are the rates?
Link Quote aggregates rates from multiple providers to ensure accuracy:
- Fetches from 2+ providers simultaneously
- Calculates weighted average from valid responses
- Filters outliers and invalid data
- Typical accuracy within 0.1% of market rates
- Sub-second latency for price updates
How often are rates updated?
- Real-time requests: Fetched on-demand when you call
POST /rates - Provider latency: CoinMarketCap (10-60s), Pyth (<1s)
- Historical storage: Each rate is timestamped and stored in PostgreSQL
- Event publishing: Real-time valuation events via ActiveMQ
Which digital assets are supported?
Link Quote supports any digital asset you configure:
Pre-configured assets include:
- Major cryptocurrencies: BTC, ETH, SOL, AVAX
- Stablecoins: USDC, USDT, DAI, PYUSD
- ERC-20 tokens
- Custom tokens via Asset Management API
You can add new assets using POST /assets endpoint.
Technical Questions
How does provider selection work?
Link Quote uses a priority-based provider selection:
-
Asset-Level Providers (highest priority)
- Check if asset has specific providers configured
- Use those if available
-
Category-Level Providers (fallback)
- If no asset providers, use category's providers
- All assets in category inherit these providers
-
All Available Providers (default)
- If no asset or category providers configured
- Query all active providers
Example:
BTC asset → has CoinMarketCap configured → only queries CoinMarketCap
ETH asset → no providers → uses category providers → queries Pyth + CoinMarketCap
What happens if a provider fails?
Link Quote has built-in redundancy:
- Multiple Providers: Queries 2+ providers in parallel
- Graceful Degradation: If one fails, uses others
- Error Handling: Returns 503 only if ALL providers fail
- Retry Logic: Implements exponential backoff for transient errors
- Event Logging: Publishes ERROR events to ActiveMQ for monitoring
Best Practice: Configure multiple providers per asset/category for maximum uptime.
Can I add custom price providers?
Yes! Use the Provider Management API:
POST /providers
{
"name": "MyCustomProvider",
"description": "Custom price feed",
"isActive": true
}
However, you'll need to extend the Link Quote service code to implement the actual provider integration. Built-in providers (CoinMarketCap, Pyth) are ready to use out-of-the-box.
How do I configure providers for an asset?
Map providers to assets or categories:
Asset-specific provider:
POST /asset-providers
{
"assetId": "550e8400-e29b-41d4-a716-446655440000",
"providerId": "123e4567-e89b-12d3-a456-426614174000"
}
Category-wide provider:
POST /category-providers
{
"categoryId": "789e4567-e89b-12d3-a456-426614174000",
"providerId": "123e4567-e89b-12d3-a456-426614174000"
}
Does Link Quote cache rates?
Server-side:
- No automatic caching
- Each request fetches fresh data from providers
- Historical rates stored in PostgreSQL for later retrieval
Client-side (recommended):
- Implement your own caching strategy
- Cache rates for 30-60 seconds
- Reduces API calls and improves performance
See Error Handling - Caching for implementation examples.
Can I get historical rate data?
Yes! Use the GET /rates endpoint:
GET /rates?name=bitcoin&fromTime=2025-11-01T00:00:00Z&toTime=2025-11-20T23:59:59Z&limit=100
Returns all stored rates for the asset within the date range, including:
- Rate value
- Timestamp
- Currency
- Provider details (in metadata)
What's the difference between POST /rates and GET /rates?
- POST /rates: Creates a NEW rate by fetching from providers (on-demand pricing)
- GET /rates: Retrieves HISTORICAL rates from database (stored data)
Use POST for real-time pricing, GET for historical analysis.
How do I filter rates by asset?
Use the name parameter (asset name, case-insensitive):
GET /rates?name=bitcoin
GET /rates?name=ethereum
You can also combine with date filters, sorting, and pagination:
GET /rates?name=usdc&fromTime=2025-11-20T00:00:00Z&sortBy=timestamp&sortOrder=desc&limit=50
What currency formats are supported?
Currently, Link Quote primarily supports:
- USD (default)
- Other fiat currencies supported by providers
The currency parameter in POST /rates specifies the target currency.
Integration Questions
How do I integrate with the LedgerLink Dashboard?
The Dashboard proxies requests through the Auth Server (BFF):
// From dashboard (Next.js API route)
const response = await fetch('/api/link-quote/v1/rates', {
method: 'POST',
body: JSON.stringify({ assetCode: 'BTC' }),
credentials: 'include', // Includes session cookies
});
The Auth Server forwards to Link Quote with proper authentication.
Can I subscribe to real-time rate updates?
Yes, via ActiveMQ event streaming:
- Connect to ActiveMQ with STOMP protocol
- Subscribe to
/queue/valuation-events - Filter events by asset ID or event type
- Receive real-time valuation events
Events include:
VALUATION_REQUESTED: Rate request receivedVALUATION_PROCESSED: Rate successfully calculatedERROR: Valuation failed
What permissions do I need?
For Dashboard Users:
- ✅ Authentication Required: Must be logged into Link Dashboard
- ❌ No RBAC: Role-based access control is not currently implemented
Current Access Pattern:
- If logged in → Full access to all operations (GET, POST, PUT, DELETE, PATCH)
- If not logged in → 401 error from Auth Server
For Direct Service Access (Internal Services):
- No authentication required at Link Quote service level
- Network-level security should be implemented
- Service-to-service calls within secure VPC/network
How do I test my integration?
-
Local Development:
# Run Link Quote locally
yarn dev:server:start
# Access Swagger docs at http://localhost:3000/api -
Sandbox Environment:
# Use sandbox URL
https://sandbox-api.ledgerlink.ai/v1 -
Mock Data: Create test assets and categories to experiment without affecting production
Can I batch fetch multiple rates?
Make parallel requests for multiple assets:
const assetCodes = ['BTC', 'ETH', 'SOL', 'USDC'];
const rates = await Promise.all(
assetCodes.map(code =>
fetch('/api/link-quote/v1/rates', {
method: 'POST',
body: JSON.stringify({ assetCode: code }),
}).then(r => r.json())
)
);
Troubleshooting
Why am I getting 503 errors?
Possible causes:
-
No providers configured for asset/category
- Solution: Configure providers via
/asset-providersor/category-providers
- Solution: Configure providers via
-
All providers failed (network, API limits, invalid keys)
- Solution: Check provider API keys, monitor provider status, implement retry logic
-
Provider API rate limits exceeded
- Solution: Implement caching, upgrade provider plan, add more providers
Why are my rates different from exchange prices?
Small discrepancies are normal:
- Aggregation: Average of multiple providers
- Timing: Slight delay from providers
- Exchange variance: Different exchanges have different prices
- Network latency: 1-2 second delay possible
Typical variance: ±0.1% from spot price
How do I debug provider issues?
Enable debug logging in local development:
# server/.env
LOG_LEVEL=debug
Check logs for:
- Provider API requests/responses
- Error messages from providers
- Rate calculation details
- Failed provider attempts
Can I use Link Quote without CoinMarketCap API key?
Yes, but with limitations:
- CoinMarketCap provider won't work
- Pyth Network will still function
- Reduced redundancy (only 1 provider)
- Higher risk of 503 errors
Recommendation: Get a CoinMarketCap API key for production use.
Performance
What are the typical response times?
-
POST /rates: 200-500ms (depends on providers)
- CoinMarketCap: 100-300ms
- Pyth Network: 50-150ms
- Parallel fetching minimizes total time
-
GET /rates: 10-50ms (database query)
-
Asset/Category CRUD: 5-20ms
What are the rate limits?
Link Dashboard (Auth Server): Rate limiting is implemented at the Dashboard/Auth Server level to protect the entire platform.
Link Quote Service: No rate limiting at the service level (relies on Dashboard protection).
External Provider Limits:
- CoinMarketCap: 333 calls/day (free tier), higher with paid plans
- Pyth Network: No rate limits (decentralized)
Best Practices:
- Dashboard rate limiting protects against excessive requests
- Implement client-side caching (30-60s minimum) to reduce load
- Use
GET /ratesfor historical data instead of re-fetching - Batch requests when possible
- Monitor provider API usage to avoid hitting CoinMarketCap limits
- Consider upgrading CoinMarketCap plan for high-volume use
How scalable is Link Quote?
- Database: PostgreSQL with indexing on common query fields
- Horizontal scaling: Stateless service, can run multiple instances
- Provider failover: Multiple providers for redundancy
- Caching strategy: Implement Redis for production high-volume use
Still have questions? Contact helpdesk@ledgerlink.ai or create an issue in the GitHub repository.