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

# PHP Server SDK

> The PHP Server SDK is an easy way to interact with our Server API from your PHP application. You can retrieve visitor history or individual identification events. View our [PHP Server SDK quickstart](/docs/php-server-quickstart) for a step-by-step guide to get started.

## How to install

Add the package to your `composer.json` file as a dependency:

```bash Bash theme={"theme":"github-dark-dimmed"}
composer require fingerprint/server-sdk
```

Initialize the client instance and use it to make API requests. You need to specify your secret API key and region (if it is not US/Global).

```php PHP theme={"theme":"github-dark-dimmed"}
<?php

require_once(__DIR__ . '/vendor/autoload.php');

use Fingerprint\ServerSdk\Api\FingerprintApi;
use Fingerprint\ServerSdk\Configuration;

$config = new Configuration(
  "SECRET_API_KEY",
  // Configuration::REGION_EUROPE
);
$client = new FingerprintApi($config);

// Search events, for example, by visitor ID
try {
  $events = $client->searchEvents(10, visitor_id: "VISITOR_ID");
  print_r($events);
} catch (Exception $e) {
  echo $e->getMessage(), PHP_EOL;
}

// Get a specific identification event
try {
  $event = $client->getEvent("EVENT_ID");
  print_r($event);
} catch (Exception $e) {
  echo $e->getMessage(), PHP_EOL;
}
```

## Migration guide for PHP SDK v7

Version 7 migrates the SDK from Server API v3 to v4. This is a breaking change.

This section summarizes the most important changes from previous versions.

PHP SDK v7 requires PHP 8.2 or higher. Support for PHP 8.1 has been dropped.

### Package and namespace rename

The Composer package changed from `fingerprint/fingerprint-pro-server-api-sdk` to `fingerprint/server-sdk`, and the namespace changed from `Fingerprint\ServerAPI` to `Fingerprint\ServerSdk`.

```json composer.json theme={"theme":"github-dark-dimmed"}
"require": {
  "fingerprint/fingerprint-pro-server-api-sdk": "^6.10.0" // [!code --]
  "fingerprint/server-sdk": "^7.0.0" // [!code ++]
}
```

Update all `use` statements to the new namespace:

```php PHP theme={"theme":"github-dark-dimmed"}
use Fingerprint\ServerAPI\Configuration; // [!code --]
use Fingerprint\ServerSdk\Configuration; // [!code ++]
```

### Client construction

The API key is now required in the `Configuration` constructor. `Configuration::getDefaultConfiguration()` and `setDefaultConfiguration()` have been removed. The `FingerprintApi` constructor also takes the configuration as its first argument, with the optional HTTP client second.

```php PHP theme={"theme":"github-dark-dimmed"}
$config = Configuration::getDefaultConfiguration("SECRET_API_KEY", Configuration::REGION_EUROPE); // [!code --]
$client = new FingerprintApi($httpClient, $config); // [!code --]
$config = new Configuration("SECRET_API_KEY", Configuration::REGION_EUROPE); // [!code ++]
$client = new FingerprintApi($config, $httpClient); // [!code ++]
// OR if you are using the default HTTP client // [!code ++]
$client = new FingerprintApi($config); // [!code ++]
```

### Get an event

The `getEvent` parameter `$request_id` is now `$event_id`, and the method returns an `Event` instead of a `list($event, $response)` tuple. The event data structure is flatter: fields are accessed directly instead of through the `products` wrapper.

```php PHP theme={"theme":"github-dark-dimmed"}
list($event, $response) = $client->getEvent(request_id: "REQUEST_ID"); // [!code --]
$visitorId = $event->getProducts()->getIdentification()->getData()->getVisitorId(); // [!code --]
$event = $client->getEvent(event_id: "EVENT_ID"); // [!code ++]
$visitorId = $event->getIdentification()->getVisitorId(); // [!code ++]
```

If you need the raw HTTP response, use the `WithHttpInfo` variant. Every operation now exposes `{operation}()`, `{operation}WithHttpInfo()`, `{operation}Async()`, and `{operation}AsyncWithHttpInfo()` methods.

```php PHP theme={"theme":"github-dark-dimmed"}
list($event, $response) = $client->getEvent("REQUEST_ID"); // [!code --]
list($event, $response) = $client->getEventWithHttpInfo("EVENT_ID"); // [!code ++]
```

### Search events

`searchEvents` now returns an `EventSearch` object instead of an array.

```php PHP theme={"theme":"github-dark-dimmed"}
list($events, $response) = $client->searchEvents(10, visitor_id: "VISITOR_ID"); // [!code --]
$events = $client->searchEvents(limit: 10, visitor_id: "VISITOR_ID"); // [!code ++]
```

### `getVisits` and `getRelatedVisitors` replaced by `searchEvents`

`getVisits` and `getRelatedVisitors` have been removed.
Use `searchEvents` with the `visitor_id` to find the events for a particular visitor.

```php PHP theme={"theme":"github-dark-dimmed"}
list($visits, $response) = $client->getVisits("VISITOR_ID"); // [!code --]
$events = $client->searchEvents(limit: 10, visitor_id: "VISITOR_ID"); // [!code ++]
```

### Update an event

`updateEvent` now takes the event ID first and an `EventUpdate` body second, returns `void` instead of an array, and issues a `PATCH` request instead of `PUT`.

```php PHP theme={"theme":"github-dark-dimmed"}
$body = new EventsUpdateRequest(['tag' => ['key' => 'value']]); // [!code --]
$client->updateEvent($body, request_id: "REQUEST_ID"); // [!code --]
$body = new EventUpdate(['tags' => ['key' => 'value']]); // [!code ++]
$client->updateEvent(event_id: "EVENT_ID", $body); // [!code ++]
```

### Handling sealed client results from a v3 JavaScript agent

PHP SDK v7 will fail to deserialize the decrypted payload of a [sealed client result](/docs/sealed-client-results) sent by a v3 JavaScript agent into an `Event` because the payload is an `EventsGetResponse` (i.e., the v3 event format), not an `Event`. In this case, `Sealed::unsealEventResponse` throws an `InvalidSealedDataException`.

To upgrade to PHP SDK v7 without requiring a concurrent upgrade to the v4 JavaScript agent, you can fall back to using the Server API if unsealing the sealed client results fails.
To enable this fallback path, your frontend must send the event ID alongside the sealed client results, as recommended by the [sealed client results guide](/docs/sealed-client-results#step-3-send-sealed_result-to-your-backend).

Both `Sealed::unsealEventResponse` and `$client->getEvent` return an `Event`, so the fallback returns the same type.

```php PHP theme={"theme":"github-dark-dimmed"}
// Partial example (imports omitted).

function getEvent(
  FingerprintApi $client,
  string $sealedResultBytes, // previously decoded using base64_decode
  string $eventId,
  array $keys
): Event {
  // Try to unseal the payload locally first.
  try {
    return Sealed::unsealEventResponse($sealedResultBytes, $keys);
  } catch (InvalidSealedDataException $e) {
    // Deserialization failed. Fall back to the Server API using the event ID
    // sent alongside the sealed client results.
    fwrite(STDERR, sprintf("Could not unseal result, falling back to Server API: %s\n", $e->getMessage()));
    return $client->getEvent($eventId);
  }
}
```

## Documentation

You can find the full documentation in the official [GitHub repository](https://github.com/fingerprintjs/php-sdk).
