METHOD for the next pass: not geo-blocked. /gh/ is a client-side SPA behind Cloudflare Turnstile (curl returns a 7.7 KB empty shell), but the public JSON API needs no browser and is explicitly Ghana-scoped: /rest/cms/pages/{rules,faq,footer,promo,app}/content?languageCode=EN&countryCode=GH&brand=2, plus /rest/market/categories for live event counts.
Our limits, and theirs
Most of the empty cells on this site are ours
A blank in a table reads as filing that fell behind. On this site it almost always means something else: a cashier that renders only for a visitor inside Ghana, a lobby served by an interface that needs a signed session, a promotions page that answers a request from abroad with a block. This page names every one of them.
The cashiers nobody outside Ghana can see
- 1xBet No payment row on the record. Everything this site says about paying it or being paid by it comes from its terms or from third parties.
- Melbet No payment row on the record. Everything this site says about paying it or being paid by it comes from its terms or from third parties.
- 22Bet No payment row on the record. Everything this site says about paying it or being paid by it comes from its terms or from third parties.
- Betwinner No payment row on the record. Everything this site says about paying it or being paid by it comes from its terms or from third parties.
Method
How the pages that could be read were reached
Written for whoever checks this next rather than for a reader, and printed anyway. A research note that lives only in somebody's head is how the same wall gets hit twice.
METHOD for the next pass: msport.com/gh is NOT geo-blocked (HTTP 200, lang=en-GH) but is a client-side Vue app. The odds API base recovered from the webpack bundle is https://www.msport.com/gh/api/, region-prefixed, and an unprefixed /api/ call defaults to the Nigeria book, with endpoints /facts-center/query/frontend/{hot-matches, focus-matches/v3, sports-matches-list/home-page, all-matches/today, market-info, super-market-info}. They need the signed browser session headers the client attaches, so drive /gh/web/sports/list/Soccer in a real browser and capture the facts-center XHR. A field on this record held a figure the same record's doNotPrint rejects, so it reached pages that render the record faithfully. Nulled at source rather than suppressed in ten templates. The deposit ceiling is single-source.
METHOD: bangbet.com is NOT geo-blocked from Europe. Its static paths (/gh/help/, /gh/news/, /gh/en/casino/*, /pages/tandcghana/index.htm) all serve full content; only the JS sportsbook app and third-party review sites were unreachable. A field on this record held a figure the same record's doNotPrint rejects, so it reached pages that render the record faithfully. Nulled at source rather than suppressed in ten templates. The per-bet payout ceiling is unit-swapped from the Kenyan page.
METHOD, worth reusing: betpawa.com.gh is not geo-blocked but is a Next.js SPA serving an identical 7,282-byte empty shell to every route. Its robots.txt explicitly allows ClaudeBot, and the site PRERENDERS full content for that user agent, /terms became 117KB of real text, /casino 675KB, each /events/group/<id> about 1.1MB of live odds. Plain browser UAs get nothing. /help, /about, /rules, /withdrawal-fee and /deposit-mtn do NOT prerender and needed a reader proxy.
METHOD: soccabet.com.gh 301-redirects to soccabet.com and the site is NOT geo-blocked. It is a client-side-rendered Angular SPA, so a fetch returns a 19KB shell containing the title and 58 characters of text; everything here was read by driving a real browser. Trustpilot, casino.guru, ghanasoccernet, telecomasia and modernghana all returned [liczba wycofana] bot challenges to fetch and needed the browser too.
METHOD: not geo-blocked. wiwi.casino is a Nuxt SPA serving an identical 34,821-byte shell to every HTML route, so text extraction sees nothing. The unlock is the SPA's own API, GET /api/platform/get_global_data with header 'Platform-id: c3559f4a-7e9d-4174-9e81-5964e5bb787b' (the UUID is in a meta tag and in the sitemap path), and GET /api/get_html_page?code=<slug> which returns base64-encoded HTML. That yielded all six legal and info pages.
Questions about what could be read
- Why can this desk not just look at the websites?
- Several of them do not open to an address outside Ghana, and most of the rest are applications that build the page in the visitor's browser and serve an empty shell to anything else. One book served what looked like a working homepage to a European address and it turned out to be the furniture of its own block page, complete with game names that are not in its product. Anything scraped from that would have been published as fact.
- Does an unreadable site mean a bookmaker is hiding something?
- No. Geographic blocking is a licensing and payments decision, and rendering a page in the browser is how most modern sites are built. The consequence is real anyway: it means an outside reader cannot check what a bookmaker says about itself, and this publication can only tell you what it was able to see.
- What is the practical effect on the verdicts?
- Two axes go empty. ten of the 13 lobbies could not be counted and six welcome offers had to be taken from affiliate agreement rather than from an operator page. Every verdict computed over a thinner model carries the share of the model beside it, on every page, without exception.