Verify Endpoint

Server-side verification of CAPTCHA tokens.

Endpoint

POST https://gkcaptcha.gatekeeper.sa/api/v1/token/verify

Request

cURL
curl -X POST https://gkcaptcha.gatekeeper.sa/api/v1/token/verify \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -d '{
    "token": "CAPTCHA_TOKEN_FROM_CLIENT"
  }'

Headers

HeaderRequiredDescription
AuthorizationYesBearer token with your secret key
Content-TypeYesMust be application/json

Body Parameters

ParameterTypeRequiredDescription
tokenstringYesThe token from the client widget
remoteipstringNoClient IP for additional validation

Response

Success Response

json
{
  "success": true,
  "data": {
    "verified": true,
    "score": 0.15,
    "hostname": "yourdomain.com",
    "action": "login",
    "timestamp": "2024-01-15T10:30:00Z",
    "challenge_ts": "2024-01-15T10:29:55Z"
  }
}

Failed Verification

json
{
  "success": true,
  "data": {
    "verified": false,
    "score": 0.85,
    "error_codes": ["timeout-or-duplicate", "invalid-input-response"]
  }
}

Response Fields

FieldTypeDescription
verifiedbooleanWhether verification passed
scorefloatRisk score (0.0 = safe, 1.0 = bot)
hostnamestringDomain where widget was solved
actionstringAction name if specified
error_codesarrayError codes if verification failed

Error Codes

CodeDescription
missing-input-secretSecret key not provided
invalid-input-secretSecret key is invalid
missing-input-responseToken not provided
invalid-input-responseToken is invalid or malformed
timeout-or-duplicateToken expired or already used
bad-requestRequest was malformed

Code Examples

Node.js / Express

server.js
const verifyCaptcha = async (token) => {
  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 })
  });

  const result = await response.json();

  if (!result.success) {
    throw new Error('API request failed');
  }

  return result.data;
};

// Usage in Express route
app.post('/submit-form', async (req, res) => {
  const { captchaToken, ...formData } = req.body;

  const verification = await verifyCaptcha(captchaToken);

  if (!verification.verified) {
    return res.status(400).json({ error: 'CAPTCHA verification failed' });
  }

  // Check hostname matches your domain
  if (verification.hostname !== 'yourdomain.com') {
    return res.status(400).json({ error: 'Invalid origin' });
  }

  // Process the form...
  res.json({ success: true });
});

Go

main.go
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

type VerifyRequest struct {
    Token string `json:"token"`
}

type VerifyResponse struct {
    Success bool         `json:"success"`
    Data    VerifyData   `json:"data"`
}

type VerifyData struct {
    Verified   bool     `json:"verified"`
    Score      float64  `json:"score"`
    Hostname   string   `json:"hostname"`
    ErrorCodes []string `json:"error_codes,omitempty"`
}

func verifyCaptcha(token string) (*VerifyData, error) {
    reqBody, _ := json.Marshal(VerifyRequest{Token: token})

    req, _ := http.NewRequest("POST", "https://gkcaptcha.gatekeeper.sa/api/v1/token/verify",
        bytes.NewBuffer(reqBody))

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer "+os.Getenv("GKCAPTCHA_SECRET_KEY"))

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var result VerifyResponse
    json.NewDecoder(resp.Body).Decode(&result)

    return &result.Data, nil
}

Python / Flask

app.py
import os
import requests

def verify_captcha(token: str) -> dict:
    response = requests.post(
        'https://gkcaptcha.gatekeeper.sa/api/v1/token/verify',
        headers={
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {os.environ["GKCAPTCHA_SECRET_KEY"]}'
        },
        json={'token': token}
    )

    result = response.json()

    if not result.get('success'):
        raise Exception('API request failed')

    return result['data']

# Usage in Flask
@app.route('/submit', methods=['POST'])
def submit_form():
    token = request.json.get('captchaToken')

    verification = verify_captcha(token)

    if not verification['verified']:
        return jsonify({'error': 'Verification failed'}), 400

    # Process form...
    return jsonify({'success': True})

Best Practices

  • Always verify tokens server-side, never trust client-side results
  • Check the hostname matches your domain
  • Handle errors gracefully - don't block users on API failures
  • Set appropriate timeouts (recommended: 10 seconds)
  • Log verification failures for security monitoring