PHP SDK
The PHP SDK (xident/xident-php) provides a clean, modern PHP 8.1+ client for server-side age verification. Zero external dependencies — uses native cURL. Works with Laravel, Symfony, WordPress, and standalone PHP.
Secret key required: Always use your secret key (sk_live_...) for the PHP SDK. The public key (pk_live_...) is for the JS SDK only. The SDK sends it via the X-API-Key header (not Authorization: Bearer).
Installation
composer require xident/xident-php Or without Composer: require_once '/path/to/xident-php/autoload.php';
Quick Start
Step 1: Create an init token and redirect the user to the verification widget:
<?php
use Xident\SDK\Client;
$xident = new Client(apiKey: $_ENV['XIDENT_SECRET_KEY']);
// 1. Create init token — redirect user to verification widget
$session = $xident->verification()->init([
'callback_url' => 'https://yoursite.com/verify-callback',
'min_age' => 18,
'success_url' => 'https://yoursite.com/welcome',
'failed_url' => 'https://yoursite.com/sorry',
]);
header('Location: ' . $session->verifyUrl);
exit; Step 2: After the user completes verification, they are redirected back with a ?token=xtk_xxx parameter. Always verify server-side — never trust URL parameters alone:
<?php
// 2. After user returns — verify result server-side
$token = $_GET['token']; // from callback URL ?token=xtk_xxx
$result = $xident->verification()->getResult($token);
if ($result->isVerified()) {
echo "Age bracket: " . $result->ageBracket(); // 18
echo "Method: " . $result->method(); // "ml_fast"
// Grant access to age-restricted content
} Laravel Example
<?php
// app/Http/Controllers/VerificationController.php
use Xident\SDK\Client;
class VerificationController extends Controller
{
public function start(Request $request)
{
$xident = new Client(apiKey: config('services.xident.secret_key'));
$session = $xident->verification()->init([
'callback_url' => route('verify.callback'),
'min_age' => 18,
'user_id' => (string) $request->user()->id,
]);
return redirect($session->verifyUrl);
}
public function callback(Request $request)
{
$xident = new Client(apiKey: config('services.xident.secret_key'));
$result = $xident->verification()->getResult($request->input('token'));
if ($result->isVerified()) {
$request->user()->update(['age_verified' => true]);
return redirect()->route('dashboard');
}
return redirect()->route('verify.failed');
}
} Symfony Example
<?php
// src/Controller/VerificationController.php
use Xident\SDK\Client;
class VerificationController extends AbstractController
{
#[Route('/verify/callback')]
public function callback(Request $request): Response
{
$xident = new Client(apiKey: $this->getParameter('xident_secret'));
$result = $xident->verification()->getResult($request->query->get('token'));
if ($result->isVerified()) {
$request->getSession()->set('age_verified', true);
return $this->redirectToRoute('dashboard');
}
return $this->redirectToRoute('verify_failed');
}
} Webhook Verification
Verify incoming webhook signatures using HMAC-SHA256:
<?php
$event = $xident->webhooks()->constructEvent(
payload: file_get_contents('php://input'),
signature: $_SERVER['HTTP_X_XIDENT_SIGNATURE'],
secret: $_ENV['XIDENT_WEBHOOK_SECRET'],
);
match ($event['type']) {
'session.completed' => handleCompleted($event['data']),
'session.failed' => handleFailed($event['data']),
default => null,
}; Error Handling
<?php
use Xident\SDK\Exceptions\XidentException;
use Xident\SDK\Exceptions\AuthenticationException;
use Xident\SDK\Exceptions\NotFoundException;
try {
$result = $xident->verification()->getResult($token);
} catch (AuthenticationException $e) {
// 401 - Invalid API key
} catch (NotFoundException $e) {
// 404 - Token not found
} catch (XidentException $e) {
echo $e->getErrorCode(); // API error code
echo $e->getRequestId(); // For support tickets
} Using the REST API Directly
If you prefer not to use the SDK, you can call the Xident API directly with cURL:
<?php
// If you prefer not to use the SDK, call the API directly:
$token = filter_input(INPUT_GET, 'token', FILTER_SANITIZE_SPECIAL_CHARS);
$ch = curl_init('https://api.xident.io/verify/v1/result/' . urlencode($token));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $_ENV['XIDENT_SECRET_KEY'],
'Accept: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($response['success'] && $response['data']['status'] === 'completed') {
// Verified
} PHP 8.5+ note: curl_close() is deprecated as of PHP 8.5 and will be removed in a future version. cURL handles are automatically freed when they go out of scope. You can safely remove the curl_close($ch) call if you're targeting PHP 8.5+.
Configuration
| Option | Default | Description |
|---|---|---|
apiKey | (required) | Your secret API key (sk_live_* or sk_test_*) |
baseUrl | https://api.xident.io | API base URL |
timeout | 30 | Request timeout in seconds |
maxRetries | 3 | Max retries on 5xx errors |
Related
- JavaScript SDK — Client-side browser integration
- Node.js SDK — Server-side Node.js alternative
- All SDKs — Overview of all Xident SDKs
- API Reference — Full REST API documentation