← Back to Skills Marketplace
marian2js

eToro Apps

by Mariano Pardo · GitHub ↗ · v1.0.0
cross-platform ✓ Security Clean
458
Downloads
1
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install etoro-apps
Description
Enables agents to interact with the eToro API to access market data, portfolio and social features, and execute trades programmatically. Supports both OAuth...
README (SKILL.md)

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 \x3Caccess_token>

Where access_token comes from:

  1. User clicks "Login with eToro" → redirects to https://www.etoro.com/sso/ with PKCE challenge.
  2. User authenticates on eToro's side.
  3. eToro redirects back with an authorization code.
  4. The code is exchanged for tokens via POST https://www.etoro.com/sso/oidc/token:
    • grant_type=authorization_code
    • code=\x3Cauth_code>
    • redirect_uri=\x3Ccallback_url>
    • code_verifier=\x3Cpkce_verifier>
    • Plus Authorization: Basic \x3Cbase64(client_id:client_secret)> header
  5. Response contains:
    • access_tokenthis 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: \x3CUUID>" \
  -H "Authorization: Bearer \x3Caccess_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):

  1. Log in to eToro.
  2. Settings > Trading.
  3. Create New Key.
  4. Choose Environment (Real or Virtual/Demo) and Permissions (Read or Write).
  5. Verify identity and copy the generated User Key.

Headers (every request):

  • x-request-id: unique UUID per request
  • x-api-key: Public API Key (\x3CPUBLIC_KEY>)
  • x-user-key: User Key (\x3CUSER_KEY>)

Example:

curl -X GET "https://public-api.etoro.com/api/v1/watchlists" \
  -H "x-request-id: \x3CUUID>" \
  -H "x-api-key: \x3CPUBLIC_KEY>" \
  -H "x-user-key: \x3CUSER_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)

  1. 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 \x3Caccess_token>" \
  -H "x-request-id: \x3CUUID>"
  1. 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 \x3Caccess_token>" \
  -H "x-request-id: \x3CUUID>" \
  -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)

  • 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 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:

Usage Guidance
This SKILL.md appears to be a straightforward eToro API integration and does not request unrelated system access. However, it will need either your OAuth access token or API keys/user key to function — these are powerful credentials that can place real trades. Before installing: - Verify the skill source/owner (confirm you trust kn730v2... and the homepage) and prefer the official eToro portal and OAuth flow. - Test in the demo/virtual environment first (use demo endpoints and demo User Keys). - If you provide API keys, give the minimum permissions (read only) until you need write/trade capabilities; rotate/revoke keys after testing. - Decide whether the agent should be allowed to call this skill autonomously; consider requiring explicit user confirmation for any real trade execution. - Confirm how credentials will be collected and stored by the agent (don’t paste keys into untrusted channels).
Capability Analysis
Type: OpenClaw Skill Name: etoro-apps Version: 1.0.0 The skill bundle contains standard metadata and detailed documentation for interacting with the eToro Public API. The `SKILL.md` file describes legitimate API endpoints for market data, portfolio management, and trading execution (both demo and real). While the skill enables high-impact actions like executing trades, the documentation transparently outlines these capabilities, distinguishes between demo and real environments, and provides clear instructions for authentication and API usage. There is no evidence of prompt injection attempts, data exfiltration, malicious execution, persistence mechanisms, or obfuscation. The content is aligned with the stated purpose of enabling programmatic interaction with eToro and lacks any indicators of intentional harmful behavior.
Capability Assessment
Purpose & Capability
The name/description (eToro trading client) matches the instructions: API base URL, auth flows (OAuth and API keys), headers, endpoints for demo vs real trading, and examples for placing orders. There are no unrelated environment variables, binaries, or install steps requested that would be unexpected for a trading integration.
Instruction Scope
SKILL.md focuses on calling eToro endpoints and handling tokens/keys. It does reference ctx.accessToken / ctx.apiKey / ctx.userKey (runtime context variables) and says keys are requested from the user at install — the registry metadata lists no required env vars, so keys are expected to be provided interactively at runtime rather than via declared env variables. This is reasonable, but you should confirm how the agent will prompt for and store those credentials. There is a minor technical mix of PKCE flow + sending client_secret in the token exchange that may be a small inaccuracy in the documentation (not a security indicator by itself).
Install Mechanism
No install spec and no code files — instruction-only skill. That minimizes the risk of arbitrary code being written to disk or executed during install.
Credentials
The skill does not declare any required env vars but explicitly requires sensitive credentials at runtime (OAuth access_token or API keys/user key). That is proportional for a trading integration. Because the skill can execute trades, granting it these credentials is high-impact; ensure you only supply demo (virtual) keys for testing and limit permissions (read vs write) as appropriate.
Persistence & Privilege
always:false and no install steps writing persistent binaries/configs. The skill is allowed to be invoked autonomously by the agent (default). Given its ability to execute trades, you should consider restricting autonomous execution or requiring explicit user confirmation before any real trade operations.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install etoro-apps
  3. After installation, invoke the skill by name or use /etoro-apps
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release — eToro API integration skill. - Enables programmatic access to the eToro API for market data, portfolio management, social features, and trade execution. - Supports both OAuth SSO and manual API key authentication methods. - Provides guidance on API request conventions, authentication headers, and environment selection (demo vs real). - Includes quick start examples for searching instruments and placing trades. - Documents the most common endpoints for market data retrieval and trading operations.
Metadata
Slug etoro-apps
Version 1.0.0
License
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is eToro Apps?

Enables agents to interact with the eToro API to access market data, portfolio and social features, and execute trades programmatically. Supports both OAuth... It is an AI Agent Skill for Claude Code / OpenClaw, with 458 downloads so far.

How do I install eToro Apps?

Run "/install etoro-apps" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is eToro Apps free?

Yes, eToro Apps is completely free (open-source). You can download, install and use it at no cost.

Which platforms does eToro Apps support?

eToro Apps is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created eToro Apps?

It is built and maintained by Mariano Pardo (@marian2js); the current version is v1.0.0.

💬 Comments