ListEventsRequestSchema (packages/client/src/actions/events.ts:34-75) declares closed: z.boolean().optional(), and toEventsSearchParams drops keys whose value is undefined. So calling client.listEvents({ pageSize: 10 }) sends no closed parameter to the Gamma /events/keyset endpoint — and the Gamma server in turn 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; the new SDKs do the same when callers omit closed.)
For a less-filtered query the bias is also visible:
$ curl -s 'https://gamma-api.polymarket.com/events?limit=50' \
| jq '[.[] | .closed] | group_by(.) | map({(.[0]|tostring): length}) | add'
returns roughly two-thirds closed=true, even though "list events" is the natural thing a brand-new SDK user does when exploring the surface.
Why this looks like a UX gap rather than a deliberate default
Both listEvents @example blocks (packages/client/src/actions/events.ts:144-160) pass closed: false explicitly:
const result = listEvents(client, {
closed: false,
pageSize: 10,
});
So the maintainer already knew that omitting closed produces the wrong result for the common "show me current events" workflow — the examples set it deliberately. New SDK users skimming the surface and calling client.listEvents({ pageSize: 10 }) (the example without closed) instead surface settled-only events. The docstring doesn't explain the default behavior.
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 doc gap.
Possible directions
- Document the actual server default in the SDK — add a TSDoc note on
closed?: boolean in ListEventsRequest clarifying that omitting it returns settled events. Cheapest fix; doesn't change behavior.
- Apply a client-side default
closed: false in listEvents / toEventsSearchParams so the SDK behavior matches the Gamma docs and the example usage. Behavior-changing, but matches the "intent" the example already encodes. Might also be worth applying to listMarkets if the same default exists there.
- 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) — the maintainer's own examples already use closed: false, so codifying that as the SDK default is consistent and removes a footgun for new users. But this is a contract decision that could go differently.
Cross-SDK
Same pattern in py-sdk: list_events(closed: bool | None = None) (src/polymarket/clients/async_public.py, clients/public.py) → list_events_spec adds closed to params via _add_optional only when non-None → server applies its closed=true default. Filing companion issue at Polymarket/py-sdk.
(Also applies cross-repo to Polymarket/polymarket-cli#71, which is the original CLI report.)
Happy to PR (1) or (2) once you've decided which direction is right.
ListEventsRequestSchema(packages/client/src/actions/events.ts:34-75) declaresclosed: z.boolean().optional(), andtoEventsSearchParamsdrops keys whose value isundefined. So callingclient.listEvents({ pageSize: 10 })sends noclosedparameter to the Gamma/events/keysetendpoint — and the Gamma server in turn applies its own default, which isclosed=truerather thanfalse.Live evidence
(Reproduction borrowed from Polymarket/polymarket-cli#71, which reports the same default-mismatch propagating into the CLI. The CLI omits the parameter when neither
--closednor--activeis set; the new SDKs do the same when callers omitclosed.)For a less-filtered query the bias is also visible:
returns roughly two-thirds
closed=true, even though "list events" is the natural thing a brand-new SDK user does when exploring the surface.Why this looks like a UX gap rather than a deliberate default
Both
listEvents@exampleblocks (packages/client/src/actions/events.ts:144-160) passclosed: falseexplicitly:So the maintainer already knew that omitting
closedproduces the wrong result for the common "show me current events" workflow — the examples set it deliberately. New SDK users skimming the surface and callingclient.listEvents({ pageSize: 10 })(the example withoutclosed) instead surface settled-only events. The docstring doesn't explain the default behavior.The public Gamma docs (https://docs.polymarket.com/developers/gamma-markets-api/get-events) say
closeddefaults tofalse, which conflicts with the server's actual behavior — so this might also be a server contract drift rather than purely an SDK doc gap.Possible directions
closed?: booleaninListEventsRequestclarifying that omitting it returns settled events. Cheapest fix; doesn't change behavior.closed: falseinlistEvents/toEventsSearchParamsso the SDK behavior matches the Gamma docs and the example usage. Behavior-changing, but matches the "intent" the example already encodes. Might also be worth applying tolistMarketsif the same default exists there.falseso docs + server + SDK all agree. Out of scope for this repo but worth flagging back to the API team.I'd lean (2) — the maintainer's own examples already use
closed: false, so codifying that as the SDK default is consistent and removes a footgun for new users. But this is a contract decision that could go differently.Cross-SDK
Same pattern in py-sdk:
list_events(closed: bool | None = None)(src/polymarket/clients/async_public.py,clients/public.py) →list_events_specaddsclosedto params via_add_optionalonly when non-None → server applies itsclosed=truedefault. Filing companion issue at Polymarket/py-sdk.(Also applies cross-repo to Polymarket/polymarket-cli#71, which is the original CLI report.)
Happy to PR (1) or (2) once you've decided which direction is right.