PHP code example of snipform / php-sdk

1. Go to this page and download the library: Download snipform/php-sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

snipform / php-sdk example snippets


use SnipForm\SnipForm;

$snipform = SnipForm::client('snipform_pat_xxx');

// List sessions matching a query — auto-paginated
foreach ($snipform->signals()
    ->last28Days()
    ->where('country', 'US')
    ->whereStartsWith('entry_path', '/blog')
    ->sessions() as $session
) {
    echo $session->entryPath.' from '.$session->source.PHP_EOL;
}

// Headline metrics for the same query
$metrics = $snipform->signals()
    ->last7Days()
    ->where('utm_content', 'pub_12345')   // an affiliate
    ->metrics();

echo "Sessions: {$metrics->sessions}, bounce: {$metrics->bounceRate}%";

$dto->toArray();   // public fields as an associative array
json_encode($dto); // implements JsonSerializable — same as toArray()

public function dashboard(SnipForm $snipform)
{
    return $snipform->signals()->last7Days()->metrics();    // serializes to JSON
}

public function sessions(SnipForm $snipform)
{
    return $snipform->signals()->last7Days()->sessions();   // page 1 of Laravel paginator JSON
}

public function property(SnipForm $snipform)
{
    return $snipform->properties()->overview();             // PropertyOverview → typed JSON
}

$property = $snipform->properties()->overview();

$property->id;             // string
$property->name;           // string
$property->domain;         // string
$property->hasSignals;     // bool — tracking has fired at least once
$property->state;          // string|null — raw state value
$property->stateName;      // string|null — human label
$property->counts;         // array — e.g. ['sessions' => 188862, 'forms' => 4, 'pages' => 2]

use SnipForm\Query\SessionField;

$snipform->signals()
    ->where(SessionField::COUNTRY, 'US')
    ->whereBetween(SessionField::TIME_ON_SITE, 60, 300)
    ->whereStartsWith(SessionField::ENTRY_PATH, '/blog')
    ->sessions();

// Strings still work — the SDK doesn't know the field's type without an
// enum case, so op/field mismatches won't be caught client-side:
$snipform->signals()->where('country', 'US')->sessions();

$snipform->signals()->whereBetween(SessionField::COUNTRY, 0, 10);
// → IncompatibleFieldOperator: Operator `between` is not valid for field
//   `country` (type: keyword). Valid ops: equals, contains, starts_with,
//   regex, exists.

->today()
->yesterday()
->last7Days()
->last28Days()
->monthToDate()
->yearToDate()
->last12Months()

// Custom date ranges — pick whichever form reads best
->between('2026-01-01', '2026-01-31')      // both at once
->customPeriod('2026-01-01', '2026-01-31') // same
->customPeriod()
    ->fromDate('2026-01-01')
    ->toDate('2026-01-31')                  // piecemeal

// Or via the enum:
use SnipForm\Query\Period;
->period(Period::LAST_28)
->period('last_28')                         // string also fine; validated upfront

foreach ($snipform->signals()->where('device', 'mobile')->sessions() as $session) { ... }
$first  = $snipform->signals()->where('device', 'mobile')->sessions()->first();
$total  = $snipform->signals()->where('device', 'mobile')->sessions()->count();
$all    = $snipform->signals()->where('device', 'mobile')->sessions()->all(); // careful

$page = $snipform->signals()->sessions(20)->page(2);

$page->items;          // SessionRow[]   (or array[] in asRaw)
$page->currentPage;    // 2
$page->lastPage;       // 5
$page->total;          // 230
$page->perPage;        // 20
$page->from;           // 21
$page->to;             // 40
$page->nextPageUrl;    // string|null
$page->prevPageUrl;    // string|null
$page->hasMore();      // bool
$page->isFirstPage();
$page->isLastPage();

// Navigation — each is one HTTP call, returns the related Page
$next  = $page->next();    // → Page 3, or null when on last page
$prev  = $page->prev();    // → Page 1, or null when on first page
$first = $page->first();
$last  = $page->last();

// Jump by URL — pass any of the paginator URLs (or a link from the
// Laravel-style `links` array) and the SDK parses the `page` query param.
$jump = $page->pageLink($page->nextPageUrl);
$jump = $page->pageLink('https://api.snipform.io/v2/.../sessions?page=7');

// Render numbered page links from Laravel's `links` collection
foreach ($page->raw()['links'] ?? [] as $link) {
    if ($link['url']) {
        $other = $page->pageLink($link['url']);
    }
}

foreach ($snipform->signals()->sessions()->page(2) as $session) { ... }
$rowsOnThisPage = count($page);   // count of items on THIS page (not total)
$first = $page[0];

public function sessions(SnipForm $snipform, Request $request)
{
    return $snipform->signals()
        ->last28Days()
        ->sessions(20)
        ->page((int) $request->input('page', 1));
}

$m = $snipform->signals()->last28Days()->metrics();
$m->sessions;          // int
$m->views;             // int
$m->viewsPerSession;   // float
$m->bounceRate;        // float (0-100)
$m->duration;          // int (seconds)
$m->avgScroll;         // float (0-100)
$m->showing;           // human-readable date span
$m->tookMs;            // server query time

$groups   = $client->linkGroups()->all();                        // LinkGroup[]
$group    = $client->linkGroups()->find($id);                    // LinkGroup
$group    = $client->linkGroups()->create([
    'name' => 'Spring affiliates',
    'description' => 'Affiliate links for Q2',
    'purpose' => 'affiliate',
    'track_clicks' => true,
]);
$group    = $client->linkGroups()->update($id, ['name' => 'Spring 2026']);
$deleted  = $client->linkGroups()->delete($id);                  // bool, cascades the group's links

// Paginated list — auto-walks every page
foreach ($client->links()->all() as $link) {
    echo $link->shortUrl.' → '.$link->destinationUrl.PHP_EOL;
}

// Filter by group
foreach ($client->links()->all(['group_id' => $groupId]) as $link) { ... }

$link = $client->links()->find($id);                             // Link
$link = $client->links()->create([
    'group_id' => $groupId,
    'destination_url' => 'https://example.com/landing',
    'domain' => 'snpf.io',
    'utm' => [
        'utm_source' => 'ofillio',
        'utm_medium' => 'affiliate',
        'utm_campaign' => 'spring_sale',
        'utm_content' => 'pub_12345',     // individual affiliate
    ],
]);
$link = $client->links()->update($id, [
    'destination_url' => 'https://example.com/new-landing',
    'is_active' => false,
]);
$client->links()->delete($id);

$link->utm('utm_content');  // 'pub_12345' or null

// Every click for one link, walking pages
foreach ($client->clicks()->forLink($linkId)->all() as $click) {
    echo $click->city.' on '.$click->device.PHP_EOL;
}

// Last 30 days of human clicks on a whole campaign
foreach ($client->clicks()
    ->forGroup($groupId)
    ->between(strtotime('-30 days'), time())
    ->usersOnly()
    ->all() as $click
) { ... }

// Just bot traffic
$bots = $client->clicks()->botsOnly()->all()->count();

// Single click
$click = $client->clicks()->find($clickId);

// Laravel
public function handleVisitor(Request $request)
{
    $resolved = $snipform->session()->resolve($request);
    // → ResolveResult { resolved: true, sessionId: 'abc...', sid: 'hash...' }
}

// Symfony
public function handle(Request $request): Response
{
    $resolved = $snipform->session()->resolve($request);
}

$resolved = $snipform->session()->resolve([
    'ip'         => $myFramework->getClientIp(),
    'user_agent' => $myFramework->getUserAgent(),
    'lang'       => $myFramework->getAcceptLanguage(),
]);

// Explicit session_id in the payload
$event = $snipform->session()->event([
    'session_id' => $resolved->sessionId,
    'name'       => 'purchase',
    'value'      => 99.99,            // optional
    'meta'       => ['order_id' => 'X-1', 'currency' => 'USD'],  // optional
]);

// Or pass the request — SDK reads session_id from the X-SnipForm-Session-Id
// header or `snip_session_id` body field (set by signals.js attachToFetch /
// attachToForm on the customer's page)
$event = $snipform->session()->event($request, [
    'name'  => 'purchase',
    'value' => 99.99,
]);

$snipform->session()->acquisition([
    'session_id'    => $resolved->sessionId,
    'cost'          => 250,          // optional, integer
    'value'         => 9900,         // optional, integer
    'currency_code' => 'USD',        // optional, ISO 4217
    'tags'          => ['affiliate'],// optional, merged
]);

// Or via Request, same as event()
$snipform->session()->acquisition($request, [
    'value' => 9900,
    'tags'  => ['paid'],
]);

public function recordConversion(Request $request)
{
    $resolved = $snipform->session()->resolve($request);
    if (! $resolved->resolved) {
        return;  // visitor hasn't been tracked yet
    }

    $snipform->session()->event([
        'session_id' => $resolved->sessionId,
        'name'       => 'purchase',
        'value'      => $order->total,
    ]);

    $snipform->session()->acquisition([
        'session_id'    => $resolved->sessionId,
        'value'         => (int) ($order->total * 100),
        'currency_code' => $order->currency,
        'tags'          => ['paid'],
    ]);
}

$schema = $snipform->conversions()->schema();
// $schema['conversion_types']     — ['lead', 'sale', 'signup', 'activation', 'download', 'custom']
// $schema['trigger_types']        — full details per type (kind, defaults, fieldOptions, matchOptions, …)
// $schema['cycle_intervals']      — ['day', 'week', 'month']
// $schema['segment_dimensions']   — list of segmentable fields
// $schema['page_match_modes']     — ['contains', 'exact', 'starts_with', 'regex']
// $schema['event_value_match_modes'] — ['exists', 'equals', 'gt', 'gte', 'lt', 'lte']

$all = $snipform->conversions()->all();                  // Conversion[]
$c   = $snipform->conversions()->find($id);              // Conversion (with .steps populated)

$conversion = $snipform->conversions()->create()
    ->name('Newsletter signup')
    ->description('Free trial sign-up flow')
    ->type('lead')
    ->conversionValue(5.00)
    ->defaultPeriod('last_28')
    ->defaultCycle('week')

    ->step('Visit pricing')->onPageView('/pricing')
    ->step('Click signup')->onEvent('signup_click')
    ->step('Submit form')->onFormSubmit($snipFormId)

    ->publish()           // optional — leaves it in 'draft' otherwise
    ->save();             // → Conversion

$snipform->conversions()->update($id, [
    'name'             => 'Renamed',
    'conversion_value' => 12.5,
]);

// Replace the full steps list atomically
$snipform->conversions()->replaceSteps($id, [
    ['name' => 'Visit', 'trigger_type' => 'page_view',   'trigger_config' => ['type' => 'page',  'field' => 'path', 'match' => 'contains', 'value' => '/pricing']],
    ['name' => 'Buy',   'trigger_type' => 'event',       'trigger_config' => ['type' => 'event', 'name' => 'purchase', 'valueMatch' => 'exists']],
]);

$snipform->conversions()->publish($id);   // draft → active
$snipform->conversions()->toggle($id);    // active <-> paused
$snipform->conversions()->delete($id);    // bool

$reader = $snipform->conversions()->for($id)
    ->between(strtotime('-30 days'), time())
    ->filter(['channel_category' => 'paid_search']);   // optional

$summary = $reader->summary();
$summary->sessions;       // int
$summary->conversions;    // int
$summary->rate;           // float (0-100)
$summary->value;          // float|null — total attributed value
$summary->funnel;         // FunnelStep[] — per-step counts + drop_off

$reader->segments('channel_category');      // ConversionSegment[]
$reader->segmentsByTag('campaign_phase');   // ConversionSegment[]

$cycles = $reader->cycles('week', page: 0, perPage: 6);
// → ['cycles' => ConversionCycle[], 'has_more' => bool, 'page' => int, 'interval' => 'week']

foreach ($cycles['cycles'] as $c) {
    echo "{$c->label}: {$c->conversions}/{$c->sessions} = {$c->rate}% (Δ{$c->delta}%)\n";
}

$step = $reader->sessionsAt($stepId, page: 1, perPage: 25);
// → ['sessions' => array[], 'page' => int, 'per_page' => int, 'total' => int, 'has_more' => bool]

// By explicit UTM keys
$result = $client->attribution()->preview([
    'utm_source'   => 'whatsapp',
    'utm_medium'   => 'social',
    'utm_campaign' => 'spring',
]);

// Or by full URL — SDK parses the query string
$result = $client->attribution()->preview([
    'url' => 'https://example.com/landing?utm_source=tg&utm_medium=messaging&utm_campaign=spring',
]);

$result->category;       // 'messaging'
$result->categoryLabel;  // 'Messaging'
$result->name;           // 'WhatsApp' | 'Telegram' | ...
$result->source;         // 'whatsapp'
$result->medium;         // 'social'
$result->method;         // 'utm' | 'click_id' | 'referrer' | 'direct' | 'custom_rule'
$result->isDirect();     // bool
$result->isPaid();       // bool — true for paid_search / paid_social / etc.

$client->attribution()->preview([
    'click_ids' => ['gclid' => 'xyz123'],
    'referrer'  => 'https://www.google.com/search?q=...',
]);

foreach ($client->attribution()->presets() as $preset) {
    // ['group' => 'Messaging', 'key' => 'whatsapp', 'label' => 'WhatsApp',
    //  'utm_source' => 'whatsapp', 'utm_medium' => 'messaging']
}

$client->properties()->overview();              // PropertyOverview
$client->properties()->asRaw()->overview();     // array

$client->signals()->last28Days()->metrics();              // MetricsResult
$client->signals()->last28Days()->asRaw()->metrics();     // array — analytics, meta, options

$client->signals()->last28Days()->sessions();             // PaginatedCollection<SessionRow>
$client->signals()->last28Days()->asRaw()->sessions();    // PaginatedCollection<array>

$client->linkGroups()->find($id);                         // LinkGroup
$client->linkGroups()->asRaw()->find($id);                // array

$client->conversions()->find($id);                        // Conversion
$client->conversions()->asRaw()->find($id);               // array

$client->conversions()->asRaw()->create()                 // ConversionBuilder (raw flag forwarded)
    ->name(...)->step('x')->onPageView(...)
    ->save();                                             // array

$client->conversions()->asRaw()->for($id)                 // ConversionAnalytics (raw flag forwarded)
    ->since(strtotime('-30 days'))
    ->summary();                                          // array

use Illuminate\Foundation\Auth\User as Authenticatable;
use SnipForm\Laravel\Concerns\Identifiable;

class User extends Authenticatable
{
    use Identifiable;
}

class User extends Authenticatable
{
    use Identifiable;

    // Custom external id — defaults to $this->getKey()
    protected function snipformExternalId(): string
    {
        return 'usr_'.$this->uuid;
    }

    // Merged on top of the auto-derived traits
    protected function snipformTraits(): array
    {
        return [
            'company' => $this->team?->name,
            'meta'    => [
                ['key' => 'plan', 'value' => $this->subscription_plan],
            ],
        ];
    }
}

use SnipForm\Laravel\Facades\Snipform;

Snipform::auth();                       // identify auth()->user(), no-op for guests
Snipform::user($someOtherUser);         // identify any model with the Identifiable trait
Snipform::payload([                     // raw passthrough — bypass the trait
    'email'  => '[email protected]',
    'traits' => ['first_name' => 'Jane'],
]);

Snipform::contacts()->find($id);        // SDK Contacts resource — find/update/delete/all
Snipform::contacts()->update($id, [
    'lifecycle_stage' => 'customer',
]);

Snipform::client();                     // escape hatch — full SDK Client

'aliases' => Facade::defaultAliases()->merge([
    'Snipform' => \SnipForm\Laravel\Facades\Snipform::class,
])->toArray(),

Route::middleware(['auth:sanctum', 'snipform.identify'])->group(function () {
    Route::get('/me', UserController::class);
    Route::get('/dashboard', DashboardController::class);
});

Route::middleware('snipform.identify:web')->group(...);

public function dashboard(\SnipForm\Client $snipform)
{
    return $snipform->signals()->last7Days()->metrics();
}

protected $middlewareGroups = [
    'web' => [
        // ...
        \SnipForm\Laravel\Middleware\SnipFormSessionMiddleware::class,
    ],
];

public function checkout(Request $request, \SnipForm\Client $snipform)
{
    $sessionId = $request->attributes->get(
        \SnipForm\Laravel\Middleware\SnipFormSessionMiddleware::ATTRIBUTE,
    );

    if ($sessionId) {
        $snipform->session()->event([
            'session_id' => $sessionId,
            'name'       => 'checkout_started',
        ]);
    }
}

use SnipForm\Exceptions\AuthenticationException;
use SnipForm\Exceptions\ApiException;
use SnipForm\Exceptions\InvalidPeriodException;
use SnipForm\Exceptions\MissingSessionIdException;
use SnipForm\Exceptions\SnipFormException;

try {
    $sessions = $snipform->signals()->last7Days()->sessions()->all();
} catch (InvalidPeriodException $e) {
    // SDK-side — invalid string passed to period(). Caught before any HTTP call.
} catch (MissingSessionIdException $e) {
    // SDK-side — session_id couldn't be resolved from the Request.
} catch (AuthenticationException $e) {
    // 401 / 403 — token bad or out of scope.
} catch (ApiException $e) {
    // 4xx / 5xx with a structured body — see $e->status, $e->errors, $e->body.
    // Validation errors are expanded into the message inline:
    //   "The given data was invalid. — period: must be one of ..."
} catch (SnipFormException $e) {
    // any other SDK-side failure (transport, JSON decode, etc.)
}

SnipForm::client('snipform_pat_xxx', [
    'base_url'    => 'https://api.snipform.io',  // default
    'path_prefix' => '/v2/',                      // default; older deployments may serve under '/api/v2/'
    'timeout'     => 30,                          // seconds, request timeout
    'verify_ssl'  => true,                        // default; set false for local self-signed certs
]);
bash
composer 
bash
php artisan vendor:publish --tag=snipform-config
json
"extra": { "laravel": { "dont-discover": ["snipform/php-sdk"] } }