eToro connector setup

Operator·4 minutes to read

This page is the setup half — registering the eToro OAuth application this deployment signs members in with, and getting its client id and secret into Botseon. Authorising a connection afterwards is the Authenticate control on the plugin sheet, which is what actually sends the member to eToro. What the connector then lets a bot do is the member's page, docs/using/connectors/etoro.md.

eToro documents two ways in: an OAuth 2.0 sign-in "for an application that signs other eToro users in and acts on their behalf", and an x-api-key / x-user-key pair that "authenticates you as yourself". The connector uses the first, with PKCE (mandatory at eToro, S256 only). The vendor facts behind this page are in docs/research/connectors/etoro.md.

1. Register the OAuth application at eToro

Register it once, signed in to eToro as the person who will administer it — in the eToro Builders portal (https://builders.etoro.com/app-registration), or with eToro's own API, POST https://public-api.etoro.com/api/v1/sso/applications (it needs a token holding etoro-public:sso-applications:write). The application needs:

  1. A name and an icon URL. eToro shows both on its consent screen.

  2. The redirect URI, matched exactly by eToro. It is the redirect URL from docs/connectors/README.md — with the quickstart's default BOTSEON_PUBLIC_URL, that is:

    http://127.0.0.1:3000/api/oauth/etoro/callback
    

    eToro asks for an HTTPS callback in production, so serve the deployment over HTTPS before members connect.

  3. The scopes. Look their ids up with GET /api/v1/sso/scopes and add these four:

    ScopeMandatory on the consent screenWhy
    etoro-public:real:readyesevery read on the real account
    etoro-public:demo:readyesevery read on the demo account
    etoro-public:real:writenotrades and watchlist changes on the real account
    etoro-public:demo:writenotrades and watchlist changes on the demo account

    The connector's first sign-in asks for the two read scopes only; a member's Allow sending asks for the write pair as well. Nothing else is needed.

  4. eToro returns the clientId and the clientSecret once. Copy the secret now: it is never shown again, only replaced.

A new application is InDev, and its allowedGcids decide who may sign in to it. That is enough for a home deployment whose members are on that list. When eToro moves an application to Approved for every eToro user is not documented; ask eToro before you open the connector to members outside the list.

2. Enter the app

One command, with the secret on standard input — there is no flag that takes it (see docs/connectors/README.md):

printf %s "$CLIENT_SECRET" | botseon oauth-app set \
  --org <organisation id> --slug etoro \
  --client-id <the clientId from step 1> \
  --auth-url https://www.etoro.com/sso \
  --token-url https://www.etoro.com/api/sso/v1/token \
  --revoke-url https://www.etoro.com/api/sso/v1/token/revoke \
  --configured-by <your user id>

All three URLs are the ones eToro's discovery document (https://www.etoro.com/.well-known/openid-configuration) names. Set the revoke URL: without it a member's Remove deletes the stored tokens in Botseon but leaves the grant live at eToro. The client secret travels as HTTP Basic at the token and revoke endpoints (packages/connectors/src/oauth-profiles/etoro.ts).

botseon oauth-app show --org <organisation id> --slug etoro says whether an app is configured and under which client id; nothing prints the secret back. Never put either value in a bot's description, a memory, or anywhere else a model reads as ordinary text.

3. What each member sets

The plugin sheet asks one setting, eToro account: real or demo. It decides which of the member's two eToro accounts every portfolio, history, order and trade call goes to. It has no default on purpose — a typo never turns into real money.

Errors you may see while setting up

SymptomCauseFix
eToro's sign-in page says the redirect URI is not registeredthe redirect URI in step 1 differs from botseon oauth-app show's by any characterregister the exact string
the member's consent screen fails or shows no scopesthe application has none of the four scopes, or InDev excludes the member's GCIDadd the scopes, or the GCID to allowedGcids
Remove works but the member still sees Botseon at eTorono --revoke-urlrun step 2 again with it
a trade says "eToro refused the request for this connection"the member's grant lacks a write scopethe member presses Allow sending
the secret is losteToro never shows it againreplace it with POST /api/v1/sso/applications/{clientId}/client-secret, then run step 2 again — the old one stops working at once

Testing it

The nightly live check and its test application ("Botseon Test", botseon-test-ci-etoro) are in docs/operations/connector-live-setup/etoro.md.

Last verified against build 0ec94c7.