PHPackages                             querri/embed - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. querri/embed

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

querri/embed
============

PHP SDK for embedding Querri analytics into your application

v0.2.0(1mo ago)01MITPHPPHP ^8.3CI passing

Since Mar 10Pushed 1mo agoCompare

[ Source](https://github.com/Querri-inc/querri-phpembed)[ Packagist](https://packagist.org/packages/querri/embed)[ Docs](https://github.com/Querri-inc/querri-phpembed)[ RSS](/packages/querri-embed/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (7)Dependencies (3)Versions (10)Used By (0)

querri/embed — PHP SDK
======================

[](#querriembed--php-sdk)

[![Packagist Version](https://camo.githubusercontent.com/7548ff6ac7458903f556292865887d908b60de4b0020c3204ff85912703ffb7f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7175657272692f656d6265642e737667)](https://packagist.org/packages/querri/embed)[![PHP Version](https://camo.githubusercontent.com/56b214f4239df0e8c34e7c86a6a788a93f1e9998acdc8b869316ec8bb6c6bf92/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7175657272692f656d6265642e737667)](https://packagist.org/packages/querri/embed)[![License](https://camo.githubusercontent.com/c9c2f424b3f9c97ec5023b8c0fd5261cf6263e37e4f996416fd6d68705e24f67/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7175657272692f656d6265642e737667)](LICENSE)

> Embed Querri analytics in your PHP application. One method call, zero config.

**Laravel** | **Symfony** | **Plain PHP** | **WordPress**

PHP SDK for creating embed sessions, managing users, and controlling access policies via the Querri API. Use it with any PHP framework alongside the [`@querri-inc/embed`](https://www.npmjs.com/package/@querri-inc/embed) frontend component. One `getSession()` call, one server endpoint, and you're done.

Get Started in 60 Seconds
-------------------------

[](#get-started-in-60-seconds)

### 1. Install

[](#1-install)

```
composer require querri/embed
```

### 2. Create a session

[](#2-create-a-session)

```
use Querri\Embed\QuerriClient;

$client = new QuerriClient('qk_your_api_key');

$session = $client->getSession([
    'user' => 'customer-42',  // external ID from your system
    'ttl'  => 3600,
]);

echo $session->sessionToken;  // JWT to pass to the frontend
```

### 3. Add the embed (React)

[](#3-add-the-embed-react)

```
import { QuerriEmbed } from '@querri-inc/embed/react';

```

### 4. Wire the endpoint

[](#4-wire-the-endpoint)

```
// public/api/querri-session.php (or your framework's route handler)
$client = new QuerriClient();  // reads QUERRI_API_KEY from env
$session = $client->getSession([
    'user' => ['external_id' => $authUser->id, 'email' => $authUser->email],
    'ttl'  => 3600,
]);
header('Content-Type: application/json');
echo json_encode($session);
```

Set `QUERRI_API_KEY` and `QUERRI_ORG_ID` [environment variables](#configuration). In production, always derive user identity from your auth system — never from the request body.

### 5. Done.

[](#5-done)

The embed handles auth, token caching, and cleanup automatically.

 ```
sequenceDiagram
    participant Browser
    participant PHP Server
    participant Querri API

    Browser->>PHP Server: POST /api/querri-session
    PHP Server->>Querri API: getOrCreate user + create session
    Querri API-->>PHP Server: { session_token }
    PHP Server-->>Browser: { session_token }
    Browser->>Querri API: Load embed with token
```

      Loading > **Security:** Always derive user identity and access from your server-side auth system. Never read `user` or `access` from the request body — a malicious client can impersonate any user or escalate access.

Configuration
-------------

[](#configuration)

The SDK reads configuration from constructor arguments or environment variables:

ParameterEnv VariableDefaultDescription`api_key``QUERRI_API_KEY`*(required)*Your Querri API key (`qk_...`)`org_id``QUERRI_ORG_ID``null`Organization ID`host``QUERRI_URL``https://app.querri.com`Querri API host`timeout`—`30.0`Request timeout in seconds`max_retries`—`3`Max retries on 429/5xx errors```
// Read from environment variables
$client = new QuerriClient();

// API key string shorthand
$client = new QuerriClient('qk_...');

// Full config array
$client = new QuerriClient([
    'api_key'     => 'qk_...',
    'org_id'      => 'org_...',
    'host'        => 'https://app.querri.com',
    'timeout'     => 30.0,
    'max_retries' => 3,
]);
```

`getSession()` — Embed Sessions
-------------------------------

[](#getsession--embed-sessions)

The flagship method that creates an embed session in three steps:

1. **User resolution** — creates or retrieves a Querri user by your external ID
2. **Access policy** — auto-creates or reuses a deterministic policy with row-level filters
3. **Session creation** — generates a JWT token for the embed iframe

### With inline access rules

[](#with-inline-access-rules)

```
$session = $client->getSession([
    'user' => [
        'external_id' => 'customer-42',
        'email'       => 'alice@acme.com',
        'first_name'  => 'Alice',
    ],
    'access' => [
        'sources' => ['src_sales_data'],
        'filters' => [
            'tenant_id' => 'acme',
            'region'    => ['us-east', 'us-west'],
        ],
    ],
    'origin' => 'https://app.acme.com',
    'ttl'    => 7200,
]);
```

### With pre-created policy IDs

[](#with-pre-created-policy-ids)

```
$session = $client->getSession([
    'user'   => ['external_id' => 'customer-42'],
    'access' => ['policy_ids' => ['pol_abc123', 'pol_def456']],
]);
```

### GetSessionResult

[](#getsessionresult)

```
$session->sessionToken;  // string — JWT for the embed
$session->expiresIn;     // int — seconds until expiry
$session->userId;        // string — Querri user ID
$session->externalId;    // string|null — your external ID

// JSON-serializable for API responses
echo json_encode($session);
// {"session_token":"...","expires_in":3600,"user_id":"...","external_id":"..."}
```

Direct Resource Usage
---------------------

[](#direct-resource-usage)

For advanced use cases, access the API resources directly:

### Users

[](#users)

```
$user = $client->users->getOrCreate('ext-123', [
    'email' => 'user@example.com',
    'role'  => 'member',
]);

$user = $client->users->retrieve('usr_abc123');
$users = $client->users->list(['limit' => 50]);
$client->users->update('usr_abc123', ['first_name' => 'Alice']);
$client->users->del('usr_abc123');
```

### Policies

[](#policies)

```
$policy = $client->policies->create([
    'name'        => 'APAC Sales',
    'source_ids'  => ['src_1'],
    'row_filters' => [
        ['column' => 'region', 'values' => ['APAC']],
    ],
]);

$client->policies->assignUsers($policy['id'], ['usr_abc123']);
$client->policies->removeUser($policy['id'], 'usr_abc123');
```

### Embed Sessions

[](#embed-sessions)

```
$session = $client->embed->createSession([
    'user_id' => 'usr_abc123',
    'ttl'     => 3600,
]);

$refreshed = $client->embed->refreshSession($session['session_token']);
$client->embed->revokeSession('ses_abc123');
$client->embed->revokeUserSessions('usr_abc123');
```

### All Resources

[](#all-resources)

Beyond the core embed resources above, the SDK provides full access to the Querri API:

ResourceAccessKey Methods`$client->dashboards`Dashboard management`list`, `create`, `retrieve`, `update`, `del`, `refresh``$client->projects`Analysis projects`list`, `create`, `retrieve`, `run`, `runStatus``$client->chats`Chats within projects`create`, `list`, `retrieve`, `del`, `cancel``$client->data`Data sources &amp; queries`listSources`, `createSource`, `query`, `appendRows``$client->sources`Connectors &amp; sync`listConnectors`, `list`, `create`, `sync``$client->files`File management`list`, `retrieve`, `del``$client->keys`API key management`create`, `list`, `retrieve`, `revoke``$client->audit`Audit log`listEvents``$client->usage`Usage metrics`getOrgUsage`, `getUserUsage``$client->sharing`Sharing &amp; permissions`shareProject`, `shareDashboard`, `shareSource`See **[docs/server-sdk.md](docs/server-sdk.md)** for complete method signatures and examples.

Error Handling
--------------

[](#error-handling)

All errors extend `QuerriException`. API errors are mapped to specific exception types:

```
QuerriException
├── ConfigException          — missing/invalid configuration
├── ConnectionException      — network failures (auto-retried)
│   └── TimeoutException     — request timeout exceeded
└── ApiException             — HTTP error responses
    ├── ValidationException  — 400
    ├── AuthenticationException — 401
    ├── PermissionException  — 403
    ├── NotFoundException    — 404
    ├── ConflictException    — 409
    ├── RateLimitException   — 429 (auto-retried)
    └── ServerException      — 5xx (auto-retried)

```

```
use Querri\Embed\Exceptions\ApiException;
use Querri\Embed\Exceptions\AuthenticationException;
use Querri\Embed\Exceptions\RateLimitException;
use Querri\Embed\Exceptions\ConfigException;

try {
    $session = $client->getSession([...]);
} catch (AuthenticationException $e) {
    // 401 — invalid API key
    echo "Auth failed: {$e->getMessage()}";
} catch (RateLimitException $e) {
    // 429 — rate limited (auto-retried up to maxRetries)
    echo "Rate limited, retry after: {$e->retryAfter}s";
} catch (ApiException $e) {
    // Any other API error
    echo "API error {$e->status}: {$e->getMessage()}";
    echo "Request ID: {$e->requestId}";
} catch (ConfigException $e) {
    // Missing API key or invalid config
    echo $e->getMessage();
}
```

The SDK automatically retries **429** (always) and **5xx** (idempotent methods only) with exponential backoff + jitter, up to `max_retries` attempts.

Example App
-----------

[](#example-app)

See [`examples/react-embed/`](examples/react-embed/) for a complete working example with a PHP backend and React frontend.

Full Reference
--------------

[](#full-reference)

See **[docs/server-sdk.md](docs/server-sdk.md)** for the complete API reference, including every method signature, framework integration guides (Laravel, Symfony), error handling details, and the `getSession()` deep dive.

Troubleshooting
---------------

[](#troubleshooting)

### "API key is required" error

[](#api-key-is-required-error)

Set the `QUERRI_API_KEY` environment variable. Find your API key at [app.querri.com/settings/api-keys](https://app.querri.com/settings/api-keys).

```
# .env or your server config
QUERRI_API_KEY=qk_your_api_key
QUERRI_ORG_ID=org_your_org_id
```

The SDK checks `getenv()`, `$_ENV`, and `$_SERVER` — covering CLI, Apache, nginx+FPM, and Docker.

### Embed is blank / session endpoint returns 500

[](#embed-is-blank--session-endpoint-returns-500)

Verify your PHP endpoint returns JSON with the correct `Content-Type`:

```
header('Content-Type: application/json');
echo json_encode($session);  // GetSessionResult is JsonSerializable
```

### CORS errors in development

[](#cors-errors-in-development)

Use Vite's dev proxy to forward `/api` requests to your PHP server — no CORS headers needed:

```
// vite.config.ts
server: { proxy: { '/api': 'http://localhost:8080' } }
```

### Class not found errors

[](#class-not-found-errors)

Ensure Composer's autoloader is loaded before using SDK classes:

```
require_once __DIR__ . '/vendor/autoload.php';
```

Important Notes
---------------

[](#important-notes)

- This SDK uses the **Server Token** auth mode. Your PHP backend creates session tokens and the frontend embed consumes them. For other auth modes (Share Key, Popup Login), see the [JS SDK docs](https://www.npmjs.com/package/@querri-inc/embed).
- **React/Vue/Angular:** Memoize the `auth` prop if it's an object. A new object reference on every render cycle causes the iframe to be destroyed and recreated.
- The PHP SDK covers the full Querri API (all 13 resources). For frontend-only use cases, see the [JS SDK](https://www.npmjs.com/package/@querri-inc/embed).

Requirements
------------

[](#requirements)

- PHP 8.3+
- `ext-json`
- `ext-hash`
- [`symfony/http-client`](https://symfony.com/doc/current/http_client.html) ^7.2

License
-------

[](#license)

MIT

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

7

Last Release

47d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ffaaef460a92f389626e43948631e7d8ebdaf72658f93d6bfe9aa06fb4e6aea9?d=identicon)[JohnRSim](/maintainers/JohnRSim)

---

Top Contributors

[![JohnRSim](https://avatars.githubusercontent.com/u/364208?v=4)](https://github.com/JohnRSim "JohnRSim (39 commits)")[![daveaingram](https://avatars.githubusercontent.com/u/583008?v=4)](https://github.com/daveaingram "daveaingram (1 commits)")

---

Tags

sdkanalyticsembedquerri

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/querri-embed/health.svg)

```
[![Health](https://phpackages.com/badges/querri-embed/health.svg)](https://phpackages.com/packages/querri-embed)
```

###  Alternatives

[w7corp/easywechat

微信SDK

10.4k811.1k62](/packages/w7corp-easywechat)[symfony/asset-mapper

Maps directories of assets &amp; makes them available in a public directory with versioned filenames.

1668.1M208](/packages/symfony-asset-mapper)[zumba/amplitude-php

PHP SDK for Amplitude

4010.1M5](/packages/zumba-amplitude-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
