Looking to hire Laravel developers? Try LaraJobs

laravel-posthog maintained by jeffersongoncalves

Description
PHP/Laravel client for the PostHog API: event capture, batch ingestion, feature flags, persons and HogQL queries.
Last update
2026/09/08 03:36 (dev-main)
License
Downloads
6

Comments
comments powered by Disqus

Laravel PostHog

Laravel PostHog

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads License

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: $identify and $create_alias helpers 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.