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
The eToro API supports two authentication methods. Both use the same base URL and endpoints — only the auth headers differ.
Method 1 — OAuth SSO (Bearer Token)
If the user authenticated via "Login with eToro" (SSO/OAuth), an access_token is available from the token exchange.
Headers (every request):
x-request-id: unique UUID per request
Authorization: Bearer <access_token>
Where access_token comes from:
- User clicks "Login with eToro" → redirects to
https://www.etoro.com/sso/ with PKCE challenge.
- User authenticates on eToro's side.
- eToro redirects back with an authorization
code.
- The code is exchanged for tokens via
POST https://www.etoro.com/sso/oidc/token:
grant_type=authorization_code
code=<auth_code>
redirect_uri=<callback_url>
code_verifier=<pkce_verifier>
- Plus
Authorization: Basic <base64(client_id:client_secret)> header
- Response contains:
access_token — this is the Bearer token for API calls (~2130 chars, JWT)
id_token — JWT with user identity (sub claim = 128-char encoded user ID)
token_type: "Bearer"
expires_in: (varies)
Example:
curl -X GET "https://public-api.etoro.com/api/v1/watchlists" \
-H "x-request-id: <UUID>" \
-H "Authorization: Bearer <access_token>"
Method 2 — Manual API Keys
If the user provides API keys manually (no OAuth), use key-based auth.
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 request
x-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>"
Choosing the Auth Method in Code
When making requests, check which credentials are available:
if (ctx.accessToken) {
// SSO auth — Bearer token from OAuth token exchange
headers["Authorization"] = `Bearer ${ctx.accessToken}`;
} else {
// Manual API key auth
headers["x-api-key"] = ctx.apiKey;
headers["x-user-key"] = ctx.userKey;
}
Request Conventions
- All paths below are relative to the Base URL (which already includes
/api/v1).
Example: GET /watchlists means GET 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
- 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).
- Some responses may use different casing for similar concepts (e.g.,
instrumentId vs InstrumentID). 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/portfolio and /trading/info/real/pnl
- 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
instrumentId 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 "Authorization: Bearer <access_token>" \
-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 "Authorization: Bearer <access_token>" \
-H "x-request-id: <UUID>" \
-H "Content-Type: application/json" \
-d '{
"InstrumentID": 100000,
"IsBuy": true,
"Leverage": 1,
"Amount": 100
}'
Note: The examples above use OAuth (Bearer token). For API key auth, replace the Authorization header with x-api-key and x-user-key headers instead.
Common IDs
instrumentId: from Search or Instruments metadata
positionId: from Portfolio endpoints
orderId: from execution responses or Portfolio endpoints
marketId: 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
internalSymbolFull as a query param and verify the exact match.
- Recommended minimal
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/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: asc or desc. candlesCount max 1000.
Use only supported interval values (confirm via docs if unsure).
Reference data
GET /market-data/exchanges (optional exchangeIds)
GET /market-data/instrument-types
GET /market-data/stocks-industries (optional stocksIndustryIds)
Trading Execution (Requests)
Requires 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-amount
POST /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-units
POST /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 or null)
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-orders
DELETE /trading/execution/demo/limit-orders/{orderId}
POST /trading/execution/limit-orders
DELETE /trading/execution/limit-orders/{orderId}
Body (PascalCase, JSON):
- Required:
InstrumentID, IsBuy, Leverage, Rate, and one of Amount or AmountInUnits
- Optional:
StopLossRate, TakeProfitRate, IsTslEnabled, IsNoStopLoss, IsNoTakeProfit
- Do not send:
IsDiscounted, CID
Trading Info & Portfolio (Requests)
GET /trading/info/demo/pnl
GET /trading/info/real/pnl
GET /trading/info/demo/portfolio
GET /trading/info/portfolio
Use these to discover positionId and orderId for 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: Instrument or Person)
ItemRank (optional, int)
Endpoints:
POST /watchlists/{watchlistId}/items
PUT /watchlists/{watchlistId}/items
DELETE /watchlists/{watchlistId}/items
Example body:
[
{ "ItemId": 12345, "ItemType": "Instrument", "ItemRank": 1 },
{ "ItemId": 67890, "ItemType": "Instrument", "ItemRank": 2 }
]
Default watchlists
POST /watchlists/default-watchlist/selected-items
GET /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:
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/post
- Body fields (lower camel, JSON):
owner (int)
message (string)
tags: { "tags": [{ "name": "...", "id": "..." }] }
mentions: { "mentions": [{ "userName": "...", "id": "...", "isD irect": true }] }
attachments: array of objects with url, title, host, description, mediaType, and optional media.
Minimal example:
{ "message": "Hello eToro feed!" }
Curated Lists & Recommendations (Requests)
GET /curated-lists
GET /market-recommendations/{itemsCount}
Popular Investors (Copiers)
User Info & Analytics (Requests)
GET /user-info/people
Optional: usernames, cidList.
Use this to map username ↔ CID (userId) when you need numeric userId for 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}/gain
GET /user-info/people/{username}/daily-gain
Required: minDate, maxDate, type (Daily or Period).
GET /user-info/people/{username}/portfolio/live
GET /user-info/people/{username}/tradeinfo
Required: period (e.g., LastTwoYears).
Responses & Schemas
For response schemas and full examples, refer to:
1---2name: etoro-apps3description: Enables agents to interact with the eToro API to access market data, portfolio and social features, and execute trades programmatically. Supports both OAuth SSO and manual API key authentication.4---5
6# eToro Public API
7
8Base URL: `https://public-api.etoro.com/api/v1`
9
10## About
11
12This skill allows to interact with the user's eToro account programatically, including executing trades.
13
14## Authentication & Required Headers
15
16The eToro API supports **two** authentication methods. Both use the same base URL and endpoints — only the auth headers differ.
17
18### Method 1 — OAuth SSO (Bearer Token)
19
20If the user authenticated via **"Login with eToro"** (SSO/OAuth), an `access_token` is available from the token exchange.
21
22**Headers (every request):**
23
24- `x-request-id`: unique UUID per request
25- `Authorization`: `Bearer <access_token>`
26
27Where `access_token` comes from:
28
291. User clicks "Login with eToro" → redirects to `https://www.etoro.com/sso/` with PKCE challenge.
302. User authenticates on eToro's side.
313. eToro redirects back with an authorization `code`.
324. The code is exchanged for tokens via `POST https://www.etoro.com/sso/oidc/token`:
33 - `grant_type=authorization_code`
34 - `code=<auth_code>`
35 - `redirect_uri=<callback_url>`
36 - `code_verifier=<pkce_verifier>`
37 - Plus `Authorization: Basic <base64(client_id:client_secret)>` header
385. Response contains:
39 - `access_token` — **this is the Bearer token for API calls** (~2130 chars, JWT)
40 - `id_token` — JWT with user identity (`sub` claim = 128-char encoded user ID)
41 - `token_type`: `"Bearer"`
42 - `expires_in`: (varies)
43
44Example:
45
46```bash
47curl -X GET "https://public-api.etoro.com/api/v1/watchlists" \
48 -H "x-request-id: <UUID>" \
49 -H "Authorization: Bearer <access_token>"
50```
51
52### Method 2 — Manual API Keys
53
54If the user provides API keys manually (no OAuth), use key-based auth.
55
56**Keys (request from the user on install)**
57
58- **Public API Key**: application
59- **User Key**: user account
60- **Environment**: Real Portfolio or Virtual Portfolio (real/demo)
61
62**Key generation (user-facing):**
63
641. Log in to eToro.
652. Settings > Trading.
663. Create New Key.
674. Choose **Environment** (Real or Virtual/Demo) and **Permissions** (Read or Write).
685. Verify identity and copy the generated User Key.
69
70**Headers (every request):**
71
72- `x-request-id`: unique UUID per request
73- `x-api-key`: Public API Key (`<PUBLIC_KEY>`)
74- `x-user-key`: User Key (`<USER_KEY>`)
75
76Example:
77
78```bash
79curl -X GET "https://public-api.etoro.com/api/v1/watchlists" \
80 -H "x-request-id: <UUID>" \
81 -H "x-api-key: <PUBLIC_KEY>" \
82 -H "x-user-key: <USER_KEY>"
83```
84
85### Choosing the Auth Method in Code
86
87When making requests, check which credentials are available:
88
89```typescript
90if (ctx.accessToken) {
91 // SSO auth — Bearer token from OAuth token exchange
92 headers["Authorization"] = `Bearer ${ctx.accessToken}`;
93} else {
94 // Manual API key auth
95 headers["x-api-key"] = ctx.apiKey;
96 headers["x-user-key"] = ctx.userKey;
97}
98```
99
100## Request Conventions
101
102- **All paths below are relative to the Base URL** (which already includes `/api/v1`).
103 Example: `GET /watchlists` means `GET https://public-api.etoro.com/api/v1/watchlists`.
104- Query params go in the URL, path params go in the URL path.
105- For query params that are documented as `array`, send them as **comma-separated values** (e.g., `instrumentIds=1001,1002`).
106- Pagination patterns vary by endpoint:
107 - Search: `pageNumber`, `pageSize`
108 - People search & trade history: `page`, `pageSize`
109 - Feeds: `take`, `offset`
110 - Watchlist items listing: `pageNumber`, `itemsPerPage`
111- **Casing matters** for request bodies:
112 - Trading execution uses **PascalCase** fields (e.g., `InstrumentID`, `IsBuy`, `Leverage`).
113 - Market close body uses `InstrumentId` (capital I, lowercase d).
114 - Watchlist items use `ItemId`, `ItemType`, `ItemRank`.
115 - Feeds post body uses lower camel (`owner`, `message`, `tags`, `mentions`, `attachments`).
116- Some responses may use different casing for similar concepts (e.g., `instrumentId` vs `InstrumentID`). When extracting IDs, handle both if present.
117
118## Demo vs Real Trading
119
120- Use **demo execution endpoints** (contain `/demo/`) for testing and paper trading.
121- Use **non-demo execution endpoints** for real trading.
122- For portfolio/PnL:
123 - Demo: `/trading/info/demo/*`
124 - Real: `/trading/info/portfolio` and `/trading/info/real/pnl`
125- Ensure your key environment matches the endpoint (Virtual vs Real). Each User Key is associated with a specific environment.
126
127## Use Defaults
128
129- 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.
130
131## Quick Start (Demo Trade)
132
1331. **Resolve `instrumentId`** using search.
134 `fields` is required on search requests.
135
136```bash
137curl -X GET "https://public-api.etoro.com/api/v1/market-data/search?internalSymbolFull=BTC&fields=instrumentId,internalSymbolFull,displayname" \
138 -H "Authorization: Bearer <access_token>" \
139 -H "x-request-id: <UUID>"
140```
141
1422. **Place a demo market order by amount** (PascalCase body):
143
144```bash
145curl -X POST "https://public-api.etoro.com/api/v1/trading/execution/demo/market-open-orders/by-amount" \
146 -H "Authorization: Bearer <access_token>" \
147 -H "x-request-id: <UUID>" \
148 -H "Content-Type: application/json" \
149 -d '{
150 "InstrumentID": 100000,
151 "IsBuy": true,
152 "Leverage": 1,
153 "Amount": 100
154 }'
155```
156
157> **Note:** The examples above use OAuth (Bearer token). For API key auth, replace the `Authorization` header with `x-api-key` and `x-user-key` headers instead.
158
159## Common IDs
160
161- `instrumentId`: from Search or Instruments metadata
162- `positionId`: from Portfolio endpoints
163- `orderId`: from execution responses or Portfolio endpoints
164- `marketId`: used by instrument feed endpoints (typically available in instrument metadata/search fields)
165- `userId`: numeric eToro user ID (often referred to as **CID** in responses; discover via People endpoints/search)
166- `watchlistId`: from watchlists list/create endpoints
167
168## Market Data (Requests)
169
170**Search instruments**
171
172- `GET /market-data/search`
173- Required query: `fields` (comma-separated list of instrument fields to return)
174- Optional: `searchText`, `pageSize`, `pageNumber`, `sort`
175- The Search endpoint supports filtering by fields returned in results; for exact symbol lookup, use `internalSymbolFull` as a query param and verify the exact match.
176- Recommended minimal `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).
177
178**Metadata**
179
180- `GET /market-data/instruments`
181 Filters: `instrumentIds`, `exchangeIds`, `stocksIndustryIds`, `instrumentTypeIds`.
182
183**Prices & history**
184
185- `GET /market-data/instruments/rates`
186 Required: `instrumentIds` (comma-separated).
187- `GET /market-data/instruments/history/closing-price`
188 Returns historical closing prices for all instruments (bulk).
189- `GET /market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}`
190 `direction`: `asc` or `desc`. `candlesCount` max 1000.
191 Use only supported `interval` values (confirm via docs if unsure).
192
193**Reference data**
194
195- `GET /market-data/exchanges` (optional `exchangeIds`)
196- `GET /market-data/instrument-types`
197- `GET /market-data/stocks-industries` (optional `stocksIndustryIds`)
198
199## Trading Execution (Requests)
200
201> Requires appropriate permissions (typically **Write**) and the correct environment (Demo vs Real).
202
203### Market Open Orders (by amount)
204
205Endpoints:
206
207- `POST /trading/execution/demo/market-open-orders/by-amount`
208- `POST /trading/execution/market-open-orders/by-amount`
209
210Body (PascalCase, JSON):
211
212- **Required:** `InstrumentID`, `IsBuy`, `Leverage`, `Amount`
213- **Optional:** `StopLossRate`, `TakeProfitRate`, `IsTslEnabled`, `IsNoStopLoss`, `IsNoTakeProfit`
214
215### Market Open Orders (by units)
216
217Endpoints:
218
219- `POST /trading/execution/demo/market-open-orders/by-units`
220- `POST /trading/execution/market-open-orders/by-units`
221
222Body (PascalCase, JSON):
223
224- **Required:** `InstrumentID`, `IsBuy`, `Leverage`, `AmountInUnits`
225- **Optional:** `StopLossRate`, `TakeProfitRate`, `IsTslEnabled`, `IsNoStopLoss`, `IsNoTakeProfit`
226
227### Cancel Market Open Orders
228
229Endpoints:
230
231- `DELETE /trading/execution/demo/market-open-orders/{orderId}`
232- `DELETE /trading/execution/market-open-orders/{orderId}`
233
234### Market Close Orders
235
236Endpoints:
237
238- `POST /trading/execution/demo/market-close-orders/positions/{positionId}`
239- `POST /trading/execution/market-close-orders/positions/{positionId}`
240- `DELETE /trading/execution/demo/market-close-orders/{orderId}`
241- `DELETE /trading/execution/market-close-orders/{orderId}`
242
243Body (JSON):
244
245- **Required:** `InstrumentId`
246- **Optional:** `UnitsToDeduct` (number or `null`)
247
248Partial close: set `UnitsToDeduct`.
249Full close: set `UnitsToDeduct` to `null`.
250You must close by `positionId`, not by symbol.
251
252### Market-if-touched (Limit) Orders
253
254Endpoints:
255
256- `POST /trading/execution/demo/limit-orders`
257- `DELETE /trading/execution/demo/limit-orders/{orderId}`
258- `POST /trading/execution/limit-orders`
259- `DELETE /trading/execution/limit-orders/{orderId}`
260
261Body (PascalCase, JSON):
262
263- **Required:** `InstrumentID`, `IsBuy`, `Leverage`, **`Rate`**, and **one of** `Amount` **or** `AmountInUnits`
264- **Optional:** `StopLossRate`, `TakeProfitRate`, `IsTslEnabled`, `IsNoStopLoss`, `IsNoTakeProfit`
265- **Do not send:** `IsDiscounted`, `CID`
266
267## Trading Info & Portfolio (Requests)
268
269- `GET /trading/info/demo/pnl`
270- `GET /trading/info/real/pnl`
271- `GET /trading/info/demo/portfolio`
272- `GET /trading/info/portfolio`
273 Use these to discover `positionId` and `orderId` for close/cancel flows.
274- `GET /trading/info/trade/history`
275 Required: `minDate` (YYYY-MM-DD). Optional: `page`, `pageSize`.
276
277## Watchlists (Requests)
278
279**User watchlists**
280
281- `GET /watchlists`
282 Optional: `itemsPerPageForSingle`, `ensureBuiltinWatchlists`, `addRelatedAssets`.
283- `GET /watchlists/{watchlistId}`
284 Optional: `pageNumber`, `itemsPerPage`.
285- `POST /watchlists`
286 Query: `name` (required), `type`, `dynamicQuery` (optional). (Uses query params, not a JSON body.)
287- `PUT /watchlists/{watchlistId}`
288 Query: `newName` (required). (Uses query params, not a JSON body.)
289- `DELETE /watchlists/{watchlistId}`
290
291**Watchlist items (body schema)**
292
293`WatchlistItemDto` fields:
294
295- `ItemId` (required, int)
296- `ItemType` (required, string: `Instrument` or `Person`)
297- `ItemRank` (optional, int)
298
299Endpoints:
300
301- `POST /watchlists/{watchlistId}/items`
302- `PUT /watchlists/{watchlistId}/items`
303- `DELETE /watchlists/{watchlistId}/items`
304
305Example body:
306
307```json
308[
309 { "ItemId": 12345, "ItemType": "Instrument", "ItemRank": 1 },
310 { "ItemId": 67890, "ItemType": "Instrument", "ItemRank": 2 }
311]
312```
313
314**Default watchlists**
315
316- `POST /watchlists/default-watchlist/selected-items`
317- `GET /watchlists/default-watchlists/items`
318 Optional: `itemsLimit`, `itemsPerPage`.
319- `POST /watchlists/newasdefault-watchlist`
320 Query: `name` (required), `type`, `dynamicQuery` (optional).
321- `PUT /watchlists/setUserSelectedUserDefault/{watchlistId}`
322- `PUT /watchlists/rank/{watchlistId}`
323 Query: `newRank` (required).
324
325**Public watchlists**
326
327- `GET /watchlists/public/{userId}`
328- `GET /watchlists/public/{userId}/{watchlistId}`
329
330## Feeds (Requests)
331
332**Read feeds**
333
334- `GET /feeds/instrument/{marketId}`
335 Optional: `requesterUserId`, `take`, `offset`, `badgesExperimentIsEnabled`, `reactionsPageSize`.
336- `GET /feeds/user/{userId}`
337 Optional: `requesterUserId`, `take`, `offset`, `badgesExperimentIsEnabled`, `reactionsPageSize`.
338
339Notes:
340
341- `marketId` is associated with an instrument (typically available via instrument metadata/search if you include it in `fields`).
342- `userId` is a numeric user identifier (CID). If you only have a username, discover the numeric ID via People endpoints (see User Info & Analytics).
343
344**Create post**
345
346- `POST /feeds/post`
347- Body fields (lower camel, JSON):
348 - `owner` (int)
349 - `message` (string)
350 - `tags`: `{ "tags": [{ "name": "...", "id": "..." }] }`
351 - `mentions`: `{ "mentions": [{ "userName": "...", "id": "...", "isD irect": true }] }`
352 - `attachments`: array of objects with `url`, `title`, `host`, `description`, `mediaType`, and optional `media`.
353
354Minimal example:
355
356```json
357{ "message": "Hello eToro feed!" }
358```
359
360## Curated Lists & Recommendations (Requests)
361
362- `GET /curated-lists`
363- `GET /market-recommendations/{itemsCount}`
364
365## Popular Investors (Copiers)
366
367- `GET /pi-data/copiers`
368
369## User Info & Analytics (Requests)
370
371- `GET /user-info/people`
372 Optional: `usernames`, `cidList`.
373 Use this to map **username ↔ CID (userId)** when you need numeric `userId` for feeds/public watchlists.
374- `GET /user-info/people/search`
375 Required: `period`. Optional: `page`, `pageSize`, `sort`, `popularInvestor`, `gainMax`, `maxDailyRiskScoreMin`, `maxDailyRiskScoreMax`, `maxMonthlyRiskScoreMin`, `maxMonthlyRiskScoreMax`, `weeksSinceRegistrationMin`, `countryId`, `instrumentId`, `instrumentPctMin`, `instrumentPctMax`, `isTestAccount`, and other filters.
376- `GET /user-info/people/{username}/gain`
377- `GET /user-info/people/{username}/daily-gain`
378 Required: `minDate`, `maxDate`, `type` (`Daily` or `Period`).
379- `GET /user-info/people/{username}/portfolio/live`
380- `GET /user-info/people/{username}/tradeinfo`
381 Required: `period` (e.g., `LastTwoYears`).
382
383## Responses & Schemas
384
385For response schemas and full examples, refer to:
386
387- https://api-portal.etoro.com/
388- MCP server: `https://api-portal.etoro.com/mcp`