cx-engine/cx-app-php-sdk

The Official CXEngine App API PHP Client/SDK

Maintainers

Package info

github.com/CX-engine/cx-app-php-sdk

pkg:composer/cx-engine/cx-app-php-sdk

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-03-31 13:04 UTC

This package is auto-updated.

Last update: 2026-03-31 13:04:30 UTC


README

Software License Latest Version on Packagist Total Downloads

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:

  1. POST /login on the central domain → retrieves a central Bearer token.
  2. POST /switch-to with workspace_id using that token → retrieves a workspace-scoped token.
  3. All subsequent requests are sent to $tenantApiUrl with 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();