Drift
TypeScript's base Exchange class accepts apiSecret as a generic ExchangeOptions field and forwards it unconditionally to the sidecar for every venue subclass. Python's base Exchange.__init__ has no api_secret parameter at all, and only 4 of the 17 venue subclasses in _exchanges.py add their own api_secret parameter + override to forward it — the other 13 don't accept it as a keyword argument, so passing one raises TypeError.
Note: the earlier, TS-side version of this gap (Exchange.getCredentials() never forwarding apiSecret at all) was already tracked and fixed — see closed issues #1371 (merged via #1375), #1041, #971, #881. This issue is the current, still-open asymmetry that remains after that fix: TypeScript's forwarding is now generic across all venues, while Python's is restricted to a hand-picked subset.
TypeScript SDK
sdks/typescript/pmxt/client.ts:238 — apiSecret?: string; on base ExchangeOptions.
sdks/typescript/pmxt/client.ts:376 — this.apiSecret = options.apiSecret; in the base Exchange constructor.
sdks/typescript/pmxt/client.ts:483-489 (getCredentials()):
protected getCredentials(): ExchangeCredentials | undefined {
if (!this.apiKey && !this.apiSecret && !this.privateKey) {
return undefined;
}
return {
apiKey: this.apiKey,
apiSecret: this.apiSecret, // forwarded unconditionally for every venue
privateKey: this.privateKey,
funderAddress: this.proxyAddress,
signatureType: this.signatureType,
};
}
Every venue class that just takes generic ExchangeOptions (e.g. Kalshi, Smarkets, Hyperliquid, Myriad, SuiBets, Rain, Hunch, Mock, Baozi, Opinion, Metaculus, PolymarketUS, KalshiDemo) therefore accepts new Kalshi({ apiSecret: '...' }).
Python SDK
Base Exchange.__init__ (sdks/python/pmxt/client.py:324-338) has no api_secret parameter, and _get_credentials_dict (client.py:559-575) never references it. Only 4 venue classes in sdks/python/pmxt/_exchanges.py add api_secret themselves: Polymarket (line 16), Limitless (line 82), Probable (line 217), GeminiTitan (line 546) — each with its own self.api_secret = api_secret and if self.api_secret: creds["apiSecret"] = self.api_secret override. The other 13 venue classes (e.g. Kalshi at _exchanges.py:131-168) have no api_secret parameter — pmxt.Kalshi(api_secret="...") raises TypeError: __init__() got an unexpected keyword argument 'api_secret'.
Expected
Python's per-venue constructors should generically accept and forward api_secret, matching TypeScript's uniform ExchangeOptions.apiSecret handling across all 17 venues — or, if apiSecret is intentionally meaningful only for specific venues, TypeScript should narrow getCredentials()/ExchangeOptions to the same venue subset Python uses.
Impact
This follows the same architectural pattern as the already-tracked #1889 (proxy_address/signature_type dropped by 15 of 17 Python venue constructors) and #1926 (api_key/private_key dropped by Baozi/Rain/Hunch/Mock/SuiBets in Python) — for the apiSecret field specifically, which neither of those covers. A user porting code from TypeScript to Python that passes apiSecret to any of the 13 unsupported Python venue classes gets an immediate, hard constructor TypeError, not a silently-ignored field.
Found by automated SDK cross-language drift audit
Drift
TypeScript's base
Exchangeclass acceptsapiSecretas a genericExchangeOptionsfield and forwards it unconditionally to the sidecar for every venue subclass. Python's baseExchange.__init__has noapi_secretparameter at all, and only 4 of the 17 venue subclasses in_exchanges.pyadd their ownapi_secretparameter + override to forward it — the other 13 don't accept it as a keyword argument, so passing one raisesTypeError.Note: the earlier, TS-side version of this gap (
Exchange.getCredentials()never forwardingapiSecretat all) was already tracked and fixed — see closed issues #1371 (merged via #1375), #1041, #971, #881. This issue is the current, still-open asymmetry that remains after that fix: TypeScript's forwarding is now generic across all venues, while Python's is restricted to a hand-picked subset.TypeScript SDK
sdks/typescript/pmxt/client.ts:238—apiSecret?: string;on baseExchangeOptions.sdks/typescript/pmxt/client.ts:376—this.apiSecret = options.apiSecret;in the baseExchangeconstructor.sdks/typescript/pmxt/client.ts:483-489(getCredentials()):Every venue class that just takes generic
ExchangeOptions(e.g.Kalshi,Smarkets,Hyperliquid,Myriad,SuiBets,Rain,Hunch,Mock,Baozi,Opinion,Metaculus,PolymarketUS,KalshiDemo) therefore acceptsnew Kalshi({ apiSecret: '...' }).Python SDK
Base
Exchange.__init__(sdks/python/pmxt/client.py:324-338) has noapi_secretparameter, and_get_credentials_dict(client.py:559-575) never references it. Only 4 venue classes insdks/python/pmxt/_exchanges.pyaddapi_secretthemselves:Polymarket(line 16),Limitless(line 82),Probable(line 217),GeminiTitan(line 546) — each with its ownself.api_secret = api_secretandif self.api_secret: creds["apiSecret"] = self.api_secretoverride. The other 13 venue classes (e.g.Kalshiat_exchanges.py:131-168) have noapi_secretparameter —pmxt.Kalshi(api_secret="...")raisesTypeError: __init__() got an unexpected keyword argument 'api_secret'.Expected
Python's per-venue constructors should generically accept and forward
api_secret, matching TypeScript's uniformExchangeOptions.apiSecrethandling across all 17 venues — or, ifapiSecretis intentionally meaningful only for specific venues, TypeScript should narrowgetCredentials()/ExchangeOptionsto the same venue subset Python uses.Impact
This follows the same architectural pattern as the already-tracked #1889 (
proxy_address/signature_typedropped by 15 of 17 Python venue constructors) and #1926 (api_key/private_keydropped by Baozi/Rain/Hunch/Mock/SuiBets in Python) — for theapiSecretfield specifically, which neither of those covers. A user porting code from TypeScript to Python that passesapiSecretto any of the 13 unsupported Python venue classes gets an immediate, hard constructorTypeError, not a silently-ignored field.Found by automated SDK cross-language drift audit