Chat
Chat answers market questions in writing: plain language in, a written market read out. Use it when you want meaning rather than metrics.
| Endpoint | Returns |
|---|---|
POST /v2/chat | The complete answer as one JSON response. |
POST /v2/chat/stream | The answer as Server-Sent Events, text arriving incrementally. |
Plan access differs by surface. POST /v2/chat requires Grow and above or PAYG. POST /v2/chat/stream requires PAYG or Enterprise. POST /x402/v2/chat is paid per request.
Analysis Types
analysisType decides what Elfa does. Both endpoints take the same request body, but each mode needs different fields. The default is chat.
| Type | In-app title | Use it for | Needs |
|---|---|---|---|
chat | Free text | Open-ended questions about why something is moving and what may happen next. | message |
macro | Understand Market Conditions | A macro market overview. | No extra field |
summary | Quick Summary | A quick market summary before digging into a token. | No extra field |
tokenIntro | What is $SOL? | What a token is, why it exists, and its narrative. | assetMetadata.symbol, or assetMetadata.chain + assetMetadata.contractAddress |
tokenAnalysis | Suggest Trade Setup for $SOL | A token trade setup: entries, exits, market and onchain context. | Same as tokenIntro |
accountAnalysis | Analyze Account @username | A Twitter/X account: who is posting, whether engagement is real, what they push. | assetMetadata.username |
message is used only for analysisType: "chat". For every other type it is ignored; Elfa uses the mode and assetMetadata.
Worked Requests
{"analysisType":"chat","message":"Why is EUL pumping and will the rally continue?","speed":"expert"}
{"analysisType":"macro","speed":"expert"}
{"analysisType":"summary","speed":"fast"}
{"analysisType":"tokenIntro","assetMetadata":{"symbol":"SOL"}}
{"analysisType":"tokenAnalysis","assetMetadata":{"symbol":"SOL"},"speed":"expert"}
{"analysisType":"accountAnalysis","assetMetadata":{"username":"elfa_ai"}}
POST /v2/chat
Send a message and receive the complete answer as JSON. Suited to agents and integrations that do not support Server-Sent Events.
Sample response (from the spec example; values are placeholders):
{
"success": true,
"data": {
"creditsConsumed": 1,
"sessionId": "string",
"message": "string"
}
}
The request that produced it:
curl -X POST "https://api.elfa.ai/v2/chat" \
-H "x-elfa-api-key: $ELFA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message":"Why is BTC moving today?","analysisType":"chat","speed":"expert"}'
| Field | Type | Meaning |
|---|---|---|
success | boolean | Whether the request succeeded. |
data.message | string | The answer. |
data.sessionId | string | The conversation id. Pass it back to continue the conversation. |
data.creditsConsumed | number | Credits this call consumed. |
data.sources | array | Present only when the request set includeSources: true. See Sources. |
data.sources[].url | string | The link the research read. |
data.sources[].kind | string | What the link points at. See Sources. |
data.sources[].title | string | What the research step did to reach the link, e.g. "Searched X". Optional. |
Request body (JSON; the body is required):
| Parameter | Required | Type | Meaning |
|---|---|---|---|
message | For chat | string | The user message. Required when analysisType is chat; ignored for all other types. |
analysisType | No | string | chat, macro, summary, tokenIntro, tokenAnalysis or accountAnalysis. Default chat. |
sessionId | No | string | Omit to start a new conversation. Pass the sessionId from a previous response to continue it. |
speed | No | string | fast, expert or adaptive. Default expert. |
assetMetadata | For token and account types | object | Required for tokenIntro, tokenAnalysis and accountAnalysis. Fields below. |
assetMetadata.symbol | See meaning | string | Token ticker, e.g. "BTC", "$ETH". Required for tokenIntro and tokenAnalysis when contractAddress is not given. |
assetMetadata.chain | See meaning | string | Blockchain name, e.g. "ethereum", "solana". Use with contractAddress as an alternative to symbol. |
assetMetadata.contractAddress | See meaning | string | Token contract address. Use with chain as an alternative to symbol. |
assetMetadata.username | For accountAnalysis | string | Twitter/X username. |
includeSources | No | boolean | true adds data.sources to the response. Default false. |
The body accepts no other fields, at the top level or in assetMetadata.
Sessions
Omit sessionId to start a new conversation. The response includes a sessionId; send it in later requests to continue the same conversation.
Speed
| Speed | Meaning |
|---|---|
fast | Cheaper and shallower. |
expert | Default. Deeper reasoning. |
adaptive | Lets Elfa choose. Available on /v2/chat, not on /x402/v2/chat. |
Sources
Sources are opt-in. Send includeSources: true to receive data.sources: the links the research behind the answer read, such as X posts, news, DEX and explorer pages, and prediction markets. Without the flag the response is unchanged.
- Links only. Page and post content is not returned.
- A source was read, not necessarily cited in
message. - Listed in the order the research read them, without duplicates, at most 50.
- Empty when the answer used no linkable source.
kind values:
kind | Points at |
|---|---|
x_post | A post on X |
x_account | An X profile |
telegram | A Telegram channel or message |
dex | A DEX pair or token page |
explorer | A block-explorer page (address, token, transaction) |
prediction_market | A Polymarket or Kalshi market |
web | Any other page, such as a news article |
kind is a string, not an enum, so new kinds can ship without breaking generated clients. Treat a value you do not recognise as web.
message Is Ignored Outside chat
A message sent with macro, summary, tokenIntro, tokenAnalysis or accountAnalysis has no effect. To steer a token or account read, set assetMetadata.
Also via x402: POST /x402/v2/chat. Same body, but speed accepts only fast and expert.
POST /v2/chat/stream
Stream the answer as Server-Sent Events. Use it when your client can consume incremental events; use POST /v2/chat when your integration needs a complete JSON response. Access: PAYG and Enterprise API keys.
Sample response: the body is text/event-stream, not one JSON document. The spec fixes only the keep-alive comment and the terminator, so those are the only literal lines shown here; it names the data: event payloads below but does not specify their JSON shapes, and gives no order beyond data: [DONE] ending the stream.
: keep-alive
data: [DONE]
The stream ends with data: [DONE].
The request:
curl -N -X POST "https://api.elfa.ai/v2/chat/stream" \
-H "x-elfa-api-key: $ELFA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message":"Why is BTC moving today?","analysisType":"chat","speed":"expert"}'
Event payloads the stream sends:
| Event | Carries |
|---|---|
session_info | sessionId and analysisType |
title | A generated session or analysis title |
text | Incremental Markdown content |
text_complete | Incremental text has finished |
status | Progress updates |
credits | Consumed credits |
complete | Final sessionId, success and creditsConsumed; plus sources when the request set includeSources: true |
invalid_request | The query was rejected by safety checks |
error | A stream failure |
Fields of the complete event and other event payloads, as the spec states them:
| Field | Type | Meaning |
|---|---|---|
session_info.sessionId | string | The conversation id. Pass it back to continue the conversation. |
session_info.analysisType | string | The analysis type of the request. |
complete.sessionId | string | The final conversation id. |
complete.success | boolean | Whether the request succeeded. |
complete.creditsConsumed | number | Credits this call consumed. |
complete.sources | array | Present only when the request set includeSources: true. Same shape as data.sources on POST /v2/chat. |
Request body (JSON; the body is required). Same schema as POST /v2/chat:
| Parameter | Required | Type | Meaning |
|---|---|---|---|
message | For chat | string | The user message. Required when analysisType is chat; ignored for all other types. |
analysisType | No | string | chat, macro, summary, tokenIntro, tokenAnalysis or accountAnalysis. Default chat. |
sessionId | No | string | Omit to start a new conversation. Pass the sessionId from a previous response to continue it. |
speed | No | string | fast, expert or adaptive. Default expert. |
assetMetadata | For token and account types | object | Required for tokenIntro, tokenAnalysis and accountAnalysis. Fields below. |
assetMetadata.symbol | See meaning | string | Token ticker, e.g. "BTC", "$ETH". Required for tokenIntro and tokenAnalysis when contractAddress is not given. |
assetMetadata.chain | See meaning | string | Blockchain name, e.g. "ethereum", "solana". Use with contractAddress as an alternative to symbol. |
assetMetadata.contractAddress | See meaning | string | Token contract address. Use with chain as an alternative to symbol. |
assetMetadata.username | For accountAnalysis | string | Twitter/X username. |
includeSources | No | boolean | true adds sources to the complete event. Default false. |
The body accepts no other fields, at the top level or in assetMetadata.
Keep-Alive
During long gaps the server may send a comment line, : keep-alive. It carries no data; SSE clients ignore it. Do not treat it as an event.
End of Stream
The stream ends with data: [DONE]. That line is not JSON; check for it before parsing.
Sources in the Stream
With includeSources: true, sources arrive on the complete event as sources, in the same shape as data.sources on POST /v2/chat.
Also via x402: not available. Streaming Chat is API-key only.
Errors
| Status | Endpoint | Meaning |
|---|---|---|
400 | Both | Invalid request. Check the per-type requirements in Analysis Types. |
401 | Both | Missing or invalid API key. |
403 | /v2/chat/stream | PAYG or Enterprise plan required. |
For everything else see v2 Enums and Errors.
Related
- Generated reference:
POST /v2/chat,POST /v2/chat/stream,POST /x402/v2/chat - Raw attention signals instead of conclusions: Mentions, Trending, Narratives, Accounts
- v2 Agent Playbooks