_parse_polymarket_url in src/polymarket/_internal/gamma_paths.py:88-97 requires the URL's first path segment to match the entity kind ("market" or "event"). For get_market(url=...), that means polymarket.com/market/<slug>. Polymarket itself does not serve URLs in that shape: every market is reachable as polymarket.com/event/<slug> and /market/<slug> is a 307 to /404. So the only realistic URL a user can paste into get_market(url=...) is rejected.
Verification
$ curl -sI 'https://polymarket.com/event/eth-updown-5m-1780069800' | head -1
HTTP/1.1 200 OK
$ curl -sI 'https://polymarket.com/market/eth-updown-5m-1780069800' | head -2
HTTP/1.1 307 Temporary Redirect
location: /404
$ curl -sI 'https://polymarket.com/market/new-rhianna-album-before-gta-vi-926' | head -1
HTTP/1.1 307 Temporary Redirect
I tried both an event-aligned slug (eth-updown-5m-..., where market slug == event slug) and a market-specific slug from a multi-market event (new-rhianna-album-before-gta-vi-926 under the what-will-happen-before-gta-vi event). Both 307 to /404.
Current behavior
With the README's own example:
# README.md:35
market: Market = client.get_market(url="https://polymarket.com/event/example-market")
trace:
_resolve_lookup("market", id=None, slug=None, url="https://polymarket.com/event/example-market")
→ ("url", "https://polymarket.com/event/example-market")
_parse_polymarket_url("https://polymarket.com/event/example-market", kind="market")
→ segments == ["event", "example-market"]
→ segments[0] != kind ("event" != "market")
→ raise UserInputError("Expected a Polymarket market URL.")
So the documented example throws the moment it runs.
The _build_entity_path API endpoint is /markets/slug/<slug> (gamma) regardless of which website path the slug came from — so the slug extraction itself is the only part the SDK needs from the URL.
Possible directions
-
Doc-only fix. Change the README example to polymarket.com/market/<slug> to match what the parser currently accepts, even though that URL doesn't exist on Polymarket. Cheap, but only helps if you assume users construct URLs in this canonical form — they don't, they paste from the address bar.
-
Accept event URLs for get_market(url=...) too. Relax _parse_polymarket_url to accept event as a valid first segment for both kind="market" and kind="event", since the public Polymarket URL structure is event-centric. Carries a subtlety: for a multi-market event (/event/what-will-happen-before-gta-vi), passing that URL to get_market(url=...) would 404 server-side because the event slug isn't a market slug — needs a clear error rather than silently extracting the wrong slug.
-
Deprecate url= on get_market and have users always pass slug= or id= directly (they can extract from any URL themselves). get_event(url=...) keeps the existing behavior since /event/<event-slug> does work end-to-end.
-
Add a small redirect-resolver that, given any Polymarket URL, asks the gamma API which entity it points to. Heavier; probably not worth it for SDK.
I think (2) or (3) is closer to what users actually need. Happy to PR (1) immediately as a low-risk band-aid that at least makes the documented example parse, while (2)/(3) is a separate larger conversation.
Cross-SDK
ts-sdk has the same parser convention — packages/client/src/actions/markets.ts:261 docstring example uses polymarket.com/market/some-market-slug, and the equivalent URL-shape check lives behind prepareMarketLookup / the markets actions there. Not filing on ts-sdk yet pending the design choice here, but the parity is intentional to flag.
_parse_polymarket_urlinsrc/polymarket/_internal/gamma_paths.py:88-97requires the URL's first path segment to match the entitykind("market" or "event"). Forget_market(url=...), that meanspolymarket.com/market/<slug>. Polymarket itself does not serve URLs in that shape: every market is reachable aspolymarket.com/event/<slug>and/market/<slug>is a 307 to/404. So the only realistic URL a user can paste intoget_market(url=...)is rejected.Verification
I tried both an event-aligned slug (
eth-updown-5m-..., where market slug == event slug) and a market-specific slug from a multi-market event (new-rhianna-album-before-gta-vi-926under thewhat-will-happen-before-gta-vievent). Both 307 to/404.Current behavior
With the README's own example:
trace:
So the documented example throws the moment it runs.
The
_build_entity_pathAPI endpoint is/markets/slug/<slug>(gamma) regardless of which website path the slug came from — so the slug extraction itself is the only part the SDK needs from the URL.Possible directions
Doc-only fix. Change the README example to
polymarket.com/market/<slug>to match what the parser currently accepts, even though that URL doesn't exist on Polymarket. Cheap, but only helps if you assume users construct URLs in this canonical form — they don't, they paste from the address bar.Accept event URLs for
get_market(url=...)too. Relax_parse_polymarket_urlto accepteventas a valid first segment for bothkind="market"andkind="event", since the public Polymarket URL structure is event-centric. Carries a subtlety: for a multi-market event (/event/what-will-happen-before-gta-vi), passing that URL toget_market(url=...)would 404 server-side because the event slug isn't a market slug — needs a clear error rather than silently extracting the wrong slug.Deprecate
url=onget_marketand have users always passslug=orid=directly (they can extract from any URL themselves).get_event(url=...)keeps the existing behavior since/event/<event-slug>does work end-to-end.Add a small redirect-resolver that, given any Polymarket URL, asks the gamma API which entity it points to. Heavier; probably not worth it for SDK.
I think (2) or (3) is closer to what users actually need. Happy to PR (1) immediately as a low-risk band-aid that at least makes the documented example parse, while (2)/(3) is a separate larger conversation.
Cross-SDK
ts-sdk has the same parser convention —
packages/client/src/actions/markets.ts:261docstring example usespolymarket.com/market/some-market-slug, and the equivalent URL-shape check lives behindprepareMarketLookup/ the markets actions there. Not filing on ts-sdk yet pending the design choice here, but the parity is intentional to flag.