One gateway URL, two credentials โ chat and embeddings needed separate API keys
What happened: both SDK clients pointed at the same PLATFORMAI_BASE_URL and shared one
PLATFORMAI_API_KEY. PlatformAI scopes keys per model endpoint, so whichever capability the
key wasn't issued for returned an auth error โ from a URL that demonstrably worked.
Fix: one required config var per capability, one client each.
PLATFORMAI_CHAT_API_KEY = _require('PLATFORMAI_CHAT_API_KEY')
PLATFORMAI_EMBED_API_KEY = _require('PLATFORMAI_EMBED_API_KEY')
_chat_client = OpenAI(base_url=config.PLATFORMAI_BASE_URL, api_key=config.PLATFORMAI_CHAT_API_KEY)
_embed_client = OpenAI(base_url=config.PLATFORMAI_BASE_URL, api_key=config.PLATFORMAI_EMBED_API_KEY)
_require on both means a missing key fails at startup, not mid-request.
Why it matters: "one endpoint, one key" is learned from OpenAI, where a single key covers everything. A gateway routes to several backends and commonly scopes keys per model family to meter them separately โ an auth failure against a working URL means the key is scoped narrower than assumed.
Reference: The provider adapter layer โ what varies per service (keys, features, model names) belongs in config, not baked into the adapter.