Quickstart
Install the CakePHP adapter.
Composer installs the shared PHP Core automatically. Configure the project key, a stable service name and the deployment environment.
composer require apirelio/cakephp:^1.0APIRELIO_API_KEY=apr_live_your_key
APIRELIO_ENDPOINT=https://apirelio.com
APIRELIO_SERVICE=billing-api
APIRELIO_ENVIRONMENT=production
APIRELIO_RELEASE=2026.08.28.1Automatic tracking
Place middleware after routing.
Add Apirelio after RoutingMiddleware so CakePHP has populated the matched route template. Keep the error handler before it so the original exception is still rendered normally.
use Apirelio\CakePHP\ApirelioMiddleware;
use Apirelio\CakePHP\Config as ApirelioConfig;
use Cake\Error\Middleware\ErrorHandlerMiddleware;
use Cake\Routing\Middleware\RoutingMiddleware;
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$middlewareQueue
->add(new ErrorHandlerMiddleware(Configure::read('Error'), $this))
->add(new RoutingMiddleware($this))
->add(new ApirelioMiddleware(new ApirelioConfig(
apiKey: (string) env('APIRELIO_API_KEY'),
endpoint: (string) env('APIRELIO_ENDPOINT', 'https://apirelio.com'),
service: (string) env('APIRELIO_SERVICE', 'billing-api'),
environment: (string) env('APIRELIO_ENVIRONMENT', 'production'),
release: env('APIRELIO_RELEASE') ?: null,
paths: ['/api/*'],
bufferPath: LOGS.'apirelio-events.ndjson',
)));
return $middlewareQueue;
}The SDK records /api/customers/{id} from CakePHP's routing parameters instead of a concrete customer URL.
Customer context
Connect authentication to account identity.
Resolvers run after upstream authentication middleware and translate your own account objects into stable customer and consuming-application identifiers.
use Apirelio\Core\Data\ApirelioApplication;
use Apirelio\Core\Data\ApirelioCustomer;
$apirelio = new ApirelioMiddleware(
config: $config,
customerResolver: static function ($request): ?ApirelioCustomer {
$account = $request->getAttribute('identity')?->getOriginalData();
return $account === null ? null : new ApirelioCustomer(
id: (string) $account->id,
name: $account->name,
plan: $account->plan,
);
},
applicationResolver: static fn ($request) => new ApirelioApplication(
id: (string) $request->getAttribute('apiClient')->id,
),
);Diagnostics
Add bounded request context.
The middleware attaches a mutable context to the CakePHP request. Only explicitly allowed scalar metadata survives PHP Core privacy filtering.
use Apirelio\CakePHP\RequestContext;
$context = $this->getRequest()->getAttribute(RequestContext::ATTRIBUTE);
$context?->addMetadata(['region' => 'eu-central']);
$context?->setErrorCode('PAYMENT_REQUIRED');Reliability
Keep delivery outside the response path.
Configure a writable NDJSON buffer for production. The locked buffer batches telemetry and contains ingestion failures without changing CakePHP's response.
new ApirelioConfig(
// ...
bufferPath: LOGS.'apirelio-events.ndjson',
batchSize: 500,
flushIntervalSeconds: 10,
)Privacy boundary
Operational metadata only.
Captured
Method, matched route, status, duration, byte counts and bounded customer identity.
Excluded
Request and response bodies, query strings, cookies, credentials, client IPs and exception messages.
Fail-safe
SDK and ingestion failures cannot replace the customer response or hide the original exception.