Etoro
Agent Skills for traders and investors
npx -y skills add marian2js/trading-skills --skill etoroAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 9 stars9 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when the user wants an agent to interact with the eToro API for market data, portfolio and social features, or trade execution.
SKILL.md
11.4 KB, as published. Nobody here has run it
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/instrumentsFilters:instrumentIds,exchangeIds,stocksIndustryIds,instrumentTypeIds.
Prices & history
GET /market-data/instruments/ratesRequired:instrumentIds(comma-separated).GET /market-data/instruments/history/closing-priceReturns 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/portfolioUse these to discoverpositionIdandorderIdfor close/cancel flows.GET /trading/info/trade/historyRequired:minDate(YYYY-MM-DD). Optional:page,pageSize.
Watchlists (Requests)
User watchlists
GET /watchlistsOptional:itemsPerPageForSingle,ensureBuiltinWatchlists,addRelatedAssets.GET /watchlists/{watchlistId}Optional:pageNumber,itemsPerPage.POST /watchlistsQuery: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/itemsOptional:itemsLimit,itemsPerPage.POST /watchlists/newasdefault-watchlistQuery: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/peopleOptional:usernames,cidList. Use this to map username ↔ CID (userId) when you need numericuserIdfor feeds/public watchlists.GET /user-info/people/searchRequired: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-gainRequired:minDate,maxDate,type(DailyorPeriod).GET /user-info/people/{username}/portfolio/liveGET /user-info/people/{username}/tradeinfoRequired: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