code-matic / opencdp-php
PHP SDK for Codematic's Customer Data Platform (CDP) with optional Customer.io integration
Requires
- php: ^8.0
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.5 || ^10.0
- squizlabs/php_codesniffer: ^3.7
Suggests
- customerio/customerio-php: Required for dual-write functionality to Customer.io
README
A PHP client library for Codematic's Customer Data Platform (CDP) with optional Customer.io integration.
See the CDP Documentation for more information.
Installation
composer require code-matic/opencdp-php
Requirements
- PHP 8.0 or higher
- Guzzle HTTP client (automatically installed)
Optional Dependencies
customerio/customerio-php- Required for dual-write functionality to Customer.io
composer require customerio/customerio-php
Features
- Send customer identification and event data to Codematic CDP
- Send transactional emails (transactional messaging and raw HTML)
- Send SMS messages
- Send push notifications
- Optional dual-write capability to Customer.io
- Comprehensive error handling and logging
- Full type safety with PHP 8.0+ features
Quick Start
<?php use Codematic\OpenCDP\CDPClient; use Codematic\OpenCDP\CDPConfig; use Codematic\OpenCDP\Identifiers; use Codematic\OpenCDP\SendEmailRequest; require 'vendor/autoload.php'; // Create a client $config = new CDPConfig( cdpApiKey: 'your-cdp-api-key' ); $client = new CDPClient($config); // Identify a user $client->identify('user123', [ 'email' => 'user@example.com', 'name' => 'John Doe', 'plan' => 'premium' ]); // Track an event $client->track('user123', 'purchase_completed', [ 'amount' => 99.99, 'item_id' => 'prod-123' ]);
Configuration
$config = new CDPConfig( cdpApiKey: 'your-cdp-api-key', cdpEndpoint: 'https://api.opencdp.io/gateway/data-gateway', // Optional custom endpoint timeout: 10000, // Request timeout in milliseconds (default: 10000) debug: false, // Enable debug logging (default: false) failOnException: false, // Throw exceptions on errors (default: false) logger: null, // Custom logger instance (LoggerInterface) sendToCustomerIo: false, // Enable dual-write to Customer.io (default: false) customerIo: [ // Required if sendToCustomerIo is true 'siteId' => 'your-customer-io-site-id', 'apiKey' => 'your-customer-io-api-key', 'region' => 'us' // or 'eu' for EU data centers ] );
Usage Examples
Identify a Person
$client->identify('user123', [ 'email' => 'user@example.com', 'name' => 'John Doe', 'plan' => 'premium', 'created_at' => time() ]);
Track an Event
$client->track('user123', 'purchase_completed', [ 'amount' => 99.99, 'currency' => 'USD', 'item_id' => 'prod-123', 'category' => 'electronics' ]);
Register a Device
use Codematic\OpenCDP\DeviceRegistrationParameters; $params = new DeviceRegistrationParameters( deviceId: 'device-abc-123', platform: 'ios', fcmToken: 'fcm-token-here', name: 'iOS Device', osVersion: '15.0', model: 'iPhone 13', appVersion: '1.0.0' ); $client->registerDevice('user123', $params);
Send Transactional Email (Using Template)
use Codematic\OpenCDP\SendEmailRequest; use Codematic\OpenCDP\Identifiers; $request = new SendEmailRequest([ 'to' => 'user@example.com', 'identifiers' => Identifiers::withId('user123'), 'transactional_message_id' => 'WELCOME_EMAIL', 'message_data' => [ 'name' => 'John', 'activation_link' => 'https://example.com/activate' ] ]); $response = $client->sendEmail($request);
Send Transactional Email (With Subject & Body Override)
$request = new SendEmailRequest([ 'to' => 'user@example.com', 'identifiers' => Identifiers::withEmail('user@example.com'), 'transactional_message_id' => 'WELCOME_EMAIL', 'subject' => 'Welcome to Our Platform!', 'body' => '<h1>Welcome!</h1><p>Thank you for joining us.</p>', 'message_data' => ['name' => 'John'] ]); $response = $client->sendEmail($request);
Send Raw Email (Without Template)
$request = new SendEmailRequest([ 'to' => 'user@example.com', 'identifiers' => Identifiers::withEmail('user@example.com'), 'from' => 'no-reply@example.com', 'subject' => 'Raw Email Test', 'body' => '<h1>This is a raw HTML email</h1>', 'plaintext_body' => 'This is a plain text email', 'reply_to' => 'support@example.com' ]); $response = $client->sendEmail($request);
Send Push Notification
use Codematic\OpenCDP\SendPushRequest; $request = new SendPushRequest( identifiers: Identifiers::withId('user123'), transactional_message_id: 'WELCOME_PUSH', title: 'Welcome!', body: 'Thank you for joining us!' ); $response = $client->sendPush($request);
Send Push with Message Data
$request = new SendPushRequest( identifiers: Identifiers::withEmail('user@example.com'), transactional_message_id: 'ORDER_UPDATE', message_data: [ 'order_id' => '12345', 'tracking_number' => 'TRK123456', 'items' => [ ['name' => 'Shoes', 'price' => '59.99'] ] ] ); $response = $client->sendPush($request);
Send SMS
use Codematic\OpenCDP\SendSmsRequest; // Using template $request = new SendSmsRequest( identifiers: Identifiers::withId('user123'), transactional_message_id: 'WELCOME_SMS', message_data: ['name' => 'John'] ); // With body override $request = new SendSmsRequest( identifiers: Identifiers::withId('user123'), transactional_message_id: 'WELCOME_SMS', body: 'Thank you for joining us!' ); // Raw SMS (without template) $request = new SendSmsRequest( identifiers: Identifiers::withId('user123'), to: '+1234567890', from: '+1987654321', body: 'This is a raw SMS message' ); $response = $client->sendSms($request);
Dual-write to Customer.io
$config = new CDPConfig( cdpApiKey: 'your-cdp-api-key', sendToCustomerIo: true, customerIo: [ 'siteId' => 'your-customer-io-site-id', 'apiKey' => 'your-customer-io-api-key', 'region' => 'us' // or 'eu' ] ); $client = new CDPClient($config); // Now all identify, track, and registerDevice calls will send data to both platforms // Note: Transactional messages (email/push/SMS) are NOT sent to Customer.io to avoid duplicates
Error Handling
By default, the SDK logs errors but doesn't throw exceptions. You can enable exception throwing:
$config = new CDPConfig( cdpApiKey: 'your-cdp-api-key', failOnException: true // Throw exceptions on errors ); $client = new CDPClient($config); try { $client->identify('user123', ['email' => 'invalid-email']); } catch (\InvalidArgumentException $e) { // Handle validation error echo "Validation error: " . $e->getMessage(); } catch (\Codematic\OpenCDP\Exceptions\CDPException $e) { // Handle CDP API error echo "CDP error: " . $e->getMessage(); echo "Status: " . $e->status; echo "Error Code: " . $e->errorCode; print_r($e->summary); }
Note on Return Types:
- Methods
identify(),track(), andregisterDevice()returnvoid. WhenfailOnExceptionisfalse, errors are logged but no exception is thrown. - Methods
sendEmail(),sendPush(), andsendSms()returnarray. WhenfailOnExceptionisfalseand an error occurs, they return an error array with'ok' => falseand an'error'key containing error details.
Exception Types
CDPException- Base exception for all CDP errorsCDPEmailException- Email sending failuresCDPPushException- Push notification failuresCDPSmsException- SMS sending failures
Debug Mode
Enable debug logging to see detailed information about SDK operations:
$config = new CDPConfig( cdpApiKey: 'your-cdp-api-key', debug: true ); $client = new CDPClient($config);
This will log all requests, responses, and errors using PHP's error_log().
Custom Logger
Provide your own logger implementation:
use Codematic\OpenCDP\LoggerInterface; class MyLogger implements LoggerInterface { public function debug(string $message, array $context = []): void { // Your debug logging logic } public function error(string $message, array $context = []): void { // Your error logging logic } public function warn(string $message, array $context = []): void { // Your warning logging logic } } $config = new CDPConfig( cdpApiKey: 'your-cdp-api-key', logger: new MyLogger() );
Unsupported Email Fields
Some email fields are accepted by the SDK but not yet processed by the backend. The SDK will log a warning when these are used:
send_at- Scheduled send timesend_to_unsubscribed- Send to unsubscribed userstracked- Email trackingdisable_css_preprocessing- CSS preprocessing controlheaders- Custom email headersdisable_message_retention- Message retention controlqueue_draft- Queue as draftfake_bcc- Fake BCC functionalityreply_to- Reply-to addresspreheader- Email preheader textattachments- Email attachments
These fields are included for future compatibility but currently have no effect on email delivery.
Testing Connection
Test your CDP connection:
$client->ping(); // Throws exception only if failOnException is true
Development
Running Tests
composer test
Code Quality
# PHP CodeSniffer (PSR-12 standards) composer phpcs # Static Analysis composer phpstan
License
MIT
Support
For questions and support, visit https://docs.opencdp.io/ or contact support@codematic.io