API Format

Complete reference for IM18+ API endpoints and PostMessage communication format. Learn how to integrate with our verification and geolocation services.

📡 PostMessage API

The IM18+ verification system uses secure PostMessage communication between your site and our verification service. This ensures privacy and security while enabling seamless cross-domain age verification.

Basic Integration

<iframe id="verification-iframe"
        src="https://verify.im18.app/api/check-anonymous.php"
        style="display: none;"></iframe>

<script>
window.addEventListener('message', function(event) {
    if (event.origin !== 'https://verify.im18.app') return;

    if (event.data.type === 'verification_result') {
        if (event.data.verified) {
            // User is verified - show content
            showMainContent();
        } else {
            // User needs verification
            redirectToVerification();
        }
    }
});
</script>

Message Format

Verification Response (Verified)

{
    "type": "verification_result",
    "verified": true,
    "data": {
        "verified_at": "2025-01-21T12:00:00Z",
        "expires_at": "2025-02-20T12:00:00Z",
        "expires_in": 2592000,
        "service": "IM18+",
        "privacy": "zero-knowledge"
    }
}

Verification Response (Not Verified)

{
    "type": "verification_result",
    "verified": false,
    "data": {
        "service": "IM18+",
        "privacy": "zero-knowledge",
        "verification_url": "https://verify.im18.app/verify.php"
    }
}

🌐 REST API Endpoints

GET /api/check-anonymous.php

Check verification status via iframe PostMessage (primary method)

Usage: Embed as invisible iframe

Response: PostMessage to parent window

Authentication: Domain whitelist required

GET /api/ip.php

Get country code for IP address using our best-in-class detection system

Parameters

ip (optional) - IP address to check. Defaults to client IP.

Response Format
{
    "success": true,
    "ip": "8.8.8.8",
    "country": "US",
    "country_name": "United States",
    "continent": "North America",
    "is_eu": false,
    "method": "best_in_class_detection"
}
Example Usage
// JavaScript
fetch('https://verify.im18.app/api/ip.php?ip=8.8.8.8')
    .then(response => response.json())
    .then(data => {
        console.log('Country:', data.country);
        if (data.country === 'US') {
            // US-specific logic
        }
    });

// PHP
$response = file_get_contents('https://verify.im18.app/api/ip.php');
$data = json_decode($response, true);
echo "Country: " . $data['country'];

⚠️ Error Handling

Common Error Responses

403 Forbidden - Domain Not Authorized

{
    "success": false,
    "error": "Unauthorized",
    "message": "Domain not authorized",
    "timestamp": "2025-01-21T12:00:00Z"
}

Solution: Register your domain at register.html

400 Bad Request - Invalid IP

{
    "success": false,
    "error": "Invalid IP address",
    "provided_ip": "invalid.ip"
}

404 Not Found - Country Unknown

{
    "success": false,
    "error": "Country not found",
    "ip": "192.168.1.1"
}

Timeout Handling

Always implement timeout handling for iframe PostMessage communication. If no response is received within 5 seconds, assume verification is required.

💻 Integration Examples

Complete JavaScript Integration

class IM18Integration {
    constructor() {
        this.verified = false;
        this.checkTimeout = 5000; // 5 second timeout
        this.init();
    }

    init() {
        // Create verification iframe
        const iframe = document.createElement('iframe');
        iframe.src = 'https://verify.im18.app/api/check-anonymous.php';
        iframe.style.display = 'none';
        document.body.appendChild(iframe);

        // Set up message listener
        window.addEventListener('message', (event) => {
            if (event.origin !== 'https://verify.im18.app') return;
            this.handleVerificationResponse(event.data);
        });

        // Timeout fallback
        setTimeout(() => {
            if (!this.verified) {
                this.showVerificationRequired();
            }
        }, this.checkTimeout);
    }

    handleVerificationResponse(data) {
        if (data.type === 'verification_result') {
            if (data.verified) {
                this.verified = true;
                this.showContent();
            } else {
                this.showVerificationRequired();
            }
        }
    }

    showContent() {
        document.getElementById('main-content').style.display = 'block';
        document.getElementById('age-gate').style.display = 'none';
    }

    showVerificationRequired() {
        document.getElementById('age-gate').style.display = 'block';
        document.getElementById('main-content').style.display = 'none';
    }
}

// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
    new IM18Integration();
});

PHP Server-Side Country Check

<?php
function checkUserCountry($userIP = null) {
    $ip = $userIP ?: $_SERVER['REMOTE_ADDR'];
    $url = "https://verify.im18.app/api/ip.php?ip=" . urlencode($ip);

    $response = file_get_contents($url);
    if ($response === false) {
        return ['success' => false, 'error' => 'API unavailable'];
    }

    return json_decode($response, true);
}

// Usage
$result = checkUserCountry();
if ($result['success']) {
    $country = $result['country'];

    // Country-specific logic
    if (in_array($country, ['US', 'CA'])) {
        // North America - show verification
        require_once 'age-verification.php';
    } else {
        // Other countries - different flow
        require_once 'international-notice.php';
    }
} else {
    // Fallback - show verification by default
    require_once 'age-verification.php';
}
?>

© 2025 IM18+ Age Verification System. Secure, federated, privacy-focused.

Home | Documentation | Developer Tools