The SDKs return Elfa's processed data — metadata, engagement metrics, and tweet links. They do not return tweet text. Fetch the linked post through the X API with your own credentials if you need it.
SDKs
The TypeScript and Python clients cover the same surface — social intelligence data, chat (including SSE streaming), the Auto condition engine, and API v3 — with typed responses and retries handled for you. If your agent has a shell, the Agent Skill is the lighter surface; if your client cannot run commands, use the MCP Server.
| SDK | Package | Source |
|---|---|---|
| TypeScript / JavaScript | @elfa-ai/sdk | elfa-ai/elfa-sdk-js |
| Python | elfa-sdk | elfa-ai/elfa-sdk-python |
Install
Node 22 or newer, or Python 3.9 or newer. Get a key from dev.elfa.ai.
@elfa-ai/sdk requires Node 22 from v6 onward — Node 18 and 20 have both reached
end of life. On an older runtime, pin @elfa-ai/sdk@5, which talks to the same API.
npm install @elfa-ai/sdk
First Request
import { ElfaSDK } from "@elfa-ai/sdk";
const elfa = new ElfaSDK({ elfaApiKey: process.env.ELFA_API_KEY! });
const trending = await elfa.getTrendingTokens({ timeWindow: "24h" });
const mentions = await elfa.getKeywordMentions({
keywords: "bitcoin,ethereum",
timeWindow: "1h",
});
Python also ships AsyncElfaClient — the same surface with await, usable as an async context manager.
Methods
| JavaScript | Python | Endpoint |
|---|---|---|
ping() | ping() | /v2/ping |
getApiKeyStatus() | get_api_key_status() | /v2/key-status |
getTrendingTokens() | get_trending_tokens() | /v2/aggregations/trending-tokens |
getTrendingCAsTwitter() | get_trending_cas_twitter() | /v2/aggregations/trending-cas/twitter |
getTrendingCAsTelegram() | get_trending_cas_telegram() | /v2/aggregations/trending-cas/telegram |
getAccountSmartStats() | get_account_smart_stats() | /v2/account/smart-stats |
getKeywordMentions() | get_keyword_mentions() | /v2/data/keyword-mentions |
getTopMentions() | get_top_mentions() | /v2/data/top-mentions |
getTokenNews() | get_token_news() | /v2/data/token-news |
getEventSummary() | get_event_summary() | /v2/data/event-summary |
getTrendingNarratives() | get_trending_narratives() | /v2/data/trending-narratives |
chat() | chat() | /v2/chat |
chatStream() | chat_stream() | /v2/chat/stream |
Chat and chat streaming take includeSources (include_sources in Python) to return the links the research read.
Time-ranged endpoints take either a time window (timeWindow / time_window, for example "24h") or an explicit range (from and to, from_time and to_time, in unix seconds). See the REST Reference for parameters and response schemas.
API v3
elfa.v3 and client.v3 cover API v3: one method per endpoint, with typed parameters and responses. No v3 endpoint returns post text. Python ships both V3Client and AsyncV3Client.
// Check the name: the first match may not be the asset you meant.
const { entities } = await elfa.v3.getEntities({ q: "btc", entityType: ["token"], limit: 1 });
if (entities.length === 0) throw new Error("no exact match");
const id = entities[0].id;
// from is required, in seconds. Milliseconds are a 400.
// An empty events reply is a quiet range, not an error.
const from = Math.floor(Date.now() / 1000) - 86400;
const { events } = await elfa.v3.getEvents({ entityIds: [id], from, limit: 10 });
const positioning = await elfa.v3.getPositioning({ entityId: id });
| JavaScript | Python | Endpoint |
|---|---|---|
getEntities() | get_entities() | /v3/entities |
getEvents() | get_events() | /v3/events |
getStorylines() | get_storylines() | /v3/events/storylines |
getArcs() | get_arcs() | /v3/events/arcs |
getCallBook(market) | get_call_book(market) | /v3/market/{crypto,equity}/call-book |
getMindshare(market) | get_mindshare(market) | /v3/market/{crypto,equity}/mindshare |
getTrendingContracts() | get_trending_contracts() | /v3/market/crypto/trending-contracts |
getCalls() | get_calls() | /v3/calls |
getCallEpisodes() | get_call_episodes() | /v3/calls/episodes |
getPositioning() | get_positioning() | /v3/calls/positioning |
getTopAccounts() | get_top_accounts() | /v3/people/accounts |
getKeyStatus() | get_key_status() | /v3/key-status |
List parameters take arrays and are sent comma-separated, and only the parameters you set are sent. An empty list raises a validation error rather than silently dropping the filter, and the JavaScript client also refuses a parameter the endpoint does not declare. Python names from and to as from_time and to_time. For access, time ranges and paging, see Rules Every Endpoint Follows.
Chat Streaming
The streaming methods take the same arguments as chat and yield one event per data: frame, ending on the terminating [DONE] frame. Streaming Chat requires a PAYG or Enterprise key — see Chat.
for await (const event of elfa.chatStream({ message: "Sentiment on SOL?" })) {
if (event.type === "text") process.stdout.write(event.content);
}
Event types are session_info, title, text, text_complete, status, credits, complete, invalid_request and error.
Auto
elfa.auto and client.auto drive the Auto condition engine — EQL queries that watch markets and fire notifications. Validate first, then create, then stream or poll.
await elfa.auto.validateQuery(query);
const created = await elfa.auto.createQuery(query);
// Create returns `id`.
for await (const event of elfa.auto.streamQuery(created.id!)) {
console.log(event.event, event.data);
}
Also available on both: builder chat, query list/get/cancel/delete, drafts, sessions, executions, symbol validation, and a stream of every query's notifications.
Options
| JavaScript | Python | Default | Purpose |
|---|---|---|---|
elfaApiKey | api_key | — | Required. Sent as x-elfa-api-key. |
baseUrl | base_url | https://api.elfa.ai | API base URL. |
timeout | timeout | 30s | Per-request timeout. |
retries | retries | 3 | Retries for idempotent requests. |
retryDelay | retry_delay | 1s | Base delay for exponential backoff. |
headers | headers | — | Extra headers on every request. |
debug | — | false | Request and response logging. |
Idempotent requests are retried with exponential backoff on network errors, rate limits, and 5xx responses. Mutations are never retried automatically.
Errors
import { ElfaApiError, RateLimitError, AuthenticationError } from "@elfa-ai/sdk";
try {
await elfa.getKeywordMentions({ keywords: "bitcoin" });
} catch (error) {
if (error instanceof AuthenticationError) console.log("Invalid API key");
else if (error instanceof RateLimitError) console.log("Retry at", error.resetTime);
else if (error instanceof ElfaApiError) console.log("API error", error.statusCode);
}
Validation errors (ValidationError / ElfaValidationError) cover rejected parameters, and network errors (NetworkError / ElfaNetworkError) cover connection failures. See Rate Limits for quota behavior.
Next Step
Read Market Intelligence for what each data method returns, or Auto for the condition engine.