Skip to content

discovery: list_events omits closed by default — first-page result is dominated by settled events #59

@Nexory

Description

@Nexory

list_events_spec (src/polymarket/_internal/actions/gamma.py:369+) accepts closed: bool | None = None and forwards it to _add_optional(params, "closed", closed), which only sets the query parameter when it's not None. So calling client.list_events() sends no closed parameter to the Gamma /events/keyset endpoint — and the Gamma server applies its own default, which is closed=true rather than false.

Live evidence

$ curl -s 'https://gamma-api.polymarket.com/events?series_id=10345&limit=100' \
    | jq '[.[] | .closed] | group_by(.) | map({(.[0]|tostring): length}) | add'
{"true": 100}

(Reproduction borrowed from Polymarket/polymarket-cli#71, which reports the same default-mismatch propagating into the CLI. The CLI omits the parameter when neither --closed nor --active is set; py-sdk does the same when callers omit closed.)

Why this looks like a UX gap rather than a deliberate default

ts-sdk's own listEvents docstring examples (packages/client/src/actions/events.ts:144-160) pass closed: false explicitly:

const result = listEvents(client, {
  closed: false,
  pageSize: 10,
});

So the team already knew omitting closed produces the wrong result for the common "show me current events" workflow. py-sdk's docstrings (async_public.py / public.py) don't document the default behavior at all, and there's no equivalent example that nudges callers to set it. A new user calling client.list_events() to explore the surface surfaces settled-only events without warning.

The public Gamma docs (https://docs.polymarket.com/developers/gamma-markets-api/get-events) say closed defaults to false, which conflicts with the server's actual behavior — so this might also be a server-contract drift rather than purely an SDK gap.

Possible directions

  1. Document the actual server default — add a docstring note on closed: bool | None in list_events and list_events_spec clarifying that omitting it returns settled events. Cheapest fix; doesn't change behavior.
  2. Apply a client-side default closed=False in list_events and the equivalent secure-client method so the SDK behavior matches the Gamma docs and ts-sdk's example usage. Behavior-changing, but matches the "intent" already encoded in ts-sdk. Same question would apply to list_markets if it has the same pattern.
  3. Server-side: change the Gamma default to false so docs + server + SDK all agree. Out of scope for this repo but worth flagging back to the API team.

I'd lean (2) — ts-sdk's examples already codify closed: false as the right default, so making py-sdk match is consistent and removes a footgun. But this is a contract decision that could go differently.

Cross-SDK / cross-repo

Same pattern in ts-sdk: Polymarket/ts-sdk#75 (ListEventsRequestSchema.closed = z.boolean().optional() + toEventsSearchParams drops undefined). Same root cause in Polymarket/polymarket-cli#71 (the original CLI-side report).

Happy to PR (1) or (2) once you've decided which direction is right.

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