Send signals
POST /track, the call everything else depends on.
POST /track
curl -X POST "https://api.thepulseapi.com/api/v1/track" \
-H "Content-Type: application/json" \
-H "x-api-key: pk_live_..." \
-d '{
"sessionId": "sess_abc123",
"organizationId": "org_abc123",
"signals": [
{ "type": "category_view", "value": "helmets-safety" },
{ "type": "price_filter", "value": "500000-1500000" }
]
}'With the SDK:
await pulse.track([
{ type: 'category_view', value: 'helmets-safety' },
{ type: 'price_filter', value: '500000-1500000' },
]);Signals are additive. Send them as they happen rather than batching a whole session at the end: persona scores decay, so ordering carries meaning.
organizationId is required
Every endpoint below reads it from the body, not from the API key. Omitting it returns 400
with a validation error naming the field. The SDK sends it for you from init().
/track also captures device, referrer and time from the request itself, so a call with no
signals at all is still worth making: it opens the session with what the request already says.
POST /track/behavior
One behaviour, named, when you have nothing to say about a category or a price.
curl -X POST "https://api.thepulseapi.com/api/v1/track/behavior" \
-H "Content-Type: application/json" \
-H "x-api-key: pk_live_..." \
-d '{
"sessionId": "sess_abc123",
"organizationId": "org_abc123",
"behavior": "sort_price_asc",
"metadata": { "page": "category" }
}'behavior is your own slug, capped at 128 characters. Sorting by price ascending says something
about a shopper that no category view does.
POST /track/keywords
A search query, turned into keyword signals for you.
curl -X POST "https://api.thepulseapi.com/api/v1/track/keywords" \
-H "Content-Type: application/json" \
-H "x-api-key: pk_live_..." \
-d '{
"sessionId": "sess_abc123",
"organizationId": "org_abc123",
"query": "mu bao hiem fullface"
}'Send the raw query. Extraction happens server-side, and the query is capped at 512 characters because the work is linear in its length.
POST /event
A named event, for things that are not persona signals.
await pulse.event('checkout_started', { cartValue: 1250000 });
