Tradovate API

Come risolvere il 401 Access Denied di user/syncrequest sul WebSocket di Tradovate

Aprite un socket, lanciate user/syncrequest, e ottenete un secco 401 Access is denied. Il socket non è mai stato autorizzato, ecco esattamente l'handshake che lo risolve.

Verificato dal Trading Systems Team di PickMyTrade Ultimo aggiornamento
· Lettura di 7 minuti
Log dei frame WebSocket di Tradovate che mostra user/syncrequest restituire una risposta 401 Access is denied

Avete aperto un WebSocket, lanciato user/syncrequest, e invece di un flusso di dati su conto e ordini avete ricevuto un secco 401 con “Access is denied.” Non c'è nulla che non va nel vostro login e nulla è rotto nel conto. Il socket semplicemente non è mai stato autorizzato, quindi il server tratta ogni richiesta su di esso come anonima. La soluzione è un ordine specifico di operazioni: prendete un token di accesso dall'endpoint di autenticazione REST, consegnatelo al socket in un frame authorize, attendete la risposta di successo, e solo allora inviate user/syncrequest. Rispettate questa sequenza e il 401 sparisce.

Questo inganna quasi tutti la prima volta che collegano il socket di Tradovate a mano, di solito perché cercano di autenticarsi come funziona REST. I WebSocket non funzionano così qui. Ripercorriamo esattamente cosa succede e la via pulita per uscirne.

Come si presenta davvero l'errore

Nel vostro log dei frame vedrete il socket connettersi, arrivare il frame open, poi il vostro user/syncrequest tornare immediatamente con un rifiuto. Si presenta più o meno così:

<-- o
--> user/syncrequest
1

<-- a[{"i":1,"s":401,"d":"Access is denied"}]

L'indizio rivelatore è lo stato 401 abbinato a Access is denied sul frame di richiesta. Se non avete mai visto una risposta di stato 200 a un frame authorize prima di questo, ecco la vostra risposta: il socket non è autenticato.

Perché il socket restituisce un 401

In realtà ci sono solo una manciata di cause radice, e si accumulano in un ordine prevedibile.

1. Il socket non è mai stato autorizzato

Questa è la causa principale. Una connessione WebSocket grezza a Tradovate non è autenticata. Aprirla e inviare immediatamente user/syncrequest equivale a entrare in un club per soci e ordinare da bere senza mostrare la tessera. Dovete inviare esattamente un frame authorize per connessione, contenente un token di accesso valido, prima che qualsiasi altra cosa possa passare.

2. Avete provato a ottenere il token tramite il socket

Un errore comune è tentare di chiamare accessTokenRequest tramite il WebSocket stesso. Quell'endpoint vive sul lato REST. Il token viene coniato via HTTPS, e poi presentato al socket. Il socket non emette mai token.

3. Un parametro environment nella richiesta del token

Se avete copiato un corpo di richiesta da qualche parte e include "environment": "demo" (o "live"), rimuovetelo. Quel campo non è accettato da accessTokenRequest e può mandare fuori strada l'intera richiesta. L'ambiente è deciso dall'host che chiamate, non da un parametro.

4. Un conto reale senza deviceId o con un dispositivo non approvato

Il demo è permissivo. Il reale no. Su un conto finanziato/reale dovete inviare un deviceId stabile quando richiedete il token, e il dispositivo deve essere approvato tramite il flusso di conferma che Tradovate esegue per la sicurezza a due fattori. Se saltate questo passaggio, il token reale che ottenete non autorizzerà il socket reale.

5. Il token è scaduto

Se prima tutto funzionava e poi ha iniziato a restituire 401 dal nulla, il token è scaduto. I token di accesso sono limitati nel tempo, quindi un socket di lunga durata alla fine vedrà un 401 come se non fosse mai stato autorizzato. Questo è un problema di rinnovo, non di configurazione.

La soluzione, passo dopo passo

1

Ottenete un token di accesso da REST

Inviate in POST le vostre credenziali all'endpoint di autenticazione via HTTPS. Usate l'host corrispondente al conto desiderato:

POST https://demo.tradovateapi.com/v1/auth/accessTokenRequest   (simulato)
POST https://live.tradovateapi.com/v1/auth/accessTokenRequest   (finanziato)

Content-Type: application/json
{
  "name": "your-username",
  "password": "your-password",
  "appId": "YourAppName",
  "appVersion": "1.0",
  "cid": 0000,
  "sec": "your-api-secret",
  "deviceId": "a-stable-unique-id"
}


La risposta vi consegna una stringa accessToken (più un timestamp di scadenza). È quel token che vuole il socket. Notate che in quel corpo non c'è alcun campo environment, l'host demo vi dà un token demo, l'host reale vi dà un token reale.

2

Aprite il socket e attendete il frame open

Connettetevi all'URL WebSocket corrispondente all'ambiente del vostro token:

wss://demo.tradovateapi.com/v1/websocket   (simulato)
wss://live.tradovateapi.com/v1/websocket   (finanziato)


Nel momento in cui la connessione è attiva, il server invia un frame open a un solo carattere: o. Non inviate nulla finché non lo avete visto. Un token demo sul socket reale (o viceversa) è un suo modo silenzioso di guadagnarsi un 401, quindi mantenete la coppia corrispondente.

3

Inviate il frame authorize

I frame su questo socket sono testo semplice: un endpoint, un id di richiesta, una riga vuota per la query string, poi il corpo, ciascuno separato da un a-capo. Il frame authorize mette il token nel corpo:

authorize
0

YOUR_ACCESS_TOKEN


Scritto come stringa unica, questo diventa authorize\n0\n\nYOUR_ACCESS_TOKEN. Il server risponde con un frame di dati e uno stato che vi interessa davvero:

a[{"i":0,"s":200}]

Lo stato 200 significa che il socket ora è autenticato per tutta la durata della connessione. Se qui ottenete qualcosa di diverso da 200, fermatevi: il token è il problema, e la sincronizzazione non si aggiusterà da sola più avanti.

4

Ora inviate user/syncrequest

Con il socket autorizzato, la stessa chiamata che falliva ora passa senza problemi. Inviatela con il successivo id di richiesta e un corpo vuoto per sincronizzare tutto ciò a cui l'utente ha accesso:

user/syncrequest
1



Questo è user/syncrequest\n1\n\n. Riceverete indietro lo snapshot iniziale di conti, posizioni, ordini, fill e saldi in contanti, e da quel momento il socket trasmette aggiornamenti incrementali man mano che cambiano. user/syncrequest è esclusivo del WebSocket, non ha un equivalente REST, ed è proprio per questo che il socket deve prima essere autorizzato.

5

Mantenete la connessione attiva

Una volta autorizzati, inviate un frame di heartbeat, un array JSON vuoto, [], ogni pochi secondi (circa ogni 2,5 secondi) affinché il server non vi disconnetta. Anche il server invia i propri heartbeat. Se smettete di ricevere notizie per circa dieci secondi, trattate il socket come morto, riconnettetevi ed eseguite di nuovo il passaggio di autorizzazione sulla nuova connessione.

POST REST verso accessTokenRequest che restituisce un accessToken, senza parametro environment nel corpoFrame authorize WebSocket contenente il token di accesso seguito da una risposta di successo con stato 200

Conti reali: il controllo di deviceId e permessi

Se il demo funziona perfettamente e il reale è l'unico posto in cui incontrate il 401, la causa è quasi sempre sul lato dell'approvazione del dispositivo piuttosto che nel vostro codice. Due cose da confermare.

Primo, assicuratevi che l'accesso API sia effettivamente abilitato sul conto e che la chiave abbia il permesso di fare ciò che state chiedendo. Nella web app di Tradovate questo si trova nelle impostazioni account, nella sezione che gestisce il componente aggiuntivo API Access e i permessi della chiave. (Confermate l'etichetta esatta nella vostra versione attuale, il testo e la posizione di questa schermata del componente aggiuntivo vengono modificati nel tempo.)

Impostazioni account di Tradovate che mostrano il componente aggiuntivo API Access e i controlli dei permessi della chiave API

Secondo, inviate un deviceId che resti lo stesso tra le esecuzioni e approvatelo. Il reale impone una sicurezza a due fattori basata sul dispositivo; un deviceId nuovo di zecca o mancante attiva un passaggio di approvazione che, finché non lo risolvete, lascia il token incapace di autorizzare il socket reale. Generate un identificatore stabile per la vostra app, riutilizzatelo ogni volta, e confermatelo tramite l'email che invia Tradovate.

Continuate a ricevere 401? Seguite questa checklist

Controllo Cosa confermare
Authorize è arrivato per primoAvete inviato un frame authorize e visto s:200 prima di qualsiasi altra richiesta.
Origine del tokenIl token proveniva da REST /auth/accessTokenRequest, non dal socket.
Nessun campo environmentIl corpo della richiesta del token non ha il parametro environment.
L'host corrisponde al tokenToken demo sul socket demo, token reale sul socket reale, mai incrociati.
deviceId (reale)È stato inviato un deviceId stabile e il dispositivo è approvato.
Freschezza del tokenIl token non è scaduto da quando lo avete ottenuto.
Permessi della chiaveL'accesso API è abilitato e la chiave può leggere/instradare su quel conto.

Se funzionava e poi si è rotto a metà sessione, andate direttamente alla durata del token. I token di accesso non durano per sempre, e un socket rimasto aperto per un po' inizierà a restituire 401 nel momento in cui il token sottostante scade. Rinnovate prima della scadenza invece di aspettare gli errori. E se è la primissima richiesta di token a fallire, tornate indietro per verificare l'accesso API e la generazione di una chiave prima di toccare affatto il socket.

Saltate del tutto l'idraulica del socket

Costruire a mano l'handshake di autenticazione, gli heartbeat, l'approvazione del dispositivo e il rinnovo del token sono un sacco di parti mobili solo per instradare un ordine. Se state collegando Tradovate ad alert di TradingView o a una strategia, PickMyTrade gestisce per voi l'intero livello di connessione, sessioni autorizzate, gestione dei dispositivi reali e rinnovo dei token inclusi, così voi inviate un segnale e viene eseguito il trade.

Saltate l'idraulica del socket

PickMyTrade gestisce per voi l'intero livello di connessione, sessioni autorizzate, gestione dei dispositivi reali e rinnovo dei token inclusi, così voi inviate un segnale e viene eseguito il trade.

Iniziate la vostra prova gratuita di 5 giorni

Domande frequenti

Perché la connessione WebSocket non è mai stata autorizzata. user/syncrequest funziona solo su un socket autorizzato. Inviate prima un frame authorize con un token di accesso valido, attendete la risposta con stato 200, poi inviate syncrequest.

Dall'endpoint REST /auth/accessTokenRequest, non dal socket. Inviate in POST le vostre credenziali via HTTPS, leggete accessToken dalla risposta JSON, e consegnate quel token al socket nel frame authorize.

No. environment non è un campo valido per quella richiesta e può farla fallire. Demo contro reale è deciso dall'host che chiamate, l'host demo per il conto simulato, l'host reale per quello finanziato.

Il reale impone un'approvazione del dispositivo che il demo salta. Inviate un deviceId stabile quando richiedete il token reale, approvate il dispositivo dalla conferma che Tradovate vi invia via email, e assicuratevi di autorizzare il socket reale con un token reale.

Il token è scaduto. I token sono limitati nel tempo, quindi un socket di lunga durata alla fine incontrerà un 401 come se non fosse mai stato autorizzato. Rinnovate il token prima che scada e riautorizzate su una sessione nuova.

Questa guida ha finalità esclusivamente educative e informative e non costituisce consulenza finanziaria, di investimento o di trading. Il trading di futures e altri prodotti a leva comporta un rischio sostanziale di perdita e non è adatto a tutti gli investitori. PickMyTrade è una piattaforma di automazione di terze parti indipendente e non è affiliata, sostenuta o sponsorizzata da Tradovate, Inc. o Bookmap. Tutti i nomi, i loghi e i marchi correlati sono di proprietà dei rispettivi titolari. Le funzionalità e i passaggi della piattaforma cambiano nel tempo, quindi verificate sempre la procedura attuale nella documentazione ufficiale della piattaforma prima di agire.