Venue Geo Availability
Check regional trading restrictions and quote warnings before asking a user to confirm a trade.
Each venue sufwan-local-test routes to restricts its own set of countries. A user in a restricted country can browse and quote normally but cannot fill on that venue.
Detect ineligibility at quote time, not at fill time. Do not hard-code country lists. Read warnings on the quote, or the live policy endpoint below.
Detecting ineligibility before the fill
The quote includes a warnings array. Any venue in the route the user cannot fill on appears there, with the venue name and a human-readable reason. The quote does not remove blocked venues. It returns the route and flags the blocked legs, so you can gray them out or route around them before the user commits. Geo is enforced at fill.
Match on the prefix Venue not available in your region to identify geo warnings. The trailing country code is omitted when the country cannot be determined.
Buy and sell quotes both carry geo warnings. On a sell, the warning names the held leg the user cannot close from their region, so there is no other route to offer.
If you ignore the warnings, POST /execution/fill returns 403 with code: "geo_blocked":
{ "message": "Venue polymarket is not available in your region (US).", "code": "geo_blocked" }Branch on code, not the message. The same code marks every regional refusal on the trading routes, including an app-wide region block and an undetermined country.
Quote warnings cover the per-venue lists only. They do not reflect your app's own blocked countries and regions, or the platform list. A user those lists block gets a clean quote and then 403 Trading is not available in your region on every trading route: fill, limit orders, cancel, withdraw and redeem. A quote and a fill sent from different countries (a VPN, a mobile network switch, or a missing x-agg-client-ip under Trusted Proxy) can also disagree.
A sell is checked like a buy. There is no close-only mode: a user who cannot fill a venue from their region cannot sell a position held there either. When a fill is split across venues and any leg is blocked, the whole fill is refused. For a buy, re-quote with that venue left out.
Geo eligibility is not exposed on the events or markets endpoints. Use quote warnings to check the proposed trade, and the policy endpoint below for country rules.
Reading the lists
GET /app/venue-geo-policy returns each venue's country policy. Authenticate with x-app-id.
const { venues } = await client.getVenueGeoPolicy();Each entry has blockedCountries. Some venues also set allowedCountries. When allowedCountries is present, the venue can be traded only from those countries. An empty blockedCountries list is not unrestricted in that case. Ignore the empty block list.
Novig is the example. It is available only in the United States, so it sets allowedCountries and leaves blockedCountries empty. A user outside those allowed countries cannot fill Novig. The United States is blocked on every other venue. That is sufwan-local-test platform policy, not a copy of each venue's own terms.
Get the per-venue blocked-country lists (ISO 3166-1 alpha-2).
This is the raw venue policy, not per-user eligibility. It does not account for the country resolved for this user, your app's disabled venues, or the fail-closed rule when the country is unknown. Do not gate a fill on it. warnings on the quote is the per-user answer.
Limit orders
A limit order has no quote. It is checked against the per-venue list for the venue it names, and refused with 403 geo_blocked before any order is created. To check before sending one, get a buy quote for that outcome. Its warnings come back even when the amount is below the venue minimum.
Country resolution
Country comes from the request's edge-detected country unless your app is enrolled in Trusted Proxy. Then it is resolved from the x-agg-client-ip you forward.
If the country cannot be determined, no venues are available and every fill is rejected. This is fail-closed.
With Trusted Proxy, a missing or bad x-agg-client-ip does not trigger this. sufwan-local-test falls back to the edge-detected country of your backend, so the user is checked as if they were in your backend's country. The fill error does not distinguish the two cases: an unresolved country reads (unknown) in the geo_blocked message, a restricted one names the country.
VPN exits resolve to the VPN's exit country.