laravel-posthog maintained by jeffersongoncalves

Laravel PostHog
A PHP/Laravel client for PostHog. Capture events, batch ingestion, identify people, evaluate feature flags and read back persons, insights, session recordings and HogQL queries — through a simple, typed API built on Laravel's Http client. Works with PostHog Cloud (US/EU) and self-hosted instances.
Features
- Event capture: single events and batched ingestion
- Person identification:
$identifyand$create_aliashelpers over the capture endpoint - Feature flags: read every flag for a person, a single flag value (including multivariate variants), or a simple boolean check
- Persons: look people up by
distinct_id - HogQL: run SQL-like queries against your event data
- Insights and session recordings: list them from the project API
- Handles PostHog's two auth models for you — the public project API key in the payload for ingestion, the personal API key as a Bearer token for reads
- Throws
PostHogException(with the original API error body) on any non-2xx response
Installation
You can install the package via composer:
composer require jeffersongoncalves/laravel-posthog
Publish the config file:
php artisan vendor:publish --tag=posthog-config
Then set your credentials:
POSTHOG_HOST=https://us.i.posthog.com
POSTHOG_PROJECT_API_KEY=phc_your_project_api_key
POSTHOG_PERSONAL_API_KEY=phx_your_personal_api_key
POSTHOG_PROJECT_ID=12345
POSTHOG_PROJECT_API_KEY is the public write-only key and is all you need for capture, batch and feature flags. POSTHOG_PERSONAL_API_KEY plus POSTHOG_PROJECT_ID are only required for the read endpoints (persons, HogQL, insights, session recordings).
Configuration
// config/posthog.php
return [
'host' => env('POSTHOG_HOST', 'https://app.posthog.com'),
'project_api_key' => env('POSTHOG_PROJECT_API_KEY', ''),
'personal_api_key' => env('POSTHOG_PERSONAL_API_KEY', ''),
'project_id' => env('POSTHOG_PROJECT_ID', ''),
'timeout' => env('POSTHOG_TIMEOUT', 10),
];
Usage
The package is resolved via the PostHog facade or by injecting JeffersonGoncalves\PostHog\PostHog.
Capturing events
use JeffersonGoncalves\PostHog\Facades\PostHog;
PostHog::capture('signup_completed', 'user_123', [
'plan' => 'pro',
'$current_url' => 'https://example.com/signup',
]);
Batching events
PostHog::batch([
['event' => 'pageview', 'distinct_id' => 'user_1'],
['event' => 'signup', 'distinct_id' => 'user_2'],
]);
Identifying people
PostHog::identify('user_123', [
'email' => 'user@example.com',
'plan' => 'pro',
]);
// Merge an anonymous session into an identified person
PostHog::alias('user_123', 'anon_abc');
Feature flags
// Every flag evaluated for this person
$flags = PostHog::featureFlags('user_123');
// A single flag: false when off, true when on, the variant key when multivariate
$variant = PostHog::featureFlag('new-pricing', 'user_123');
// Simple boolean check (a variant counts as enabled)
if (PostHog::isFeatureEnabled('new-pricing', 'user_123')) {
// Show new pricing
}
Group-based flags are supported by passing the groups map:
PostHog::isFeatureEnabled('beta-dashboard', 'user_123', ['company' => 'acme-inc']);
Persons
$persons = PostHog::persons('user_123');
HogQL queries
$result = PostHog::query(
'SELECT event, count() FROM events WHERE timestamp > now() - interval 7 day GROUP BY event ORDER BY count() DESC LIMIT 10'
);
Insights and session recordings
$insights = PostHog::insights();
$recordings = PostHog::sessionRecordings(['limit' => 20]);
Error handling
Any non-2xx API response throws JeffersonGoncalves\PostHog\Exceptions\PostHogException, which exposes the decoded error body:
use JeffersonGoncalves\PostHog\Exceptions\PostHogException;
try {
PostHog::persons('user_123');
} catch (PostHogException $e) {
logger()->error($e->getMessage(), $e->errorBody());
}
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.