Overview
The Alpha SDK supports two methods for discovering markets:
- API-based - Uses the Alpha REST API (requires API key)
- On-chain - Reads directly from the Algorand blockchain (no API key needed)
The smart default method getLiveMarkets() automatically chooses based on whether an API key is configured.
Comparison Table
API Method
On-Chain Method
Alpha REST API
Methods:
getLiveMarketsFromApi()
getMarketFromApi(marketId)
getRewardMarkets()
Pros:
- ✅ Rich metadata (images, categories, volume)
- ✅ Market probabilities (
yesProb, noProb)
- ✅ Faster than on-chain discovery
- ✅ Paginated results
- ✅ Market slugs for URLs
- ✅ Featured market flags
- ✅ Liquidity reward data
Cons:
- ❌ Requires API key
- ❌ Centralized dependency
- ❌ Rate limited
Best for:
- Consumer-facing applications
- Rich UI/UX experiences
- Market browsing interfaces
- Analytics dashboards
Direct Blockchain
Methods:
getMarketsOnChain()
getMarketOnChain(marketAppId)
Pros:
- ✅ No API key required
- ✅ Fully decentralized
- ✅ Direct source of truth
- ✅ No rate limits
- ✅ Works if API is down
Cons:
- ❌ No images or categories
- ❌ No volume data
- ❌ No probabilities
- ❌ Slower (multiple indexer calls)
- ❌ Requires pagination handling
Best for:
- Decentralized applications
- Trading bots
- Arbitrage tools
- Backend services
- API fallback scenarios
Data Field Comparison
Available in Both Methods
These core fields are available from both API and on-chain sources:
Market identifier (UUID from API, app ID string from on-chain)
Algorand application ID of the market contract
Resolution timestamp in seconds (Unix epoch)
Whether the market has been resolved
Whether the market is currently tradeable
Base fee percentage in microunits (e.g. 70000 = 7%)
API Only
These fields are only available when using API-based methods:
Current YES probability (0-1)
Current NO probability (0-1)
Total trading volume in microunits
Market categories (e.g. ['Politics', 'USA'])
Whether the market is featured
Liquidity reward pool (microunits)
Rewards already distributed (microunits)
Max spread to qualify for rewards (microunits)
Min order size for rewards (microunits)
Most recent reward payout (microunits)
Timestamp of last reward payout
Code Examples
Using API (with API key)
import { AlphaClient } from '@alpha-arcade/sdk';
import algosdk from 'algosdk';
const client = new AlphaClient({
algodClient: new algosdk.Algodv2('', 'https://mainnet-api.algonode.cloud', 443),
indexerClient: new algosdk.Indexer('', 'https://mainnet-idx.algonode.cloud', 443),
signer: algosdk.makeBasicAccountTransactionSigner(account),
activeAddress: account.addr.toString(),
matcherAppId: 741347297,
usdcAssetId: 31566704,
apiKey: process.env.ALPHA_API_KEY, // ✅ API key provided
});
// Automatically uses API
const markets = await client.getLiveMarkets();
// Rich metadata available
markets.forEach(m => {
console.log(`${m.title}`);
console.log(` Image: ${m.image}`);
console.log(` Categories: ${m.categories?.join(', ')}`);
console.log(` Volume: $${m.volume! / 1e6}`);
console.log(` YES: ${m.yesProb}%, NO: ${m.noProb}%`);
});
Using On-Chain (no API key)
import { AlphaClient } from '@alpha-arcade/sdk';
import algosdk from 'algosdk';
const client = new AlphaClient({
algodClient: new algosdk.Algodv2('', 'https://mainnet-api.algonode.cloud', 443),
indexerClient: new algosdk.Indexer('', 'https://mainnet-idx.algonode.cloud', 443),
signer: algosdk.makeBasicAccountTransactionSigner(account),
activeAddress: account.addr.toString(),
matcherAppId: 741347297,
usdcAssetId: 31566704,
// ❌ No apiKey - falls back to on-chain
});
// Automatically uses on-chain discovery
const markets = await client.getLiveMarkets();
// Only core data available
markets.forEach(m => {
console.log(`${m.title}`);
console.log(` App ID: ${m.marketAppId}`);
console.log(` YES ASA: ${m.yesAssetId}`);
console.log(` NO ASA: ${m.noAssetId}`);
console.log(` Ends: ${new Date(m.endTs * 1000).toISOString()}`);
// ❌ m.image, m.volume, m.yesProb are undefined
});
Explicit Method Selection
You can explicitly choose the method regardless of API key configuration:
// Force API (throws if no API key)
const apiMarkets = await client.getLiveMarketsFromApi();
// Force on-chain (works even with API key)
const onChainMarkets = await client.getMarketsOnChain();
// Smart default (recommended)
const markets = await client.getLiveMarkets();
Market Identification
API-based ID
When using the API, markets are identified by UUID:
const market = await client.getMarketFromApi('abc123-def456-ghi789');
console.log(market?.id); // 'abc123-def456-ghi789'
console.log(market?.marketAppId); // 1234567890
On-chain ID
When reading from blockchain, markets are identified by app ID:
const market = await client.getMarketOnChain(1234567890);
console.log(market?.id); // '1234567890'
console.log(market?.marketAppId); // 1234567890
Smart Default Behavior
The getMarket() method adapts based on configuration:
// With API key: expects UUID
const market1 = await client.getMarket('abc123-def456-ghi789');
// Without API key: expects app ID string
const market2 = await client.getMarket('1234567890');
API Method
Speed: ~500-1000ms for 100 markets (single paginated request)
console.time('API fetch');
const markets = await client.getLiveMarketsFromApi();
console.timeEnd('API fetch');
// API fetch: 750ms
Optimization:
- Results are cached server-side
- Pagination is automatic
- Single HTTP request per page
On-Chain Method
Speed: ~3-10 seconds for 100 markets (multiple indexer queries)
console.time('On-chain fetch');
const markets = await client.getMarketsOnChain();
console.timeEnd('On-chain fetch');
// On-chain fetch: 5200ms
Optimization:
- Uses indexer pagination (100 apps/page)
- Decodes global state for each app
- Groups multi-choice options
Recommendation: For UI/UX, use API when possible. For decentralization, on-chain is acceptable for backend/batch operations.
When to Use Each Method
Use API Method When:
✅ Building consumer-facing UI
✅ Need images and categories
✅ Displaying market probabilities
✅ Showing trading volume
✅ Fetching liquidity reward markets
✅ Performance is critical
Example: Market browsing page with filters
const markets = await client.getLiveMarketsFromApi();
// Filter by category
const politicsMarkets = markets.filter(m =>
m.categories?.includes('Politics')
);
// Sort by volume
const topVolume = markets.sort((a, b) =>
(b.volume || 0) - (a.volume || 0)
);
Use On-Chain Method When:
✅ Building fully decentralized dApp
✅ No API key available
✅ API is down (fallback)
✅ Need trustless verification
✅ Building trading bot (core data only)
✅ Backend batch processing
Example: Automated trading bot
// No API dependency - fully on-chain
const markets = await client.getMarketsOnChain();
// Trade based on app ID and token ASAs
for (const market of markets) {
const orderbook = await client.getOrderbook(market.marketAppId);
// Execute strategy using core on-chain data
// (no need for images, categories, etc.)
}
Hybrid Approach
Combine both methods for resilience:
const fetchMarketsWithFallback = async () => {
try {
// Try API first (faster + richer data)
console.log('Fetching from API...');
return await client.getLiveMarketsFromApi();
} catch (error) {
// Fall back to on-chain if API fails
console.warn('API failed, falling back to on-chain:', error.message);
return await client.getMarketsOnChain();
}
};
const markets = await fetchMarketsWithFallback();
console.log(`Fetched ${markets.length} markets (source: ${markets[0]?.source})`);
Getting an API Key
- Visit Alpha Arcade Account page
- Generate an API key
- Add to your environment:
ALPHA_API_KEY=your_api_key_here
- Configure the client:
const client = new AlphaClient({
// ... other config
apiKey: process.env.ALPHA_API_KEY,
});