cx-engine / cx-app-php-sdk
The Official CXEngine App API PHP Client/SDK
Requires
- php: >=8.2
- illuminate/collections: >=11.0
- illuminate/support: >=11.0
- nesbot/carbon: >=2.68
- saloonphp/pagination-plugin: ^2.0
- saloonphp/rate-limit-plugin: ^2.0
- saloonphp/saloon: ^4.0
Requires (Dev)
- spatie/ray: ^1.37
This package is auto-updated.
Last update: 2026-03-31 13:04:30 UTC
README
PHP SDK for the CX Engine App API.
Installation
This library requires PHP >=8.2.
You can install the package via composer:
composer require cx-engine/cx-app-php-sdk
Authentication
Direct Tenant Auth
To connect directly to a tenant, instantiate CxEngineConnector with the tenant URL, email and password:
use CXEngine\AppSdk\CxEngineConnector; $api = new CxEngineConnector( apiUrl: 'https://tenant.cx-engine.app', email: 'user@example.com', password: 'secret', );
On the first request, the connector will POST /login with the provided credentials and store the returned Bearer token automatically.
Central + Workspace Switch
If you need to authenticate against the central domain first and then switch to a specific workspace, pass $tenantId and $tenantApiUrl:
use CXEngine\AppSdk\CxEngineConnector; $api = new CxEngineConnector( apiUrl: 'https://cx-engine.app', email: 'user@example.com', password: 'secret', tenantId: 'workspace-uuid', tenantApiUrl: 'https://tenant.cx-engine.app', );
The connector performs a two-step flow automatically:
- POST
/loginon the central domain → retrieves a central Bearer token. - POST
/switch-towithworkspace_idusing that token → retrieves a workspace-scoped token. - All subsequent requests are sent to
$tenantApiUrlwith the workspace token.
If authentication fails at any step, a CXEngine\AppSdk\Exceptions\AuthenticationException is thrown.
Usage
Resources
Resources group related API endpoints into convenient classes. Each resource is accessed via a method on the connector instance:
$api->routingContacts(): RoutingContactResource $api->routingFields(): RoutingFieldResource $api->geoRouting(): GeoRoutingResource $api->callQueues(): CallQueueResource $api->ctis(): CtiResource $api->cfdTokens(): CfdTokenResource $api->surveys(): SurveyResource
Example usage:
use CXEngine\AppSdk\CxEngineConnector; $api = new CxEngineConnector(...); // List all routing contacts $response = $api->routingContacts()->index(); // List active call queues only $response = $api->callQueues()->index(['active' => true]); // Access call queue sub-resources $response = $api->callQueues()->timeSpans()->index(); $response = $api->callQueues()->groups()->index(); $response = $api->callQueues()->exceptions()->index(); $response = $api->callQueues()->holidays()->index(); // Sub-resources that require a parent ID — pass it to the accessor $response = $api->ctis()->destinations($ctiId)->index(); $response = $api->ctis()->destinations($ctiId)->show($destId); $response = $api->routingFields()->options($fieldId)->index(); // GeoRouting is namespaced into models, lists, and destinations $response = $api->geoRouting()->models()->index(); $response = $api->geoRouting()->lists()->index(); $response = $api->geoRouting()->lists()->destinations($listId)->index(); // Survey records $response = $api->surveys()->records()->index();
Responses
Whether you use Requests or Resources, the response is always an instance of Saloon\Http\Response. It provides useful methods to check status and retrieve data:
// Check response status $response->ok(); $response->failed(); $response->status(); $response->headers(); // Get response data $response->json(); // as an array $response->body(); // as a raw string
You can learn more about responses by reading the Saloon documentation.
Entities
Entity classes represent the data structures of the API. They live under CXEngine\AppSdk\Entities\SmartRoutings\* and are simple typed value objects.
Use them when creating or updating resources:
use CXEngine\AppSdk\CxEngineConnector; use CXEngine\AppSdk\Entities\SmartRoutings\RoutingContact; $api = new CxEngineConnector(...); // Create $contact = new RoutingContact( company: 'Acme Corp', first_name: 'John', last_name: 'Doe', customer_id: 42, ); $response = $api->routingContacts()->store($contact); // Update — set the id, then call update() $contact->id = $response->json('id'); $contact->company = 'Acme Ltd'; $api->routingContacts()->update($contact);
You can also serialize an entity to an array at any time:
$contact->toArray(); // includes null fields $contact->toArray(filter: true); // excludes null fields
Pagination
On index routes that return paginated results, you can use the connector's paginate() method to iterate over all pages:
use CXEngine\AppSdk\Requests\SmartRoutings\RoutingContacts\GetRoutingContactsRequest; // Create a PagedPaginator instance $paginator = $api->paginate(new GetRoutingContactsRequest(['company' => 'Acme'])); // Iterate over all items across all pages (lazy-loaded) foreach ($paginator->items() as $item) { // $item is the raw array for each record }
Read more about lazy pagination in the Saloon documentation.
Extending the SDK
You can extend the SDK by creating your own Resources and Requests, then adding them to a custom connector:
use CXEngine\AppSdk\CxEngineConnector; class MyCustomConnector extends CxEngineConnector { public function defaultConfig(): array { return [ 'timeout' => 120, ]; } public function customResource(): \App\Resources\CustomResource { return new \App\Resources\CustomResource($this); } } $api = new MyCustomConnector( apiUrl: 'https://tenant.cx-engine.app', email: 'user@example.com', password: 'secret', ); $api->customResource()->index();