eToro API
Enables agents to interact with the eToro API to access market data, portfolio and social features, and execute trades programmatically.
技能说明
name: etoro-api version: 1.0.0 description: Enables agents to interact with the eToro API to access market data, portfolio and social features, and execute trades programmatically. homepage: https://api-portal.etoro.com/ metadata: { "openclaw": { "emoji": "📈", "category": "finance", "api_base": "https://public-api.etoro.com/api/v1", }, }
eToro Public API
Base URL: https://public-api.etoro.com/api/v1
About
This skill allows to interact with the user's eToro account programatically, including executing trades.
Authentication & Required Headers
Keys (request from the user on install)
- Public API Key: application
- User Key: user account
- Environment: Real Portfolio or Virtual Portfolio (real/demo)
Key generation (user-facing):
- Log in to eToro.
- Settings > Trading.
- Create New Key.
- Choose Environment (Real or Virtual/Demo) and Permissions (Read or Write).
- Verify identity and copy the generated User Key.
Headers (every request):
x-request-id: unique UUID per requestx-api-key: Public API Key (<PUBLIC_KEY>)x-user-key: User Key (<USER_KEY>)
Example:
curl -X GET "https://public-api.etoro.com/api/v1/watchlists" \
-H "x-request-id: <UUID>" \
-H "x-api-key: <PUBLIC_KEY>" \
-H "x-user-key: <USER_KEY>"
Request Conventions
- All paths below are relative to the Base URL (which already includes
/api/v1).
Example:GET /watchlistsmeansGET https://public-api.etoro.com/api/v1/watchlists. - Query params go in the URL, path params go in the URL path.
- For query params that are documented as
array, send them as comma-separated values (e.g.,instrumentIds=1001,1002). - Pagination patterns vary by endpoint:
- Search:
pageNumber,pageSize - People search & trade history:
page,pageSize - Feeds:
take,offset - Watchlist items listing:
pageNumber,itemsPerPage
- Search:
- Casing matters for request bodies:
- Trading execution uses PascalCase fields (e.g.,
InstrumentID,IsBuy,Leverage). - Market close body uses
InstrumentId(capital I, lowercase d). - Watchlist items use
ItemId,ItemType,ItemRank. - Feeds post body uses lower camel (
owner,message,tags,mentions,attachments).
- Trading execution uses PascalCase fields (e.g.,
- Some responses may use different casing for similar concepts (e.g.,
instrumentIdvsInstrumentID). When extracting IDs, handle both if present.
Demo vs Real Trading
- Use demo execution endpoints (contain
/demo/) for testing and paper trading. - Use non-demo execution endpoints for real trading.
- For portfolio/PnL:
- Demo:
/trading/info/demo/* - Real:
/trading/info/portfolioand/trading/info/real/pnl
- Demo:
- Ensure your key environment matches the endpoint (Virtual vs Real). Each User Key is associated with a specific environment.
Use Defaults
- Important: You don't need to specify all parameters. If the user doesn't specify leverage for example, don't send it on the API request.
Quick Start (Demo Trade)
- Resolve
instrumentIdusing search.
fieldsis required on search requests.
curl -X GET "https://public-api.etoro.com/api/v1/market-data/search?internalSymbolFull=BTC&fields=instrumentId,internalSymbolFull,displayname" \
-H "x-api-key: <PUBLIC_KEY>" \
-H "x-user-key: <USER_KEY>" \
-H "x-request-id: <UUID>"
- Place a demo market order by amount (PascalCase body):
curl -X POST "https://public-api.etoro.com/api/v1/trading/execution/demo/market-open-orders/by-amount" \
-H "x-api-key: <PUBLIC_KEY>" \
-H "x-user-key: <USER_KEY>" \
-H "x-request-id: <UUID>" \
-H "Content-Type: application/json" \
-d '{
"InstrumentID": 100000,
"IsBuy": true,
"Leverage": 1,
"Amount": 100
}'
Common IDs
instrumentId: from Search or Instruments metadatapositionId: from Portfolio endpointsorderId: from execution responses or Portfolio endpointsmarketId: used by instrument feed endpoints (typically available in instrument metadata/search fields)userId: numeric eToro user ID (often referred to as CID in responses; discover via People endpoints/search)watchlistId: from watchlists list/create endpoints
Market Data (Requests)
Search instruments
GET /market-data/search- Required query:
fields(comma-separated list of instrument fields to return) - Optional:
searchText,pageSize,pageNumber,sort - The Search endpoint supports filtering by fields returned in results; for exact symbol lookup, use
internalSymbolFullas a query param and verify the exact match. - Recommended minimal
fieldswhen you need IDs: include the instrument identifier (may appear asinstrumentIdorInstrumentID), plusinternalSymbolFullanddisplayname(andmarketIdif you plan to use Feeds).
Metadata
GET /market-data/instruments
Filters:instrumentIds,exchangeIds,stocksIndustryIds,instrumentTypeIds.
Prices & history
GET /market-data/instruments/rates
Required:instrumentIds(comma-separated).GET /market-data/instruments/history/closing-price
Returns historical closing prices for all instruments (bulk).GET /market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}
direction:ascordesc.candlesCountmax 1000.
Use only supportedintervalvalues (confirm via docs if unsure).
Reference data
GET /market-data/exchanges(optionalexchangeIds)GET /market-data/instrument-typesGET /market-data/stocks-industries(optionalstocksIndustryIds)
Trading Execution (Requests)
Requires a key with appropriate permissions (typically Write) and the correct environment (Demo vs Real).
Market Open Orders (by amount)
Endpoints:
POST /trading/execution/demo/market-open-orders/by-amountPOST /trading/execution/market-open-orders/by-amount
Body (PascalCase, JSON):
- Required:
InstrumentID,IsBuy,Leverage,Amount - Optional:
StopLossRate,TakeProfitRate,IsTslEnabled,IsNoStopLoss,IsNoTakeProfit
Market Open Orders (by units)
Endpoints:
POST /trading/execution/demo/market-open-orders/by-unitsPOST /trading/execution/market-open-orders/by-units
Body (PascalCase, JSON):
- Required:
InstrumentID,IsBuy,Leverage,AmountInUnits - Optional:
StopLossRate,TakeProfitRate,IsTslEnabled,IsNoStopLoss,IsNoTakeProfit
Cancel Market Open Orders
Endpoints:
DELETE /trading/execution/demo/market-open-orders/{orderId}DELETE /trading/execution/market-open-orders/{orderId}
Market Close Orders
Endpoints:
POST /trading/execution/demo/market-close-orders/positions/{positionId}POST /trading/execution/market-close-orders/positions/{positionId}DELETE /trading/execution/demo/market-close-orders/{orderId}DELETE /trading/execution/market-close-orders/{orderId}
Body (JSON):
- Required:
InstrumentId - Optional:
UnitsToDeduct(number ornull)
Partial close: set UnitsToDeduct.
Full close: set UnitsToDeduct to null.
You must close by positionId, not by symbol.
Market-if-touched (Limit) Orders
Endpoints:
POST /trading/execution/demo/limit-ordersDELETE /trading/execution/demo/limit-orders/{orderId}POST /trading/execution/limit-ordersDELETE /trading/execution/limit-orders/{orderId}
Body (PascalCase, JSON):
- Required:
InstrumentID,IsBuy,Leverage,Rate, and one ofAmountorAmountInUnits - Optional:
StopLossRate,TakeProfitRate,IsTslEnabled,IsNoStopLoss,IsNoTakeProfit - Do not send:
IsDiscounted,CID
Trading Info & Portfolio (Requests)
GET /trading/info/demo/pnlGET /trading/info/real/pnlGET /trading/info/demo/portfolioGET /trading/info/portfolio
Use these to discoverpositionIdandorderIdfor close/cancel flows.GET /trading/info/trade/history
Required:minDate(YYYY-MM-DD). Optional:page,pageSize.
Watchlists (Requests)
User watchlists
GET /watchlists
Optional:itemsPerPageForSingle,ensureBuiltinWatchlists,addRelatedAssets.GET /watchlists/{watchlistId}
Optional:pageNumber,itemsPerPage.POST /watchlists
Query:name(required),type,dynamicQuery(optional). (Uses query params, not a JSON body.)PUT /watchlists/{watchlistId}
Query:newName(required). (Uses query params, not a JSON body.)DELETE /watchlists/{watchlistId}
Watchlist items (body schema)
WatchlistItemDto fields:
ItemId(required, int)ItemType(required, string:InstrumentorPerson)ItemRank(optional, int)
Endpoints:
POST /watchlists/{watchlistId}/itemsPUT /watchlists/{watchlistId}/itemsDELETE /watchlists/{watchlistId}/items
Example body:
[
{ "ItemId": 12345, "ItemType": "Instrument", "ItemRank": 1 },
{ "ItemId": 67890, "ItemType": "Instrument", "ItemRank": 2 }
]
Default watchlists
POST /watchlists/default-watchlist/selected-itemsGET /watchlists/default-watchlists/items
Optional:itemsLimit,itemsPerPage.POST /watchlists/newasdefault-watchlist
Query:name(required),type,dynamicQuery(optional).PUT /watchlists/setUserSelectedUserDefault/{watchlistId}PUT /watchlists/rank/{watchlistId}
Query:newRank(required).
Public watchlists
GET /watchlists/public/{userId}GET /watchlists/public/{userId}/{watchlistId}
Feeds (Requests)
Read feeds
GET /feeds/instrument/{marketId}
Optional:requesterUserId,take,offset,badgesExperimentIsEnabled,reactionsPageSize.GET /feeds/user/{userId}
Optional:requesterUserId,take,offset,badgesExperimentIsEnabled,reactionsPageSize.
Notes:
marketIdis associated with an instrument (typically available via instrument metadata/search if you include it infields).userIdis a numeric user identifier (CID). If you only have a username, discover the numeric ID via People endpoints (see User Info & Analytics).
Create post
POST /feeds/post- Body fields (lower camel, JSON):
owner(int)message(string)tags:{ "tags": [{ "name": "...", "id": "..." }] }mentions:{ "mentions": [{ "userName": "...", "id": "...", "isDirect": true }] }attachments: array of objects withurl,title,host,description,mediaType, and optionalmedia.
Minimal example:
{ "message": "Hello eToro feed!" }
Curated Lists & Recommendations (Requests)
GET /curated-listsGET /market-recommendations/{itemsCount}
Popular Investors (Copiers)
GET /pi-data/copiers
User Info & Analytics (Requests)
GET /user-info/people
Optional:usernames,cidList.
Use this to map username ↔ CID (userId) when you need numericuserIdfor feeds/public watchlists.GET /user-info/people/search
Required:period. Optional:page,pageSize,sort,popularInvestor,gainMax,maxDailyRiskScoreMin,maxDailyRiskScoreMax,maxMonthlyRiskScoreMin,maxMonthlyRiskScoreMax,weeksSinceRegistrationMin,countryId,instrumentId,instrumentPctMin,instrumentPctMax,isTestAccount, and other filters.GET /user-info/people/{username}/gainGET /user-info/people/{username}/daily-gain
Required:minDate,maxDate,type(DailyorPeriod).GET /user-info/people/{username}/portfolio/liveGET /user-info/people/{username}/tradeinfo
Required:period(e.g.,LastTwoYears).
Responses & Schemas
For response schemas and full examples, refer to:
- https://api-portal.etoro.com/
- MCP server:
https://api-portal.etoro.com/mcp
如何使用「eToro API」?
- 打开小龙虾AI(Web 或 iOS App)
- 点击上方「立即使用」按钮,或在对话框中输入任务描述
- 小龙虾AI 会自动匹配并调用「eToro API」技能完成任务
- 结果即时呈现,支持继续对话优化