Claude API 2026-10-21 und die neuen Anthropic-SDKs: Der Key wandert in den Authorization-Header, und ein Gateway, das X-Api-Key liest, verliert ihn
Wer die API direkt aufruft, muss wegen des neuen Headers nichts ändern. Ein Gateway muss beide Varianten lesen, weil Claude Code und jeder festgepinnte Service weiter die alte schicken, und ein SDK-Client weigert sich jetzt, Gateway-Token und Upstream-Key gleichzeitig zu verwenden.
Inhalt
Am 21. Oktober hat Anthropic die API-Version 2026-10-21 veröffentlicht, dazu neue Major-Versionen aller sieben SDKs und der ant CLI, die alle standardmäßig die neue Version senden. Der Großteil des Migration Guides sortiert Typen um. Eine Zeile darin ändert, was über die Leitung geht: Die SDKs schicken deinen API-Key jetzt als Authorization: Bearer statt als X-Api-Key.
Für einen Client, der die API direkt aufruft, ändert diese Zeile nichts, denn die API liest den Key aus beiden Headern. Brechen tut es dazwischen. Ein Gateway, Proxy oder eine eigene Middleware, die X-Api-Key liest, findet den Key nicht mehr, und ein Client, der bisher ein Gateway-Token plus einen Upstream-Key mitschickte, lässt sich gar nicht mehr erzeugen. Kein Flag holt das alte Verhalten zurück. Und die alte Form verschwindet nicht: Claude Code 2.1.307 schickt sie weiterhin, ein Gateway bekommt also am selben Tag beide. Ich habe beide SDK-Generationen und Claude Code gegen einen lokalen Listener laufen lassen, der Header mitschreibt, mit Dummy-Keys und ohne Weiterleitung, um zu sehen, was bei einem Gateway ankommt.
Was schickt das neue Anthropic SDK an ein Gateway?
Einen anderen Credential-Header und einen anderen Versions-String. Das sind die Header, die ich mitgeschrieben habe; die Top-Level-Keys im Body waren in beiden Generationen gleich. So sah der Listener denselben messages.create-Aufruf mit gesetztem api_key:
anthropic 1.17.0 x-api-key: sk-ant-FAKE-key anthropic-version: 2023-06-01
anthropic 2.1.0 authorization: Bearer sk-ant-FAKE-key anthropic-version: 2026-10-21
sdk (JS) 0.137.0 x-api-key: sk-ant-FAKE-key anthropic-version: 2023-06-01
sdk (JS) 1.1.0 authorization: Bearer sk-ant-FAKE-key anthropic-version: 2026-10-21Bei den neuen Versionen fehlt der X-Api-Key-Header komplett. Ein Gateway, das seine eigenen Nutzer über diesen Header authentifiziert, sieht einen Request ohne Credential. Lehnt es solche Requests ab, gibt es am Deploy-Tag ein 401, und das ist der gute Fall. Riskant ist ein Design, das einen Request trotzdem weiterleitet, wenn das eigene Credential fehlt: Dann kann jede Zuordnung pro Nutzer, die an X-Api-Key hing, verloren gehen, und der Request geht mit dem raus, was der Client in Authorization gesteckt hat. Das ist ein Designrisiko, das du in deinem Gateway prüfen solltest, nicht etwas, das ich beobachtet habe.
Der Listener folgt derselben Idee wie der in der Anleitung zum Claude-Code-Gateway, mit einer Änderung: Statt mit 503 zu antworten, gibt er ein Stub-message-Objekt zurück, damit das SDK eine Antwort parst und sauber beendet. Richte einen Client mit base_url= und einem Fake-Key darauf, und du kannst beide Majors in einer Minute vergleichen.
Warum lehnt ein Anthropic-SDK-2.x-Client Gateway-Token und API-Key zusammen ab?
Weil sich Key und Auth-Token jetzt einen Header teilen, kann ein Client nur noch ein Credential halten. In 1.x schickte ein Client, der mit beidem gebaut wurde, auch beides: X-Api-Key für den Key und Authorization für das Token. Dieses Paar war ein verbreitetes Gateway-Setup: Das Token authentifiziert dich beim Gateway, der Key geht upstream weiter. In 2.1.0 scheitert derselbe Konstruktor schon vor dem ersten Request:
ValueError: Pass at most one of `api_key=`, `auth_token=`, `credentials=`, `config=`, or `profile=`. Received `api_key=`, `auth_token=`.TypeScript 1.1.0 wirft für apiKey plus authToken einen TypeError mit demselben Wortlaut. Der Guide nennt die Entsprechungen: ArgumentException in C#, IllegalStateException bei build() in Java, InvalidArgumentException in PHP, ArgumentError in Ruby. Go tanzt aus der Reihe: NewClient gibt keinen Fehler zurück, stattdessen scheitert jeder Request, den dieser Client macht.
Der dokumentierte Weg, das Paar zu behalten: das Gateway-Token als Credential übergeben und den Key als normalen Header ergänzen. Mit 2.1.0 kamen damit beide Header an, das Token in Authorization und der Key in X-Api-Key:
client = anthropic.Anthropic(
auth_token=gateway_token,
default_headers={"X-Api-Key": upstream_key},
base_url=gateway_url,
)Die andere Hälfte ist Sache des Gateways. Der Guide sagt klar, dass das Gateway den eingehenden Authorization-Header mit seinem Token vor dem Weiterleiten entfernen soll, weil „the Claude API expects one credential per request.“ Ein Gateway, das alles durchreicht, schickt jetzt zwei.
Bei Umgebungsvariablen gibt es eine leisere Variante davon. Laut Guide nehmen die neuen Clients den Key und loggen einmal eine Warnung, wenn im Code nichts übergeben wird und sowohl ANTHROPIC_API_KEY als auch ANTHROPIC_AUTH_TOKEN gesetzt sind. Hat sich dein Deployment darauf verlassen, dass beide beim Gateway ankommen, fällt eines davon weg.
Wie bringst du einen Anthropic-SDK-2.x-Client dazu, wieder X-Api-Key zu senden?
Pro Sprache. Einen globalen Schalter gibt es nicht. In Python ist der Fix aus dem Guide ein auth-Hook am HTTP-Client, der bei jedem Request läuft, auch bei Retries. Mit 2.1.0 hat er den Key zurückverschoben: Der Listener sah x-api-key und kein authorization. Importiert wird httpx2, das das SDK schon in 1.17.0 verwendet hat, nicht httpx.
import httpx2
from anthropic import Anthropic, DefaultHttpxClient
def send_x_api_key(request: httpx2.Request) -> httpx2.Request:
if request.headers.get("Authorization") == f"Bearer {api_key}":
del request.headers["Authorization"]
request.headers["X-Api-Key"] = api_key
return request
client = Anthropic(
api_key=api_key,
base_url=gateway_url,
http_client=DefaultHttpxClient(auth=send_x_api_key),
)In TypeScript sind es zwei Default-Header, und Authorization: null verhindert, dass der Key doppelt rausgeht. Version 1.1.0 schickte damit nur x-api-key:
const client = new Anthropic({
apiKey,
baseURL: gatewayUrl,
defaultHeaders: { "X-Api-Key": apiKey, Authorization: null },
});Go nutzt option. plus option., Java putHeader statt apiKey, PHP und Ruby eine Middleware. Zwei Details im Guide übersieht man leicht. In PHP nicht extraHeaders dafür verwenden: Jeder Request mit eigenen extraHeaders ersetzt die des Clients, und jeder Beta-Endpoint hat welche. Und die ant CLI kann keinen Header hinzufügen, ein Gateway vor ant muss also Authorization lernen. Eine Lösung auf Client-Seite gibt es nicht.
Auch Code, der Header pro Request setzt, ändert seine Bedeutung, und zwar in beide Richtungen. Laut Guide ersetzt in Python, TypeScript, Go und PHP ein X-Api-Key pro Request nicht mehr den Key des Clients; beide gehen raus, also gehört der Override in Authorization. Und wenn dein Code X-Api-Key gelöscht hat, um nur ein Auth-Token zu schicken, streich diese Löschung ersatzlos, statt sie auf Authorization umzubiegen: Wer Authorization entfernt, entfernt das Token.
Wechselt auch Claude Code zu Authorization: Bearer?
In 2.1.307 nicht. Claude Code steht nicht auf der SDK-Liste, und 2.1.307, das Release, das /claude-api api-version eingeführt hat, um deinen Code auf 2026-10-21 zu migrieren, schickte noch die alte Form, als ich es mit gesetztem ANTHROPIC_API_KEY auf den Listener gerichtet habe:
POST /v1/messages?beta=true
user-agent: claude-cli/2.1.307 (external, sdk-cli)
anthropic-version: 2023-06-01
x-api-key: sk-ant-FAKE-keyFür einen API-Key gilt die Zuordnung aus dem Gateway-Artikel also weiter: ANTHROPIC_API_KEY geht als x-api-key raus. (ANTHROPIC_AUTH_TOKEN habe ich nicht erneut getestet; laut Gateway-Doku geht es als Authorization: Bearer raus.) Manche SDK-Clients ändern ihr Verhalten gar nicht: Laut Guide schicken die Foundry-Clients weiter x-api-key, und die Bedrock-Mantle-Clients schickten schon vorher ein Bearer-Token. Ein Gateway, das Entwickler in Claude Code und Services auf den neuen SDKs bedient, bekommt am selben Tag beide Formen, und zwar so lange, wie irgendetwas Python unter 2.0 oder TypeScript unter 1.0 pinnt.
Was macht die Claude API 2026-10-21 mit temperature auf Sonnet 4.6?
Sie lehnt den Parameter ab. Unter 2026-10-21 gibt ein Messages- oder Batch-Request mit temperature, top_p oder top_k ein 400 zurück, selbst mit dem Default-Wert. Auf Claude 4.7 und neuer ändert sich am Sampling selbst nichts, weil diese Modelle ohnehin nur die Defaults akzeptieren, wie die Notizen zur Opus-5.5-Migration beschrieben haben. Ein Request, der einen Default ausdrücklich mitschickt, muss ihn trotzdem streichen. Auf Modellen, die noch andere Werte annehmen, etwa Sonnet 4.6, ist eine niedrige temperature für Klassifikation oder Bewertung weg, und laut Guide gibt es keinen Ersatz dafür.
Die SDK-Seite hat sich früher bewegt, als man denkt. In meinen Läufen war temperature schon in Python 1.17.0 kein Keyword-Argument von messages.create mehr, und 2.1.0 ist gleich: Beide werfen dafür TypeError. Code, der sie trotzdem schickt, tut das über extra_body, und das reichten beide Versionen unverändert durch. Mit 2.1.0 macht die Default-Version daraus ein 400 auf dem Server.
Der Guide lässt die Wahl, den Parameter zu streichen oder diesen Request auf 2023-06-01 zu lassen. Mit 2.1.0 geht das pro Request, ohne das ganze SDK zu pinnen; der Listener sah anthropic-version: 2023-06-01 und temperature im Body:
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=256,
messages=messages,
extra_headers={"anthropic-version": "2023-06-01"},
extra_body={"temperature": 0.0},
)Dieser Pin funktioniert nur hinter einem Gateway, das anthropic-version unverändert weiterleitet, wie es der Kompatibilitätsguide für Gateways verlangt. Ein Gateway, das Requests mit seinem eigenen SDK neu baut oder allen Requests upstream dieselbe Version aufzwingt, entscheidet das für jeden Client dahinter, und am Tag seines Upgrades wird das temperature: 0 eines alten Clients zum 400. Auf der Client-Seite macht der Pin auch nichts rückgängig: Der Credential-Header ist eine Änderung im SDK, nicht in der API-Version.
Ich würde den Pin als Brücke mit Ablaufdatum sehen. Meine Einschätzung: Wenn der Score oder das Label wirklich an temperature 0 hängt, miss dieselbe Stichprobe jetzt mit 1.0, solange du beides noch vergleichen kannst, und lass die Zahlen entscheiden.
Was geht beim Upgrade der Anthropic-SDKs sonst noch kaputt?
Ein paar Dinge, die später scheitern, ohne Fehlermeldung oder nur bei einem Teil des Traffics:
- Der Importpfad in Go. Das SDK heißt jetzt
github., also ändert sich jeder Import, und Code auf dem alten Pfad bleibt auf v1. Diecom/ anthropics/ anthropic-sdk-go/ v2 antCLI ist der heiklere Fall: Ihr Modulpfad endet ebenfalls auf/v2, und der altego install-Pfad installiert weiter die neueste v1, ohne Fehler oder Warnung. Ein Build-Skript, das „upgegradet“ hat, kann also noch das alte Format schicken. - Der Gesprächsverlauf. Unter
2026-10-21geben laut Guide eindocument-Block direkt in einerassistant-Nachricht und nicht leerecitationsauftext-Blöcken in eineruser-Nachricht beide ein 400 zurück, auch beim Token Counting und in Batches. Auffallen wird das in einem Gateway oder einer App, die den Verlauf neu aufbaut und dabei Blöcke zwischen Rollen verschiebt. - TypeScript-Plattformpakete.
@anthropic-ai/,bedrock-sdk vertex-sdkund die anderen Plattformpakete brauchen die passende Core-Major-Version, sonst installiert der Paketmanager eine zweite Kopie von@anthropic-ai/sdk. - Bedrock vor Claude 4.7. Auf Amazon Bedrock funktioniert
2026-10-21nur für Claude 4.7 und neuer. Aufrufe an Opus 4.6 oder älter bleiben dort auf dem alten SDK oder schicken weiter die alte Version.
Was sollte ein Gateway-Betreiber für die neuen Anthropic-SDKs zuerst reparieren?
Das Gateway, nicht die Clients. Clients unter den neuen Majors zu pinnen, verschafft nur Zeit für Code, den du selbst kontrollierst, und das ist selten aller Code: Der Dependency-Bot eines anderen Teams öffnet den Upgrade-PR, oder ein neuer Service startet gleich auf dem aktuellen SDK. Claude Code schickt derweil weiter x-api-key. Das Gateway ist der einzige Ort, der alle diese Clients sieht, also ist es der Ort, an dem beide Formen akzeptiert werden.
Was „beide akzeptieren“ heißt, hängt davon ab, wessen Key nach oben geht. Hält das Gateway das Upstream-Credential, lies das Gateway-Credential des Aufrufers aus X-Api-Key oder, falls das fehlt, aus Authorization nach Bearer , prüfe es, entferne beide Header und setz vor dem Weiterleiten deinen eigenen. Bringen Aufrufer ihren eigenen Upstream-Key neben einem Gateway-Token mit, ist die dokumentierte Aufteilung: Token in Authorization, Key in X-Api-Key. Authentifiziere das Token, entferne Authorization, leite den Key weiter. So oder so: Leg fest, was passiert, wenn beide Header ankommen und nicht übereinstimmen, statt die Reihenfolge der Header entscheiden zu lassen. Leite anthropic-version so weiter, wie es ankam, und logge, welchen Header jeder Request benutzt hat. So siehst du, wann die alte Form ausläuft, und erwischst einen Pfad, der trotzdem weiterleitet, bevor er dich die Zuordnung kostet. Dann richte je einen Client jeder Generation auf einen Listener, der Header mitschreibt, bevor der erste Service ohne dein Zutun upgradet.
01 / Diskussion
Hier gibt es keine Kommentarspalte. Diskussionen laufen auf X.
02 / Weitere Artikel
Claude Code in tmux: send-keys sieht keinen Permission-Prompt, claude agents --json schon
Ein tmux-Pane ist ein guter Ort, um einen Claude-Code-Agenten zu hosten, und eine schlechte Schnittstelle, um ihn zu steuern. In meinem Test verschwand eine Aufgabe, die ich in ein Pane mit offenem Permission-Prompt getippt hatte, und das Enter dahinter genehmigte den wartenden Befehl. Status, Wartegrund und das Ende eines Turns meldet Claude Code inzwischen selbst. Der Bildschirm darf also wieder einfach ein Bildschirm sein.
Claude Code /auto-mode-setup: dem Auto-Mode-Classifier deine Umgebung beibringen und prüfen, welches Modell deine Aktionen wirklich bewertet
Das Setup entwirft eine Vertrauensliste aus deinem Repo und den letzten Befehlen deines Agenten, und dieser Entwurf ersetzt den mitgelieferten Environment-Text, statt ihn zu ergänzen. Lies ihn als Diff gegen die Defaults. Und prüf, welches Modell deine Aktionen bewertet, bevor du Zeit in die Wahl eines Modells steckst.
Claude Code hinter einem LLM-Gateway: Die Credential entscheidet, wer zahlt, und ohne sie bekommt der Proxy deinen claude.ai-Login
Zwölf Beta-Werte pro Request mit Abo-Login, zehn mit Gateway-Token, und das Paar, das verschwindet, sagt mehr als die Tabellen in der Doku. Was ein Gateway unverändert durchreichen muss, welcher Default still teurer wird und warum ein Pinning per allowedProviders Entwicklern auch ihren eigenen Debugging-Listener nimmt.