Install
openclaw skills install etoro-apiClawHub Security found sensitive or high-impact capabilities. Review the scan results before using.
Enables agents to interact with the eToro API to access market data, portfolio and social features, and execute trades programmatically.
openclaw skills install etoro-apiBase URL: https://public-api.etoro.com/api/v1
This skill allows to interact with the user's eToro account programatically, including executing trades.
Keys (request from the user on install)
Key generation (user-facing):
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>"
/api/v1).GET /watchlists means GET https://public-api.etoro.com/api/v1/watchlists.array, send them as comma-separated values (e.g., instrumentIds=1001,1002).pageNumber, pageSizepage, pageSizetake, offsetpageNumber, itemsPerPageInstrumentID, IsBuy, Leverage).InstrumentId (capital I, lowercase d).ItemId, ItemType, ItemRank.owner, message, tags, mentions, attachments).instrumentId vs InstrumentID). When extracting IDs, handle both if present./demo/) for testing and paper trading./trading/info/demo/*/trading/info/portfolio and /trading/info/real/pnlinstrumentId using search.fields is 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>"
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
}'
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 endpointsSearch instruments
GET /market-data/searchfields (comma-separated list of instrument fields to return)searchText, pageSize, pageNumber, sortinternalSymbolFull as a query param and verify the exact match.fields when you need IDs: include the instrument identifier (may appear as instrumentId or InstrumentID), plus internalSymbolFull and displayname (and marketId if you plan to use Feeds).Metadata
GET /market-data/instrumentsinstrumentIds, exchangeIds, stocksIndustryIds, instrumentTypeIds.Prices & history
GET /market-data/instruments/ratesinstrumentIds (comma-separated).GET /market-data/instruments/history/closing-priceGET /market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}direction: asc or desc. candlesCount max 1000.interval values (confirm via docs if unsure).Reference data
GET /market-data/exchanges (optional exchangeIds)GET /market-data/instrument-typesGET /market-data/stocks-industries (optional stocksIndustryIds)Requires a key with appropriate permissions (typically Write) and the correct environment (Demo vs Real).
Endpoints:
POST /trading/execution/demo/market-open-orders/by-amountPOST /trading/execution/market-open-orders/by-amountBody (PascalCase, JSON):
InstrumentID, IsBuy, Leverage, AmountStopLossRate, TakeProfitRate, IsTslEnabled, IsNoStopLoss, IsNoTakeProfitEndpoints:
POST /trading/execution/demo/market-open-orders/by-unitsPOST /trading/execution/market-open-orders/by-unitsBody (PascalCase, JSON):
InstrumentID, IsBuy, Leverage, AmountInUnitsStopLossRate, TakeProfitRate, IsTslEnabled, IsNoStopLoss, IsNoTakeProfitEndpoints:
DELETE /trading/execution/demo/market-open-orders/{orderId}DELETE /trading/execution/market-open-orders/{orderId}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):
InstrumentIdUnitsToDeduct (number or null)Partial close: set UnitsToDeduct.
Full close: set UnitsToDeduct to null.
You must close by positionId, not by symbol.
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):
InstrumentID, IsBuy, Leverage, Rate, and one of Amount or AmountInUnitsStopLossRate, TakeProfitRate, IsTslEnabled, IsNoStopLoss, IsNoTakeProfitIsDiscounted, CIDGET /trading/info/demo/pnlGET /trading/info/real/pnlGET /trading/info/demo/portfolioGET /trading/info/portfoliopositionId and orderId for close/cancel flows.GET /trading/info/trade/historyminDate (YYYY-MM-DD). Optional: page, pageSize.User watchlists
GET /watchlistsitemsPerPageForSingle, ensureBuiltinWatchlists, addRelatedAssets.GET /watchlists/{watchlistId}pageNumber, itemsPerPage.POST /watchlistsname (required), type, dynamicQuery (optional). (Uses query params, not a JSON body.)PUT /watchlists/{watchlistId}newName (required). (Uses query params, not a JSON body.)DELETE /watchlists/{watchlistId}Watchlist items (body schema)
WatchlistItemDto fields:
ItemId (required, int)ItemType (required, string: Instrument or Person)ItemRank (optional, int)Endpoints:
POST /watchlists/{watchlistId}/itemsPUT /watchlists/{watchlistId}/itemsDELETE /watchlists/{watchlistId}/itemsExample body:
[
{ "ItemId": 12345, "ItemType": "Instrument", "ItemRank": 1 },
{ "ItemId": 67890, "ItemType": "Instrument", "ItemRank": 2 }
]
Default watchlists
POST /watchlists/default-watchlist/selected-itemsGET /watchlists/default-watchlists/itemsitemsLimit, itemsPerPage.POST /watchlists/newasdefault-watchlistname (required), type, dynamicQuery (optional).PUT /watchlists/setUserSelectedUserDefault/{watchlistId}PUT /watchlists/rank/{watchlistId}newRank (required).Public watchlists
GET /watchlists/public/{userId}GET /watchlists/public/{userId}/{watchlistId}Read feeds
GET /feeds/instrument/{marketId}requesterUserId, take, offset, badgesExperimentIsEnabled, reactionsPageSize.GET /feeds/user/{userId}requesterUserId, take, offset, badgesExperimentIsEnabled, reactionsPageSize.Notes:
marketId is associated with an instrument (typically available via instrument metadata/search if you include it in fields).userId is 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/postowner (int)message (string)tags: { "tags": [{ "name": "...", "id": "..." }] }mentions: { "mentions": [{ "userName": "...", "id": "...", "isDirect": true }] }attachments: array of objects with url, title, host, description, mediaType, and optional media.Minimal example:
{ "message": "Hello eToro feed!" }
GET /curated-listsGET /market-recommendations/{itemsCount}GET /pi-data/copiersGET /user-info/peopleusernames, cidList.userId for feeds/public watchlists.GET /user-info/people/searchperiod. 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-gainminDate, maxDate, type (Daily or Period).GET /user-info/people/{username}/portfolio/liveGET /user-info/people/{username}/tradeinfoperiod (e.g., LastTwoYears).For response schemas and full examples, refer to:
https://api-portal.etoro.com/mcp