> ## Documentation Index
> Fetch the complete documentation index at: https://docs.proofage.net/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP SDK

> Create verifications and verify webhooks from PHP with proofage/php-sdk.

`proofage/php-sdk` is the framework-neutral PHP client: request signing, every endpoint, streaming media downloads and webhook verification. Its only runtime dependencies are PHP 8.1+, `ext-curl`, `ext-json` and the `psr/http-message` interfaces.

On Laravel, use the [Laravel SDK](/integration/server-sdks/laravel), which wraps this one.

## Install

```bash theme={null}
composer require proofage/php-sdk
```

## Configure

```php theme={null}
use ProofAge\Sdk\Client;

$client = new Client([
    'api_key' => getenv('PROOFAGE_API_KEY'),
    'secret_key' => getenv('PROOFAGE_SECRET_KEY'),
    'base_url' => 'https://api.proofage.net',
]);
```

| Key | Default | |
| - | - | - |
| `api_key` | required | The workspace's public key. |
| `secret_key` | required | Used only to sign. |
| `base_url` | required | `https://api.proofage.net`, without a path. |
| `timeout` | `30` | Seconds per attempt. |
| `retry_attempts` | `3` | Attempts for interactive requests. |
| `retry_delay` | `1000` | Milliseconds between attempts. |
| `download_retry_attempts` | `1` | Media downloads retry only a failed connection. |

## Create a verification

```php theme={null}
$verification = $client->verifications()->create([
    'external_id' => 'user_12345',
    'callback_url' => 'https://yourapp.example/verified',
]);

$verification['url']; // send the person here
```

Methods return the decoded JSON as an array.

## Read results

```php theme={null}
$v = $client->verifications($verificationId);

$v->get();          // status, reason, duplicate_check, …
$v->document();     // document fields and media
$v->estimation();   // minimum-age result
```

`downloadMediaTo()` streams an image to a file and only writes it after a `2xx`.

## Receive webhooks

```php theme={null}
use ProofAge\Sdk\Webhooks\WebhookVerifier;
use ProofAge\Sdk\Exceptions\WebhookVerificationException;

$verifier = new WebhookVerifier(getenv('PROOFAGE_API_KEY'), getenv('PROOFAGE_SECRET_KEY'));

try {
    $verifier->verifyHeaders(getallheaders(), file_get_contents('php://input'));
} catch (WebhookVerificationException $e) {
    http_response_code($e->statusCode);
    echo json_encode($e->toArray());
    exit;
}

$payload = json_decode(file_get_contents('php://input'), true);
```

Give the verifier the workspace's **active** secret key: webhooks are signed with it. The timestamp tolerance is 300 seconds (the constructor's third argument). Failures carry a code: `MISSING_SIGNATURE`, `MISSING_TIMESTAMP`, `MISSING_AUTH_CLIENT`, `INVALID_AUTH_CLIENT`, `TIMESTAMP_TOO_OLD` or `INVALID_SIGNATURE`.

## Everything else

```php theme={null}
$client->workspace()->get();
$client->workspace()->getConsent();
$v->acceptConsent(['consent_version_id' => $consent['id'], 'text_sha256' => $consent['text_sha256']]);
$v->uploadMedia(['type' => 'selfie', 'file' => '/tmp/selfie.jpg']);
$v->uploadMedia(['type' => 'document', 'side' => 'front', 'document' => 'passport', 'file' => '/tmp/front.jpg']);
$v->submit();
$v->blockFace(['reason_code' => 'underage']);
```

## Errors and retries

| Exception | When |
| - | - |
| `AuthenticationException` | `401`. |
| `ValidationException` | `422`; `getErrors()` for fields, `getErrorCode()` for a refused image. |
| `TransportException` | No response: DNS, connection, TLS or a timeout. |
| `ProofAgeException` | Any other error, and the base class: `getCode()` is the HTTP status, `getErrorCode()` the API's code. |

A `GET` is retried after a transport failure, a `429` or a `5xx`. A `POST` is retried only when the connection failed before sending, or on a `429` with `Retry-After`; a `5xx` or a timeout on a `POST` is thrown at once, because the server may already have acted.

Dumping a client or an exception with `print_r()` or `var_dump()` never shows the secret key.

## Links

* [Packagist: proofage/php-sdk](https://packagist.org/packages/proofage/php-sdk)
* [GitHub: ProofAge/php-sdk](https://github.com/ProofAge/php-sdk)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.