Gap
docs/api-reference/configuration.mdx's self-hosted credentials table has a single catch-all row for private_key/privateKey, captioned "for Polymarket / Limitless / Probable / Opinion / etc." The "etc." misrepresents at least three of the nine self-hosted venues, which don't accept a private key at all and use structurally different credential shapes.
Core
core/src/server/exchange-factory.ts shows the actual per-venue credential shape used when constructing each exchange in self-hosted mode:
exchange-factory.ts:112-114 (metaculus case) — only apiToken (mapped from credentials?.apiToken || process.env.METACULUS_API_TOKEN). Confirmed in core/src/exchanges/metaculus/index.ts:59-111: the class reads credentials?.apiToken and sends Authorization: Token <apiToken>; there is no privateKey field anywhere in MetaculusExchange.
exchange-factory.ts:130-136 (gemini-titan case) — only apiKey/apiSecret (HMAC), from GEMINI_API_KEY/GEMINI_API_SECRET. core/src/exchanges/gemini-titan/index.ts:30-33's GeminiTitanExchangeOptions has no privateKey field.
exchange-factory.ts:137-141 (suibets case) — only walletAddress (from SUIBETS_WALLET_ADDRESS) plus baseUrl. core/src/exchanges/suibets/index.ts:17,55,60 confirms SuiBetsExchange only reads credentials?.walletAddress; there is no privateKey field.
None of these three venues can be configured with private_key/privateKey — a reader following the doc's "Polymarket / Limitless / Probable / Opinion / etc." pattern for Metaculus, GeminiTitan, or SuiBets would pass a field the exchange never reads and get an authentication failure with no explanation from the docs.
TypeScript SDK
N/A — this is a documentation-accuracy gap, not an SDK code gap. (The TS SDK's Metaculus/GeminiTitan/SuiBets classes already require the correct venue-specific fields, matching core.)
Python SDK
N/A — same as above; this is a docs-only gap.
Evidence
Compared docs/api-reference/configuration.mdx:80 ("private_key | privateKey | str | EVM private key, for Polymarket / Limitless / Probable / Opinion / etc.") against core/src/server/exchange-factory.ts's metaculus, gemini-titan, and suibets cases, none of which read or forward a privateKey/private_key credential. This is the same class of finding as #2109 (Kalshi) and #2110 (Smarkets) already filed against this same doc file, but for the generic "etc." row rather than a named venue-specific row.
Impact
A self-hosted user configuring Metaculus, GeminiTitan, or SuiBets by following this table's guidance will supply a private_key that is silently ignored, then hit an opaque "not authenticated" error for a venue that actually needs apiToken (Metaculus), apiKey/apiSecret (GeminiTitan), or walletAddress (SuiBets) — none of which this table mentions.
Found by automated Core-to-SDK surface coverage audit
Gap
docs/api-reference/configuration.mdx's self-hosted credentials table has a single catch-all row forprivate_key/privateKey, captioned "for Polymarket / Limitless / Probable / Opinion / etc." The "etc." misrepresents at least three of the nine self-hosted venues, which don't accept a private key at all and use structurally different credential shapes.Core
core/src/server/exchange-factory.tsshows the actual per-venue credential shape used when constructing each exchange in self-hosted mode:exchange-factory.ts:112-114(metaculus case) — onlyapiToken(mapped fromcredentials?.apiToken || process.env.METACULUS_API_TOKEN). Confirmed incore/src/exchanges/metaculus/index.ts:59-111: the class readscredentials?.apiTokenand sendsAuthorization: Token <apiToken>; there is noprivateKeyfield anywhere inMetaculusExchange.exchange-factory.ts:130-136(gemini-titan case) — onlyapiKey/apiSecret(HMAC), fromGEMINI_API_KEY/GEMINI_API_SECRET.core/src/exchanges/gemini-titan/index.ts:30-33'sGeminiTitanExchangeOptionshas noprivateKeyfield.exchange-factory.ts:137-141(suibets case) — onlywalletAddress(fromSUIBETS_WALLET_ADDRESS) plusbaseUrl.core/src/exchanges/suibets/index.ts:17,55,60confirmsSuiBetsExchangeonly readscredentials?.walletAddress; there is noprivateKeyfield.None of these three venues can be configured with
private_key/privateKey— a reader following the doc's "Polymarket / Limitless / Probable / Opinion / etc." pattern for Metaculus, GeminiTitan, or SuiBets would pass a field the exchange never reads and get an authentication failure with no explanation from the docs.TypeScript SDK
N/A — this is a documentation-accuracy gap, not an SDK code gap. (The TS SDK's
Metaculus/GeminiTitan/SuiBetsclasses already require the correct venue-specific fields, matching core.)Python SDK
N/A — same as above; this is a docs-only gap.
Evidence
Compared
docs/api-reference/configuration.mdx:80("private_key|privateKey|str| EVM private key, for Polymarket / Limitless / Probable / Opinion / etc.") againstcore/src/server/exchange-factory.ts'smetaculus,gemini-titan, andsuibetscases, none of which read or forward aprivateKey/private_keycredential. This is the same class of finding as #2109 (Kalshi) and #2110 (Smarkets) already filed against this same doc file, but for the generic "etc." row rather than a named venue-specific row.Impact
A self-hosted user configuring Metaculus, GeminiTitan, or SuiBets by following this table's guidance will supply a
private_keythat is silently ignored, then hit an opaque "not authenticated" error for a venue that actually needsapiToken(Metaculus),apiKey/apiSecret(GeminiTitan), orwalletAddress(SuiBets) — none of which this table mentions.Found by automated Core-to-SDK surface coverage audit