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

OptionTypeDescription
sdkKeystringRequired if not providing data. Your unique project identifier from Convert.
sdkKeySecretstringRequired when using an authenticated SDK key.
dataarray|ConfigResponseDataRequired if not providing sdkKey. Provide project configuration directly.
environmentstringTarget environment (e.g., 'staging', 'production').
dataRefreshIntervalintCache TTL in milliseconds. Default: 300000 (5 minutes).
debugToken?stringQA/preview debug token. Widens the config fetch to every non-archived experience and bypasses caching. Default: null. See QA Debug Token.
loggerarrayLogging configuration with logLevel and customLoggers keys.
cacheCacheInterfacePSR-16 compatible cache. Used for config caching AND visitor data persistence. Defaults to ArrayCache (in-memory).
dataStoreobjectCustom data store for visitor data. Overrides cache for visitor data if provided.
bucketing.hash_seedintMurmurHash3 seed. Default: 9999.
bucketing.max_trafficintMax hash value (100% traffic). Default: 10000.
bucketing.excludeExperienceIdHashboolExclude the experience ID from the hash input. Default: false.
events.batch_sizeintMax events per tracking batch. Default: 10.
network.trackingboolSet false to disable tracking events. Default: true.
network.cacheLevelstring'low' for short-lived cache (dev only). Default: 'default'.
network.sourcestringSDK source identifier. Default: 'php-sdk'. Can be overridden by the VERSION environment variable.
rules.keys_case_sensitiveboolWhether rule keys are case-sensitive. Default: true.
rules.comparisonProcessormixedAllows 3rd party comparison processor. Default: null.
rules.negationstringNegation character for rule matching. Default: '!'.
api.endpoint.configstringCDN endpoint for fetching config. Default: 'https://cdn-4.convertexperiments.com/api/v1'.
api.endpoint.trackstringTracking API endpoint. Default: 'https://[project_id].metrics.convertexperiments.com/v1'.

PSR Standards Integration

Config KeyPSR StandardInterfaceDefault
logger.customLoggers[]PSR-3Psr\Log\LoggerInterfaceEmpty array (no custom loggers)
cachePSR-16Psr\SimpleCache\CacheInterfaceConvertSdk\Cache\ArrayCache (in-memory)
(auto-discovered)PSR-18Psr\Http\Client\ClientInterfaceAuto-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): boolisIn 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=1 onto every config-fetch URL, regardless of network.cacheLevel;
  • bypasses the PSR-16 config cache entirely — the config cache entry is neither read nor written, so every request fetches live from origin (dataRefreshInterval has no effect while the token is set);
  • redacts the token from log output, including the endpoint field of debug/error entries and the message of any PSR-18 client exception (which is also redacted in the RuntimeException the 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:

KeyTypeDescription
logLevelLogLevelThe minimum log level. Default: LogLevel::Debug. One of: Trace, Debug, Info, Warn, Error, Silent.
customLoggersarrayAn 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.

LevelBacked valueWhat is logged
LogLevel::Trace0Internal method calls, config data, initialization steps
LogLevel::Debug1Event firing, entity lookups, bucketing internals, rule mismatches
LogLevel::Info2Targeting decisions worth narrating — unrestricted audiences/locations, queue release
LogLevel::Warn3Failed HTTP requests, retry attempts, discarded batches, unresolved preview or mutual-exclusion targets
LogLevel::Error4Initialization failures, config fetch errors, invalid config
LogLevel::Silent5Nothing — suppresses output entirely

Persistent DataStore

The PHP SDK uses a PSR-16 (Psr\SimpleCache\CacheInterface) cache for dual purposes:

  1. Config caching — Stores the fetched project configuration with a TTL (controlled by dataRefreshInterval), avoiding redundant HTTP requests within the cache window.
  2. 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

VariableUsed ByDefaultDescription
CONFIG_ENDPOINTSDK runtimehttps://cdn-4.convertexperiments.com/api/v1Override the CDN endpoint used to fetch project configuration.
TRACK_ENDPOINTSDK runtimehttps://[project_id].metrics.convertexperiments.com/v1Override the Tracking API endpoint. [project_id] is replaced at runtime.
VERSIONSDK runtimephp-sdkOverride the source identifier sent with tracking requests.

Next Steps


Did this page help you?