Skip to content

Session Actions

Two write endpoints let your server add to a session the tracker already opened in the browser: a custom event, or acquisition metadata (revenue, currency, tags). Both need the signals:write scope and both need the visitor’s session id, which only the browser knows. See Session Handoff for getting it to your backend.

MethodPathScope
POST/v2/property/session/eventsignals:write
POST/v2/property/session/acquisitionsignals:write

Both endpoints look for the session id in this order and use the first one found:

PriorityWhereSet by
1session_id in the JSON bodyyou
2X-Snipform-Session-Id request headersignals.attachToFetch() when your frontend calls your own API, forwarded by you
3snip_session_id body fieldsignals.attachToForm() hidden input, forwarded by you

If none is present the response is 422 with error_code: "validation_failed" and the message session_id missing - provide it in the body, X-Snipform-Session-Id header, or snip_session_id form field.

POST /v2/property/session/event

FieldRulesNotes
session_idstringOptional if the header or form field carries it
namerequired, string, max 255The event name as it will appear in sessions, conversions and breakdowns
valueany scalarStored as a string; numeric strings are also indexed as a number for event_value_num filters
metaobjectKey/value pairs stored with the event
Terminal window
curl -X POST https://api.snipform.io/v2/property/session/event \
-H "Authorization: Bearer $SNIPFORM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"session_id": "9f1c2c1e-7b1a-4f0e-9f2b-1d2c3b4a5e6f",
"name": "trial_started",
"value": "pro",
"meta": { "plan": "pro", "seats": 5 }
}'

created_ts is unix seconds. The event becomes queryable on the session immediately: event_name, event_value and event_value_num in the field catalog, the Event fires trigger in Conversions, and the An event fires trigger in Automations.

Statuserror_codeWhen
404not_foundsession not found for this property
422validation_failedname missing or over 255 characters, meta not an object, or no session id anywhere

POST /v2/property/session/acquisition

Records money and context on the session. Only the keys you send are touched.

FieldRulesNotes
session_idstringOptional if the header or form field carries it
valueinteger, min 0Revenue in minor units (cents). Recorded as an acquisition event; the session’s value is the rollup of its acquisition events
currency_codestring, exactly 3 charsISO 4217, uppercased. Defaults to the session’s existing currency, else USD
tagsarray of strings, each max 255Merged with existing tags and de-duplicated
costinteger, min 0Accepted for backwards compatibility but no longer stamps the session. Session cost comes from cost entries and connected ad platforms; see Google Ads & Meta

A tag in the form {source}:order:{id} (for example shopify:order:1001) is read as an order reference: the order id is stored on the acquisition event and the value is labelled as order revenue rather than a plain acquisition value.

Terminal window
curl -X POST https://api.snipform.io/v2/property/session/acquisition \
-H "Authorization: Bearer $SNIPFORM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"session_id": "9f1c2c1e-7b1a-4f0e-9f2b-1d2c3b4a5e6f",
"value": 12900,
"currency_code": "EUR",
"tags": ["plan:pro", "billing:annual"]
}'

amount_usd is the USD-normalised figure (also minor units) that ROAS and cross-currency comparisons use. If you send only tags, value is the session’s current value block, which may be null.

Statuserror_codeWhen
404not_foundsession not found for this property
422validation_failedvalue or cost negative or non-integer, currency_code not 3 characters, a tag over 255 characters, or no session id anywhere
  1. The tracker runs on the storefront. Before checkout, signals.bindTo('/api/snip-session') posts the session id to your backend and you store it on the cart or order.
  2. Your payment provider calls your webhook when the order is paid.
  3. Your webhook handler calls /v2/property/session/acquisition with the stored session id, the order total in cents, the currency, and a {shop}:order:{id} tag.
  4. The session now carries revenue; any conversion with an Acquisition step counts it, and Automations with the A purchase is recorded trigger fire.

In PHP the same flow is two lines with the SDK: Snipform::revenue(12900, 'EUR') from a request that carries the session id, or Snipform::acquisitionFor($sessionId, [...]) from a queue job.