Switch from hCaptcha

Migrate from hCaptcha to gkCAPTCHA in under 15 minutes.

Why Switch?

  • PDPL compliance: gkCAPTCHA is fully compliant with Saudi Arabia's Personal Data Protection Law. hCaptcha processes data on US-based infrastructure, which may conflict with PDPL data localization requirements.
  • Data residency: All data is processed and stored in our Riyadh data center. No user data ever leaves Saudi Arabia.
  • Privacy-first: gkCAPTCHA uses no tracking cookies, no persistent fingerprinting, and no cross-site tracking. Behavioral data is processed in real-time and never stored.

Code Changes

Client-Side (HTML)

Before (hCaptcha)

index.html
<!-- hCaptcha -->
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<form action="/submit" method="POST">
  <div class="h-captcha" data-sitekey="YOUR_SITE_KEY"></div>
  <button type="submit">Submit</button>
</form>

After (gkCAPTCHA)

index.html
<!-- gkCAPTCHA -->
<script src="https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js" async defer></script>
<form action="/submit" method="POST">
  <gk-captcha site-key="pk_live_..."></gk-captcha>
  <button type="submit">Submit</button>
</form>

Server-Side (Verification)

Before (hCaptcha)

server.ts
// hCaptcha server-side verification
const response = await fetch('https://hcaptcha.com/siteverify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    secret: process.env.HCAPTCHA_SECRET_KEY,
    response: req.body['h-captcha-response'],
  }),
})
const data = await response.json()
// { success: bool, challenge_ts, hostname, "error-codes": [] }

After (gkCAPTCHA)

server.ts
// gkCAPTCHA server-side verification
const response = await fetch('https://gkcaptcha.gatekeeper.sa/api/v1/token/verify', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.GKCAPTCHA_SECRET_KEY}`,
  },
  body: JSON.stringify({ token: req.body['gk-captcha-token'] }),
})
const data = await response.json()
// { success: bool, score: 0.0-1.0, timestamp, reason_code? }

Step-by-Step Migration

  1. Sign up at gatekeeper.sa and create a site to get your site key (pk_live_...) and secret key (sk_live_...).
  2. Remove the hCaptcha script tag: remove the script loading js.hcaptcha.com/1/api.js.
  3. Add the gkCAPTCHA script tag: <script src="https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js" async defer></script>
  4. Replace the widget element: change <div class="h-captcha" ...> to <gk-captcha site-key="pk_live_...">.
  5. Update server-side verification: change the endpoint from hcaptcha.com/siteverify to gkcaptcha.gatekeeper.sa/api/token/verify. Use JSON body with Authorization header instead of form-encoded params.
  6. Update environment variables: rename HCAPTCHA_SECRET_KEY to GKCAPTCHA_SECRET_KEY and HCAPTCHA_SITE_KEY to GKCAPTCHA_SITE_KEY.
  7. Test in staging: verify the widget renders, verification succeeds, and your form submission flow works end-to-end.

Testing Checklist

  • Widget renders on the page
  • Verification succeeds with valid interaction
  • Verification rejects without interaction
  • Error handling works when API is unreachable
  • Form submission flow works end-to-end
  • Mobile layout renders correctly