API V1 to V2 Migration Guide
Overview
This guide helps you migrate from our V1 API endpoints to the new V2 API. The V2 API provides enhanced data privacy compliance, improved performance, and consistent data formatting while maintaining similar functionality.
Migration Options
We provide two migration paths to help you transition from V1 to V2:
🚀 Option 1: SDK Migration (Recommended)
Easiest and fastest migration path - Use our official SDKs for a drop-in replacement experience.
⚙️ Option 2: Raw API Migration
Manual migration - Directly update your API calls to use V2 endpoints.
🚀 SDK Migration (Recommended)
Why Choose the SDK?
Benefit | SDK | Raw API |
---|---|---|
Migration Effort | ✅ Minimal - Drop-in replacement | ❌ Manual endpoint updates required |
V1 Compatibility | ✅ V1 compatibility layer included | ❌ Breaking changes |
Raw Tweet Content | ✅ Optional access with Twitter API key | ❌ Not available |
Type Safety | ✅ Full TypeScript support | ❌ Manual type definitions |
Error Handling | ✅ Smart error handling & retries | ❌ Manual error handling |
Rate Limiting | ✅ Built-in rate limit management | ❌ Manual rate limit handling |
TypeScript/JavaScript SDK
Installation
npm install @elfa-ai/sdk
Quick Migration Example
// Before (V1 Raw API)
const response = await fetch('/v1/trending-tokens?timeWindow=24h&page=1&pageSize=50');
const data = await response.json();
// After (SDK - Drop-in replacement)
import { ElfaSDK } from '@elfa-ai/sdk';
const elfa = new ElfaSDK({
elfaApiKey: 'your-elfa-api-key',
twitterApiKey: 'optional-twitter-bearer-token' // For raw tweet content
});
const data = await elfa.getTrendingTokens({
timeWindow: '24h',
pageSize: 50
});
V1 Compatibility Layer
For the smoothest migration, use our V1 compatibility layer:
import { V1CompatibilityLayer } from '@elfa-ai/sdk/compatibility';
// Drop-in replacement for your existing V1 code
const client = new V1CompatibilityLayer({
elfaApiKey: 'your-elfa-api-key',
enableV1Behavior: true
});
// Your existing V1 method calls work unchanged
const trending = await client.getTrendingTokens({ timeWindow: '24h' });
const mentions = await client.searchMentions({ keywords: 'bitcoin' });
Complete V1 SDK Method Mapping
All V1 endpoints are fully supported through the V1 compatibility layer:
V1 Endpoint | SDK Method | V2 Mapping | Status |
---|---|---|---|
/v1/ping | ping() | /v2/ping | ✅ Ready |
/v1/key-status | getKeyStatus() | /v2/key-status | ✅ Ready |
/v1/mentions | getMentionsWithSmartEngagement() | /v1/mentions | ⚠️ Legacy (will be deprecated) |
/v1/top-mentions | getTopMentions() | /v2/data/top-mentions | ✅ Ready |
/v1/mentions/search | getMentionsByKeywords() | /v2/data/keyword-mentions | ✅ Ready |
/v1/trending-tokens | getTrendingTokens() | /v2/aggregations/trending-tokens | ✅ Ready |
/v1/account/smart-stats | getAccountSmartStats() | /v2/account/smart-stats | ✅ Ready |
Key SDK Usage Examples
Get Trending Tokens
const trending = await client.getTrendingTokens({
timeWindow: '24h',
pageSize: 50,
minMentions: 5
});
Search Keyword Mentions
const mentions = await client.getMentionsByKeywords({
keywords: 'bitcoin,ethereum',
from: 1640995200,
to: 1641081600,
fetchRawTweets: true // Requires Twitter API key
});
Get Top Mentions
const topMentions = await client.getTopMentions({
ticker: 'bitcoin',
timeWindow: '1h',
pageSize: 10
});
Get Account Smart Stats
const stats = await client.getAccountSmartStats({
username: 'elonmusk'
});
Python SDK (Coming Soon)
We're actively developing a Python SDK with the same ease-of-use and compatibility features:
# Coming soon
from elfa_sdk import ElfaSDK
elfa = ElfaSDK(
elfa_api_key="your-elfa-api-key",
twitter_api_key="optional-twitter-bearer-token"
)
trending = await elfa.get_trending_tokens(time_window="24h", page_size=50)
⚙️ Raw API Migration
If you prefer to migrate manually or need direct API control, follow this detailed guide:
Base URL Changes
- V1:
/v1/...
- V2:
/v2/...
Key Differences
1. Data Privacy & Compliance
- V2 removes raw tweet content to comply with platform ToS
- Returns sanitized metadata (engagement metrics, timestamps, account info)
- No direct tweet text or content exposure
2. Response Format
- V1: Varied response structures
- V2: Consistent
{ success: boolean, data: any, metadata?: any }
format
3. Pagination Patterns
- Search endpoints: Use
limit + cursor
for efficient pagination - Aggregation endpoints: Use
page + pageSize
for bounded result sets
Endpoint Migration Map
V1 Endpoint | V2 Equivalent | Status | Changes |
---|---|---|---|
GET /v1/trending-tokens | GET /v2/aggregations/trending-tokens | ✅ Direct migration | Same parameters, enhanced response |
GET /v1/mentions/search | GET /v2/data/keyword-mentions | ⚠️ Breaking changes | New parameters, sanitized data |
GET /v1/token-mentions | GET /v2/data/token-news | ⚠️ Breaking changes | Different pagination, sanitized data |
GET /v1/account/smart-stats | GET /v2/account/smart-stats | ✅ Direct migration | Same functionality |
GET /v1/top-mentions | GET /v2/data/top-mentions | ✅ Direct migration | Same functionality, sanitized data |
GET /v1/mentions | ❌ No V2 equivalent | Deprecated | Use keyword-mentions instead |
Detailed Migration Instructions
1. Trending Tokens
✅ EASY MIGRATION - Same parameters
V1 Request:
GET /v1/trending-tokens?timeWindow=24h&page=1&pageSize=50&minMentions=5
V2 Request:
GET /v2/aggregations/trending-tokens?timeWindow=24h&page=1&pageSize=50&minMentions=5
Changes:
- ✅ Same parameters:
timeWindow
,page
,pageSize
,minMentions
- ✅ Same functionality: Returns trending tokens by mention count
- 🔄 Enhanced response: Consistent V2 format with metadata
2. Keyword/Mentions Search
⚠️ BREAKING CHANGES - Updated parameters and data format
V1 Request:
GET /v1/mentions/search?keywords=bitcoin,ethereum&from=1640995200&to=1641081600&limit=20&searchType=or&cursor=abc123
V2 Request:
GET /v2/data/keyword-mentions?keywords=bitcoin,ethereum&from=1640995200&to=1641081600&limit=20&searchType=or&cursor=abc123
Key Changes:
- ✅ Same parameters:
keywords
,from
,to
,limit
,searchType
,cursor
- ❌ Removed: Raw tweet content/text
- ✅ Added:
accountName
parameter for filtering by specific accounts - 🔄 Sanitized data: Only metadata (engagement metrics, timestamps, account info)
New Features:
- Account filtering: Add
accountName=elonmusk
to filter mentions by specific accounts - Either/or search: Provide either
keywords
ORaccountName
(or both)
3. Token News/Mentions
⚠️ BREAKING CHANGES - New pagination pattern
V1 Request:
GET /v1/token-mentions?from=1640995200&to=1641081600&page=1&coinIds=bitcoin,ethereum&isNews=true
V2 Request:
GET /v2/data/token-news?from=1640995200&to=1641081600&page=1&pageSize=20&coinIds=bitcoin,ethereum
Key Changes:
- ✅ Same core params:
from
,to
,coinIds
- 🔄 Pagination change: Added explicit
pageSize
parameter (default: 20) - ❌ Removed:
isNews
parameter (V2 only returns news mentions) - ❌ Removed: Raw tweet content
- 🔄 Different response: Sanitized news mention data only
4. Top Mentions by Ticker
✅ AVAILABLE IN V2 - New endpoint with same functionality
V1 Request:
GET /v1/top-mentions?ticker=bitcoin&timeWindow=1h&page=1&pageSize=10&includeAccountDetails=false
V2 Request:
GET /v2/data/top-mentions?ticker=bitcoin&timeWindow=1h&page=1&pageSize=10
Key Changes:
- ✅ Same core parameters:
ticker
,timeWindow
,page
,pageSize
- ❌ Removed:
includeAccountDetails
parameter (account info always included) - ❌ Removed: Raw tweet content
- ✅ Same ranking: Still sorts by view_count → mentioned_at → relevance
- 🔄 Sanitized data: Only metadata (engagement metrics, timestamps, account info)
Features Preserved:
- Smart ticker matching:
$TICKER
for exact cashtag matches,TICKER
for broader search - Engagement-based ranking: High-performing tweets ranked first
- Time window filtering: Support for 1h, 24h, 7d, etc.
- Account information: Username, verification status, account tags
5. Account Smart Stats
✅ DIRECT MIGRATION - No changes needed
V1 & V2 Request (identical):
GET /v1/account/smart-stats?username=elonmusk
GET /v2/account/smart-stats?username=elonmusk
Changes:
- ✅ No parameter changes
- ✅ Same functionality
- 🔄 Consistent V2 response format
6. Contract Addresses (NEW in V2)
🆕 V2 EXCLUSIVE FEATURES
# Twitter contract addresses
GET /v2/aggregations/trending-cas/twitter?timeWindow=24h&page=1&pageSize=50&minMentions=5
# Telegram contract addresses
GET /v2/aggregations/trending-cas/telegram?timeWindow=24h&page=1&pageSize=50&minMentions=5
Response Format Changes
V1 Response Example:
{
"success": true,
"data": [
{
"id": "123",
"content": "Just bought some $BTC! 🚀", // ❌ Raw content removed in V2
"mentioned_at": "2024-01-01T00:00:00Z",
"account_name": "cryptotrader",
"like_count": 42
}
],
"metadata": { "total": 100 }
}
V2 Response Example:
{
"success": true,
"data": [
{
"source_ref_id": "123",
"mentioned_at": "2024-01-01T00:00:00Z",
"account_name": "cryptotrader",
"like_count": 42,
"repost_count": 5,
"view_count": 1000,
// ❌ No raw content/text
"account_tags": ["smart"]
}
],
"metadata": {
"total": 100,
"page": 1,
"pageSize": 20
}
}
Pagination Pattern Guide
Understanding V2 Pagination Patterns
Pattern 1: Search Endpoints → limit + cursor
- Use for:
keyword-mentions
- Best for: Large result sets, real-time data
- Parameters:
limit=20&cursor=abc123
Pattern 2: Aggregation Endpoints → page + pageSize
- Use for:
trending-tokens
,trending-cas
,token-news
- Best for: Bounded analytics data
- Parameters:
page=1&pageSize=50
Cursor vs Page Pagination
When to use Cursor (limit + cursor):
# Good for: Large datasets, real-time feeds
GET /v2/data/keyword-mentions?keywords=bitcoin&limit=20&cursor=eyJ0aW1lc3RhbXAiOjE2NDA5OTUyMDB9
# Next page:
GET /v2/data/keyword-mentions?keywords=bitcoin&limit=20&cursor=<cursor_from_previous_response>
When to use Page (page + pageSize):
# Good for: Small bounded datasets, analytics
GET /v2/aggregations/trending-tokens?timeWindow=24h&page=1&pageSize=50
# Next page:
GET /v2/aggregations/trending-tokens?timeWindow=24h&page=2&pageSize=50
Migration Checklist
Before Migration:
- Review your current V1 usage patterns
- Identify which endpoints you're using
- Update API base URLs from
/v1/
to/v2/
- Review new response formats (no raw content)
During Migration:
For trending-tokens:
- Change URL path to
/v2/aggregations/trending-tokens
- Update response parsing (new format)
For keyword search:
- Change URL path to
/v2/data/keyword-mentions
- Update response parsing (no raw content)
- Consider using new
accountName
parameter
For token mentions/news:
- Change URL path to
/v2/data/token-news
- Add explicit
pageSize
parameter - Remove
isNews
parameter (always news in V2) - Update response parsing (sanitized data)
For top mentions:
- Change URL path to
/v2/data/top-mentions
- Remove
includeAccountDetails
parameter (always included) - Update response parsing (sanitized data)
For account stats:
- Change URL path to
/v2/account/smart-stats
- Update response parsing (new format)
After Migration:
- Test all endpoints with your integration
- Verify pagination works correctly
- Update error handling for new response format
- Monitor API performance and adjust pagination sizes
Code Examples
JavaScript/TypeScript Migration
Before (V1):
// V1 trending tokens
const response = await fetch('/v1/trending-tokens?timeWindow=24h&page=1&pageSize=50');
const data = await response.json();
console.log(data.data); // Direct array access
// V1 top mentions with raw content
const topMentions = await fetch('/v1/top-mentions?ticker=bitcoin&timeWindow=1h');
const topData = await topMentions.json();
console.log(topData.data.data[0].content); // Raw tweet content
// V1 keyword search with raw content
const searchResponse = await fetch('/v1/mentions/search?keywords=bitcoin&from=1640995200&to=1641081600');
const searchData = await searchResponse.json();
console.log(searchData.data[0].content); // Raw tweet content
After (V2):
// V2 trending tokens
const response = await fetch('/v2/aggregations/trending-tokens?timeWindow=24h&page=1&pageSize=50');
const data = await response.json();
console.log(data.data); // Same array access
console.log(data.metadata); // Enhanced metadata
// V2 top mentions (sanitized data only)
const topMentions = await fetch('/v2/data/top-mentions?ticker=bitcoin&timeWindow=1h');
const topData = await topMentions.json();
console.log(topData.data[0].source_ref_id); // Reference ID instead of content
console.log(topData.data[0].view_count); // Engagement metrics preserved
// topData.data[0].content is undefined (removed for compliance)
// V2 keyword search (sanitized data only)
const searchResponse = await fetch('/v2/data/keyword-mentions?keywords=bitcoin&from=1640995200&to=1641081600');
const searchData = await searchResponse.json();
console.log(searchData.data[0].source_ref_id); // Reference ID instead of content
console.log(searchData.data[0].like_count); // Engagement metrics available
// searchData.data[0].content is undefined (removed for compliance)
API Limits & Defaults
Parameter | V1 Default | V2 Default | Max Value |
---|---|---|---|
pageSize | 20-50 | 20 (data), 50 (aggregations) | 100 |
limit | 20 | 20 | 30 |
page | 1 | 1 | No limit |
timeWindow | "24h" | "24h" | - |
Troubleshooting
Common Migration Issues:
1. "Raw content is undefined"
- Cause: V2 removes raw tweet content for compliance
- Solution: Use engagement metrics and metadata instead of content
2. "Pagination not working"
- Cause: Mixed pagination patterns
- Solution: Use
limit+cursor
for search,page+pageSize
for aggregations
3. "Different response structure"
- Cause: V2 uses consistent
{success, data, metadata}
format - Solution: Update response parsing to use
response.data
instead of direct access
4. "Missing endpoints"
- Cause: Some V1 endpoints deprecated in V2
- Solution: Use
keyword-mentions
as replacement for deprecated search endpoints
Support
For migration support or questions:
- Review the V2 API documentation
- Check response format examples
- Test endpoints in development first
- Contact support if you encounter breaking changes not covered in this guide
Timeline
- V1 API: Remains available during migration period
- V2 API: Available now for migration
- Migration deadline: TBD (will be announced with sufficient notice)
- V1 deprecation: TBD (only after successful V2 adoption)