Tradovate API

Tradovate-Zugriffstoken-Fehler 400 “Invalid JSON”

Sie senden korrekte Zugangsdaten an den Access-Token-Endpunkt und erhalten trotzdem ein 400 “invalid JSON”. Hier sind alle Formatierungsfehler, die das auslösen, und die korrigierte Anfrage für curl, Python und JavaScript.

Geprüft vom PickMyTrade Trading Systems Team Zuletzt aktualisiert
· 7 Minuten Lesezeit
REST-Client mit einer 400-Antwort und der Fehlermeldung invalid JSON bei der Access-Token-Anfrage

Sie senden Ihren Benutzernamen und Ihr Passwort an den Access-Token-Endpunkt, und statt eines Tokens erhalten Sie ein schroffes 400 mit einer Meldung wie [Invalid JSON: expected '}' or ',', offset: 0x00000028]. Die Zugangsdaten sind in Ordnung. Das Konto funktioniert in der Web-Plattform. Woran liegt es also?

Hier die Kurzantwort: Der Server hat Ihre Anmeldung überhaupt nie gelesen. Ein 400 “invalid JSON” tritt in der Parsing-Phase auf, noch vor jeder Prüfung der Zugangsdaten. Irgendetwas an der Form Ihres Anfrage-Bodys, den Anführungszeichen, dem Header, der Art, wie Ihre Sprache ihn serialisiert hat, ist kein gültiges JSON. Beheben Sie die Formatierung, und exakt dieselben Zugangsdaten kommen problemlos durch.

Diese Anleitung geht jede Variante dieses Formatierungsfehlers durch, in der Reihenfolge, in der Sie am wahrscheinlichsten darauf stoßen, mit der korrigierten Anfrage für curl, Python und JavaScript.

Wie der Fehler tatsächlich aussieht

Die Anfrage geht an den Authentifizierungs-Endpunkt. In der Demo-Umgebung ist das:

POST https://demo.tradovateapi.com/v1/auth/accesstokenrequest

Bei Live ist es https://live.tradovateapi.com/v1/auth/accesstokenrequest. Gleicher Body, anderer Host, die beiden zu verwechseln ist ein eigenes Problem, erzeugt aber keine “invalid JSON”-Meldung, stellen Sie das also erst einmal zurück.

Ein erfolgreicher Aufruf liefert ein JSON-Objekt mit accessToken und expirationTime zurück. Ein fehlerhafter liefert HTTP 400 sowie einen Body, der die Beschwerde des Parsers und einen Byte-Offset benennt. Dieser Offset ist Ihr bester Hinweis, wir kommen später darauf zurück.

Die eigentliche Ursache: Ihr Body ist kein gültiges JSON

JSON hat strikte Regeln, die viel Code stillschweigend bricht. Die häufigsten Wege, wie ein Anmelde-Body ungültig wird:

  • Einfache Anführungszeichen. JSON verlangt doppelte Anführungszeichen um Schlüssel und String-Werte. Wenn Sie ein Python-Dict, ein JavaScript-Objekt oder einen Ruby-Hash direkt in die Anfrage drucken, erhalten Sie einfache Anführungszeichen, und es ist kein JSON mehr.
  • Ein nachgestelltes Komma. Ein Komma nach dem letzten Feld ist in den meisten Sprachen erlaubt und in JSON verboten.
  • Formular-Kodierung. Viele HTTP-Bibliotheken greifen standardmäßig auf application/x-www-form-urlencoded zurück. Der Server, der JSON erwartet, scheitert bereits am allerersten Byte.
  • Doppelte Kodierung. Sie serialisieren das Objekt einmal zu einem String und übergeben diesen String dann an einen Client, der ihn erneut serialisiert. Jetzt ist der Body ein zitierter String, kein Objekt.
  • Versteckte Zeichen. Eine Byte-Order-Mark oder ein aus einem Dokument oder Chat eingefügtes “typografisches Anführungszeichen” sieht auf dem Bildschirm identisch aus, bricht aber den Parser.

Jeder dieser Punkte erzeugt dieselbe Familie von 400-Fehlern. Gehen wir sie einzeln durch.

Lösung 1: Senden Sie echtes, doppelt zitiertes JSON

Beginnen wir mit dem Ziel. So sieht ein gültiger Body aus, überall doppelte Anführungszeichen, kein nachgestelltes Komma, cid als reine Zahl:

{ "name": "your_username", "password": "your_password", "appId": "My App", "appVersion": "1.0", "cid": 8, "sec": "your-api-secret", "deviceId": "123e4567-e89b-12d3-a456-426614174000" }

Nur name und password sind strikt erforderlich; der Rest identifiziert Ihre Anwendung und wird für vollen API-Zugriff benötigt. Vergleichen Sie das mit der defekten Version, die üblicherweise verschickt wird, einem Sprachobjekt, das als Text ausgegeben wurde:

{'name': 'your_username', 'password': 'your_password', 'appId': 'My App', 'cid': '8'}

Zwei Probleme dabei: durchgehend einfache Anführungszeichen, und cid in Anführungszeichen, wodurch es als String gelesen wird. Tauschen Sie die einfachen gegen doppelte Anführungszeichen und entfernen Sie die Anführungszeichen beim cid-Wert, und der Body validiert.

Nebeneinanderstellung eines defekten, einfach zitierten Anfrage-Bodys und eines korrigierten, doppelt zitierten JSON-Bodys

Lösung 2: Setzen Sie den Content-Type-Header

Gültiges JSON im Body reicht nicht aus. Sie müssen dem Server auch mitteilen, dass der Body tatsächlich JSON ist. Fügen Sie der Anfrage diese Header hinzu:

Content-Type: application/json
Accept: application/json

Ohne Content-Type: application/json greifen die meisten Clients auf Formular-Kodierung zurück, und der Server versucht, Formularfelder als JSON-Dokument zu parsen. Das Parsen schlägt bei Byte null fehl, und Sie erhalten ein 400. Allein dieser eine Header behebt einen überraschend großen Anteil der “invalid JSON”-Meldungen.

Lösung 3: Nutzen Sie in Python json= statt data=

Die requests-Bibliothek bringt hier ständig Nutzer zu Fall. Wenn Sie Ihr Dictionary über den Parameter data übergeben, wird es formularkodiert, und die doppelten Anführungszeichen erscheinen nie. Übergeben Sie es stattdessen über json, das serialisiert das Dict zu korrektem JSON und setzt den Content-Type-Header automatisch.

Falsch: requests.post(url, data=credentials)
Richtig: requests.post(url, json=credentials)

Mit json=credentials fassen Sie die Anführungszeichen nie von Hand an, die Bibliothek macht das korrekt. Stellen Sie nur sicher, dass credentials ein echtes Dict ist (mit cid als int), kein bereits als String serialisierter Blob. Haben Sie bereits json.dumps() darauf angewendet, verwerfen Sie das entweder und nutzen json=, oder behalten Sie den String und übergeben ihn über data= mit manuell gesetztem Content-Type-Header. Tun Sie nicht beides.

Header-Tab eines HTTP-Clients mit Content-Type application/json und einem rohen, sendebereiten JSON-Body

Lösung 4: Serialisieren Sie in JavaScript genau einmal

Bei fetch ist der klassische Fehler, JSON.stringify zu vergessen (wodurch der Body zum nutzlosen String [object Object] wird) oder es zweimal aufzurufen. Tun Sie es einmal und setzen Sie den Header:

fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json", "Accept": "application/json" },
  body: JSON.stringify(credentials)
})

Ist credentials bereits ein String, wickeln Sie ihn nicht erneut in JSON.stringify ein, der zweite Durchlauf escaped jedes Anführungszeichen, und der Server erhält einen einzigen langen, zitierten String, der kein Objekt ist.

Lösung 5: Escapen Sie bei curl Ihre Anführungszeichen

Die Shell frisst Anführungszeichen, ein roher JSON-Payload in der Befehlszeile braucht daher Sorgfalt. Escapen Sie die inneren doppelten Anführungszeichen mit Backslashes:

curl -X POST https://demo.tradovateapi.com/v1/auth/accesstokenrequest \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{ \"name\": \"your_username\", \"password\": \"your_password\", \"appId\": \"My App\", \"appVersion\": \"1.0\", \"cid\": 8, \"deviceId\": \"123e4567-e89b-12d3-a456-426614174000\", \"sec\": \"your-api-secret\" }"

Ein einfacherer Weg: Legen Sie das JSON in einer Datei ab und übergeben Sie -d @body.json, das umgeht die Shell-Zitierung vollständig. Beachten Sie, dass ein reines -d standardmäßig auf Formular-Kodierung setzt, der Header Content-Type: application/json also weiterhin explizit gesetzt werden muss.

Lösung 6: Prüfen Sie Ihre Feldtypen

Selbst sauberes JSON wird abgelehnt, wenn ein Wert den falschen Typ hat. Der häufigste Stolperstein ist cid: Es ist eine Ganzzahl, senden Sie also "cid": 8, niemals "cid": "8". Halten Sie die String-Felder (name, password, appId, appVersion, sec, deviceId) in Anführungszeichen und lassen Sie cid als reine Zahl. Hier die Kurzreferenz:

Feld Typ Erforderlich? Beispiel
namestringJa"trader_jane"
passwordstringJa"S3cureP@ss!"
appIdstringFür vollen Zugriff"My App"
appVersionstringFür vollen Zugriff"1.0"
cidintegerFür vollen Zugriff8
secstringFür vollen Zugriff"f03741b6-..."
deviceIdstringEmpfohlen"123e4567-..."

Enthält Ihr Passwort ein doppeltes Anführungszeichen, einen Backslash oder einen Zeilenumbruch, müssen diese Zeichen innerhalb des JSON-Strings escaped werden. Wenn Sie den Body von Ihrem Serialisierer erstellen lassen (die oben genannten Ansätze json= und JSON.stringify), erledigt das dies für Sie.

Den Offset im Fehler lesen

Wenn Ihnen die Meldung einen Offset wie 0x00000028 liefert, nutzen Sie ihn. Der Wert ist hexadezimal, 0x28 entspricht dezimal 40, und er zeigt auf das Byte, an dem der Parser gestoppt hat. Zählen Sie im exakten von Ihnen gesendeten Body nach (protokollieren Sie ihn, raten Sie nicht) und untersuchen Sie dieses Zeichen. Ein einfaches Anführungszeichen, ein Komma ohne nachfolgenden Inhalt oder ein Steuerzeichen sitzt fast immer genau dort. Ein Offset von 0x0 ist anders: Er bedeutet, dass der Parser nichts zum Lesen fand, Ihr Body also leer war oder den Client nie verlassen hat.

Die Lösung überprüfen

Sobald der Body sauber und der Header gesetzt ist, führen Sie die Anfrage erneut aus. Ein funktionierender Aufruf liefert HTTP 200 mit einem JSON-Payload, das Ihren accessToken, eine userId und eine expirationTime von rund 90 Minuten enthält. Kopieren Sie dieses Token in einen Authorization: Bearer <token>-Header für jeden Folgeaufruf.

Erfolgreiche 200-Antwort mit einem Access Token und einer Ablaufzeit aus der Access-Token-Anfrage

Erhalten Sie weiterhin dasselbe 400, protokollieren Sie die rohen Bytes dessen, was Sie tatsächlich senden, nicht das, was Sie zu senden glauben, und vergleichen Sie es mit dem gültigen Beispiel oben. Der Unterschied ist fast immer ein Anführungszeichen oder ein Komma.

Wenn das JSON sauber ist und es trotzdem scheitert

Ist der Parser zufrieden, die Anfrage schlägt aber weiterhin fehl, haben Sie das Formatierungsproblem hinter sich gelassen und stehen vor einem Authentifizierungs- oder Umgebungsproblem:

  • Falscher Host. Demo-Zugangsdaten auf dem Live-Host (oder umgekehrt) scheitern selbst bei perfektem JSON.
  • Falsches API-Secret oder falsche cid. Ein falsches sec oder cid liefert ein 400, das nichts mit der Formatierung zu tun hat, der Body wurde einwandfrei geparst, die Werte stimmen nur nicht überein.
  • Sitzungslimit oder Ratenlimit. Wiederholtes Bombardieren des Endpunkts kann Sie aussperren. Sehen Sie bei wiederholten Fehlern unter Last unseren Hinweis zum Tradovate-API-429-Ratenlimit.
  • Abgelaufenes Token bei späteren Aufrufen. Das Token selbst hält nur rund 90 Minuten; erneuern Sie es, bevor es abläuft, statt sich jedes Mal neu zu authentifizieren. Siehe Tradovate-API-401-nicht-autorisiert (abgelaufenes Token).

Vereinfachen Sie die Authentifizierung mit PickMyTrade

Möchten Sie lieber nicht Token-Anfragen, 90-Minuten-Abläufe und JSON-Zitierung ständig im Blick behalten? PickMyTrade verbindet Ihr Tradovate-Konto und leitet Ihre TradingView-Alerts zu Live-Orders weiter, die Authentifizierung und Sitzungsverwaltung laufen im Hintergrund, sodass Sie keinen Auth-Code debuggen müssen.

Verzichten Sie ganz auf Auth-Code

PickMyTrade verbindet Ihr Tradovate-Konto und übernimmt Token-Anfragen, Erneuerungen und JSON-Formatierung im Hintergrund, sodass Ihre Alerts geroutet werden, ohne dass Sie auch nur einen einzigen Auth-Aufruf debuggen müssen.

Starten Sie Ihre kostenlose 5-Tage-Testversion

Häufig gestellte Fragen

Das 400 wird ausgelöst, bevor der Server Ihre Anmeldung überhaupt prüft. Der Body ist kein gültiges JSON, oder er wurde nicht als JSON gesendet. Achten Sie auf einfache Anführungszeichen, ein nachgestelltes Komma, Formular-Kodierung, oder einen fehlenden Content-Type: application/json-Header. Beheben Sie den Body, und dieselben Zugangsdaten authentifizieren sich einwandfrei.

Das ist die Byte-Position, an der der JSON-Parser gestoppt hat, in Hexadezimalschreibweise. 0x28 entspricht dezimal 40, schauen Sie sich also das etwa 40. Zeichen des exakten gesendeten Bodys an, dort ist die Syntax gebrochen. Ein Offset von 0x0 bedeutet, dass der Body leer war oder nie ankam.

Eine Zahl. Senden Sie "cid": 8, nicht "cid": "8". Werden Anführungszeichen gesetzt, wird aus einem Ganzzahlfeld ein String, was die Anfrage ablehnen lassen kann, selbst wenn das JSON ansonsten gültig ist.

Der Explorer erstellt für Sie einen sauberen, doppelt zitierten Body und setzt den Header. Ihr Client gibt möglicherweise ein Sprachobjekt mit einfachen Anführungszeichen aus, kodiert die Daten als Formular, oder kodiert den String doppelt. Kopieren Sie den exakten Body des Explorers und gleichen Sie ihn Byte für Byte ab.

Ja. Escapen Sie die inneren doppelten Anführungszeichen mit Backslashes, oder umschließen Sie den gesamten Payload mit einfachen Anführungszeichen, damit die Shell die inneren doppelten Anführungszeichen nicht anfasst. Den Body aus einer Datei mit -d @body.json zu übergeben umgeht das Zitier-Problem komplett.

Diese Anleitung dient ausschließlich zu Bildungs- und Informationszwecken und stellt keine Finanz-, Anlage- oder Handelsberatung dar. Der Handel mit Futures und anderen gehebelten Produkten birgt ein erhebliches Verlustrisiko und ist nicht für jeden Anleger geeignet. PickMyTrade ist eine unabhängige Automatisierungsplattform eines Drittanbieters und steht in keiner Verbindung zu Tradovate, Inc. oder Bookmap und wird von diesen weder unterstützt noch gesponsert. Alle zugehörigen Namen, Logos und Marken sind Eigentum ihrer jeweiligen Inhaber. Funktionen und Abläufe der Plattform ändern sich mit der Zeit, bestätigen Sie den aktuellen Prozess daher stets in der offiziellen Plattform-Dokumentation, bevor Sie handeln.