BazaarLinkBazaarLink
Anmelden
DokumentationAPI-ReferenzSDK-ReferenzAgentic-NutzungKI-Skills

BazaarLink-Dokumentation

BazaarLink ist ein einheitliches KI-API-Gateway für Taiwan — das Zugang zu Hunderten von Modellen von OpenAI, Anthropic, Google, Meta und mehr über einen einzigen, OpenAI-kompatiblen API-Endpunkt bietet.

KI-Agent Skill-Datei
Laden Sie unsere Skill-Datei in Ihren KI-Assistenten (Claude, Cursor, Copilot…), um ihm volles Wissen über die BazaarLink-API zu geben:
Read https://bazaarlink.ai/skill.md and follow the instructions to integrate BazaarLink into your app.
Kostenlose Modelle & Rate-Limits
Informationen zu kostenlosen Modellen, Anfragen-pro-Minute-Limits und Gratisguthaben finden Sie unter Rate-Limits · FAQ

Preise

BazaarLink bepreist die Modellnutzung ohne Aufschlag (identisch mit dem offiziellen Listenpreis jedes Anbieters). Bei der Aufladung (Einzahlung) werden Plattformgebühren erhoben: eine Transaktionsgebühr von 10 % plus 5 % Taiwan VAT auf TWD-Kanälen. Abrechnung in USD mit TWD-Angeboten und elektronischen Einheitsrechnungen. Selbstbedienungs-Aufladungen mit nutzungsabhängiger Bezahlung; Unternehmen können eine monatliche Abrechnung vereinbaren (Netto-30, verhandelbar).

So funktioniert es

  • Verbrauch (Lastschrift): Jeder API-Anruf wird nach tatsächlicher Token-Nutzung zum offiziellen USD-Listenpreis des Anbieters abgerechnet und von Ihrem Guthaben abgezogen – kein Aufschlag, keine zusätzliche Gebühr für den Verbrauch.
  • Aufladung (Einzahlung): TWD wird zum Echtzeit-Verkaufskurs in USD umgewandelt und Ihrem Guthaben hinzugefügt; Bei der Aufladung wird eine Transaktionsgebühr von 10 % erhoben.
  • • Kreditkarte: Es fällt eine zusätzliche Pauschalgebühr in Höhe von US$ 0.60 an; eine Quittung wird ausgestellt.
  • • TWD-Kanäle: 5% Taiwan VAT wird hinzugefügt und eine einheitliche elektronische Rechnung für Taiwan wird ausgestellt.
  • • Banküberweisung: Für größere oder geschäftliche Aufladungen kontaktieren Sie uns, um eine Überweisung und individuelle Rechnungsstellung zu vereinbaren.
  • Invoicing: elektronische einheitliche Rechnungen werden für Ausgaben-Workflows in Taiwan unterstützt; Unternehmen, die eine Beschaffung oder eine monatliche Abrechnung benötigen, können Unternehmenskonditionen vereinbaren (Netto-30, verhandelbar).
Beispiel
Für eine Aufladung in Höhe von US$10.00: TWD Kanal = $10.00 + 10 % Gebühr US$1.00 + 5% VAT US$0.55 = US$11.55 (einheitliche Rechnung ausgestellt); Kreditkarte = $10.00 + Gebühr US$1.00+ Pauschalgebühr US$0.60 = US$11.60. Nach der Aufladung wird Ihr Guthaben in US$10.00 ohne weiteren Aufschlag zu offiziellen Listenpreisen ausgegeben.

Zum Wechselkurs

Die Devisenumrechnung verwendet den Echtzeitkurs. Bei der monatlichen Abrechnung wird der Tarif zum Zeitpunkt der Abrechnung (Abrechnung) verwendet, während Prepaid-Aufladungen zum Tarif zum Zeitpunkt der Aufladung umgerechnet werden. Der Tarif und der Zeitstempel werden zusammen mit den Rechnungsunterlagen gespeichert.

Abrechnungsschutz bei fehlgeschlagenen Anfragen

Wenn eine Upstream-Anfrage ohne abrechenbare Nutzungsdaten fehlschlägt, gibt BazaarLink den gesamten reservierten Betrag automatisch zurück. Auch wenn der Stream bereits begonnen hatte, beträgt die Belastung für diesen Versuch 0 USD.

Wann nichts berechnet wird
Es ist keine Einstellung erforderlich. Die Regel gilt automatisch für öffentliche Inferenz- und Medien-APIs. Selbst wenn der Upstream-Anbieter BazaarLink bereits Kosten berechnet hat, kann BazaarLink diese Fehlerkosten selbst tragen, statt sie Ihnen weiterzugeben.
  • Der Upstream ist nicht erreichbar, lehnt die Anfrage ab oder liefert kein nutzbares Ergebnis
  • Ein Stream endet vor dem abschließenden Nutzungsdatensatz, auch nach teilweiser Ausgabe
  • Die Antwort enthält keine usage-Daten oder nur ein leeres usage-Objekt mit Nullwerten

0 Ausgabe-Tokens bedeutet nicht immer kostenlos

Wenn eine Anfrage normal endet und der Anbieter gültige usage-Daten liefert, rechnet BazaarLink diese Nutzung ab. Beurteilen Sie die Kosten nicht allein anhand der Ausgabe-Tokens: Bei 0 Ausgabe-Tokens können Eingabe-Tokens oder gültige vom Upstream gemeldete Kosten weiterhin berechnet werden. Prüfen Sie usage.cost oder den Aktivitätseintrag für den endgültigen Betrag.

Schnellstart

Drei Wege zur Integration

Ansatz
Am besten für
Start
Raw APIJede Sprache, keine Abhängigkeiten, volle Kontrolle über Requests
OpenAI / Anthropic SDKBereits auf einem offiziellen SDK — nur Base-URL und Key tauschen
Agent-FrameworksLangChain, Vercel AI SDK, CrewAI und andere Agent-Apps

Starten Sie in unter 5 Minuten. BazaarLink ist vollständig kompatibel mit dem OpenAI SDK — ändern Sie einfach die

Base-URL

https://bazaarlink.ai/api/v1

OpenAI SDK verwenden

BazaarLink ist vollständig kompatibel mit dem OpenAI SDK. Ändern Sie einfach die Base-URL und den API-Schlüssel — der gesamte andere Code bleibt gleich.

from openai import OpenAI

client = OpenAI(
    base_url="https://bazaarlink.ai/api/v1",
    api_key="sk-bl-YOUR_API_KEY",
)

completion = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[
        {"role": "user", "content": "What is the meaning of life?"}
    ],
)

print(completion.choices[0].message.content)
API-Schlüssel benötigt?
Holen Sie sich Ihren API-Schlüssel auf der API-Schlüssel-Seite. Alle Schlüssel beginnen mit sk-bl-.
Modell-ID-Format — Format provider/model-name verwenden
Verwenden Sie immer das vollständige provider/model-Format (z.B. openai/gpt-4.1). Gängige Familien (gpt-*, claude-*) erhalten auf jedem Endpunkt automatisch ein Präfix, und chat/completions löst zusätzlich jeden eindeutigen blanken Namen aus dem Katalog auf — Namen, die nicht aufgelöst werden können, geben jedoch einen 400-Fehler zurück, daher ist die vollständige Form die einzige garantierte.
✓ openai/gpt-4o   anthropic/claude-sonnet-4.6   google/gemini-2.5-flash
✗ gpt-4.1   claude-sonnet-4.6   gemini-2.5-flash

Eigene Upstream-Schlüssel (BYOK)

Binden Sie Ihre eigenen Upstream-Provider-API-Schlüssel (OpenAI- oder Anthropic-kompatible Schnittstelle) an Ihr Konto oder Ihre Organisation — passende Anfragen laufen dann über Ihren Schlüssel direkt zum Upstream, wahlweise mit nahtlosem (seamless) oder striktem (strict) Fallback. Persönliche Schlüssel verwalten Sie im BYOK-Tab der Schlüsselseite, Organisationen in den Org-Einstellungen. Zu den BYOK-Einstellungen →

Inhaltsfilterung

Beidseitiger Inhaltsschutz für Ihren API-Traffic: Anfragen mit Prompt-Injection-Versuchen werden blockiert (400), sensible Daten in Anfragen und Antworten (API-Schlüssel, Kartennummern, Ausweisnummern u. a.) werden automatisch geschwärzt. Regeln und Ausnahmeliste sind anpassbar, Nutzungsstatistiken inklusive. Zu den Inhaltsfilter-Einstellungen →

Von OpenRouter migrieren

Die BazaarLink-API ist OpenRouter-kompatibel — die meisten Integrationen wechseln durch Ändern von zwei Werten: die Base-URL zu https://bazaarlink.ai/api/v1 und den API-Schlüssel zu einem BazaarLink-Schlüssel, der mit sk-bl- beginnt.

  1. Base-URL: https://openrouter.ai/api/v1 → https://bazaarlink.ai/api/v1
  2. API-Schlüssel: sk-or-... → sk-bl-... (erstellen Sie einen unter /keys)
  3. Modell-IDs: gleiches provider/model-Format (z.B. anthropic/claude-sonnet-4.6); vollständiger Katalog unter GET /api/v1/models
  4. models[]-Fallbacks, Provider-Routing-Präferenzen, Streaming, Tool Calling und Structured Outputs verwenden dieselbe Request-Form
  from openai import OpenAI

  client = OpenAI(
-     base_url="https://openrouter.ai/api/v1",
-     api_key="sk-or-...",
+     base_url="https://bazaarlink.ai/api/v1",
+     api_key="sk-bl-...",
  )
Note
Die Abrechnung erfolgt in USD, taiwanesische E-Rechnungen sind verfügbar. Für OpenRouter-spezifische Funktionen (z.B. :nitro-Provider-Sortierung) finden Sie das äquivalente Verhalten in den Abschnitten Modellvarianten und Anbieterauswahl auf der API-Referenz-Seite.

Authentifizierung

Alle API-Anfragen erfordern einen Authorization-Header mit Ihrem API-Schlüssel.

Authorization: Bearer sk-bl-YOUR_API_KEY

Holen Sie sich Ihren API-Schlüssel vom Dashboard. Bewahren Sie Ihren Schlüssel sicher auf — exponieren Sie ihn nicht in clientseitigem Code.

Sicherheitshinweis
API-Schlüssel niemals in clientseitigem JavaScript exponieren. Leiten Sie Anfragen immer über Ihren Backend-Server weiter.

Optionale Header

HTTP-Referer
string
Ihre Website-URL, für Nutzungsverfolgung und Analysen (optional)
X-Title
string
Ihr App-Name, angezeigt in Dashboards (optional)

Prinzipien

BazaarLink basiert auf drei Kernprinzipien:

1. Einheitliche Schnittstelle

Eine API, ein SDK, Hunderte von Modellen. Wechseln Sie zwischen OpenAI, Anthropic, Google Gemini, Meta Llama und anderen, ohne Ihren Code zu ändern — ändern Sie einfach die Modell-ID.

2. Preisoptimierung

BazaarLink leitet automatisch zum kostengünstigsten Anbieter für Ihr gewähltes Modell weiter. Sie zahlen nur, was Sie nutzen, abgerechnet in USD mit voller Rechnungsunterstützung.

3. Hochverfügbarkeit

Automatisches Failover bedeutet: Wenn ein Anbieter ausfällt, werden Ihre Anfragen nahtlos umgeleitet. Keine Codeänderungen, keine Ausfallzeit.

Multimodal

BazaarLink unterstützt multimodale Eingaben — senden Sie Bilder, Audio und Dateien zusammen mit Text an Modelle, die sie unterstützen. Inhalte werden an den Upstream-Anbieter weitergeleitet.

Unterstützte Modalitäten

Eingabe
Beschreibung
Beispielmodelle
TextStandard-TextnachrichtenAlle Modelle
BilderURL oder Base64-Daten-URI — PNG, JPEG, WebP, GIFopenai/gpt-5.3-codexanthropic/claude-opus-4.6google/gemini-2.5-flash-lite+142 weitere
Dateien / PDFsDokument via Base64-Daten-URI (`data:application/pdf;base64,...`)openai/gpt-5.3-codexanthropic/claude-opus-4.6google/gemini-2.5-flash-lite+70 weitere
AudioRoh-Base64 — keine URL-Unterstützung. Erfordert `format`-Feldgoogle/gemini-2.5-flash-litexiaomi/mimo-v2.5google/gemini-3.1-pro-preview+13 weitere
VideoURL (CDN) oder Base64-Daten-URIgoogle/gemini-2.5-flash-liteqwen/qwen3.5-plus-02-15minimax/minimax-m3+37 weitere

Beispiele:

# Image — URL or base64 data URI
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"text","text":"What is in this?"},
        {"type":"image_url","image_url":{"url":"https://example.com/photo.jpg"}}
      ]}]}'

# File / PDF — base64 data URI only, no URL
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"file","file":{"filename":"doc.pdf","file_data":"data:application/pdf;base64,JVBER..."}},
        {"type":"text","text":"Summarize this."}
      ]}]}'

# Audio — raw base64, no URL. "format" is required
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"text","text":"Transcribe this."},
        {"type":"input_audio","input_audio":{"data":"UklGRi...","format":"wav"}}
      ]}]}'

# Video — URL (CDN) or base64 data URI
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"text","text":"Describe this video."},
        {"type":"video_url","video_url":{"url":"https://example.com/clip.mp4"}}
      ]}]}'

Bilder senden

Verwenden Sie das Content-Array-Format mit image_url-Teilen. Unterstützte Formate: PNG, JPEG, WebP und GIF (einschließlich animiert). Sie können mehrere Bilder in einer einzigen Nachricht einschließen — jedes als separater image_url-Teil:

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer sk-bl-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [{"role":"user","content":[
      {"type":"text","text":"What is in this image?"},
      {"type":"image_url","image_url":{"url":"https://example.com/photo.jpg","detail":"auto"}}
    ]}]
  }'
Bilder senden
Fügen Sie neben Bildern immer einen Textteil hinzu. Die Text-zuerst-Reihenfolge (Textteil vor Bildteilen) wird für beste Kompatibilität über alle Anbieter empfohlen.
Bilder senden
Prüfen Sie auf der Modellseite die unterstützten Eingabemodalitäten jedes Modells. Die Modalitätsspalte zeigt, welche Eingaben jedes Modell akzeptiert.

Limits

BazaarLink erzwingt zwei unabhängige Limits: ein Rate Limit für Anfragen pro Minute und ein Guthaben-Limit für Kontoausgaben. Bei Überschreitung des Rate Limits erhalten Sie HTTP 429; ist das Guthaben aufgebraucht, erhalten Sie HTTP 402.

Rate-Grenzwerte

Rate Limits gelten pro Benutzer (nicht pro Schlüssel), gemessen in Anfragen pro Minute (RPM). Es gibt kein Tageslimit. Die Stufe wird automatisch durch Ihr Kontoguthaben bestimmt.

Stufe
RPM
Tagesnutzung
Hinweise
Kostenlos (< $5 Guthaben)20 RPMUnbegrenztEntwicklung & Test
Bezahlt (≥ $5 Guthaben)200 RPMUnbegrenztProduktions-Workloads

Bei Überschreitung eines Rate Limits erhalten Sie eine 429-Antwort mit einem Retry-After-Header. Implementieren Sie exponentielles Backoff beim erneuten Versuch.

Antwort-Header

Jede erfolgreiche Antwort enthält Rate-Limit-Header für die clientseitige Nachverfolgung:

X-RateLimit-Limit: 200        # Max requests per minute for your tier
X-RateLimit-Remaining: 198    # Remaining requests in current window
X-RateLimit-Reset: 1740000060 # Unix timestamp when the window resets
X-Request-Id: chatcmpl-abc123 # Unique request ID for debugging

Guthaben-Limits

Eine 402-Antwort bedeutet, dass Ihr Kontoguthaben oder das Ausgabenlimit eines Schlüssels null erreicht hat — nicht, dass Sie zu schnell Anfragen senden. Diese Antworten enthalten keine Rate-Limit-Header, und wenn das Limit während des Streamings erreicht wird, erhalten Sie ein SSE-Fehlerereignis statt einer HTTP-Statusänderung.

402 Unzureichendes Guthaben
Wenn Ihr Guthaben $0 erreicht, gibt die API HTTP 402 mit der Meldung "Insufficient credits. Please top up to continue." zurück — überwachen Sie usage.cost in den Antworten, um die Ausgaben in Echtzeit zu verfolgen.

Persönlicher Schutzschalter

Ein festes 1-Minuten- und 1-Stunden-USD-Ausgabenlimit für alle Ihre API-Schlüssel. Neue Anfragen erhalten HTTP 429, sobald ein Fensterschwellenwert erreicht wird; das Fenster wird automatisch an der Zeitgrenze zurückgesetzt.

cbEnabled
boolean
Aktiviert
cbMinuteUsd
number | null
USD-Limit pro Minute · Standard verwenden
cbHourlyUsd
number | null
USD-Limit pro Stunde · Standard verwenden
(Standardwerte übernommen)
Werte müssen mindestens 0,01 betragen (oder leer für Standard)
Persönlicher Schutzschalter · Anpassen

Bilderzeugung

Bilder über /v1/chat/completions mit modalities:["image"] oder das OpenAI DALL·E-kompatible /v1/images/generations generieren.

curl -N https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"openai/gpt-5.4-image-2","messages":[{"role":"user","content":"a red cat on a sofa"}],"modalities":["image","text"],"stream":true}'

Vollständiger Ablauf (Streaming, Bildbearbeitung, SSE-Protokoll, Modellliste) → API-Referenz

Videogenerierung

Asynchroner 3-Schritt-Ablauf (submit → poll → content). Videogenerierung dauert 30 Sekunden bis 5 Minuten.

curl https://bazaarlink.ai/api/v1/videos \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"alibaba/wan2.7-t2v","prompt":"a bird flying over mountains","duration":3}'
# → 202 { "id": "vjob_xxx", "status": "pending" }

Vollständiger Ablauf (Polling, Download, Aufgabentypen, Hinweise) → API-Referenz

PDF-Eingaben

Senden Sie PDF-Dokumente direkt in Nachrichten an Modelle mit nativer PDF-Unterstützung (z. B. Claude, Gemini). BazaarLink leitet die Datei direkt an das Modell weiter — abgerechnet als normale Input-Tokens, ohne Zusatzkosten oder zusätzlichen Verarbeitungsschritt.

Unterstützte Formate

  • PDF-Dokumente (Text, Bilder, Tabellen, gescannt)
  • Base64-kodierte Daten-URL (`data:application/pdf;base64,...`)
  • Mehrseitige Dokumente
  • Nur passwortfreie PDFs
import base64

with open("document.pdf", "rb") as f:
    pdf_data = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6",
    messages=[{
        "role": "user",
        "content": [
            {
                "type": "file",
                "file": {
                    "filename": "document.pdf",
                    "file_data": f"data:application/pdf;base64,{pdf_data}",
                },
            },
            {"type": "text", "text": "Summarize this document."},
        ],
    }],
)

Video-Eingaben

Senden Sie Videodateien an Modelle mit Videoeingabe-Unterstützung zur Analyse, Beschriftung oder Beantwortung von Fragen zu Szenen und Ereignissen. Funktioniert mit einer direkten URL oder einem base64-Daten-URI — eine URL ist effizienter für öffentlich zugängliche Videos, base64 für lokale Dateien oder private Videos.

Unterstützte Formate

MP4 (H.264)MPEGMOVWebM
response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{
        "role": "user",
        "content": [
            {
                "type": "video_url",
                "video_url": {"url": "https://example.com/video.mp4"},
            },
            {"type": "text", "text": "What is happening in this video?"},
        ],
    }],
)

Vollständige API-Referenz →

Management-API-Schlüssel

Management-Schlüssel sind für programmatische Schlüsselverwaltung konzipiert. Sie können Standard-API-Schlüssel erstellen, auflisten, aktualisieren, deaktivieren und löschen — aber keine KI-Modellaufrufe durchführen.

Hinweis
Management-Schlüssel können keine KI-Modelle aufrufen (chat/completions/messages/embeddings). Verwenden Sie einen Standard-API-Schlüssel für den Modellzugriff.

Management-Schlüssel erstellen

Gehen Sie zur Management API Keys-Seite und klicken Sie auf "Create" — das ist eine eigene Seite, kein Typ-Auswahlfeld auf der Standard-API-Keys-Seite.

Schlüssel auflisten

GET https://bazaarlink.ai/api/v1/keys
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Response
{
  "keys": [
    {
      "id": "clxyz123...",
      "name": "Production Key",
      "keyType": "standard",
      "keyPrefix": "sk-bl-abc1",
      "keySuffix": "XyZ9",
      "enabled": true,
      "spendLimitUsd": 10.00,
      "spendLimitPeriod": "month",
      "expiresAt": null,
      "createdAt": "2026-01-01T00:00:00.000Z",
      "lastUsed": "2026-03-01T12:34:56.000Z",
      "requestCount": 1234,
      "totalTokens": 5678901
    }
  ]
}

Unterschlüssel erstellen

POST https://bazaarlink.ai/api/v1/keys
Authorization: Bearer sk-bl-YOUR_MGMT_KEY
Content-Type: application/json

{
  "name": "Agent Key",
  "limit": 10.00,
  "limit_reset": "monthly",
  "expires_at": "2026-12-31T23:59:59Z"
}

# limit_reset: daily | weekly | monthly
# expires_at:  ISO 8601 datetime (optional)

# Response — save the key value, it won't be shown again
{
  "id": "clxyz789...",
  "name": "Agent Key",
  "key": "sk-bl-xyz789abcdef...",
  "keyType": "standard",
  "spendLimitUsd": 10.00,
  "spendLimitPeriod": "month",
  "expiresAt": "2026-12-31T23:59:59.000Z",
  "enabled": true,
  "createdAt": "2026-03-01T00:00:00.000Z"
}

Schlüssel aktualisieren

PATCH https://bazaarlink.ai/api/v1/keys/:id
Authorization: Bearer sk-bl-YOUR_MGMT_KEY
Content-Type: application/json

{"enabled": false}              # disable key
{"spendLimitUsd": 5, "spendLimitPeriod": "week"}  # set spend limit
{"spendLimitUsd": null}         # remove spend limit
# Response: {"updated": true}

Schlüssel widerrufen

DELETE https://bazaarlink.ai/api/v1/keys/:id
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Returns 204 No Content on success

Guthaben abfragen

GET https://bazaarlink.ai/api/v1/credits
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Response
{
  "data": {
    "total_credits": 12.345,
    "total_usage": 3.210
  }
}

Nutzung abfragen

GET https://bazaarlink.ai/api/v1/usage?period=month
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# period: day | week | month | year

App-Zuordnung

Identifizieren Sie Ihre Anwendung in Request-Headern, um Nutzungsverfolgung, Dashboard-Sichtbarkeit und feinkörnige Analysen zu ermöglichen.

Hinweis
Diese Header sind vollständig optional und beeinflussen die API-Funktionalität nicht. Es wird jedoch empfohlen, sie für Debugging und Nutzungszuordnung zu setzen.

Verfügbare Header

HeaderDescription
HTTP-RefererIhre Website-URL, für Nutzungsverfolgung und Analysen (optional)
X-TitleIhr App-Name, angezeigt in Dashboards (optional)
from openai import OpenAI

client = OpenAI(
    base_url="https://bazaarlink.ai/api/v1",
    api_key="sk-bl-YOUR_KEY",
    default_headers={
        "HTTP-Referer": "https://yourapp.com",  # Optional: your site URL
        "X-Title": "My Application",             # Optional: your app name
    },
)

response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)

Fehlercodes

Fehlerantwortformat

Modellinferenz-Endpunkte geben eine OpenAI-kompatible Fehlerhülle zurück. Das Feld type kann variieren oder fehlen; verwenden Sie für die Programmlogik den HTTP-Status und error.code, statt die Meldung auszuwerten.

{
  "error": {
    "message": "Insufficient credits. Please top up to continue.",
    "type": "invalid_request_error",
    "code": "insufficient_credits"
  }
}

HTTP Status und Fehlercode

Before streaming, the HTTP status identifies the broad failure class. error.code is either that number or a stable string for a specific remedy. Prefer the string code when present, otherwise use the HTTP status.

Code
Name
Beschreibung
400Bad RequestFehlerhafte Anfrage, leeres messages-Array oder fehlende Pflichtfelder
401Nicht autorisiertAPI-Schlüssel fehlt, ist ungültig oder deaktiviert
402Zahlung erforderlichUnzureichendes Kontoguthaben, Schlüssel-Ausgabenlimit erreicht oder monatliches/wöchentliches Budgetlimit überschritten
403VerbotenKonto ist gesperrt oder hat keine Berechtigung
404Nicht gefundenRequested model, generation, key, or other resource does not exist
409KonfliktResource is not in the required state, such as an incomplete video job
410GegangenRequested model has been retired and must be replaced
413Payload zu großRequest-Body überschreitet 10 MB; reduzieren Sie die Inhaltsgröße oder teilen Sie die Anfrage auf
416Range nicht erfüllbarRequested byte range is invalid for generated video content
429Zu viele AnfragenRate Limit überschritten; prüfen Sie den Retry-After-Header vor dem erneuten Versuch
500ServerfehlerInterner BazaarLink-Fehler
502Bad GatewayAlle Upstream-Anbieter fehlgeschlagen; Failover wurde versucht
503Dienst nicht verfügbarKein Upstream-Anbieter für dieses Modell konfiguriert; Admin kontaktieren
504Gateway-TimeoutUpstream connection or stream stalled and timed out

Maschinenlesbare Abrechnungscodes

A 402 can represent different controls. Use these stable codes to choose the correct action.

Code
Beschreibung
budget_cap_reachedA weekly or monthly budget cap was reached; raise or reset the cap.
credit_limit_exceededA monthly-billing organization's credit line was exhausted; contact billing.
insufficient_creditsThe prepaid balance is insufficient; add credits.
spend_limit_exceededThe API key reached its daily, weekly, or monthly spend limit.

Stable error.code catalog

These string codes are emitted by public inference and media paths. Branch on the string code when present; the HTTP status remains the broad failure class.

Modell und Endpunkt
Modellsuch-, Lebenszyklus-, Preis-, Modalitäts- und Endpunktkompatibilitätsfehler.
Code
HTTP-Status
unknown_model400
invalid_model_id400
model_not_found404
model_retired410
model_endpoint_mismatch400
embedding_on_chat_endpoint400
model_not_priced400
invalid_modality_for_model400
Anfrage und Sicherheit
Ungültige Parameter, Kontext, Tools, Schemata und Inhaltssicherheitsverweigerungen.
Code
HTTP-Status
missing_required_field400
unsupported_param400
max_tokens_invalid400
context_too_long400
tool_use_unsupported400
malformed_tool_messages400
invalid_response_format_schema400
invalid_tools_definition400
content_moderation403
content_filter403
unknown_4xx400
Bildgenerierung und -bearbeitung
Bildeingabe-, mehrteilige Bearbeitungs-, Ausgabe- und Bild-Pipeline-Fehler.
Code
HTTP-Status
invalid_image_url400
input_images_not_supported400
invalid_content_type400
mask_not_supported400
unsupported_response_format400
missing_prompt400
missing_image400
too_many_images400
invalid_image_type400
image_too_large400
invalid_n400
pipeline_error502
no_images502
Upstream-Routing
Sanitized Provider-Konnektivität, Authentifizierung, Drosselung und Verfügbarkeitsfehler.
Code
HTTP-Status
upstream_unreachable502
upstream_auth_failed502
upstream_rate_limited429
upstream_unavailable502/503

Ratengrenzen, Budgets und Notbremsen

These controls can reject an otherwise valid request and require different recovery actions.

Control
HTTP-Status
So identifizieren Sie es
Anforderungsratenbegrenzung429Numerischer Code 429; Verwenden Sie die Header „Retry-After“ und „X-RateLimit-*“.
Rate-Limit-Strafblock429Numerischer Code 429 und eine vorübergehende Einschränkungsnachricht; Verwenden Sie Retry-After.
Globale Ausgaben-Notbremse503Numerischer Code 503, Nachricht zum globalen Ausgabenlimit und Wiederholungsversuch nach 30 oder 300 Sekunden.
Scoped spend brake429Numeric code 429 and a spend circuit-breaker message naming the scope.
Abrechnungs- und Budgetkontrollen402Verwenden Sie die oben aufgeführten stabilen Abrechnungszeichenfolgencodes.

Compatibility note: rate-limit and emergency-brake paths currently emit numeric error.code values. Use HTTP status, Retry-After, and the documented response message.

Video- und Medienressourcenstatus

Video validation commonly returns numeric code 400. Missing jobs return 404, retired models 410, unfinished video content 409, and invalid video byte ranges 416.

Retry-Richtlinie

Retry only failures that may recover without changing the request. Honor Retry-After or use exponential backoff with jitter. Do not stack SDK and manual retries.

Wiederholen Sie den Vorgang mit Backoff
429, 502, 503, and 504. Check the original generation job before creating another after an ambiguous network failure.
Fix vor dem erneuten Versuch
400, 401, 402, 403, 404, 409, 410, 413, and 416. Fix the request, credentials, balance, permissions, resource state, or Range header first.

Fehlerbehandlung

import random
import time
from openai import OpenAI, APIStatusError

client = OpenAI(
    base_url="https://bazaarlink.ai/api/v1",
    api_key="sk-bl-YOUR_API_KEY",
    max_retries=0,  # Avoid double retries; this example handles them.
)

RETRYABLE = {429, 502, 503, 504}

for attempt in range(5):
    try:
        response = client.chat.completions.create(
            model="openai/gpt-4.1",
            messages=[{"role": "user", "content": "Hello!"}],
        )
        break
    except APIStatusError as error:
        if error.status_code not in RETRYABLE or attempt == 4:
            raise
        retry_after = error.response.headers.get("Retry-After")
        delay = (
            float(retry_after)
            if retry_after
            else min(8, 0.5 * (2 ** attempt)) + random.uniform(0, 0.25)
        )
        time.sleep(delay)

Streaming-Fehlerformate

Fehler, die vor dem Streamen von Tokens auftreten, geben eine Standard-HTTP-Fehlerantwort mit einem JSON-Body zurück.

After a stream starts, the HTTP response is already 200. Parse each SSE data frame and treat a top-level error or choices[0].finish_reason === "error" as a failed, incomplete response.

Wenn der Stream mitten in der Übertragung fehlschlägt, sendet BazaarLink ein letztes SSE-Event mit einem error-Objekt auf oberster Ebene, gefolgt von data: [DONE]. Chunks, die von manchen Upstreams unverändert weitergeleitet werden, können den Fehler stattdessen auf der Choice tragen (choices[0].finish_reason === "error") — behandeln Sie beide Fälle.

// If the stream fails mid-flight, BazaarLink emits a final SSE event
// with a top-level "error" object, followed by data: [DONE]
data: {"error":{"message":"Upstream stream interrupted. The response is incomplete.","type":"upstream_error","code":502}}

data: [DONE]

// Chunks relayed verbatim from some upstreams may instead carry the error
// inline on the choice: choices[0].finish_reason === "error" with an
// "error" object ({ code, message }) on the choice — handle both shapes.
// Branch on error.code; error.type can vary by failure path.

Tool-Aufruf

Tool Calling (auch bekannt als Function Calling) ermöglicht es Modellen, von Ihnen definierte externe Funktionen aufzurufen. Das Modell entscheidet, wann ein Tool aufgerufen wird, und generiert strukturierte Argumente — Ihr Code führt die Funktion aus und gibt Ergebnisse zurück, um die Konversation fortzusetzen.

Unterstützte Modelle

Die meisten Frontier-Modelle unterstützen Tool Calling. Hier sind einige beliebte Optionen:

Tools definieren

Jedes Tool ist ein JSON-Objekt, das eine Funktion beschreibt, die das Modell aufrufen kann. Das parameters-Feld verwendet JSON Schema.

nameerforderlich
string
Funktionsname (a-z, A-Z, 0-9, Unterstriche, Bindestriche)
descriptionerforderlich
string
Klare Beschreibung, wann und wie die Funktion verwendet werden soll
parameterserforderlich
object
JSON-Schema-Objekt, das Funktionsparameter definiert

tool_choice-Optionen

Wert
Verhalten
"auto"Modell entscheidet, ob ein Tool aufgerufen wird (Standard)
"none"Modell wird kein Tool aufrufen
"required"Modell muss mindestens ein Tool aufrufen
{"type": "function", "function": {"name": "get_weather"}}Modell muss die angegebene Funktion aufrufen

Vollständiger Ablauf

Tool Calling ist ein mehrstufiger Prozess: (1) Anfrage mit Tools senden → (2) Modell gibt tool_calls zurück → (3) Funktionen ausführen → (4) Ergebnisse zurücksenden → (5) Modell generiert finale Antwort.

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [{"role":"user","content":"What is the weather in Taipei?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "City name"},
            "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
          },
          "required": ["city"]
        }
      }
    }],
    "tool_choice": "auto"
  }'
# Response carries tool_calls — run get_weather() yourself, then send the
# result back with role:"tool" (same shape as the Python/TS steps 3-5) to
# get the model's final answer.

Parallele Tool-Aufrufe

Einige Modelle können mehrere Tools in einer einzigen Antwort aufrufen. Behandeln Sie jeden Tool-Aufruf und geben Sie alle Ergebnisse zurück:

# Model may return multiple tool_calls
if message.tool_calls:
    messages = [
        {"role": "user", "content": "Weather and time in Tokyo?"},
        message,
    ]

    for tool_call in message.tool_calls:
        # Execute each function
        if tool_call.function.name == "get_weather":
            result = {"temperature": 22, "condition": "Clear"}
        elif tool_call.function.name == "get_time":
            result = {"time": "2026-02-23T15:30:00+09:00"}

        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result),
        })

    # Send all results back at once
    final = client.chat.completions.create(
        model="openai/gpt-4.1",
        messages=messages,
        tools=tools,
    )
    print(final.choices[0].message.content)

Tool-Aufrufe beim Streaming

Beim Streaming treffen Tool-Aufrufe als partielle, nach Position indizierte Deltas ein — sammeln Sie den Argument-String jedes Deltas nach Index, bis finish_reason zu "tool_calls" wird, was den Abschluss des Aufrufs anzeigt.

# Streaming: tool_calls arrive as partial deltas indexed by position —
# accumulate function.arguments per index until finish_reason == "tool_calls".
stream = client.chat.completions.create(
    model="openai/gpt-4.1",
    messages=[{"role": "user", "content": "What's the weather in Taipei?"}],
    tools=tools,
    tool_choice="auto",
    stream=True,
)

tool_calls = {}
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.tool_calls:
        for tc in delta.tool_calls:
            entry = tool_calls.setdefault(tc.index, {"id": "", "name": "", "arguments": ""})
            if tc.id:
                entry["id"] = tc.id
            if tc.function.name:
                entry["name"] = tc.function.name
            if tc.function.arguments:
                entry["arguments"] += tc.function.arguments
    if chunk.choices[0].finish_reason == "tool_calls":
        for call in tool_calls.values():
            print(call["name"], json.loads(call["arguments"]))

Einfache Agenten-Schleife

Ein generisches Muster, das das Modell weiter aufruft, solange es Tools anfordert, und stoppt, sobald es eine endgültige Antwort liefert — verwenden Sie max_iterations, um Endlosschleifen zu vermeiden.

# Generic loop: keep calling the model while it keeps requesting tools,
# stop once it returns a plain answer. max_iterations guards against loops.
messages = [{"role": "user", "content": "What's the weather in Taipei, and what time is it there?"}]
max_iterations = 10

for _ in range(max_iterations):
    response = client.chat.completions.create(
        model="openai/gpt-4.1",
        messages=messages,
        tools=tools,
    )
    message = response.choices[0].message
    messages.append(message)

    if not message.tool_calls:
        break  # model gave a final answer

    for tool_call in message.tool_calls:
        args = json.loads(tool_call.function.arguments)
        result = TOOL_MAPPING[tool_call.function.name](**args)
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result),
        })
else:
    print("Warning: max_iterations reached without a final answer")

print(messages[-1].content)

Best Practices für Funktionsdefinitionen

  • Verwenden Sie spezifische, aussagekräftige Namen — get_weather_forecast statt nur weather.
  • Beschreiben Sie klar, was die Funktion tut und wann sie verwendet werden soll — das Modell verlässt sich allein auf diesen Text, um zu entscheiden, ob es sie aufruft.
  • Schränken Sie Werte wo möglich mit enum ein und fügen Sie in der Beschreibung ein Beispiel hinzu, um fehlerhafte Argumente zu reduzieren.
  • Markieren Sie nur wirklich erforderliche Felder als required — optionale Felder sollten tatsächlich weggelassen werden können.

Strukturierte Ausgabe

Erzwingen Sie, dass das Modell gültiges JSON gemäß einem Schema zurückgibt. Dies ist essenziell für zuverlässige Anwendungen, die Modellausgaben programmatisch verarbeiten.

Methode 1: response_format (JSON Schema)

um strikte JSON-Schema-Konformität zu erzwingen:

typeerforderlich
string
Muss "json_schema" sein
json_schema.nameerforderlich
string
Ein Name für das Schema (wird für Caching verwendet)
json_schema.strict
boolean
Bei true garantiert exakte Schema-Konformität
json_schema.schemaerforderlich
object
Die JSON-Schema-Definition
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [{"role":"user","content":"Review the movie Inception"}],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "movie_review",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "title": {"type": "string"},
            "rating": {"type": "integer", "description": "Rating 1-10"},
            "summary": {"type": "string"},
            "pros": {"type": "array", "items": {"type": "string"}},
            "cons": {"type": "array", "items": {"type": "string"}}
          },
          "required": ["title", "rating", "summary", "pros", "cons"],
          "additionalProperties": false
        }
      }
    }
  }'

Tipps

  • Verwenden Sie klare, beschreibende Eigenschaftsnamen — das Modell nutzt sie als Kontext.
  • Fügen Sie Schema-Eigenschaften Beschreibungen hinzu, um das Modell zu leiten.
  • Setzen Sie strict: true für garantierte Schema-Konformität (kann die Latenz leicht erhöhen).
  • Halten Sie Schemas einfach — tief verschachtelte Schemas können die Ausgabequalität reduzieren.
  • Testen Sie mit verschiedenen Modellen — einige verarbeiten komplexe Schemas besser als andere.

Assistant Prefill

Fügen Sie als letzten Eintrag eine unvollständige assistant-Nachricht hinzu, um auf kompatiblen Modellrouten eine Fortsetzung anzufordern.

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4.6",
    "messages": [
      {"role":"user","content":"What is the capital of France?"},
      {"role":"assistant","content":"The capital of France is"}
    ]
  }'
# Model continues: " Paris, known for the Eiffel Tower..."
Funktionsweise
BazaarLink behält die letzte assistant-Nachricht bei und leitet sie weiter. Das Fortsetzungsverhalten wird vom ausgewählten Upstream-Modell und Anbieter implementiert und ist daher nicht auf jeder Route garantiert.

Nachrichtentransformationen

Nachrichten automatisch transformieren, damit sie in die Kontextlimits des Modells passen. Wenn Ihre Nachrichten das Kontextfenster eines Modells überschreiten, verkürzen Transformationen die Konversation intelligent, indem Nachrichten aus der Mitte entfernt werden.

Auto
Modelle mit einem Kontextfenster von 8.192 Tokens oder weniger wenden middle-out standardmäßig automatisch an. Um es abzuwählen, übergeben Sie `transforms: []`. Um es für jedes Modell zu aktivieren, übergeben Sie `transforms: ["middle-out"]`.

Nutzung

// Enable middle-out on any model
{
  "model": "openai/gpt-4.1",
  "transforms": ["middle-out"],
  "messages": [
    { "role": "system", "content": "You are a helpful assistant." },
    ... // long conversation — middle will be trimmed to fit context
  ]
}

// Disable auto-trimming for small-context models
{ "transforms": [] }

Transformationstypen

Transformation
Beschreibung
middle-outEntfernt zuerst Nachrichten aus der Mitte und bewahrt den Anfang (System-Prompt, Kontext) und das Ende (aktuelle Nachrichten)

Standardverhalten

Modelle mit ≤8k Kontext haben middle-out automatisch aktiviert. Für größere Kontextmodelle aktivieren Sie es explizit. Anthropic Claude-Modelle erzwingen außerdem automatisch das 1.000-Nachrichten-Limit unabhängig von der transforms-Einstellung.

Keine Datenspeicherung

BazaarLink speichert standardmäßig keine Nachrichteninhalte. Diese Seite beschreibt, wie Ihre Daten verarbeitet werden. Geeignet für Anwendungen, die sensible Daten verarbeiten.

Aktuelle Datenverarbeitung

  • Nachrichteninhalte: werden standardmäßig nicht gespeichert, nach der Verarbeitung aus dem Speicher entfernt
  • Abrechnungsmetadaten: Token-Zählungen, Zeitstempel, Modell-IDs
  • Nutzungsprotokolle: nur Anfragstatistiken, keine Nachrichteninhalte
  • Upstream-Weiterleitung: Nachrichten werden an Upstream-Anbieter weitergeleitet — unterliegen deren Datenschutzrichtlinien

Prompt-Caching

Prompt-Caching verwendet zuvor berechnete Prompt-Tokens wieder, was Kosten und Latenz erheblich reduziert — besonders für Anwendungen mit großen, wiederkehrenden System-Prompts.

Note
BazaarLink verfolgt Cache-Einsparungen automatisch und spiegelt sie in der Abrechnung wider. Das `cached_tokens`-Feld in der Antwort zeigt tatsächliche Cache-Treffer; `cacheDiscount` zeigt den bei dieser Anfrage eingesparten Betrag.

Funktionsweise

Ob Konfiguration nötig ist, hängt vom Anbieter ab. Modelle der OpenAI-Familie cachen lange, wiederholte Prompt-Präfixe automatisch — ohne Änderung der Anfrage. Claude-Modelle (Anthropic) cachen nur, wenn die Anfrage einen expliziten cache_control-Breakpoint enthält; BazaarLink fügt diesen nicht selbst hinzu, ohne Markierung wird eine Claude-Anfrage nie gecacht. BazaarLink leitet vorhandene Cache-Markierungen unverändert weiter und meldet die resultierenden Cache-Read/Write-Token in der Nutzungsantwort.

# OpenAI-family models: nothing to add, long repeated prefixes cache automatically.
response = client.chat.completions.create(
    model="openai/gpt-4.1",
    messages=[
        {"role": "system", "content": "You are an expert..."},  # cached automatically if long/repeated
        {"role": "user", "content": "Question here"},
    ],
)

# Check cache savings in the response usage
usage = response.usage
print(f"Prompt tokens: {usage.prompt_tokens}")
print(f"Cached tokens: {usage.prompt_tokens_details.cached_tokens}")
print(f"Cache savings: {usage.prompt_tokens_details.cached_tokens / usage.prompt_tokens * 100:.1f}%")
Claude benötigt einen expliziten cache_control-Marker
Fügen Sie cache_control: {"type": "ephemeral"} zu dem Content-Block hinzu, den Sie cachen möchten (siehe Beispiel unten). Anthropic erzwingt außerdem eine eigene Mindest-Prompt-Länge, unterhalb derer trotz Markierung nicht gecacht wird — ohne Fehlermeldung. Prüfen Sie cached_tokens (OpenAI-Format) bzw. cache_read_input_tokens / cache_creation_input_tokens (Anthropic-Format) in der Antwort, um einen Treffer zu bestätigen.
# Claude models: you must mark the block to cache yourself.
response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6",
    messages=[
        {
            "role": "system",
            "content": [
                {"type": "text", "text": "You are an expert...", "cache_control": {"type": "ephemeral"}}
            ],
        },  # BazaarLink does not add cache_control on your behalf
        {"role": "user", "content": "Question here"},
    ],
)

usage = response.usage
print(f"Cache read tokens: {getattr(usage, 'cache_read_input_tokens', 0)}")
print(f"Cache write tokens: {getattr(usage, 'cache_creation_input_tokens', 0)}")

Reasoning-Tokens

Reasoning-Modelle (z.B. DeepSeek R1, o1-Serie) denken intern nach, bevor sie ihre endgültige Antwort produzieren. Diese internen Tokens werden Reasoning-Tokens genannt und separat abgerechnet.

Note
BazaarLink meldet Reasoning-Tokens in `usage.completion_tokens_details.reasoning_tokens` und zeigt sie in der Abrechnung separat an.

Reasoning-Tokens aus Antworten lesen

response = client.chat.completions.create(
    model="deepseek/deepseek-r1",
    messages=[{"role": "user", "content": "Solve: if f(x) = x^2 + 3x, what is f(5)?"}],
)

# Read reasoning tokens from usage
usage = response.usage
print(f"Completion tokens: {usage.completion_tokens}")
if hasattr(usage, "completion_tokens_details"):
    details = usage.completion_tokens_details
    print(f"Reasoning tokens: {details.reasoning_tokens}")
    print(f"Output tokens: {details.accepted_prediction_tokens}")
const response = await client.chat.completions.create({
  model: "openai/o3-mini",
  messages: [{ role: "user", content: "Prove that sqrt(2) is irrational." }],
  // @ts-ignore - BazaarLink extension
  reasoning_effort: "high",  // low | medium | high
});

const usage = response.usage;
console.log("Reasoning tokens:", usage?.completion_tokens_details?.reasoning_tokens);

Denkmodus-Steuerung

Einige Modelle unterstützen das Umschalten ihres "Denkmodus". Der Denkmodus generiert interne Reasoning-Tokens vor der endgültigen Antwort und verbessert die Qualität auf Kosten von mehr Tokens.

ModellfamilieParameterStandard
qwen3-*enable_thinking: booleanfalse (Plattformstandard)
openai/o1, o3, o4-minireasoning_effort: "low" | "medium" | "high"medium
deepseek/deepseek-r1Immer aktiviert (kann nicht deaktiviert werden)
# Qwen3: explicitly enable thinking mode
response = client.chat.completions.create(
    model="qwen/qwen3-32b",
    messages=[{"role": "user", "content": "Prove the Pythagorean theorem"}],
    extra_body={"enable_thinking": True},  # opt-in to thinking
)

# usage.completion_tokens_details.reasoning_tokens shows thinking token count

Einheitliches reasoning-Objekt (neues Format)

BazaarLink unterstützt auch das einheitliche reasoning-Objekt, das mit einer einzigen konsistenten API über alle Modellfamilien hinweg funktioniert:

FeldWerteGilt für
reasoning.effort"xhigh" | "high" | "medium" | "low" | "none"OpenAI o-series, Grok
reasoning.max_tokensintegerAnthropic Claude, Gemini
reasoning.excludebooleanDenkprozess in der Antwort ausblenden (Modell denkt trotzdem nach)
// Claude extended thinking — specify thinking budget in tokens
const response = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4.5",
  messages: [{ role: "user", content: "Prove the Pythagorean theorem" }],
  // @ts-ignore - BazaarLink extension
  reasoning: { max_tokens: 5000 },
});

// OpenAI o3 — specify effort level
const response2 = await client.chat.completions.create({
  model: "openai/o3",
  messages: [{ role: "user", content: "Solve this math problem..." }],
  // @ts-ignore - BazaarLink extension
  reasoning: { effort: "high" },
});

// Hide thinking content from response (model still thinks)
const response3 = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4.5",
  messages: [{ role: "user", content: "What is 2+2?" }],
  // @ts-ignore - BazaarLink extension
  reasoning: { max_tokens: 2000, exclude: true },
});
Preise
Denk-Tokens werden als Completion-Tokens berechnet. Einige Anbieter berechnen einen höheren Preis für den Denkmodus — Qwen3 kostet 2x den Standardpreis, wenn Denken aktiviert ist. BazaarLink setzt Qwen3 standardmäßig auf enable_thinking=false, um unerwartete Kosten zu vermeiden.

Latenz & Performance

Die Optimierung der KI-API-Antwortlatenz ist entscheidend für die Benutzererfahrung. Nachfolgend die Schlüsselfaktoren, die die Latenz in der BazaarLink-Architektur beeinflussen, und Best Practices zur Optimierung.

Note
BazaarLink erfasst `duration_ms` (End-to-End-Latenz) und `throughput` (Tokens/Sek.) für jede Anfrage — abrufbar über GET /api/v1/generation?id=... oder im Activity-Export-CSV.

Faktoren, die die Latenz beeinflussen

  • Modellgröße: größere Modelle (70B+) sind generell langsamer bei der Generierung
  • Anbieterlast: variiert über Anbieter und Tageszeit hinweg
  • Token-Anzahl: höhere max_tokens bedeuten längere Completion-Zeit
  • Streaming vs. Non-Streaming: stream: true liefert das erste Token schneller
  • Kontextlänge: sehr lange Kontexte erhöhen die Vorverarbeitungszeit

Optimierungstipps

  • Bevorzugen Sie Streaming (stream: true) zur Verbesserung der gefühlten Latenz
  • Verwenden Sie die :nitro-Variante für Hochdurchsatz-Anbieter
  • Wählen Sie kleinere Modelle (flash/mini/haiku) für latenzsensitive Szenarien
  • Verwenden Sie provider.sort: "latency" für automatische Auswahl des latenzärmsten Anbieters
  • Aktivieren Sie Prompt-Caching zur Latenzreduktion bei wiederholten Anfragen
import time

# Measure time to first token with streaming
start = time.time()
first_token_time = None

stream = client.chat.completions.create(
    model="google/gemini-2.5-flash",  # Fast model
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content and not first_token_time:
        first_token_time = time.time() - start

print(f"Time to first token: {first_token_time:.3f}s")
# Look up per-request latency and throughput after the fact, using the
# generation ID from the response (or the final streamed chunk).
curl "https://bazaarlink.ai/api/v1/generation?id=chatcmpl-abc123" \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY"

# Response
{
  "data": {
    "id": "chatcmpl-abc123",
    "model": "google/gemini-2.5-flash",
    "duration_ms": 842,
    "throughput": 61.2,
    "usage": { "prompt_tokens": 12, "completion_tokens": 48, "total_tokens": 60 }
  }
}
# Use provider.sort for automatic latency optimization
response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={
        "provider": {
            "sort": "latency",  # Always pick lowest-latency provider
        }
    },
)

Verfügbarkeitsoptimierung

BazaarLink maximiert die API-Verfügbarkeit durch mehrere Ebenen: automatisches Failover, Circuit Breaker und Anbieter-Gesundheitsüberwachung.

Note
BazaarLink verfolgt die Verfügbarkeit aller Upstream-Anbieter. Wenn die Fehlerrate eines Anbieters einen Schwellenwert überschreitet, löst der Circuit Breaker automatisch aus und leitet Anfragen an den nächsten verfügbaren Anbieter weiter.

Verfügbarkeitsmechanismen

  • Circuit Breaker: erkennt und isoliert automatisch fehlgeschlagene Anbieter
  • Automatisches Failover: wechselt nahtlos zu einem Backup-Anbieter — keine Codeänderungen erforderlich
  • Anbieter-Gesundheitsüberwachung: verfolgt kontinuierlich Fehlerraten und Latenz pro Anbieter
  • Retry-Logik: transiente Fehler (5xx) werden automatisch wiederholt

Leistungsschalter

# BazaarLink handles failover automatically — no code changes needed.
# Configure fallback models for maximum resilience:

response = client.chat.completions.create(
    model="openai/gpt-4o",       # Primary model
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={
        "models": [              # Fallback chain
            "openai/gpt-4o",
            "anthropic/claude-sonnet-4.6",
            "google/gemini-2.5-flash",
        ],
        "route": "fallback",     # Enable fallback routing
    },
)

# Check if failover was used (in usage logs)
# "is_failover": true indicates the primary provider was bypassed
Anbieter-Health-Monitoring ist eine interne Betriebsansicht
GET /api/admin/provider-health ist ein interner Endpunkt für das Betriebs-Dashboard, geschützt durch Admin-Authentifizierung. Er liefert vollständige Betriebsdaten (Anfragevolumen, Fehlerraten, Latenz-Perzentile, Failover-Statistiken je Anbieter u.v.m.) — keine öffentliche Kunden-API, daher bilden wir die genauen Felder hier nicht nach.

Guardrails

Fügen Sie Ihren API-Anfragen Inhaltssicherheitsmechanismen hinzu, um schädliche Inhalte zu filtern und Compliance-Richtlinien durchzusetzen. BazaarLink bietet anpassbare Content-Filter-Guardrails derzeit nur auf Organisationsebene an; persönliche (Nicht-Organisations-) API-Schlüssel haben keine entsprechende Einstellung — die Inhaltssicherheit verlässt sich vollständig auf die eigenen integrierten Sicherheitssysteme der jeweiligen Upstream-Modellanbieter.

Aktueller Umfang
Persönliche API-Schlüssel haben keine integrierten benutzerdefinierten Guardrails — die Inhaltssicherheit verlässt sich vollständig auf die Sicherheitssysteme des Upstream-Anbieters. Wenn Sie anpassbare Content-Filter-Regeln benötigen (Blockieren/Schwärzen/Protokollieren, Schlüsselwort- und Regex-Regeln, integrierte PII-Vorlagen), erstellen Sie eine Organisation und verwenden Sie einen Organisations-API-Schlüssel — konfigurierbar unter "Content Filter Guardrails."

Geplante Funktionen (weder für persönliche noch für Organisations-Schlüssel verfügbar)

Guardrail
Beschreibung
PII-ErkennungPersönlich identifizierbare Informationen erkennen und schwärzen
ThemenbeschränkungModellantworten auf zugelassene Themen beschränken
AusgabevalidierungModellausgaben vor der Rückgabe gegen benutzerdefinierte Regeln validieren

Aktuelles Verhalten

Persönliche API-Schlüssel: Alle Upstream-Anbieter haben eigene Inhaltssicherheitssysteme — Modellantworten, die Inhaltsfilter auslösen, werden mit finish_reason: "content_filter" zurückgegeben, und BazaarLink wendet keine zusätzliche Filterung an. Organisations-API-Schlüssel: org_admin kann unter "Content Filter Guardrails" benutzerdefinierte Regeln (Blockieren/Schwärzen/Protokollieren) konfigurieren, die angewendet werden, bevor der Text das Modell erreicht.

Cursor IDE Integration

Verwende BazaarLink als Cursors OpenAI Override URL. Drop-in-Setup mit automatischer Responses-API-Konvertierung, Tool-Format-Normalisierung und der bz--Präfix-Konvention für Claude-Modelle.

Schnelleinrichtung

Öffne in Cursor Einstellungen → Modelle und dann:

  1. Setze Override OpenAI Base URL auf https://bazaarlink.ai/v1
  2. Setze Override OpenAI API Key auf deinen sk-bl-... BazaarLink-Key
  3. Füge den gewünschten Modellnamen hinzu — siehe unten für Claude (das bz--Präfix).
Abwärtskompatibilität
Die alte URL https://bazaarlink.ai/v1/cursor funktioniert weiterhin — sie ist jetzt ein dünner Re-Export von /v1/chat/completions. Neue Setups sollten /v1 direkt verwenden.

Das bz--Präfix (für Claude-Modelle)

Cursors clientseitige Validierung leitet jeden Modellnamen, der mit claude- beginnt, durch Cursors eigene Anthropic-Integration und umgeht deine Override URL. Um Cursor dazu zu bringen, die Anfrage an BazaarLink zu senden, präfixiere den Modellnamen mit bz-. Der Server entfernt das Präfix und löst den Rest über die Alias-Map auf.

In Cursor eingebenWird aufgelöst zu
bz-claude-sonnet-4.6anthropic/claude-sonnet-4.6
bz-claude-opus-4.7anthropic/claude-opus-4.7
gpt-4oopenai/gpt-4o
gemini-2.5-flashgoogle/gemini-2.5-flash

Punkt- vs. Bindestrich-Varianten werden normalisiert: bz-claude-sonnet-4.6 und bz-claude-sonnet-4-6 lösen beide zum selben Modell auf.

CURSOR_MODEL_MAP-Umgebungsvariable (Betreiber-Override)

Für selbst gehostete BazaarLink-Deployments: Mit dieser Env-Var lassen sich beliebige Cursor-seitige Modellnamen auf kanonische Katalog-IDs ummappen:

CURSOR_MODEL_MAP=gpt-claude-sonnet:anthropic/claude-sonnet-4.6,gpt-opus:anthropic/claude-opus-4.7

Jetzt wird in Cursor eingegebenes gpt-claude-sonnet serverseitig auf anthropic/claude-sonnet-4.6 gemappt. Nützlich, wenn Cursor denken soll, ein Modell sei GPT-Familie (damit es durch die Override URL geroutet wird), während du tatsächlich Claude bereitstellst.

Was automatisch passiert

Wenn eine Anfrage an /api/v1/chat/completions geht, wendet BazaarLink folgende Kompatibilitätstransformationen transparent an — clientseitig ist nichts zu tun:

  • Erkennt Responses-API-Bodies automatisch — wenn der Body input statt messages hat, wird er ins Chat-Completions-Format konvertiert (Cursor sendet das Responses-API-Format für GPT-Familien-Modelle).
  • Wickelt flache Tool-Definitionen ein — Cursor Agent sendet { name, description, parameters } ohne function-Wrapper. Wir wrappen sie, damit Anthropic nicht mit Tool '' not found in provided tools ablehnt.
  • Erzwingt korrektes tool_choice — Cursor sendet { type: "auto" } (Objektform, kein function). Die OpenAI-Spezifikation verlangt die String-Form für auto/none/required, daher konvertieren wir.
  • Entfernt OpenAI-spezifische Felder beim Routing zu Nicht-OpenAI-Providern — parallel_tool_calls, logprobs, top_logprobs, logit_bias, service_tier, user werden vor dem Weiterleiten entfernt (sonst gibt Anthropic 400 zurück).
  • Mappt max_output_tokens → max_tokens und entfernt Responses-API-spezifische Felder (previous_response_id, truncation, background, store). Das reasoning-Feld bleibt für Chat-Completions-native Bodies erhalten.

Cursor-Agent-Modus

Tool-Calling läuft über den Standard-Chat-Completions-Tool-Call-Flow. Cursor sendet tools (Shell, Read, Write, Grep etc.) mit tool_choice: "auto"; BazaarLink leitet an den gewählten Provider weiter, der entscheidet, ob ein Tool aufgerufen wird. Tool-Aufrufe kommen als Standard-OpenAI-tool_calls-Deltas zurück; Cursor führt lokal aus und setzt das Gespräch fort. Funktioniert gleich, ob du gpt-4o (nativ OpenAI) oder bz-claude-sonnet-4.6 wählst.

Upstream-Ablehnungen debuggen
Wenn du Provider-4xx-Fehler siehst, schau ins Admin-Panel Provider Health. Jede 4xx-Antwort wird mit dem vollständigen Upstream-Fehler-Body und einer Zusammenfassung des weitergeleiteten Request-Bodys gespeichert — klicke auf eine 🔴-Zeile, um das JSON aufzuklappen.

Modell-Routing

BazaarLink verwendet das Format provider/model-name, um Anfragen an den richtigen Upstream-Anbieter weiterzuleiten. Dies gibt Ihnen Zugang zu allen gängigen Modellen über einen einzigen API-Endpunkt.

Modell-ID-Format

{provider}/{model-name}

# Examples
openai/gpt-5.4-mini
anthropic/claude-sonnet-4.6
google/gemini-3-flash-preview
deepseek/deepseek-v3.2

Routing-Priorität

Wenn Sie eine Anfrage senden, löst BazaarLink den Upstream-Anbieter in dieser Reihenfolge auf:

  1. Exakte Übereinstimmung — sucht nach einer Modellroute, die der vollständigen Modell-ID entspricht
  2. Anbieter-Wildcard — fällt auf provider/*-Routen zurück (z.B. openai/*)
  3. Globale Wildcard — fällt auf *-Wildcard-Routen zurück
  4. Standard-Anbieterschlüssel — nur für bekannte Katalogmodelle; verwendet aktivierte, als Standard markierte Schlüssel

Alle verfügbaren Modelle durchsuchen auf der Modellseite.

Auto Router

Auto Router v3 bewertet die Anfrage in eine von 14 Aufgabenstufen und verwendet dann die aktuell konfigurierte Primary- und Fallback-Kette dieser Stufe. Bezahlte und kostenlose Tabellen werden im Admin getrennt verwaltet.

  • auto — verwendet die bezahlte Routing-Tabelle; das erfolgreiche tatsächliche Modell wird zum veröffentlichten Preis berechnet.
  • auto:free — verwendet die kostenlose Routing-Tabelle; innerhalb des Kontingents kostet der Aufruf 0 USD. Danach können Konten mit Guthaben zu bezahltem auto wechseln, sofern der bezahlte Fallback nicht deaktiviert ist.

Verwendung

Setzen Sie das Modell auf "auto" (kostenpflichtig) oder "auto:free" (kostenlos), um automatisches Routing zu aktivieren:

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto","messages":[{"role":"user","content":"Review this TypeScript function"}]}'

Wie v3 eine Stufe auswählt

Allgemeine Stufen: simple, standard, complex, reasoning. Spezialstufen: coding, vision, image, video, data, search, social, email, calendar, trading. Ergebnisse an einer unsicheren Grenze werden um eine Stufe angehoben.

  • Tier-Bewertung: messages, tools, Länge, Schlüsselwörter und Struktur wählen eine von 14 Stufen
  • Feste Regeln: Bild-, formale Denk- und Spezialaufgaben können eine Stufe direkt wählen
  • Route-Lookup: liest Primary und bis zu fünf Fallbacks; eine deaktivierte Stufe liefert 503
  • Ausführung: versucht Primary und danach die Fallbacks in konfigurierter Reihenfolge
  • Antwortverfolgung: das aufgelöste Modell wird im Antwort-Body und X-Auto-Resolved-Model-Header zurückgegeben

Aktuelle Modelltabellen

Die Tabellen lesen dieselbe Live-Konfiguration wie Inferenz und Admin. Primary, Fallback-Reihenfolge und Status jeder Stufe können ohne Deployment geändert werden.

auto

Tier
Primary
Fallbacks
State
simpleopenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-previewanthropic/claude-haiku-4.5
enabled
standardgoogle/gemini-3-flash-preview
openai/gpt-5.4-minianthropic/claude-haiku-4.5
enabled
complexgoogle/gemini-3.1-pro-preview
anthropic/claude-sonnet-4.6openai/gpt-5.4-pro
enabled
reasoninganthropic/claude-opus-4.7
openai/gpt-5.4-progoogle/gemini-3.1-pro-preview
enabled
codingopenai/gpt-5.3-codex
anthropic/claude-sonnet-4.6openai/gpt-5.4-pro
enabled
visionopenai/gpt-5.4-image-2
enabled
imageopenai/gpt-5.4-image-2
enabled
videobytedance/seedance-2.0-fast
bytedance/seedance-2.0anthropic/claude-sonnet-4.6
enabled
dataopenai/gpt-5.4-pro
anthropic/claude-sonnet-4.6google/gemini-3.1-pro-preview
enabled
searchperplexity/sonar-pro
perplexity/sonar-reasoning-proopenai/gpt-5.4-pro
enabled
socialopenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-previewanthropic/claude-haiku-4.5
enabled
emailopenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-previewanthropic/claude-sonnet-4.6
enabled
calendaropenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-preview
enabled
tradinganthropic/claude-opus-4.7
openai/gpt-5.4-progoogle/gemini-3.1-pro-preview
enabled

auto:free

Tier
Primary
Fallbacks
State
simpledeepseek/deepseek-v4-flash
enabled
standarddeepseek/deepseek-v4-flash
enabled
complexminimax/minimax-m2.5
enabled
reasoningminimax/minimax-m2.5
enabled
codingdeepseek/deepseek-v4-flash
enabled
visionopenai/gpt-5.4-image-2
disabled
imageopenai/gpt-5.4-image-2
disabled
videogoogle/gemini-2.5-flash-lite
disabled
datadeepseek/deepseek-v4-flash
enabled
searchminimax/minimax-m2.5
enabled
socialdeepseek/deepseek-v4-flash
enabled
emaildeepseek/deepseek-v4-flash
enabled
calendardeepseek/deepseek-v4-flash
enabled
tradingdeepseek/deepseek-v4-flash
enabled

Ausgewählte Modelle bieten ein ratenbegrenztes kostenloses Kontingent. Die Berechtigung wird pro Modell von der Plattform vergeben — rufen Sie das Modell mit seiner regulären ID auf; das Suffix :free ist ein optionaler Alias (bei einem kostenpflichtigen Modell macht es dieses nicht kostenlos).

Nach dem Aufbrauchen des Kontingents
Ist das Kontingent erschöpft, laufen Anfragen bei vorhandenem Guthaben automatisch zum regulären Preis des Modells weiter — ohne Unterbrechung und exakt wie ein normaler kostenpflichtiger Aufruf abgerechnet. Wer lieber einen Fehler als eine Abrechnung möchte, sendet den Header X-Free-Fallback: false oder deaktiviert den automatischen Wechsel in den Schlüsseleinstellungen; dann kommt ein 429 zurück. Ohne Guthaben liefern Anfragen über dem Kontingent immer 429.
X-Auto-Resolved-Model
Das tatsächlich gewählte Modell wird im X-Auto-Resolved-Model-Header und im model-Feld der Antwort zurückgegeben.

Modellvarianten

Hängen Sie ein Suffix an jede Modell-ID an, um das Routing-Verhalten zu ändern. BazaarLink unterstützt 7 Variantentypen.

Variantentypen
Es gibt zwei Kategorien von Varianten: Unabhängige Modell-IDs (das suffixed Modell ist ein eigenständiger Endpunkt) und Routing-Shortcuts (das Suffix ändert, wie BazaarLink einen Anbieter auswählt, ohne das Modell selbst zu ändern).

Unabhängige Modell-IDs

Diese Varianten existieren als separate Modelle mit eigener Preisgestaltung und Fähigkeiten. BazaarLink probiert zuerst die vollständige Modell-ID (mit Suffix) und fällt dann auf das Basismodell zurück.

:free
:extended
:thinking
:exacto

Routing-Shortcuts

Diese Suffixe ändern die Anbieterauswahl, ohne die Modellidentität zu ändern. Das Suffix wird vor dem Routenabgleich entfernt.

:floor   # lowest listed input price first
:nitro   # throughput-oriented shortcut
:online  # enable web-search routing

Multi-Provider-Verhalten

Für Upstreams, die Varianten unterstützen, werden Suffixe unverändert weitergeleitet. Für direkte Anbieter (z.B. direkt OpenAI, Fireworks) wird das Suffix entfernt und BazaarLink verarbeitet das Routing lokal.

Kostenlose Modelle

Ausgewählte Modelle bieten ein ratenbegrenztes kostenloses Kontingent. Die Berechtigung wird pro Modell von der Plattform vergeben — rufen Sie das Modell mit seiner regulären ID auf; das Suffix :free ist ein optionaler Alias (bei einem kostenpflichtigen Modell macht es dieses nicht kostenlos).

  • Rufen Sie die reguläre Modell-ID auf (z. B. deepseek/deepseek-v4-flash). Anfragen innerhalb des kostenlosen Kontingents werden automatisch kostenlos bedient.
  • Die kostenlose Nutzung ist pro Nutzer durch Anfragen pro Minute und ein Tageslimit begrenzt. Die Limits skalieren mit der Kontostufe (kein Guthaben / mit Guthaben).
  • Wenn Sie das kostenlose Kontingent überschreiten und Guthaben haben, laufen Anfragen automatisch zum gelisteten Preis auf der bezahlten Stufe weiter. Senden Sie X-Free-Fallback: false, um den automatischen Fallback zu deaktivieren und stattdessen 429 zu erhalten. Ohne Guthaben liefern Anfragen über dem Kontingent 429.
  • GET /api/v1/models listet für jedes Modell mit kostenlosem Kontingent einen :free-Eintrag; auto:free routet immer zu einem kostenlosen Modell.

Modelle mit kostenlosem Kontingent

Diese Modell-IDs direkt aufrufen, um das kostenlose Kontingent zu nutzen. Die Liste ändert sich mit dem Angebot — die aktuelle Fassung liefert die API.

deepseek/deepseek-v4-flash

Grenzen des kostenlosen Kontingents

Position
Wert
Anfragen pro Minute (RPM)10 / min
Tägliches Anfragebudget150 / day
Kontostufen-Multiplikator — ohne Guthaben× 1
Kontostufen-Multiplikator — mit Guthaben× 3

Tagesbudget = obiges Anfragebudget × Kontostufen-Multiplikator, je kostenlosem Modell getrennt gezählt. Für auto:free gilt zusätzlich eine parallele Obergrenze pro IP. Einzelne Modelle können strengere oder großzügigere Limits haben; die effektiven Werte zeigt der Block „Kostenloses Kontingent“ auf der Modellseite.

Nach dem Aufbrauchen des Kontingents

Ist das Kontingent erschöpft, laufen Anfragen bei vorhandenem Guthaben automatisch zum regulären Preis des Modells weiter — ohne Unterbrechung und exakt wie ein normaler kostenpflichtiger Aufruf abgerechnet. Wer lieber einen Fehler als eine Abrechnung möchte, sendet den Header X-Free-Fallback: false oder deaktiviert den automatischen Wechsel in den Schlüsseleinstellungen; dann kommt ein 429 zurück. Ohne Guthaben liefern Anfragen über dem Kontingent immer 429.

# Return 429 instead of switching to paid routing
-H "X-Free-Fallback: false"

Organisationsverwaltung

BazaarLink-Organisationen verwenden eine dreistufige Architektur: Organisation → Team → Mitglied. Guthaben wird auf Org-Ebene gespeichert; jedes Team und Mitglied kann ein monatliches Ausgabenlimit haben. API-Anfragen prüfen Mitglied → Team → Org-Guthaben in Reihenfolge.

Organisation verwalten
Um Teams hinzuzufügen, Mitglieder einzuladen oder Einstellungen zu ändern, Einstellungen öffnen und Organisation auswählen

Dreistufiges Budgetsystem

Bei jeder API-Anfrage werden drei Budgetebenen der Reihe nach geprüft. Überschreitung einer Ebene gibt HTTP 429 zurück:

  1. Monatliches Mitgliederbudget (OrgMember.monthlyBudget)
  2. Monatliches Teambudget (Team.monthlyBudget)
  3. Org-Guthabenstand (Organization.credits)

Nutzungsberichte

Die Berichtsseite im Org-Portal bietet monatliche Ausgabenanalysen über vier Dimensionen:

  • Übersicht: Gesamtausgaben, Margenrate, täglicher Trendchart
  • Nach Team: Ausgaben pro Team, Anteil %, Modellaufschlüsselung, Budgetauslastung
  • Nach Modell: Ausgaben pro Modell, Durchschnittspreis ($/1M Tokens)
  • Nach Mitglied: Ausgaben pro Mitglied — nur org_admin

Alle Ansichten unterstützen CSV-Export mit BOM-Präfix für direkte Excel-Kompatibilität.

Organisationen erstellen & verwalten

  1. Gehen Sie zu Einstellungen → Organisationen → Neue Organisation erstellen
  2. Erstellen Sie Teams im Org-Portal (optional: Kostenstelle und Monatsbudget)
  3. Laden Sie Mitglieder per E-Mail ein, weisen Sie eine Rolle und ein Team zu
  4. Stellen Sie API-Schlüssel für Mitglieder aus — die Nutzung wird automatisch dem korrekten Team/Mitglied zugeordnet
  5. Sehen Sie die Berichtsseite für monatliche Ausgaben aufgeschlüsselt nach Team, Modell oder Mitglied
  6. Sehen Sie sich die Seite „Berichte“ für die monatlichen Ausgaben an, aufgeschlüsselt nach Team, Modell oder Mitglied

Mitgliederrollen

org_adminVolle Kontrolle: Mitglieder, Teams, Abrechnung, Einstellungen
billing_viewerLesezugriff auf Finanzberichte (kann keine Mitgliederdetails sehen)
team_adminMitglieder und Budget innerhalb des eigenen Teams verwalten
MitgliedAPI nutzen, unterliegt Team- und Org-Budgetlimits

Was kann eine Organisation sonst noch verwalten?

Über Mitglieder und Teams hinaus bietet der Bereich Organisationsmanagement:

  • API keys and model restrictions
  • Content filtering before text reaches a model
  • Allowed Models by organization, team, member, or key
  • Monthly budgets and spend emergency brakes
  • Reports, billing, change logs, and security logs
  • Education sessions and quotas for eligible organizations
  • Institution-Pläne: Bildungsorganisationen können zusätzlich Studentensitzungen und Quoten verwalten

Inhaltsfilterung

Organization-owned rules inspect text before it reaches a model. An org_admin can enable, edit, and test them in Settings.

  • block: reject with HTTP 403
  • redact: replace matches with [REDACTED]
  • flag: send unchanged and record an audit event
  • Built-in sensitive-data and prompt-injection templates plus custom keyword or regex rules
  • Up to 100 safety-checked rules with a test preview
Derzeit auf Texteingabe beschränkt
Images, audio, video, some structured or multimodal content, and model output are not inspected.

Management API (v1)

Die /api/v1/orgs/-Endpunkte akzeptieren sowohl Bearer-Management-Schlüssel (sk-bl-...) als auch Session-Cookie und ermöglichen Server-zu-Server-Org-Verwaltung ohne Browser-Session.

Authentifizierung
Alle /api/v1/orgs/-Endpunkte erfordern die org_admin-Rolle. Übergeben Sie Authorization: Bearer sk-bl-<key> oder ein Session-Cookie. Management-Schlüssel können unter Einstellungen → API-Schlüssel erstellt werden.

Organisationen

GET/api/v1/orgs

Listet alle Organisationen auf, denen der Aufrufer angehört, mit Rolle und joinedAt.

GET/api/v1/orgs/:orgId

Ruft Org-Details einschließlich Team- und Mitgliederanzahl ab.

curl https://bazaarlink.ai/api/v1/orgs \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

Teams

GET/api/v1/orgs/:orgId/teams

Listet Teams mit Mitgliederanzahl auf, sortiert nach Name.

POST/api/v1/orgs/:orgId/teams
nameerforderlich
string
Anzeigename des Teams (muss innerhalb der Org eindeutig sein)
costCenterCode
string
Kostenstellen-Code für die Buchhaltung
monthlyBudget
number | null
Monatliches Ausgabenlimit des Teams in USD
PATCH/api/v1/orgs/:orgId/teams/:teamId

Teilweises Update — geben Sie nur die zu ändernden Felder an.

DELETE/api/v1/orgs/:orgId/teams/:teamId
# Create a team
curl https://bazaarlink.ai/api/v1/orgs/{orgId}/teams \
  -X POST \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Engineering", "costCenterCode": "ENG-001", "monthlyBudget": 500}'

Mitglieder

GET/api/v1/orgs/:orgId/members

Listet alle Mitglieder mit verschachtelten Benutzer- (id/name/email) und Team-Informationen auf.

POST/api/v1/orgs/:orgId/members
emailerforderlich
string
E-Mail eines bestehenden BazaarLink-Benutzers
role
string
org_admin | billing_viewer | team_admin | member (Standard: member)
teamId
string
Einem Team zuweisen (erforderlich, wenn role team_admin ist)
monthlyBudget
number | null
Monatliches Ausgabenlimit pro Mitglied in USD

404, wenn die E-Mail-Adresse kein BazaarLink-Konto hat. 409, wenn bereits Mitglied. Standardrolle: member.

PATCH/api/v1/orgs/:orgId/members/:memberId

Teilweises Update von role, teamId oder monthlyBudget.

DELETE/api/v1/orgs/:orgId/members/:memberId

Gibt 400 zurück, wenn das Ziel der letzte org_admin ist.

# Add a member
curl https://bazaarlink.ai/api/v1/orgs/{orgId}/members \
  -X POST \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "alice@example.com", "role": "member", "monthlyBudget": 50}'

# Remove a member
curl https://bazaarlink.ai/api/v1/orgs/{orgId}/members/{memberId} \
  -X DELETE \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

Berichts-API

Monatliche Ausgabendaten programmatisch abfragen. Zugänglich für org_admin und billing_viewer. Akzeptiert sowohl Web-Session als auch Bearer-Management-Schlüssel.

Query-Parameter: year (Standard aktuell), month (Standard aktuell, 1–12).

Endpunkt
Beschreibung
GET /api/orgs/:orgId/reports/overviewGesamtausgaben, Margenrate, täglicher Trend
GET /api/orgs/:orgId/reports/by-teamAusgaben pro Team, Anteil in %, Modell-Aufschlüsselung, Budget-Auslastung
GET /api/orgs/:orgId/reports/by-modelAusgaben pro Modell, Durchschnittspreis ($/1M Tokens)
GET /api/orgs/:orgId/reports/by-memberAusgaben pro Mitglied — nur org_admin
GET /api/orgs/:orgId/reports/exportCSV-Download; fügen Sie ?view=overview|by-team|by-model|by-member hinzu
# Monthly overview via management key
curl "https://bazaarlink.ai/api/orgs/{orgId}/reports/overview?year=2026&month=3" \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

# By-team breakdown
curl "https://bazaarlink.ai/api/orgs/{orgId}/reports/by-team?year=2026&month=3" \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

# Export CSV (downloads file)
curl "https://bazaarlink.ai/api/orgs/{orgId}/reports/export?year=2026&month=3&view=by-team" \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
  -o report.csv

Fehlerantwort-Referenz

401API-Key ungültig oder widerrufen
403RBAC-Ablehnung (unzureichende Rolle) oder Modell nicht in Allowed Models Whitelist
402Eine der drei Budget-Ebenen überschritten; Response Body enthält Scope (member / team / org) und Reset Time
429Spend Circuit Breaker ausgelöst; Retry-After-Header zeigt Recovery-Zeit in Sekunden
503Plattformweite Notbremsung oder vorübergehender Serviceausfall

Erlaubte Modelle (Whitelist)

Schränken Sie ein, welche Modelle Ihre Organisation, Teams oder einzelne Mitglieder aufrufen dürfen. Nützlich, um teure oder ungeprüfte Modelle zu blockieren, Modellstandards durchzusetzen oder ein Team auf einen einzigen Provider zu beschränken.

So funktioniert es

  • Drei unabhängige Ebenen — Organisation, Team, Mitglied — jede führt ihre eigene Liste (String[] in der Datenbank).
  • Wenn alle drei Ebenen leer sind, sind alle Modelle erlaubt (Standardverhalten).
  • Wenn eine oder mehrere Ebenen nicht leer sind, ist die effektive Liste die Schnittmenge der nicht leeren Ebenen — ein Modell muss auf jeder eingeschränkten Ebene erlaubt sein, um durchzukommen.
  • Änderungen werden innerhalb weniger Sekunden wirksam (60s In-Memory + 5min Redis-Cache; beide werden bei einer Aktualisierung geleert).

Musterformat

  • Exakte Übereinstimmung — z. B. openai/gpt-4o (nur genau dieses Modell).
  • Provider-Wildcard — z. B. openai/* (jedes Modell unter dem openai/-Präfix).
  • Nur Kleinbuchstaben. Maximal 200 Einträge pro Liste, 100 Zeichen pro Eintrag.

Wo verwalten

Org-Portal → Erlaubte Modelle. org_admin kann Org-, Team- und Mitgliederlisten bearbeiten; team_admin kann das eigene Team und dessen Mitglieder bearbeiten.

Fehlerantwort bei Blockierung

Aufrufe an ein nicht erlaubtes Modell geben HTTP 403 mit folgendem Body zurück:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": {
    "message": "Model is not allowed for this account",
    "code": "model_not_allowed"
  }
}

Verwaltungs-API

Alle Endpunkte akzeptieren Web-Session oder Bearer Management Key (sk-bl-...). PATCH ersetzt die gesamte Liste; übergeben Sie [], um sie zu leeren.

# Org-level list
GET    /api/orgs/:orgId/allowed-models
PATCH  /api/orgs/:orgId/allowed-models

# Team-level list
GET    /api/orgs/:orgId/teams/:teamId/allowed-models
PATCH  /api/orgs/:orgId/teams/:teamId/allowed-models

# Member-level list
GET    /api/orgs/:orgId/members/:memberId/allowed-models
PATCH  /api/orgs/:orgId/members/:memberId/allowed-models

# Example: restrict an org to OpenAI + a specific Anthropic model
curl -X PATCH https://bazaarlink.ai/api/orgs/$ORG_ID/allowed-models \
  -H "Authorization: Bearer sk-bl-..." \
  -H "Content-Type: application/json" \
  -d '{"allowedModels": ["openai/*", "anthropic/claude-sonnet-4.6"]}'

Circuit Breaker (Ausgaben-Notabschaltung)

Eine doppelte Ausgabenobergrenze, die weitere Anfragen blockiert, wenn die Upstream-Kosten in die Höhe schnellen. Entwickelt, um außer Kontrolle geratene Skripte, Endlosschleifen oder Missbrauch gestohlener Schlüssel einzudämmen, bevor sie echtes Geld kosten.

So funktioniert es

  • Pro Scope werden zwei feste Fenster in Redis verfolgt: 1-Minuten- und 1-Stunden-Upstream-Kosten (USD).
  • Wenn die Ausgaben in einem der Fenster den Schwellenwert erreichen, werden alle nachfolgenden Anfragen in diesem Scope abgelehnt, bis das Fenster zurückgesetzt wird.
  • Standardwerte: 5 $ / Minute, 20 $ / Stunde, standardmäßig aktiviert.
  • Zähler leben in Redis mit TTL — die Wiederherstellung erfolgt automatisch, kein manuelles Zurücksetzen für Org-/Team-/Member-Trips erforderlich.

Scopes (Member überschreibt Team überschreibt Org)

Jede Ebene kann eigene Schwellenwerte setzen. Auflösungsreihenfolge ist Member → Team → Org → Plattform-Standard — der erste nicht-null Wert pro Feld gewinnt (cbEnabled, cbMinuteUsd, cbHourlyUsd).

  • Org-Ebene — gilt für alle Schlüssel der Organisation. Eingestellt im Org-Portal → Circuit Breaker.
  • Team-Ebene — gilt für alle Schlüssel, die diesem Team zugewiesen sind. Überschreibt Org für diese Schlüssel.
  • Member-Ebene — gilt nur für Schlüssel, die diesem Mitglied zugewiesen sind. Überschreibt Team und Org.

Auslöseverhalten

Bei Auslösung schlagen Anfragen schnell fehl (es wird kein Upstream-Aufruf getätigt). Die Antwort ist HTTP 429 mit folgendem Body:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": {
    "message": "Spend circuit breaker tripped at member scope (minute window: $5.2341 ≥ $5.00). Try again later or contact your organization owner."
  }
}
Global vs. bereichsspezifisch
Ein separater globaler plattformweiter Circuit Breaker (vom Betreiber gesteuert, nicht im Org-Portal sichtbar) gibt HTTP 503 mit einem Retry-After-Header zurück. Betreiber setzen ihn, um die Plattform gegen Multi-Tenant-Missbrauch zu verteidigen — er kann nicht aus Ihren Org-Einstellungen heraus überschrieben werden.

Audit-Log

Jedes Auslöseereignis und jede Konfigurationsänderung wird aufgezeichnet:

  • Auslöseereignisse — Aktionen org.cb.tripped / team.cb.tripped / org_member.cb.tripped. Dedupliziert auf einen Eintrag pro Scope+Fenster pro Stunde, sodass eine anhaltende Auslösung das Log nicht überflutet.
  • Konfigurationsänderungen — Aktionen org.cb.update / team.cb.update / org_member.cb.update. Erfassen Vorher/Nachher-Werte sowie den Akteur.

Verwaltungs-API

Org-Admins können Einstellungen über die API lesen und aktualisieren. Alle Endpunkte akzeptieren Web-Session oder Bearer Management Key (sk-bl-...). Senden Sie eine beliebige Teilmenge von Feldern im PATCH-Body; null löscht ein Feld und fällt auf die übergeordnete Ebene zurück.

# Org-level config
GET    /api/orgs/:orgId/circuit-breaker
PATCH  /api/orgs/:orgId/circuit-breaker

# Team-level config
GET    /api/orgs/:orgId/teams/:teamId/circuit-breaker
PATCH  /api/orgs/:orgId/teams/:teamId/circuit-breaker

# Member-level config
GET    /api/orgs/:orgId/members/:memberId/circuit-breaker
PATCH  /api/orgs/:orgId/members/:memberId/circuit-breaker

# Example: tighten the org-level cap to $2/min, $10/hr
curl -X PATCH https://bazaarlink.ai/api/orgs/$ORG_ID/circuit-breaker \
  -H "Authorization: Bearer sk-bl-..." \
  -H "Content-Type: application/json" \
  -d '{"cbMinuteUsd": 2, "cbHourlyUsd": 10, "cbEnabled": true}'

# GET response (org scope)
{
  "settings":         { "cbEnabled": true, "cbMinuteUsd": 2,  "cbHourlyUsd": 10  },
  "resolvedSettings": { "cbEnabled": true, "cbMinuteUsd": 2,  "cbHourlyUsd": 10  },
  "liveSpend":        { "minuteSpend": 0.4123, "hourSpend": 3.8721 }
}

API-Schlüssel-Rotation

Regelmäßige Rotation von API-Schlüsseln ist eine Sicherheits-Best-Practice. BazaarLink unterstützt Null-Ausfallzeit-Schlüsselrotation — erstellen Sie zuerst einen neuen Schlüssel, migrieren Sie dann, und widerrufen Sie dann den alten.

Hinweis
API-Schlüssel können jederzeit über das Dashboard oder die Management-API widerrufen werden. Der Widerruf ist sofort wirksam — alle Anfragen mit diesem Schlüssel werden sofort fehlschlagen.

Rotationsschritte

  1. Neuen API-Schlüssel erstellen
  2. Anwendung oder Umgebungsvariablen auf den neuen Schlüssel aktualisieren
  3. Verifizieren, dass der neue Schlüssel korrekt funktioniert
  4. Alten Schlüssel deaktivieren oder löschen
# Key CRUD via Bearer auth requires a MANAGEMENT key (keyType: "management").
# Standard keys get 403 on /api/v1/keys — create a management key first,
# or rotate keys from the dashboard UI instead.

# Step 1: Create new key (management key auth)
POST https://bazaarlink.ai/api/v1/keys
Authorization: Bearer $BL_MANAGEMENT_KEY
{"name": "Production v2"}
# → saves new key: sk-bl-NEW_KEY_VALUE

# Step 2: Update your application
# export BAZAARLINK_API_KEY=sk-bl-NEW_KEY_VALUE

# Step 3: Verify new key works
curl https://bazaarlink.ai/api/v1/models \
  -H "Authorization: Bearer sk-bl-NEW_KEY_VALUE"

# Step 4: Revoke old key (management key auth again)
DELETE https://bazaarlink.ai/api/v1/keys/:old_key_id
Authorization: Bearer $BL_MANAGEMENT_KEY

Aktivitätsexport

Laden Sie Ihren vollständigen API-Nutzungsverlauf als CSV für Finanzprüfungen, Kostenanalysen oder Compliance-Berichte herunter.

CSV-Export

Melden Sie sich an und gehen Sie zur Protokolle-Seite. Klicken Sie auf die CSV-Export-Schaltfläche in der oberen rechten Ecke, um Ihren vollständigen Verlauf als CSV-Datei herunterzuladen. Kein API-Aufruf erforderlich.

CSV-Spalten

Column
Description
dateISO 8601 timestamp (UTC)
modelModel ID (e.g. openai/gpt-4o)
providerUpstream provider name
prompt_tokensInput token count
completion_tokensOutput token count
total_tokensTotal tokens (prompt + completion)
reasoning_tokensReasoning tokens (o-series / thinking models)
cached_tokensPrompt cache hit tokens
cost_usdCost in USD credits
duration_msEnd-to-end latency in milliseconds
finish_reasonstop / length / content_filter / error
statusHTTP status code from upstream
app_nameX-Title header value (app attribution)

JSON-Nutzungs-API

Für programmatischen Zugriff fragen Sie aggregierte Statistiken nach Zeitraum, Modell oder Schlüssel ab:

# Query usage data (grouped / aggregated)
GET https://bazaarlink.ai/api/v1/usage
Authorization: Bearer sk-bl-YOUR_KEY

# With period filtering (day | week | month | year)
GET https://bazaarlink.ai/api/v1/usage?period=month

# Response
{
  "period": "month",
  "since": "2025-01-01T00:00:00.000Z",
  "credits": 10.5000,
  "totals": {
    "spend": 0.1812,
    "requests": 309,
    "tokens": 161200,
    "promptTokens": 95000,
    "completionTokens": 66200
  },
  "byModel": [{ "model": "openai/gpt-4o", "spend": 0.0028, "tokens": 1200, "requests": 5 }],
  "byKey":   [{ "keyName": "My Agent", "spend": 0.0028, "tokens": 1200, "requests": 5 }],
  "byApp":   [{ "appName": "MyApp", "spend": 0.0015, "tokens": 600, "requests": 3 }],
  "timeSeries": [{ "date": "2025-01-15", "model": "openai/gpt-4o", "cost": 0.0012, "tokens": 500, "requests": 2 }]
}

Nutzungsabrechnung

Fragen Sie detaillierte Nutzungsstatistiken über die API ab, einschließlich Token-Verbrauch, Kostenanalyse und Anfrageverlauf.

Hinweis
Nutzungsdaten werden in USD abgerechnet. Einzelne Anfragedatensätze sind auf der Protokolle-Seite oder über CSV-Export verfügbar. Aggregierte Statistiken (nach Zeitraum, Modell oder Schlüssel) sind über den `/api/v1/usage`-Endpunkt mit Bearer-Token-Auth verfügbar.

Antwortfeld-Referenz

FieldTypeDescription
modelstringModel ID used (e.g., openai/gpt-4o)
providerstringUpstream provider name
prompt_tokensnumberInput tokens consumed
completion_tokensnumberOutput tokens generated
total_tokensnumberTotal tokens (prompt + completion)
reasoning_tokensnumberReasoning tokens (for thinking models)
cached_tokensnumberPrompt tokens served from cache
costnumberTotal cost in USD credits
duration_msnumberEnd-to-end latency in milliseconds
throughputnumberGeneration speed in tokens/sec
finish_reasonstringstop | length | content_filter | error
statusnumberHTTP status code from upstream
app_namestring | nullApplication name (X-Title header)
key_namestringAPI key name used for the request
import httpx

# Aggregated stats (Bearer token — period: day | week | month | year)
response = httpx.get(
    "https://bazaarlink.ai/api/v1/usage",
    headers={"Authorization": "Bearer sk-bl-YOUR_KEY"},
    params={"period": "month"},
)

data = response.json()
totals = data["totals"]
print("This month: US$%.4f  (%d requests)" % (totals["spend"], totals["requests"]))

# Cost breakdown by model
for m in data["byModel"]:
    print("  %s: US$%.4f  (%d reqs, %d tokens)" % (m["model"], m["spend"], m["requests"], m["tokens"]))

Institutionsplan

Der Institution Plan ermöglicht es jeder Institution (Schule, Unternehmen, Konferenz, Behörde usw.), kurzlebige Session-Tokens für ihre Mitglieder aus einem einzigen Schlüssel auf Organisationsebene auszustellen. Mitglieder müssen kein Plattformkonto erstellen. Die Organisation steuert über die E-Mail-Domain (z. B. nthu.edu.tw), welche Mitglieder Tokens anfordern dürfen; die gesamte Nutzung wird dem Konto der Organisation in Rechnung gestellt. Diese Seite verwendet das Bildungsszenario als Beispiel — der gleiche Mechanismus funktioniert für jede Institution, die kurzfristigen Mehrbenutzer-Zugriff benötigt.

Für wen ist das gedacht
Schulen und Bildungseinrichtungen, die einer ganzen Klasse Zugriff auf die AI-API geben möchten, ohne individuelle Konten für die Studierenden zu erstellen und ohne langlebige API-Schlüssel an Minderjährige weiterzugeben.

Architekturüberblick

  • InstitutionsschlüsselBeginnt mit sk-edu-. Wird von einem org_admin auf der Organisationsschlüssel-Seite erstellt. Kann nicht direkt als Bearer-Token zum Aufrufen der API verwendet werden — direkte Aufrufe geben 403 zurück.
  • Member-SitzungstokenBeginnt mit edu-sess-. Studierende erhalten ihn nach E-Mail-Verifizierung. Standard-Lebensdauer beträgt 24 Stunden; widerrufbar durch einen Org-Administrator.
  • Zulässige DomänenDie Organisation konfiguriert, welche E-Mail-Domains (exakte Übereinstimmung, kein Suffix-Bypass) eine Session anfordern dürfen.
  • NutzungszuordnungAlle studentischen Anfragen werden dem Konto der Organisation in Rechnung gestellt. Die Nutzung ist pro Session und pro E-Mail im Org-Dashboard einsehbar.

Schritt 1 — Plattform-Administrator setzt den Org-Typ auf Education

Suchen Sie unter sales@bazaarlink.ai / support@bazaarlink.ai die Zielorganisation, wechseln Sie zum Tab "Org Type", wählen Sie Institution und legen Sie die zulässigen E-Mail-Domains fest:

{
  "orgType": "education",
  "eduConfig": {
    "allowedDomains": ["nthu.edu.tw", "student.nthu.edu.tw"],
    "sessionTtlSeconds": 86400,
    "verificationTtlSeconds": 900,
    "maxSessionsPerEmailPerKey": 5
  }
}
Domain-Abgleich erfolgt exakt
nthu.edu.tw passt nur auf @nthu.edu.tw — es passt nicht auf @nthu.edu.attacker.com. Subdomains müssen explizit aufgeführt werden (z. B. student.nthu.edu.tw).

Schritt 2 — Org-Administrator erstellt einen Institution Key

Wählen Sie auf der API-Schlüssel-Seite der Organisation beim Erstellen eines neuen Schlüssels "Education" als Schlüsseltyp. Das System generiert einen sk-edu-...-Schlüssel und zeigt ihn EINMAL an — speichern Sie ihn und verteilen Sie ihn über Ihre offiziellen Kanäle an die Studierenden dieser Organisation.

Schritt 3 — Studierender fordert einen Verifizierungscode an

Studierende gehen auf /access und geben den Edu-Schlüssel und ihre Schul-E-Mail ein; oder sie rufen die API direkt auf:

POST/api/edu/request-code
curl -X POST https://bazaarlink.ai/api/edu/request-code \
  -H "Content-Type: application/json" \
  -d '{
    "key": "sk-edu-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "email": "alice@nthu.edu.tw"
  }'

# Success (incl. unknown key/email — enumeration defence) → {"ok":true,"sent":true}
# Rate limit / resend cooldown → 429 {"error":"rate_limited"} or {"error":"cooldown"}
# Sends a 6-digit verification code to the email; default 15-minute lifetime
Anti-Enumeration
request-code gibt immer 202 zurück, unabhängig davon, ob der Schlüssel existiert oder die E-Mail-Domain zugelassen ist. Dadurch wird verhindert, dass Angreifer ermitteln können, welche Edu-Schlüssel existieren. Fehlgeschlagene Versuche werden im Org-Audit-Log erfasst.

Schritt 4 — Studierender übermittelt den Code und tauscht ihn gegen ein Session-Token ein

POST/api/edu/verify
curl -X POST https://bazaarlink.ai/api/edu/verify \
  -H "Content-Type: application/json" \
  -d '{
    "key":   "sk-edu-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "email": "alice@nthu.edu.tw",
    "code":  "646291"
  }'

# Success → 200
{
  "token":     "edu-sess-827d11a1ec67d175cfd4f67f929261f4",
  "expiresAt": "2026-05-04T11:16:00.163Z",
  "organization": { "id": "...", "name": "NTHU AI Lab" }
}

# Wrong code → 400 {"error":"invalid"}
# 5 wrong attempts → 429 {"error":"too_many_attempts"} (code invalidated; re-request)

Schritt 5 — Verwenden Sie das Session-Token, um die API aufzurufen

Verwenden Sie das edu-sess-...-Token als Bearer-Token gegen jeden Chat-/Completions-/Embeddings-Endpoint:

curl -X POST https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer edu-sess-827d11a1ec67d175cfd4f67f929261f4" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-haiku-4.5",
    "messages": [{"role": "user", "content": "Hello"}]
  }'
sk-edu--Schlüssel können nicht direkt verwendet werden
Wenn Sie sk-edu-... direkt als Bearer-Token an einen Chat-Endpoint senden, erhalten Sie:
403 — Education keys cannot be used directly. Visit /access to exchange for a session.
Dies ist ein bewusst eingebautes Reverse-Gate — es verhindert, dass Schulen langlebige Schlüssel an einzelne Studierende weitergeben.

Org-Dashboard — Überwachung und Widerruf

Organisationen vom Typ Education erhalten in der Seitennavigation einen Education-Tab, der Folgendes bietet:

  • EinstellungenPassen Sie die zulässigen Domains, die TTL, die maximale Anzahl von Sessions pro E-Mail und Schlüssel sowie die Quoten pro Session für Anfragen / Tokens / USD an.
  • SitzungenListen Sie alle aktiven / abgelaufenen / widerrufenen Sessions auf; filtern Sie nach E-Mail; widerrufen Sie einzelne Sessions.
  • NutzungsstatistikenAnzahl der Aufrufe pro Session, Token-Verbrauch und kumulierte Kosten.

Sicherheit und Limits

ElementStandardwertBeschreibung
Session TTL24 StundenLebensdauer des Session-Tokens; abgelaufene Sessions erfordern eine erneute Verifizierung.
Bestätigungscode TTL15 MinutenLebensdauer des E-Mail-Verifizierungscodes.
Bestätigungscodelänge6 ZiffernWird als HMAC-SHA256-Hash in Redis gespeichert, niemals im Klartext.
Schätzwert5 VersucheDarüber hinaus wird der Code sofort ungültig.
Abklingzeit des Anforderungscodes60 SekundenMindestabstand zwischen wiederholten Anfragen für dasselbe (Schlüssel, E-Mail)-Paar.
Ratenbegrenzung pro IP10 / 15 MinAnti-Spam.
Ratenbegrenzung pro Schlüssel100 / StundeVerhindert Massen-E-Mail-Versand.
Max. Sitzungen pro E-Mail5Konfigurierbar in eduConfig; verhindert, dass ein einzelnes Postfach Tokens hortet.
Revocation-Weitergabe≤ 60 SekundenL1/L2-Cache-TTL; nach dem Widerruf in der Datenbank dauert es bis zu 60 Sekunden, bis er auf alle Knoten propagiert wird.

Abrechnung und Nutzungszuordnung

Alle über Session-Tokens getätigten Anfragen werden zu 100 % der Organisation in Rechnung gestellt, der der Edu-Schlüssel gehört, im Einklang mit der Abrechnung der Upstream-Provider (OpenAI / Anthropic / etc.) (pro Token). Das Org-Dashboard unterstützt Drill-down nach Session, nach E-Mail und nach Schlüssel.

Feedback melden

Helfen Sie uns, BazaarLink zu verbessern, indem Sie Probleme, Fehler oder Vorschläge melden. Wir überwachen aktiv alle Feedback-Kanäle.

So melden Sie

Kanal
Am besten für
Antwortzeit
KontaktseiteAllgemeines Feedback, Feature-Anfragen1-2 Werktage
E-MailFehlerberichte, technische ProblemeInnerhalb von 24 Stunden
API-Antwort-HeaderAutomatisch gemeldete Fehler und MetrikenAutomatisch

Was Sie einschließen sollten

  • Anfrage-ID (aus dem Antwort-id-Feld)
  • Verwendetes Modell und gesendete Parameter
  • Erwartetes vs. tatsächliches Verhalten
  • Zeitstempel und Häufigkeit des Problems
  • Fehlermeldungen oder HTTP-Statuscodes

Besuchen Sie unsere Kontaktseite, um Feedback zu senden.

FAQ

Wie unterscheidet sich BazaarLink vom direkten Aufruf bei OpenAI?
BazaarLink bietet USD-Abrechnung mit NTD-Angeboten, einheitliche Rechnungen, chinesischen Support und eine einzelne API für alle gängigen Modelle. Sie können OpenAI, Anthropic, Google und mehr mit dem gleichen Code ansprechen.
Muss ich meinen bestehenden Code ändern?
Ändern Sie einfach die Base-URL und den API-Schlüssel. Alle anderen Einstellungen (außer Modell-IDs) bleiben unverändert.
Speichert BazaarLink meine Nachrichten?
Standardmäßig speichern wir keine Nachrichteninhalte. Wir protokollieren nur Token-Zählungen und Zeitstempel für Abrechnungszwecke.
Wie erhalte ich eine einheitliche Rechnung (統一發票)?
Einheitliche Rechnungen werden am Monatsende für Business-Plan und höher automatisch ausgestellt. Kontaktieren Sie den Support für sofortige Ausstellung.
Welche Zahlungsmethoden werden unterstützt?
Alle gängigen Kreditkarten werden akzeptiert (Visa, Mastercard, American Express).
Welche OpenAI SDK-Funktionen werden unterstützt?
Chat Completions, Streaming, Tool Calling, Structured Output (response_format) und Assistant Prefill funktionieren alle. Funktionen werden an den Upstream-Anbieter weitergeleitet.
Kann ich BazaarLink mit Agent-Frameworks wie LangChain oder CrewAI verwenden?
Ja! Jedes Framework, das die OpenAI-API unterstützt, funktioniert mit BazaarLink. Setzen Sie einfach die Base-URL und verwenden Sie Ihren BazaarLink-API-Schlüssel. Siehe den Abschnitt Agentic-Nutzung für Beispiele.
Support
Support
Hi! How can we help you?
Send a message and we'll get back to you soon.