Zero-dependency PHP SDK for PeekAPI. PSR-15 middleware for Slim/Mezzio and a dedicated Laravel middleware with auto-configuration from env vars.
composer require peekapi/peekapiSet environment variables and register the middleware:
# .env
PEEKAPI_API_KEY=ak_live_xxx
PEEKAPI_ENDPOINT=https://...// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\PeekApi\Middleware\Laravel::class);
})// Or app/Http/Kernel.php (Laravel 10)
protected $middleware = [
\PeekApi\Middleware\Laravel::class,
// ...
];The Laravel middleware auto-configures from PEEKAPI_API_KEY and PEEKAPI_ENDPOINT env vars.
use PeekApi\Client;
use PeekApi\Middleware\PSR15;
use Slim\Factory\AppFactory;
$client = new Client([
'api_key' => 'ak_live_xxx',
]);
$app = AppFactory::create();
$app->add(new PSR15($client));
$app->get('/api/hello', function ($request, $response) {
$response->getBody()->write(json_encode(['message' => 'hello']));
return $response->withHeader('Content-Type', 'application/json');
});
$app->run();// config/pipeline.php
use PeekApi\Client;
use PeekApi\Middleware\PSR15;
$client = new Client(['api_key' => 'ak_live_xxx']);
$app->pipe(new PSR15($client));use PeekApi\Client;
$client = new Client(['api_key' => 'ak_live_xxx']);
$client->track([
'method' => 'GET',
'path' => '/api/users',
'status_code' => 200,
'response_time_ms' => 42,
]);
// Graceful shutdown (flushes remaining events)
$client->shutdown();| Option | Default | Description |
|---|---|---|
api_key |
required | Your PeekAPI key |
endpoint |
PeekAPI cloud | Ingestion endpoint URL |
flush_interval |
10 |
Seconds between automatic flushes |
batch_size |
100 |
Events per HTTP POST (triggers flush) |
max_buffer_size |
10_000 |
Max events held in memory |
max_storage_bytes |
5_242_880 |
Max disk fallback file size (5MB) |
max_event_bytes |
65_536 |
Per-event size limit (64KB) |
storage_path |
auto | Custom path for JSONL persistence file |
debug |
false |
Enable debug logging to stderr |
on_error |
null |
Callback callable(Throwable): void for flush errors |
- Middleware intercepts every request/response
- Captures method, path, status code, response time, request/response sizes, consumer ID
- Events are buffered in memory and flushed synchronously when
batchSizeis reached - On network failure: exponential backoff with jitter, up to 5 retries
- After max retries: events are persisted to a JSONL file on disk
- On next startup: persisted events are recovered and re-sent
- On shutdown:
register_shutdown_functionflushes remaining events or persists to disk
By default, consumers are identified by:
X-API-Keyheader — stored as-isAuthorizationheader — hashed with SHA-256 (stored ashash_<hex>)
Override with the identify_consumer option to use any header:
$client = new PeekApi\Client([
'api_key' => '...',
'identify_consumer' => fn(array $headers) => $headers['x-tenant-id'] ?? null,
]);The callback receives an associative array of lowercase header names and should return a consumer ID string or null.
- Zero runtime dependencies — uses only
ext-curlandext-json - Disk persistence — undelivered events saved to JSONL, recovered on restart
- Exponential backoff — with jitter, max 5 consecutive failures before disk fallback
- SSRF protection — private IP blocking, HTTPS enforcement (HTTP only for localhost)
- Input sanitization — path (2048), method (16), consumer_id (256) truncation
- Per-event size limit — strips metadata first, drops if still too large (default 64KB)
- Graceful shutdown —
register_shutdown_function+__destructfallback - PSR-15 compatible — works with any PSR-15 framework
- Laravel auto-config — reads from
PEEKAPI_API_KEY/PEEKAPI_ENDPOINTenv vars
- PHP >= 8.2
ext-curlext-json
Bug reports and feature requests: peekapi-dev/community
- Fork & clone the repo
- Install dependencies —
composer install - Run tests —
composer exec phpunit - Submit a PR
If you find PeekAPI useful, give this repo a star — it helps others discover the project.
Show that your API is monitored by PeekAPI:
[](https://peekapi.dev)MIT