Drift
The Python Exchange base class constructor accepts an api_token parameter that sends apiToken to the sidecar. TypeScript's ExchangeOptions interface has no corresponding field, so TypeScript callers have no way to pass this credential through the base class.
TypeScript SDK
sdks/typescript/pmxt/client.ts, lines 167–213 — ExchangeOptions interface (no apiToken field):
// sdks/typescript/pmxt/client.ts lines 167–213
export interface ExchangeOptions {
exchange?: string;
pmxtApiKey?: string;
baseUrl?: string;
apiKey?: string;
apiSecret?: string;
// ... other fields
// apiToken is absent
}
The TypeScript Exchange constructor passes ExchangeOptions to the sidecar via _getCredentialsDict() — apiToken is never included.
Python SDK
sdks/python/pmxt/client.py, line 263 — api_token in base class __init__:
# sdks/python/pmxt/client.py line 263
def __init__(
self,
exchange: str,
...
api_token: Optional[str] = None,
...
):
self._api_token = api_token
_get_credentials_dict (client.py) then includes "apiToken": self._api_token when set, sending it to the sidecar with every request.
Metaculus (in _exchanges.py) is the concrete exchange that relies on this path.
Expected
ExchangeOptions in TypeScript should include an apiToken?: string field, and the TypeScript Exchange._getCredentialsDict() should include it when present — mirroring Python's behaviour. Alternatively, if api_token is purely a Metaculus-specific credential, it should be removed from the Python base class and handled only in the Metaculus subclass in both languages (with a dedicated constructor parameter).
Impact
TypeScript users of Metaculus cannot pass a bearer token through the base-class credential path. Python users can, creating an undocumented asymmetry. Any sidecar exchange handler that checks for apiToken in the credentials object will never receive it from TypeScript clients.
Found by automated SDK cross-language drift audit
Drift
The Python
Exchangebase class constructor accepts anapi_tokenparameter that sendsapiTokento the sidecar. TypeScript'sExchangeOptionsinterface has no corresponding field, so TypeScript callers have no way to pass this credential through the base class.TypeScript SDK
sdks/typescript/pmxt/client.ts, lines 167–213 —ExchangeOptionsinterface (noapiTokenfield):The TypeScript
Exchangeconstructor passesExchangeOptionsto the sidecar via_getCredentialsDict()—apiTokenis never included.Python SDK
sdks/python/pmxt/client.py, line 263 —api_tokenin base class__init__:_get_credentials_dict(client.py) then includes"apiToken": self._api_tokenwhen set, sending it to the sidecar with every request.Metaculus(in_exchanges.py) is the concrete exchange that relies on this path.Expected
ExchangeOptionsin TypeScript should include anapiToken?: stringfield, and the TypeScriptExchange._getCredentialsDict()should include it when present — mirroring Python's behaviour. Alternatively, ifapi_tokenis purely a Metaculus-specific credential, it should be removed from the Python base class and handled only in theMetaculussubclass in both languages (with a dedicated constructor parameter).Impact
TypeScript users of
Metaculuscannot pass a bearer token through the base-class credential path. Python users can, creating an undocumented asymmetry. Any sidecar exchange handler that checks forapiTokenin the credentials object will never receive it from TypeScript clients.Found by automated SDK cross-language drift audit