Skip to content

auth: builder API key management operations are missing (parity gap with ts-sdk) #51

@Nexory

Description

@Nexory

polymarket.auth.BuilderApiKey is exported in src/polymarket/__init__.py and consumed internally by the relayer auth path (_internal/actions/relayer/auth.py:15,51), but the SDK does not expose any way for a user to manage the underlying builder-api-key resource.

Missing operations

ts-sdk's packages/client/src/actions/auth.ts exposes the full /auth/builder-api-key CRUD:

Operation ts-sdk py-sdk
createBuilderApiKey ✓ uses secureClob (L2 HMAC) ❌ missing
fetchBuilderApiKeys ✓ uses secureClob ❌ missing
revokeBuilderApiKey ✓ but with auth bug, see ts-sdk#68 ❌ missing
delete_api_key (regular, on /auth/api-key) ✓ uses secureClob ✓ uses secure_clob
fetch_api_keys
create_api_key / derive_api_key

The standard api-key surface is implemented symmetrically. Only the builder-api-key surface is unimplemented on the Python side.

Why this looks like a gap, not a design choice

  • BuilderApiKey is in the public __init__.py exports — users encounter the type but cannot obtain one through the SDK.
  • It is used internally for relayer signing (isinstance(api_key, BuilderApiKey)) — the type clearly has a runtime role.
  • ts-sdk's docs/sdk-direction.md and py-sdk's docs/sdk-direction.md both state "Preserve feature parity direction with other Polymarket SDKs while adapting API shape to Python ecosystem norms."
  • Existing PRs #21 (gasless relayer support) and #24 (list_builder_trades) show the builder surface is an active area in py-sdk — the management functions just haven't been ported yet.

Suggested action

Add to _internal/actions/auth.py (mirroring the existing fetch_api_keys / delete_api_key patterns):

async def create_builder_api_key(secure_clob: AsyncTransport) -> BuilderApiKey:
    payload = await secure_clob.post_json('/auth/builder-api-key')
    # parse into BuilderApiKey
    ...

async def fetch_builder_api_keys(secure_clob: AsyncTransport) -> tuple[BuilderApiKey, ...]:
    payload = await secure_clob.get_json('/auth/builder-api-key')
    ...

async def revoke_builder_api_key(secure_clob: AsyncTransport) -> None:
    payload = await secure_clob.delete_json('/auth/builder-api-key')
    if payload != 'OK':
        raise UnexpectedResponseError(...)

Plus sync variants and the corresponding public methods on SecureClient / AsyncSecureClient.

Important: avoid ts-sdk's revoke bug

When implementing the revoke path, please make sure it uses secure_clob (L2 HMAC) and not the unauthenticated clob transport. ts-sdk's revokeBuilderApiKey currently uses the unauthenticated client.clob — see ts-sdk#68 for the full pattern. The py-sdk port should mirror delete_api_key (which correctly uses secure_clob), not the ts-sdk version.

Happy to send a PR once external PRs are accepted post-beta.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions