Configuration Options
Full SDK config reference with PSR integration
Full SDK Configuration Options
use ConvertSdk\ConvertSDK;
$sdk = ConvertSDK::create([
'sdkKey' => '', // either this or 'data' is required
'sdkKeySecret' => '', // required when using an authenticated SDK key
'environment' => 'production',
'dataRefreshInterval' => 300000, // config cache TTL in ms (5 minutes)
'data' => [], // static project configuration (alternative to sdkKey)
'debugToken' => null, // QA/preview: load draft + paused experiences, bypass the config cache
'logger' => [ // optional logging configuration
'logLevel' => \ConvertSdk\Enums\LogLevel::Debug,
'customLoggers' => [$psrLogger], // array of PSR-3 LoggerInterface instances
],
'cache' => $psrCache, // optional PSR-16 CacheInterface instance (e.g., Redis, Memcached)
'dataStore' => null, // optional visitor data store (defaults to the PSR-16 cache above)
'bucketing' => [
'hash_seed' => 9999, // MurmurHash seed
'max_traffic' => 10000, // max hash value (100% traffic)
'excludeExperienceIdHash' => false, // exclude experience ID from hash input
],
'events' => [
'batch_size' => 10, // max events per network batch
],
'network' => [
'tracking' => true, // set false to disable tracking events
'cacheLevel' => 'default', // 'low' for short-lived cache (dev only)
'source' => 'php-sdk', // SDK source identifier
],
'rules' => [
'keys_case_sensitive' => true,
'comparisonProcessor' => null, // allows 3rd party comparison processor
'negation' => '!', // negation character for rule matching
],
'api' => [
'endpoint' => [
'config' => 'https://cdn-4.convertexperiments.com/api/v1',
'track' => 'https://[project_id].metrics.convertexperiments.com/v1',
],
],
]);Configuration Options Reference
| Option | Type | Description |
|---|---|---|
sdkKey | string | Required if not providing data. Your unique project identifier from Convert. |
sdkKeySecret | string | Required when using an authenticated SDK key. |
data | array|ConfigResponseData | Required if not providing sdkKey. Provide project configuration directly. |
environment | string | Target environment (e.g., 'staging', 'production'). |
dataRefreshInterval | int | Cache TTL in milliseconds. Default: 300000 (5 minutes). |
debugToken | ?string | QA/preview debug token. Widens the config fetch to every non-archived experience and bypasses caching. Default: null. See QA Debug Token. |
logger | array | Logging configuration with logLevel and customLoggers keys. |
cache | CacheInterface | PSR-16 compatible cache. Used for config caching AND visitor data persistence. Defaults to ArrayCache (in-memory). |
dataStore | object | Custom data store for visitor data. Overrides cache for visitor data if provided. |
bucketing.hash_seed | int | MurmurHash3 seed. Default: 9999. |
bucketing.max_traffic | int | Max hash value (100% traffic). Default: 10000. |
bucketing.excludeExperienceIdHash | bool | Exclude the experience ID from the hash input. Default: false. |
events.batch_size | int | Max events per tracking batch. Default: 10. |
network.tracking | bool | Set false to disable tracking events. Default: true. |
network.cacheLevel | string | 'low' for short-lived cache (dev only). Default: 'default'. |
network.source | string | SDK source identifier. Default: 'php-sdk'. Can be overridden by the VERSION environment variable. |
rules.keys_case_sensitive | bool | Whether rule keys are case-sensitive. Default: true. |
rules.comparisonProcessor | mixed | Allows 3rd party comparison processor. Default: null. |
rules.negation | string | Negation character for rule matching. Default: '!'. |
api.endpoint.config | string | CDN endpoint for fetching config. Default: 'https://cdn-4.convertexperiments.com/api/v1'. |
api.endpoint.track | string | Tracking API endpoint. Default: 'https://[project_id].metrics.convertexperiments.com/v1'. |
PSR Standards Integration
| Config Key | PSR Standard | Interface | Default |
|---|---|---|---|
logger.customLoggers[] | PSR-3 | Psr\Log\LoggerInterface | Empty array (no custom loggers) |
cache | PSR-16 | Psr\SimpleCache\CacheInterface | ConvertSdk\Cache\ArrayCache (in-memory) |
| (auto-discovered) | PSR-18 | Psr\Http\Client\ClientInterface | Auto-discovered via php-http/discovery |
The cache option serves a dual purpose: it stores both the fetched project configuration (with TTL) and visitor bucketing data for cross-request persistence. See Persistent DataStore for details.
Rule Comparison Operators
rules.comparisonProcessor defaults to ConvertSdk\Utils\Comparisons. A rule's match_type from the served config is dispatched to the static method of the same name on that class, so the set of methods it exposes is the set of operators the SDK can evaluate:
equals, equalsNumber, matches, less, lessEqual, contains, isIn, startsWith, endsWith, regexMatches, exists, not_exists, doesNotExist
All share the signature (mixed $value, mixed $testAgainst, bool $negation = false): bool — isIn adds a trailing string $splitter = '|', and the exists family defaults $testAgainst to null since it ignores it. exists is true when the value is neither null nor an empty string; not_exists is its inverse, and doesNotExist is an alias of it (both names exist because the served config uses both). Supplying your own processor replaces the whole set — implement every match_type your project's audiences use, with the same signature.
Outgoing User-Agent
Every request the SDK makes — config fetches and tracking POSTs alike — is sent with a fixed User-Agent: ConvertAgent/1.0 header. This is what makes Convert's tracking server recognise the traffic as an SDK rather than as a bot, so events are not silently dropped at ingest.
The header is applied after any headers the SDK merges internally, so it cannot be overridden. It is set by the SDK on your behalf — the manual User-Agent requirement described in Direct Tracking Endpoint applies only when you call /v1/track yourself, without the SDK.
QA Debug Token
By default the config fetch returns only the experiences that are actively serving. Setting debugToken widens it to every non-archived experience — drafts and paused ones included — so you can build and QA against experiments that aren't live yet.
You generate the token in the Convert app — see QA & Preview for where to find it and how long it lasts. This page covers what the PHP SDK does with it.
use ConvertSdk\ConvertSDK;
$sdk = ConvertSDK::create([
'sdkKey' => 'your-sdk-key',
'debugToken' => 'your-qa-debug-token',
]);While a non-empty debugToken is set, the SDK:
- appends
debug_token=<token>and forces_conv_low_cache=1onto every config-fetch URL, regardless ofnetwork.cacheLevel; - bypasses the PSR-16 config cache entirely — the config cache entry is neither read nor written, so every request fetches live from origin (
dataRefreshIntervalhas no effect while the token is set); - redacts the token from log output, including the
endpointfield of debug/error entries and the message of any PSR-18 client exception (which is also redacted in theRuntimeExceptionthe SDK rethrows); - never sends the token to the tracking endpoint — it rides on config requests only.
An empty-string debugToken is treated as unset.
Never ship a debug token to production. It exposes unreleased experiments in the config, and it disables config caching — every request becomes an origin fetch. Keep it in a QA/staging build or behind an environment variable.
For the wider QA story — preview links, setPreview(), and the zero-trace guarantee — see QA & Preview and Code Examples → Experiment Preview.
Logger Configuration
The logger config accepts an array with two keys:
| Key | Type | Description |
|---|---|---|
logLevel | LogLevel | The minimum log level. Default: LogLevel::Debug. One of: Trace, Debug, Info, Warn, Error, Silent. |
customLoggers | array | An array of PSR-3 logger entries. Each entry is either a LoggerInterface instance or an array ['logger' => $loggerInstance, 'logLevel' => LogLevel::Info] for per-logger level overrides. |
use ConvertSdk\ConvertSDK;
use ConvertSdk\Enums\LogLevel;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$monolog = new Logger('convert');
$monolog->pushHandler(new StreamHandler('php://stderr'));
$convert = ConvertSDK::create([
'sdkKey' => 'YOUR_SDK_KEY',
'logger' => [
'logLevel' => LogLevel::Debug,
'customLoggers' => [
$monolog, // uses the global logLevel
// Or with per-logger level override:
// ['logger' => $monolog, 'logLevel' => LogLevel::Warn],
],
],
]);Log Levels
LogLevel is an int-backed enum ordered from most to least verbose. A client configured at a given level receives messages at that level and every more-severe one (higher backed value) — a client set to Warn sees warnings and errors, but not info, debug, or trace.
| Level | Backed value | What is logged |
|---|---|---|
LogLevel::Trace | 0 | Internal method calls, config data, initialization steps |
LogLevel::Debug | 1 | Event firing, entity lookups, bucketing internals, rule mismatches |
LogLevel::Info | 2 | Targeting decisions worth narrating — unrestricted audiences/locations, queue release |
LogLevel::Warn | 3 | Failed HTTP requests, retry attempts, discarded batches, unresolved preview or mutual-exclusion targets |
LogLevel::Error | 4 | Initialization failures, config fetch errors, invalid config |
LogLevel::Silent | 5 | Nothing — suppresses output entirely |
Persistent DataStore
The PHP SDK uses a PSR-16 (Psr\SimpleCache\CacheInterface) cache for dual purposes:
- Config caching — Stores the fetched project configuration with a TTL (controlled by
dataRefreshInterval), avoiding redundant HTTP requests within the cache window. - Visitor data persistence — Stores visitor bucketing data, segments, and properties across requests when a persistent cache backend is used.
By default, the SDK uses ConvertSdk\Cache\ArrayCache, an in-memory implementation. This means bucketing decisions are lost between PHP requests. To persist data across requests, provide a PSR-16 cache backed by Redis, Memcached, or another persistent store.
Using Redis
use ConvertSdk\ConvertSDK;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Psr16Cache;
// Create a PSR-16 cache backed by Redis
$redisConnection = RedisAdapter::createConnection('redis://localhost:6379');
$psr6Cache = new RedisAdapter($redisConnection);
$cache = new Psr16Cache($psr6Cache);
$sdk = ConvertSDK::create([
'sdkKey' => 'your-sdk-key',
'cache' => $cache, // PSR-16 CacheInterface
]);Using Memcached
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
use Symfony\Component\Cache\Psr16Cache;
$memcached = MemcachedAdapter::createConnection('memcached://localhost:11211');
$psr6Cache = new MemcachedAdapter($memcached);
$cache = new Psr16Cache($psr6Cache);
$sdk = ConvertSDK::create([
'sdkKey' => 'your-sdk-key',
'cache' => $cache,
]);Custom DataStore
If you need a separate store for visitor data (distinct from the config cache), pass the dataStore option:
$sdk = ConvertSDK::create([
'sdkKey' => 'your-sdk-key',
'cache' => $configCache, // Used for config caching
'dataStore' => $visitorCache, // Used for visitor data persistence
]);When dataStore is not provided, the cache instance is used for both purposes.
How Cross-Request Persistence Works
Without a persistent cache, each PHP request creates a fresh in-memory ArrayCache. Bucketing decisions are recalculated every request, which is deterministic (same visitor ID produces same bucketing) but incurs repeated computation.
With a persistent cache (Redis, Memcached, etc.):
- The first request calculates bucketing and stores results in the cache.
- Subsequent requests for the same visitor read from the cache, skipping bucketing computation.
- If the project configuration changes, the cached config expires based on
dataRefreshInterval, and a fresh config is fetched automatically.
Environment Variables
| Variable | Used By | Default | Description |
|---|---|---|---|
CONFIG_ENDPOINT | SDK runtime | https://cdn-4.convertexperiments.com/api/v1 | Override the CDN endpoint used to fetch project configuration. |
TRACK_ENDPOINT | SDK runtime | https://[project_id].metrics.convertexperiments.com/v1 | Override the Tracking API endpoint. [project_id] is replaced at runtime. |
VERSION | SDK runtime | php-sdk | Override the source identifier sent with tracking requests. |
Next Steps
- Code Examples — All SDK methods with examples
- Return Types — DTOs and enums reference
Updated 21 days ago