API-Referenz
SUB&SUB stellt einen Multi-Provider-Relay unter https://api.subnsub.com/v1 bereit. OpenAI-Clients sprechen /v1/chat/completions an; Anthropic-Clients /v1/messages. Derselbe sk-cf-...-Key routet beide — du wählst das Modell im Request-Body und der Relay wählt das Upstream.
Schnellstart
Drei Dinge, die du brauchst:
- Base-URL:
https://api.subnsub.com/v1(OpenAI-Clients) oderhttps://api.subnsub.com(Anthropic-Clients — das SDK hängt/v1/messagesselbst an) - API-Key:
sk-cf-..., ausgestellt über die Konsole - Modell: eines der 21 verifizierten Modelle — z. B.
gpt-5.4-minioderclaude-haiku-4.5
Authentifizierung
Jede Anfrage muss einen Authorization: Bearer sk-cf-...-Header tragen. Keys werden über die Konsole ausgestellt und als SHA-256-Hashes gespeichert — sobald du den Erstellungsbildschirm verlässt, ist der Klartext für immer weg, also speichere ihn sofort.
Endpoints
POST /v1/chat/completions
Sende eine Chat-Completion-Anfrage. Die Request-Struktur entspricht der OpenAI Chat Completions API — die OpenAI-SDKs funktionieren unverändert.
| Parameter | Typ | Beschreibung |
|---|---|---|
| model | string | Eine der verifizierten Modell-IDs. |
| messages | array | Konversationsverlauf. Jedes Element: {role, content} mit role ∈ system / user / assistant. |
| stream | boolean | Wenn true, wird die Antwort als SSE-Chunks gesendet. Siehe Streaming. |
| stream_options | object | Optional. Der Relay erzwingt immer {include_usage: true} upstream, damit der letzte Chunk den Token-Usage-Block trägt — ein Überschreiben hat keine Wirkung. |
| max_tokens | integer | Begrenzt die Completion-Länge. Standard ist das Maximum des Modells. |
| temperature | number | 0 – 2. Höher = zufälliger. |
POST /v1/messages
Anthropic-nativer Endpoint für die claude-*-Modelle — das Anthropic-SDK (anthropic-sdk-python, @anthropic-ai/sdk, claude-code) funktioniert unverändert gegen diesen Pfad. Richte deine Base-URL auf https://api.subnsub.com und authentifiziere dich über den x-api-key-Header (die Authorization-Bearer-Form funktioniert ebenfalls, falls dein Client sie bevorzugt).
| Parameter | Typ | Beschreibung |
|---|---|---|
| model | string | Eine claude-*-Modell-ID (siehe Verfügbare Modelle). Wird hier ein OpenAI-Modell übergeben, gibt es 400 invalid_request_error zurück. |
| max_tokens | integer | Von Anthropic erforderlich — begrenzt die Länge der Assistant-Antwort. |
| messages | array | Konversationsverlauf, Anthropic-Struktur: {role, content} mit role ∈ user / assistant. |
| stream | boolean | Wenn true, wird die standardmäßige Anthropic-SSE-Event-Sequenz zurückgegeben: message_start, content_block_delta, message_delta, message_stop. |
| thinking | object | Wird unverändert weitergeleitet. Kombiniere es mit einer -thinking-Modellvariante, um Extended Thinking zu aktivieren. |
| cache_control | object | Prompt-Caching wird unterstützt. Cache-Write-Tokens werden mit 1,25× und Cache-Read-Tokens mit 0,10× des Eingabe-Satzes des Tiers berechnet. |
GET /v1/models
Listet die Modelle auf, die du tatsächlich aufrufen kannst. Der Relay führt die OpenAI- und Anthropic-Kataloge von sub2api zusammen und filtert auf die 21 herunter, die wir Ende-zu-Ende gegen den aktuellen Account-Pool getestet haben — Phantom-IDs, die zur Routing-Zeit 503 liefern, oder beim ersten Token ein Upstream-400, werden ausgeblendet. Ist jedes konfigurierte Upstream unerreichbar, gibt der Endpoint 502 models_unreachable zurück statt einer irreführenden leeren Liste.
# sample response (truncated)
{
"object": "list",
"data": [
{ "id": "gpt-5.4-mini", "type": "model", ... },
{ "id": "gpt-5.4", "type": "model", ... },
{ "id": "claude-sonnet-4.5", "type": "model", ... },
{ "id": "claude-haiku-4.5", "type": "model", ... },
...
]
}
Verfügbare Modelle
Zwei Upstream-Familien. Die 7 OpenAI-Modelle routen zu geteilten Accounts der ChatGPT-Klasse; die 14 Claude-Modelle routen über einen Kiro-Reverse-Proxy auf AWS CodeWhisperer. Die Sätze pro Token hängen vom Tier ab (siehe Preise) — derselbe Key funktioniert für beide.
OpenAI
| Modell-ID | Familie | Tier | Hinweise |
|---|---|---|---|
| gpt-5.4-mini | GPT-5.4 | Mini | Schnell & günstig. Empfohlener Standard für Chat & Coding. |
| gpt-5.3-codex | Codex | Mini | Coding-optimiertes 5.3. Gleicher Preis wie mini. |
| gpt-5.2 | GPT-5.2 | Standard | Stabiles 5.2. |
| gpt-5.2-chat-latest | GPT-5.2 | Standard | Verfolgt automatisch das neueste 5.2-Chat-Tuning (mappt derzeit upstream auf gpt-5.2). |
| gpt-5.4 | GPT-5.4 | Standard | GPT-5.4 in voller Größe — langsamer, stärkeres Reasoning. |
| gpt-5.4-2026-03-05 | GPT-5.4 | Standard | Datums-Snapshot von gpt-5.4. |
| gpt-5.5 | GPT-5.5 | Premium | Neueres Flaggschiff. |
Anthropic
| Modell-ID | Familie | Tier | Hinweise |
|---|---|---|---|
| claude-haiku-4.5 | Haiku 4.5 | Mini | Kleinstes Claude — gleicher Satz pro Token wie gpt-5.4-mini. |
| claude-haiku-4.5-thinking | Haiku 4.5 | Mini | Extended-Thinking-Variante von haiku-4.5. Kombiniere sie mit dem thinking-Request-Feld. |
| claude-sonnet-4.5 | Sonnet 4.5 | Standard | Claude der Mittelklasse — gleicher Satz pro Token wie gpt-5.4. |
| claude-sonnet-4.5-thinking | Sonnet 4.5 | Standard | Extended-Thinking-Variante von sonnet-4.5. |
| claude-sonnet-4.6 | Sonnet 4.6 | Standard | Neueres Sonnet-Tuning — Standard-Tier, gleicher Satz wie sonnet-4.5. |
| claude-sonnet-4.6-thinking | Sonnet 4.6 | Standard | Extended-Thinking-Variante von sonnet-4.6. |
| claude-opus-4.5 | Opus 4.5 | Ultra | Claude an der Spitze. Wird zu Anthropics Listenpreis abgerechnet — ohne Marge (siehe Preise). |
| claude-opus-4.5-thinking | Opus 4.5 | Ultra | Extended-Thinking-Variante von opus-4.5 (adaptives Thinking). |
| claude-opus-4.6 | Opus 4.6 | Ultra | Neueres Opus-Tuning. |
| claude-opus-4.6-thinking | Opus 4.6 | Ultra | Extended-Thinking-Variante von opus-4.6. |
| claude-opus-4.7 | Opus 4.7 | Ultra | Vorheriger Opus-Snapshot. |
| claude-opus-4.7-thinking | Opus 4.7 | Ultra | Extended-Thinking-Variante von opus-4.7. |
| claude-opus-4.8 | Opus 4.8 | Ultra | Neuester Opus-Snapshot. |
| claude-opus-4.8-thinking | Opus 4.8 | Ultra | Extended-Thinking-Variante von opus-4.8. |
gpt-5.2-pro, gpt-5.2-pro-2025-12-11), gpt-4o, gpt-4o-mini, gpt-5, gpt-5-mini, Image-/Audio-/Realtime-Varianten, claude-haiku-4-6 und datierte Upstream-IDs (z. B. claude-sonnet-4-5-20250929). Ein Aufruf gibt 400 model_not_available zurück. Pro-Modelle sind nicht im Angebot, weil die zugrunde liegenden Social-Tier-Accounts im Pool ihre winzigen Kontingente in wenigen Anfragen erschöpfen würden.
Reasoning-Aufwand
Jedes OpenAI-Modell oben ist ein Reasoning-Modell — das Backend kann mehr oder weniger "Denk"-Tokens aufwenden, bevor es sichtbare Ausgabe erzeugt. Setze reasoning_effort im Request-Body von OpenAI /v1/chat/completions, um das Budget zu steuern. Verwende für Claude das Anthropic-native thinking-Request-Feld (oder wähle eine -thinking-Modellvariante) — siehe den Abschnitt /v1/messages. Die OpenAI-Modelle akzeptieren dieselben fünf Aufwandswerte:
| Wert | Verhalten |
|---|---|
| none | Kein Denken — direkt zur Antwort. Am günstigsten und schnellsten. |
| low | Ein kurzer Reasoning-Durchlauf. |
| medium | Standard, wenn du das Feld nicht übergibst. Ausgewogen. |
| high | Tieferes Reasoning. Empfohlen für nicht-triviales Coding / mehrstufige Probleme. |
| xhigh | Maximaler Aufwand. Am langsamsten und teuersten; reserviere ihn für schwierige Analysen, bei denen du ihn wirklich brauchst. |
# Two equivalent forms — pick whichever your SDK supports
{
"model": "gpt-5.4-mini",
"reasoning_effort": "high",
"messages": [ ... ]
}
{
"model": "gpt-5.5",
"reasoning": { "effort": "xhigh" },
"messages": [ ... ]
}
'minimal', aber die Modelle in unserem Pool lehnen es ab: "'minimal' is not supported with this model". Bleib bei den fünf Werten oben.
Streaming
Setze "stream": true, um Server-Sent Events zu empfangen. Der letzte Chunk trägt einen usage-Block (wir erzwingen stream_options.include_usage upstream, sodass Token-Zählungen immer ausgegeben werden), danach schließt ein wörtliches data: [DONE] den Stream.
# Streaming format (line by line)
data: {"id":"resp_...","choices":[{"delta":{"content":"Hi"}}]}
data: {"id":"resp_...","choices":[{"delta":{"content":"!"}}]}
data: {"id":"resp_...","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":11,"total_tokens":29}}
data: [DONE]
Websuche
Hänge :online an eine beliebige vom Endpoint unterstützte Modell-ID an, und der Relay führt vor dem Weiterleiten an das Modell eine Websuche durch und stellt die Ergebnisse der Konversation voran, damit die Antwort auf frischen Daten basiert. Der Suffix funktioniert auf /v1/chat/completions und /v1/messages (Letzteres erfordert weiterhin eine claude-*-Basis); es sind keine suchspezifischen Request-Felder erforderlich.
# Same call as before — just :online on the model
curl https://api.subnsub.com/v1/chat/completions \
-H "Authorization: Bearer sk-cf-xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.4-mini:online",
"messages": [
{"role": "user", "content": "What did Anthropic ship this week?"}
]
}'
So funktioniert es: Der Relay entfernt :online, nimmt die jüngste User-Nachricht als Query (auf 400 Zeichen begrenzt), ruft Tavily für bis zu 3 Ergebnisse mit extrahiertem Seitentext (falls verfügbar) auf, plus eine optionale von Tavily generierte Zusammenfassung, und stellt sie dann demselben User-Turn als klar abgegrenzten <search_results>-Block voran, bevor die Anfrage upstream gesendet wird. Der Suchaufruf hat einen Timeout von 8 Sekunden. Die Ergebnisse werden bewusst in die User-Rolle eingefügt — niemals in den System-Prompt — sodass nicht vertrauenswürdige Snippets nicht auf System-Priorität angehoben werden können.
Der <search_results>-Block sieht so aus. Ihm geht eine einzeilige Anweisung voraus, die das Modell anweist, den Block als nicht vertrauenswürdige externe Daten zu behandeln und nummerierte Einträge inline zu zitieren:
<search_results query="What did Anthropic ship this week?" retrieved="2026-05-21">
Summary: <short LLM-generated synthesis of the result set>
[1] Anthropic launches Opus 4.8
URL: https://www.anthropic.com/news/opus-4-8
<extracted page text, or short snippet if extraction failed — up to ~2000 chars>
[2] ...
</search_results>
| Verhalten | Detail |
|---|---|
| Kosten | Heute kein Aufschlag — du zahlst den normalen Satz des Modells pro Token; der Relay übernimmt den Suchaufruf. Der eingefügte <search_results>-Block zählt jedoch als Eingabe-Tokens, rechne also mit einer höheren Prompt-Token-Rechnung als bei derselben Frage ohne :online. |
| Fehlerverhalten | Weich. Wenn Tavily einen Timeout hat oder Fehler liefert, läuft die Anfrage ohne Suchkontext weiter zum Modell (du bekommst trotzdem eine Antwort, nur ohne Fundierung). Der einzige harte Fehler ist 503 search_unavailable, wenn die Suche auf dem Relay gar nicht konfiguriert ist. |
| count_tokens | /v1/messages/count_tokens entfernt den Suffix, ruft aber nie Tavily auf — die Zählung spiegelt deinen ursprünglichen Prompt wider, nicht den erweiterten. |
| Mehrere Turns | Nur der letzte User-Turn wird abgefragt & erweitert; frühere Turns bleiben unberührt. Um erneut zu suchen, sende eine neue User-Nachricht, während :online weiterhin am Modell hängt. |
Wann :online verwenden
Der Relay macht einen einzigen Tavily-Aufruf pro Anfrage und fügt die Ergebnisse ein — es ist keine agentische Suchschleife. Das Modell entscheidet nicht anhand des Gesehenen, erneut zu suchen, wie es Perplexity Sonar oder das Browse-Tool von ChatGPT tun. Plane diese Einschränkung ein:
| Gut geeignet | Schlecht geeignet |
|---|---|
| Zeitkritische Fakten (Nachrichten, Preise, Versionsnummern, Release-Daten) | Privater oder eingefügter Code, der nicht im öffentlichen Web steht — fügt Prompt-Rauschen hinzu ohne Fundierung |
| Ein offizielles Dokument oder eine Ankündigung finden | Mathematik, Reasoning, Übersetzung, kreatives Schreiben — nichts zum Fundieren |
| Alles, was du sonst per Google verifizieren würdest | Stabiles Wissen, das bereits in den Trainingsdaten steckt ("was ist ein Binärbaum") |
Formuliere die letzte User-Nachricht als eigenständige Suchanfrage. Die Suche läuft gegen den wörtlichen Text deines jüngsten User-Turns (auf 400 Zeichen begrenzt), sodass konversationelle Rückfragen wie "und was ist mit der neuesten Version?" zu nutzlosen Queries ohne Kontext werden. Wiederhole in einem Mehrturn-Chat das Thema, wenn du :online hinzufügst — z. B. "neueste Version des Anthropic Python SDK" statt "die neueste".
Für Fragen, die mehrstufige Synthese brauchen (Vergleichen-und-Gegenüberstellen, tiefe Recherche), zerlege sie in mehrere Turns und füge jedem :online hinzu. Das Modell liest die frischen Ergebnisse jedes Turns; du steuerst die nächste Query manuell. Beachte, dass der eingefügte <search_results>-Block nur upstream gesendet wird — er wird nicht an deinen Client zurückgespiegelt und nicht in die nächste Anfrage übernommen. Wenn also ein späterer Turn von Details früherer Quellen abhängt, bitte das Modell, sie in seiner sichtbaren Antwort zusammenzufassen. Ein One-Shot-Recherchemodus wird nicht unterstützt.
reasoning_effort: "high"), damit das Modell die zurückgegebenen Quellen tatsächlich abwägt, statt sich auf das erste Ergebnis zu verlassen. Die eingefügte Anweisung bittet das Modell, nummerierte Quellen als [1], [2] inline zu zitieren, sodass die Ausgabe meist solche Zitate trägt — auch wenn das Modell nicht streng an dieses Format gebunden ist.
Fehler
Der Umschlag hängt davon ab, welchen Endpoint du aufgerufen hast — der Relay gibt Fehler im Protokoll zurück, das zum SDK des Aufrufers passt, und Upstream-Fehler werden wörtlich durchgereicht.
OpenAI-Pfade (/v1/chat/completions, /v1/responses, /v1/models) — OpenAI-Umschlag:
{ "error": { "message": "...", "type": "...", "code": "..." } }
Anthropic-Pfade (/v1/messages, /v1/messages/count_tokens) — Anthropic-Umschlag:
{ "type": "error", "error": { "type": "...", "message": "..." } }
Der Anthropic-Umschlag verwendet eine andere Struktur — kein code-Feld, und der Diskriminator type: "error" steht auf oberster Ebene (wobei das innere error.type die Kategorie angibt, z. B. authentication_error, invalid_request_error, permission_error, api_error). Anthropic-SDKs parsen diese Struktur bereits; gewöhnliche OpenAI-SDK-Fehlerhandler tun das nicht, rufe /v1/messages also mit einem Anthropic-SDK auf (oder nutze rohes HTTP).
Die Statuscodes sind über beide Protokolle hinweg die kanonischen HTTP-Codes:
| Status | OpenAI code / Anthropic error.type | Bedeutung |
|---|---|---|
| 401 | invalid_api_key / authentication_error | Fehlender oder unbekannter sk-cf-...-Key. |
| 402 | insufficient_balance / permission_error | Das Konto-Guthaben ist negativ. Lade im Abrechnungs-Tab der Konsole auf. |
| 403 | key_revoked / permission_error | Der Key wurde widerrufen. |
| 400 | model_not_available / invalid_request_error | Das model, das du gesendet hast, steht nicht im verifizierten Katalog oder ist falsch für den Endpoint (z. B. ein OpenAI-Modell auf /v1/messages) — prüfe Verfügbare Modelle. |
| 503 | — | Derzeit bedient kein Upstream-Account die Anfrage — meist ein poolweites Rate-Limit-Fenster, kein Konfigurationsproblem. |
| 503 | search_unavailable / api_error | Du hast :online verwendet, aber die Websuche ist auf diesem Relay nicht konfiguriert. Siehe Websuche. |
| 502 | upstream_unreachable / api_error | Der Relay konnte das Backend nicht erreichen. Wiederhole nach kurzem Backoff. |
Preise & Abrechnung
Pay-as-you-go, abgerechnet pro Token in Mikrodollar (1 Mikro = $0,000001 = 1/10.000 Cent), sodass Anfragen unter einem Cent genau erfasst werden. Die Sätze gelten pro 1M Tokens, nach Tier — siehe die Modelltabelle, welchem Tier jedes Modell zugeordnet ist.
| Tier | Modelle | Eingabe / 1M | Ausgabe / 1M |
|---|---|---|---|
| Mini | gpt-5.4-mini, gpt-5.3-codex, claude-haiku-4.5, claude-haiku-4.5-thinking | $0.20 | $1.60 |
| Standard | gpt-5.2, gpt-5.2-chat-latest, gpt-5.4, gpt-5.4-2026-03-05, claude-sonnet-4.5, claude-sonnet-4.5-thinking, claude-sonnet-4.6, claude-sonnet-4.6-thinking | $0.75 | $6.00 |
| Premium | gpt-5.5 | $1.10 | $8.80 |
| Ultra | claude-opus-4.5, claude-opus-4.5-thinking, claude-opus-4.6, claude-opus-4.6-thinking, claude-opus-4.7, claude-opus-4.7-thinking, claude-opus-4.8, claude-opus-4.8-thinking | $5.00 | $25.00 |
Die Sätze des Ultra-Tiers entsprechen Anthropics veröffentlichtem Opus-Listenpreis — direkte Weitergabe, ohne Marge. Die anderen Tiers laufen dank der gepoolten Abo-Grundlage unter ihren Upstream-Sätzen.
Reasoning-Tokens (wenn du reasoning_effort bei OpenAI setzt oder eine Claude--thinking-Variante nutzt) zählen als Ausgabe-Tokens zum Tier-Satz des Modells — es gibt keinen separaten Aufschlag für hohen Aufwand, aber eine tief denkende Anfrage kann leicht 10–50× mehr Ausgabe-Tokens erzeugen als eine ohne Aufwand, sodass die Dollar-Rechnung entsprechend skaliert.
Anthropic-Prompt-Caching wird als separater Posten abgerechnet: Cache-Writes mit 1,25× und Cache-Reads mit 0,10× des Eingabe-Satzes des Tiers. Ein haiku-4.5-Cache-Hit kostet also 0.20 × 0.10 = $0.02 per 1M tokens, und ein sonnet-4.5-Cache-Hit kostet 0.75 × 0.10 = $0.075 per 1M tokens. Cache-Spalten werden in jeder Settle-Zeile erfasst, sodass die Konsole die Aufschlüsselung zeigen kann.
Das Guthaben wird in Echtzeit abgezogen, sobald jede Anfrage zurückkehrt — bei Streaming-Anfragen läuft die Abrechnung, nachdem der [DONE]-Chunk eingetroffen ist. Sieh dir dein Live-Guthaben und die Abrechnungen pro Anfrage unter /console#billing an.
Rate-Limits
Heute keine Rate-Limits pro Key. Die Nebenläufigkeit des Upstream-Account-Pools & das serverseitige Throttling von OpenAI gelten; wenn du an diese stößt, gibt der Relay 429 mit einem retry-after-Header zurück. Limits für RPM / TPM pro Key kommen nach dem MVP.