Download the PHP package snipform/php-sdk without Composer

On this page you can find all versions of the php package snipform/php-sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package php-sdk

SnipForm PHP SDK

Official PHP SDK for the SnipForm API. Eloquent-flavoured query builder over the V2 endpoints.

Quick start

Contents

Data Objects (DTOs)

Every typed return object extends SnipForm\Data\SnipFormDTO — a pure typed value object with public readonly fields. Two helpers:

DTOs hold no original payload; if you need the raw API JSON, flip the resource into raw mode with asRaw().

Returning from a Laravel controller

DTOs and PaginatedCollection both implement JsonSerializable, so a Laravel (or any PSR-7) controller can return them directly:

A PaginatedCollection serializes as Laravel's standard pagination JSON (data, current_page, last_page, total, next_page_url, …). Only page 1 is serialized — iterate first if you want all pages.

Property

The token is scoped to a single SnipForm Property. Pull its identity + headline counts:

Signals query builder

The first argument to every where*() method is a public field id. Pass it as a SessionField enum case (IDE-discoverable, type-checked) or as a bare string (escape hatch, no SDK-side validation).

Field/subfield/type are resolved server-side from the id, so the wire stays small.

Type-safe operators: when you pass an enum case, the SDK validates the operator against the field's type and throws IncompatibleFieldOperator before HTTP:

SessionField cases are grouped by concern: entry/exit page, referrer, tags, geo, browser/device/OS, bot detection, channel + UTM attribution, acquisition value, short links, forms, events, session metrics. Bare string fallback covers anything new the server adds before the enum catches up.

Method Op Use for
where($id, $value) equals equality (array value = IN)
orWhere(...) equals (where=or) OR clause
whereNot(...) equals (not=true) negate
orWhereNot(...) equals (where=or, not=true) OR negate
whereStartsWith($id, $v) starts_with prefix
whereContains($id, $v) contains substring
whereRegex($id, $pat) regex regex
whereGt / Gte / Lt / Lte gt / gte / lt / lte numeric comparison
whereBetween($id, $a, $b) between numeric range
whereExists($id) exists field is present
whereNotExists($id) exists (not=true) field is absent

Each clause posts as {id, op, value, where?, not?}. where and not are omitted at default values.

Periods

Use the typed shorthands for autocomplete, or pass a Period case to period().

Invalid period strings throw SnipForm\Exceptions\InvalidPeriodException immediately — no HTTP round-trip.

Sessions, lazy

->sessions() returns a PaginatedCollection you can iterate. Each iteration step pulls the next page transparently.

Pages — explicit pagination

->page($n) returns a Data\Page object that carries the page's items plus the full Laravel paginator meta and navigation methods. One HTTP call gives you both — no separate ->count().

Page is iterable, countable, and array-accessible — so existing foreach/count/$page[0] usage keeps working:

Returning a Page from a Laravel controller serializes it as the standard Laravel paginator JSON for that page:

Metrics

Returns a MetricsResult value object:

To reach trend data (previous-period, percent, difference), use asRaw().

Short links

Three resources: groups (folders), links (the short URLs themselves), and clicks (the redirect events). Scoped to the property your token belongs to.

Link groups

Links

Each link exposes a small accessor for utm values:

Clicks

Read-only — clicks are recorded server-side from short-link redirects. The fluent filter builder chains until you call ->all() or ->find():

Filters:

Method Effect
forLink($id) scope to one short link
forGroup($id) scope to a link group
between($fromTs, $toTs) unix timestamp range
since($fromTs) open-ended range
usersOnly() exclude bot clicks
botsOnly() only bot clicks
perPage($n) page size, 1–100

Session actions

Three writes scoped to a single SignalSession: resolve a visitor's session id from their request, submit a custom event, and patch acquisition metadata.

Resolve

Looks up the SignalSession that belongs to a visitor — by hashing their IP + User-Agent + language with the same daily salt the JS tracker uses. The visitor must already have been tracked once today on this property for the lookup to find a match.

The SDK accepts a Symfony or Laravel Request and pulls those values for you. Pass $request from your controller:

Or pass values explicitly if you're not on a Symfony-flavoured framework:

$resolved->resolved is false if the visitor hasn't been tracked yet today on this property. Handle that case before chaining further writes.

Important: the ip must be the visitor's IP from your incoming request, not your server's outbound IP. Your framework's $request->getClientIp() / equivalent does the right thing automatically (resolves through proxies / CDNs). The SDK does not inspect the transport-level IP of its own outbound call.

Event

Submit a custom event for a session. Identifies the target session in one of two ways:

Returns a typed Event value object.

Acquisition

Patch acquisition metadata onto a session. Partial — only supplied keys are written. Tags merge with existing tags (deduped); cost / value / currency overwrite.

Returns the resulting acquisition_meta array along with the session id.

Typical end-to-end flow

Conversions

Two surfaces:

Schema

Inspect the catalog of trigger types, conversion types, segment dimensions, and valid match modes before building a config:

Definition CRUD

Create a conversion via the fluent builder — each step() opens a sub-builder whose ->on*() method commits the step and returns the parent for chaining:

Step trigger terminals:

Method Triggers when
->onPageView($value, $match = 'contains', $field = 'path') Visitor reaches a page
->onEntryPage($value, $match = 'contains', $field = 'entry_path') Session entered on a page
->onEvent($name, $value = null, $valueMatch = 'exists') Custom event fires
->onFormSubmit($snipFormId) A specific SnipForm submits
->onShortLink($id, $scope = 'link') Session arrived via short link/group

Each step builder also exposes ->optional() to mark the step is_required: false.

Patch existing definitions:

Analytics

->for($id) returns a ConversionAnalytics you chain a window onto, then call a terminal:

Slice by a flat dimension or a custom tag key:

Cycle through day/week/month buckets with deltas vs the prior bucket:

Drill into sessions that reached a specific funnel step:

Window setters: ->between($fromTs, $toTs) or ->since($fromTs) (open-ended to now). Both take unix timestamps.

Attribution

$client->attribution() exposes the SnipForm channel-attribution engine for diagnostics — useful for "Test attribution" buttons in a link builder UI, or for verifying that a campaign's UTM combo will land in the channel category you expect.

The engine runs the same code path that classifies real tracker sessions, so a positive preview is contractual: if the engine says messaging/WhatsApp now, a visitor landing with those tags in production will be classified the same way.

Click IDs + referrer

Both can be passed when you want to simulate something beyond bare UTMs — e.g. checking that a gclid lands in paid_search even if the merchant forgot to set utm_medium=cpc:

Preset catalog

presets() returns the canonical chip catalog the SnipForm app's link builder uses. Render the chip strip in your own link-creation UX so the UTM taxonomy stays consistent between SnipForm and your app:

asRaw() — opt-out of typed objects

Every resource (and every builder chain) supports ->asRaw(). Terminals return the underlying API array instead of hydrating a typed DTO. Useful when you want fields the SDK doesn't surface, or when you're forwarding API responses to a frontend that already expects the SnipForm JSON shape.

Each $client->resource() call returns a fresh instance, so flipping asRaw on one chain doesn't affect the next.

Laravel

Optional Laravel layer that ships in SnipForm\Laravel\*. The SDK doesn't depend on Laravel — these classes only load when illuminate/support is installed. Composer's package discovery wires the provider; everything is opt-in via config.

Auto-identify on login

The happy path: every time a user logs into your app, attach their session to a SnipForm Contact automatically. No code at the callsite.

1. Set the token in .env:

2. Add the Identifiable trait to your User model:

That's it. The provider registers a listener on Illuminate\Auth\Events\Login and fires identify against Snipform whenever a user authenticates.

What gets sent. Identifiable auto-derives the payload by probing common columns:

Where Columns checked
external_id $user->getKey()
email (top level) email
traits.* first_name, last_name, phone, company, job_title, website, country, city
traits.first_name / traits.last_name (fallback) name split on whitespace

Override what's sent by adding hooks to your model:

Performance — three layers of "don't overburden the API":

  1. afterResponse queueing. The identify call runs after Laravel sends the response. Login is never blocked.
  2. Cache-backed dedup. The provider wires Laravel's default cache as an atomic gate via Cache::add. The first request per (user, payload) per TTL goes over the wire; the rest are no-ops.
  3. Server-side idempotency. Even if you bypass the dedup, the SnipForm API merges traits in place — repeat calls with the same payload are a no-op database read.

Config knobs (all .env-driven):

Full control over the rest by publishing the config file:

Snipform facade

Explicit identify calls — useful for paths the Login event doesn't cover (impersonation, webhook handlers, side flows):

All identify calls honor the same dedup + queue config — Snipform::auth() called a hundred times in the same hour costs you one API call.

To register the Snipform alias globally (so you don't have to use it everywhere), add to config/app.php:

Identify middleware (SPAs / token APIs)

Some apps don't go through the form login flow — token-auth APIs (auth:sanctum, auth:api), SPAs that maintain a session via Sanctum's stateful cookie, etc. The Login event never fires in those cases.

The snipform.identify middleware (alias registered by the provider) runs identify against the auth user on every request it's applied to. Cheap to use because the dedup gate short-circuits repeats:

Per-request cost when the cache is warm: one cache hit. When the cache misses: one identify call, deferred until after the response is sent.

To target a non-default guard:

Manual setup — Client injection

If you'd rather skip the Laravel layer and reach for the raw SDK, the Client is still bound as a singleton:

Config also reads from the legacy config/services.php → snipform location for back-compat — apps that wired the SDK before the Laravel layer existed keep working untouched.

To opt out of the auto-registered provider entirely, add to your app's composer.json:

SnipFormSessionMiddleware

Older / lighter helper that just lifts the visitor's session id off the inbound request and stashes it on $request->attributes. Use it when you want the id without invoking the SDK on every request (analytics-only handlers, presence checks, conditional logging).

Pulls from, in priority order:

  1. X-SnipForm-Session-Id header (set by signals.js attachToFetch())
  2. snip_session_id form field (set by attachToForm())
  3. snip_session_id query string param

Register on the web/api middleware group:

Then in any downstream controller:

The Session resource also accepts a Request directly — $snipform->session()->event($request, [...]) — and pulls the same fields. The middleware is purely a convenience for the "I want the id but don't need the SDK yet" case.

Authentication

The SDK takes a property-scoped Personal Access Token. Generate one in Property → Settings → API Tokens. Tokens carry scope (e.g. signals:read, conversions:write) — the SDK forwards them and the API enforces.

Error handling

ApiException exposes:

Property Type Notes
->status int HTTP status code
->errors array Laravel-style ['field' => ['msg', ...]] — empty for non-validation errors
->body array Full unwrapped response body

Configuration

Tests

The unit suite is hermetic — no network, no env config required:

There's also a tests/Integration suite that hits a live SnipForm deployment. Copy the env template, fill in a token + base URL, then:

Integration tests are skipped when SNIPFORM_TEST_TOKEN isn't set, so CI without secrets still runs unit-only.


All versions of php-sdk with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
guzzlehttp/guzzle Version ^7.0
symfony/http-foundation Version ^6.0|^7.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package snipform/php-sdk contains the following files

Loading the files please wait ...