Skip to content

gamma: get_market(url=...) only accepts /market/{slug} URLs but Polymarket only serves /event/{slug} #57

@Nexory

Description

@Nexory

_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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

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