Reference for every object exposed by the Personyze REST API. Each section below covers one object: its purpose, supported HTTP methods, columns (with type and indexing notes), and copy-paste-ready curl examples.
Prerequisites — read these first if you haven’t:
- REST API Overview & Quick Start — request shape, HTTP methods, response codes
- Authentication — getting your API key, sending it, multi-account setups
- Path Parameters — the
where/columns/order_by/limitsyntax that runs through every example below
Object index
Click an object to jump to its section. Each section has its own anchor URL — you can deep-link directly to any object’s reference.
CRUD content (read/write)
Hold your campaigns, audience, catalog, and configuration. Full CRUD for External API user and above.
usersCustomer profiles. Column names are dynamic.user_listsNamed lists of users (manual or imported).user_list_usersMembership of users in user_lists.actionsPersonalization actions. Read-only over REST today.conditionsAudience conditions. Read-only over REST today.placeholdersDOM placeholder containers (where actions render).containers_grab_variableGrab DOM/JS values back into the visitor profile.productsProduct catalog rows. Column names are dynamic.articlesArticle catalog rows. Column names are dynamic.Interactions / events (write-mostly)
Append-only logs of visitor interactions. Mostly used by SDKs and back-end integrations.
products_interactionsView / cart / purchase events on products.eventsGeneric event log (read-only).formsForm-submission log (read-only).doFire-and-forget command dispatcher.couponsCoupon codes used at a checkout the tag did not see.Privacy requests
Find, export and delete one person, as Settings → Data & privacy → Visitor requests does. Your account’s own API key only.
privacy-personEvery profile that matches a person, and what each store holds.privacy-exportEverything held about them, as one JSON file.privacy-deleteThe full erasure, logged, with a receipt.Reports / archive (read-only)
sessions_archiveOne row per visitor session, with location/device/browser metadata.user_interestsPer-user inferred interests, categories, tags.products_stats_*Per-product interaction counters over six rolling windows.summary_actionsDaily aggregated KPI per action.Tracker / SDK helpers
Used by the JS tracker, native SDKs, and integrations to self-bootstrap. Not usually called by REST API consumers directly.
tracker_codeReturns the JS snippet to embed in a customer page (HTML output).users
Customer profiles. Each row is one visitor or customer. Column names are dynamic — beyond the documented housekeeping columns, you can store any custom keys/values your account needs.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Identifying / housekeeping columns
| Column | Notes |
|---|---|
user_id |
Personyze internal primary key. Auto-assigned on insert. Indexed. |
internal_id |
Your external identifier (CRM ID, account ID, SKU). Indexed. |
fb_id |
Facebook user ID. Indexed. |
email |
Visitor email. Indexed. |
last_session_time |
Unix seconds. Indexed. |
data_last_modified |
Unix seconds. Indexed. |
session_counter |
Total sessions seen so far for this user. |
Common profile fields (custom)
first_name, middle_name, last_name, sex, birthday, timezone, current_city, current_state, current_country, religion, political, interests, relationship_status, education_year, plus custom_t_1…custom_t_6 (text), custom_i_1…custom_i_4 (integer), custom_f_1…custom_f_2 (float), custom_d_1, custom_d_2 (date) — and any additional fields you’ve configured on your account.
Examples
# Lookup by your external id
curl 'https://api:KEY@app.personyze.com/rest/users/where/internal_id=42'
# Recent active visitors (last 7 days)
curl 'https://api:KEY@app.personyze.com/rest/users
/where/last_session_time>1730000000
/columns/user_id,internal_id,email,first_name,last_session_time
/order_by_desc/last_session_time
/limit/1000'
# Create
curl -X POST 'https://api:KEY@app.personyze.com/rest/users' \
-H 'Content-Type: application/json' \
-d '{"internal_id":"acct-987","email":"alice@example.com","first_name":"Alice","custom_field_x":"vip"}'
# → 5712334 (new user_id)
# Update
curl -X PUT 'https://api:KEY@app.personyze.com/rest/users/where/internal_id=acct-987' \
-H 'Content-Type: application/json' \
-d '{"first_name":"Alicia"}'
# → 1 (rows affected)
Indexed columns / scan limits
GET /rest/users without a where requires order_by on an indexed column — user_id, last_session_time, data_last_modified, fb_id, email, or internal_id. Otherwise: 400 Cannot do this operation on whole table.
Deleting
DELETE /rest/users/where/… removes the profile row only: the person’s visits, events, form answers, chats and the rest stay, and the request is not logged. To answer a person’s request to be forgotten, use privacy-delete.
Throttling
POST /rest/users is serialized per Personyze account: at most one in-flight insert at a time. Requests that wait more than 1 second are rejected with 400 Too many simultaneous requests — retry with exponential backoff.
user_lists
Named lists of users (e.g. “VIPs”, “Newsletter opt-ins”). One row per list. Membership lives in a separate object — see user_list_users.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Columns
| Column | Notes |
|---|---|
id |
Primary key. Auto-assigned. |
name |
List display name. Indexed. |
Examples
# All lists
curl 'https://api:KEY@app.personyze.com/rest/user_lists'
# Create
curl -X POST 'https://api:KEY@app.personyze.com/rest/user_lists' \
-H 'Content-Type: application/json' \
-d '{"name":"VIPs"}'
# → 17
# Rename
curl -X PUT 'https://api:KEY@app.personyze.com/rest/user_lists/17' \
-H 'Content-Type: application/json' \
-d '{"name":"VIP customers"}'
# → 1
# Delete (also clears all memberships in user_list_users via FK cascade)
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/user_lists/17'
# → 1
user_list_users
Membership: which users belong to which user_lists. One row per (user_list_id, user_id) pair.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | — | ✅ |
POST accepts either an existing user_id, or a lookup key (user_internal_id, user_email) — the API resolves it to a user_id, creating a stub users row if needed.
Columns
| Column | Notes |
|---|---|
user_list_id |
FK → user_lists.id. Composite-key part. |
user_id |
FK → users.user_id. Composite-key part. |
POST body extras (resolved to user_id server-side, then dropped)
| Field | Resolves to |
|---|---|
user_internal_id |
user_id for the user with that internal_id. Creates the user if missing. |
user_email |
user_id for the user with that email. Creates the user if missing. |
Examples
# Members of list 17
curl 'https://api:KEY@app.personyze.com/rest/user_list_users/where/user_list_id=17/limit/1000'
# Add by user_id
curl -X POST 'https://api:KEY@app.personyze.com/rest/user_list_users' \
-H 'Content-Type: application/json' \
-d '{"user_list_id":17,"user_id":5712334}'
# Add by external id (auto-creates a users row if needed)
curl -X POST 'https://api:KEY@app.personyze.com/rest/user_list_users' \
-H 'Content-Type: application/json' \
-d '{"user_list_id":17,"user_internal_id":"acct-987"}'
# Add by email
curl -X POST 'https://api:KEY@app.personyze.com/rest/user_list_users' \
-H 'Content-Type: application/json' \
-d '{"user_list_id":17,"user_email":"alice@example.com"}'
# Remove
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/user_list_users
/where/user_list_id=17&user_id=5712334'
actions
Personalization actions — what your campaigns do: render HTML, show a popup, send an email, push a notification, etc. Read-only over REST today (create/edit through the GUI).
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Columns
| Column | Notes |
|---|---|
id |
Primary key. |
version_tag |
production or testing. |
name |
Action display name. |
type_id |
The action type (HTML / popup / email / push / …). Resolved from the underlying action_js_id. |
placeholders |
JSON array of placeholder IDs the action targets. |
content_type |
Mime / kind of content (from actions_js). |
content_param |
Name of the JS-param key whose value is the renderable content. |
content_begin |
Computed: opening fragment of the rendered content (after wrapper substitution). |
content_end |
Computed: closing fragment. |
presenting_rules |
JSON: timing / frequency rules. |
libs_app |
App libraries the action depends on. |
Examples
# All production actions
curl 'https://api:KEY@app.personyze.com/rest/actions
/where/version_tag=production
/columns/id,name,type_id,placeholders'
# One action's full content
curl 'https://api:KEY@app.personyze.com/rest/actions/where/id=42
/columns/id,name,content_type,content_param,content_begin,content_end'
conditions
Audience conditions — the when of campaigns. Read-only over REST.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Columns
| Column | Notes |
|---|---|
id |
Primary key. |
name |
Condition display name. |
Examples
# All tracker/offline conditions
curl 'https://api:KEY@app.personyze.com/rest/conditions/limit/1000'
placeholders
Containers of type placeholder — DOM slots where actions render content. Manage the catalog of placeholders defined for your site.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Columns
| Column | Notes |
|---|---|
id |
Primary key. |
name |
Display name. |
html_id |
DOM selector / id where the placeholder mounts. |
units_count_max |
Max number of action-units that can fill this placeholder. Default 1. |
Examples
# All placeholders
curl 'https://api:KEY@app.personyze.com/rest/placeholders'
# One
curl 'https://api:KEY@app.personyze.com/rest/placeholders/14'
# Create
curl -X POST 'https://api:KEY@app.personyze.com/rest/placeholders' \
-H 'Content-Type: application/json' \
-d '{"name":"Hero banner","html_id":"#hero","units_count_max":1}'
# → 88
# Update
curl -X PUT 'https://api:KEY@app.personyze.com/rest/placeholders/88' \
-H 'Content-Type: application/json' \
-d '{"units_count_max":3}'
# → 1
# Delete
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/placeholders/88'
# → 1
container_types='placeholder', so other container types (e.g. “grab variable”) aren’t visible from this endpoint — see containers_grab_variable.containers_grab_variable
“Grab variable” containers — pull DOM/JS values from the visitor’s page back into the visitor profile. Each container says “watch this variable / DOM element; when it appears, capture it as a profile field.”
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Columns
| Column | Notes |
|---|---|
id |
Primary key. |
name |
Display name. |
is_active |
1 / 0. |
variable_path |
DOM path or JS expression to grab. |
mask |
Optional regex/template applied to the grabbed string. |
constant_value |
Optional fallback / forced value. |
watch_variable |
Re-grab whenever the variable changes (1 / 0). |
profile_column |
Profile column the value is written to. |
Examples
# All grab-variable containers
curl 'https://api:KEY@app.personyze.com/rest/containers_grab_variable'
# Create
curl -X POST 'https://api:KEY@app.personyze.com/rest/containers_grab_variable' \
-H 'Content-Type: application/json' \
-d '{"name":"Cart total",
"variable_path":"window.dataLayer[0].cart.total",
"mask":"^([0-9.]+)$",
"watch_variable":1}'
# → 153
# Update
curl -X PUT 'https://api:KEY@app.personyze.com/rest/containers_grab_variable/153' \
-H 'Content-Type: application/json' \
-d '{"is_active":0}'
# Delete
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/containers_grab_variable/153'
products
Product catalog. Each row is one SKU. Column names are dynamic — beyond the documented housekeeping columns, you can store any custom fields your catalog needs.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Identifying / housekeeping columns
| Column | Notes |
|---|---|
id |
Primary key. Auto-assigned. |
internal_id |
Your SKU / external identifier. |
data_last_modified |
Unix seconds. |
is_in_stock |
'yes' / 'no' enum (not 1/0). |
Common product fields (custom)
title, description_short, description_long, price, sale_price, image_big_url, image_medium_url, image_small_url, cart_url, brand, manufacturer, category, inventory, expiration_date, size, color, rank, is_new, age_from, age_to, available_location, not_available_location, etc. The actual field set depends on your account configuration.
Renamed inputs (on POST / PUT)
| Input | Stored as |
|---|---|
image_1 |
image_big_url |
image_2 |
image_medium_url |
image_3 |
image_small_url |
Examples
# In-stock products in a category
curl 'https://api:KEY@app.personyze.com/rest/products
/where/category=tools&is_in_stock=yes
/columns/id,internal_id,title,price,inventory
/order_by/title
/limit/100'
# Lookup by internal_id
curl 'https://api:KEY@app.personyze.com/rest/products/where/internal_id=SKU-1234'
# Insert (or "patch" — duplicate internal_id will UPDATE rather than fail)
curl -X POST 'https://api:KEY@app.personyze.com/rest/products' \
-H 'Content-Type: application/json' \
-d '{"internal_id":"SKU-1234",
"title":"Cordless Drill",
"price":129.99,
"is_in_stock":"yes",
"image_1":"https://cdn.example.com/big.jpg"}'
# → 51234
# Update by internal_id
curl -X PUT 'https://api:KEY@app.personyze.com/rest/products/where/internal_id=SKU-1234' \
-H 'Content-Type: application/json' \
-d '{"price":119.99,"is_in_stock":"no"}'
# Delete
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/products/where/internal_id=SKU-1234'
POST does patch-on-duplicate: an existing internal_id updates the row instead of failing. For bulk import from a feed URL, use scheduled feed sync via the Personyze GUI rather than per-row REST calls.articles
Article catalog (blog posts, news, knowledge-base entries). Same shape as products but for editorial content.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Identifying / housekeeping columns
| Column | Notes |
|---|---|
id |
Primary key. Auto-assigned. |
internal_id |
Your external identifier (slug, CMS id). |
data_last_modified |
Unix seconds. |
is_published |
'yes' / 'no' enum. |
Common article fields (custom)
title, description_short, description_long, image_big_url, image_medium_url, image_small_url, author, publish_date, category, tags, rank, etc. The actual list depends on your site’s other_columns_info config.
Renamed inputs
| Input | Stored as |
|---|---|
image_1 |
image_big_url |
image_2 |
image_medium_url |
image_3 |
image_small_url |
Examples
# Recent published articles
curl 'https://api:KEY@app.personyze.com/rest/articles
/where/is_published=yes
/columns/id,internal_id,title,author,publish_date
/order_by_desc/publish_date
/limit/100'
# Lookup by internal_id
curl 'https://api:KEY@app.personyze.com/rest/articles/where/internal_id=how-to-personalize'
# Insert
curl -X POST 'https://api:KEY@app.personyze.com/rest/articles' \
-H 'Content-Type: application/json' \
-d '{"internal_id":"how-to-personalize",
"title":"How to personalize your site",
"author":"Alice",
"is_published":"yes",
"image_1":"https://cdn.example.com/big.jpg"}'
# Update
curl -X PUT 'https://api:KEY@app.personyze.com/rest/articles/where/internal_id=how-to-personalize' \
-H 'Content-Type: application/json' \
-d '{"is_published":"no"}'
# Delete
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/articles/where/internal_id=how-to-personalize'
POST does patch-on-duplicate (same as products). For tracking visitor interactions on articles (viewed / commented / liked), use do with the Article … commands — there’s no dedicated REST object today.products_interactions
Log of interactions on products: views, adds-to-cart, purchases, “favorite,” “delivered.” Append-mostly. Backed by an archive table.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ |
Columns
| Column | Notes |
|---|---|
user_id |
FK → users.user_id. Indexed. |
product_internal_id |
FK → products.internal_id. Leading column of a composite index [product_internal_id, user_id, transaction_time]. |
quantity |
Default 1 on insert. |
status |
One of viewed, delivered, extra (≈ added-to-cart), favorite, goal (purchase). Indexed. |
action_id |
If the interaction was attributed to a Personyze action, its ID. Otherwise null. |
transaction_time |
Unix seconds — order/transaction time. |
time |
Unix seconds — when the row was logged. Indexed. |
amount |
Monetary value (per the site’s currency settings). |
Insert: identifying the user
POST accepts any one of these to identify the user:
| Field | Resolves to |
|---|---|
user_id (numeric) |
Direct PK lookup. |
user_internal_id |
user_id of the user with that internal_id. Auto-creates a stub users row if missing. |
user_email |
user_id of the user with that email. Auto-creates if missing. |
Examples
# All purchases in a window, paged
curl 'https://api:KEY@app.personyze.com/rest/products_interactions
/where/status=goal&time>1730000000
/order_by_desc/time
/limit/1000'
# A specific user's history with a product
curl 'https://api:KEY@app.personyze.com/rest/products_interactions
/where/product_internal_id=SKU-1234
/columns/user_id,status,quantity,amount,transaction_time'
# Log a purchase
curl -X POST 'https://api:KEY@app.personyze.com/rest/products_interactions' \
-H 'Content-Type: application/json' \
-d '{"user_internal_id":"acct-987",
"product_internal_id":"SKU-1234",
"quantity":2,
"status":"goal",
"transaction_time":1734000000,
"amount":259.98}'
# Delete by composite key
curl -X DELETE 'https://api:KEY@app.personyze.com/rest/products_interactions
/where/user_id=5712334&product_internal_id=SKU-1234&status=viewed'
Indexed columns
user_id, [product_internal_id, user_id, transaction_time], status, time. Queries without a where on one of these (or order_by on the same) are rejected as full-table scans.
events
Generic event log — one row per tracked event captured by the JS tracker, SDK, or do endpoint. Read-only over REST today.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Columns
| Column | Notes |
|---|---|
id |
Primary key. |
user_id |
FK → users.user_id. Indexed. |
time |
Unix seconds. |
visit_id |
FK → visit row. |
container_id |
FK → containers.id (the source of the event). Indexed. |
container_types |
The container’s type (click event, submit event, etc.). |
value |
Event payload string. |
first_visit_id |
First visit_id of the session. |
session_start_time |
Unix seconds. |
Examples
# Recent events for a user
curl 'https://api:KEY@app.personyze.com/rest/events
/where/user_id=5712334
/order_by_desc/time
/limit/100'
# Events from a specific container in a window
curl 'https://api:KEY@app.personyze.com/rest/events
/where/container_id=1234&time>1730000000&time<1731000000
/columns/id,user_id,time,value
/order_by_desc/time
/limit/1000'
id, user_id, container_id, …) or the request is rejected. For aggregated KPIs over time, use summary_actions instead — it has pre-computed daily counters per action.forms
Form-submission log. One row per form-submit event captured by the tracker. Read-only over REST today.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Columns
| Column | Notes |
|---|---|
user_id |
FK → users.user_id. Indexed. |
time |
Unix seconds. |
action_id |
Personyze action that triggered/owned this form, if any. |
session_start_time |
Unix seconds. |
plus data (JSON) |
The submitted form payload, packed as JSON. Read inline (its keys appear as columns in the response). |
The data JSON is automatically expanded into top-level keys on read — request specific custom fields by name.
Examples
# Submissions for a user
curl 'https://api:KEY@app.personyze.com/rest/forms
/where/user_id=5712334
/order_by_desc/time
/limit/100'
# Submissions tied to a specific action
curl 'https://api:KEY@app.personyze.com/rest/forms
/where/action_id=42&time>1730000000
/columns/user_id,time,email,name,message
/limit/1000'
Indexed columns include user_id, action_id, and time. Queries must filter on one of these.
do
Fire-and-forget command dispatcher: send a single user-profile update or interaction event without speaking the tracker protocol. The body is an array of commands; each is dispatched independently.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| — | ✅ | — | — |
Request shape
[
[<key-type>, <key-value>, <command>, <arg1>, <arg2>, ...],
[<key-type>, <key-value>, <command>, <arg1>, <arg2>, ...],
...
]
<key-type>:"user_id","internal_id", or"email". Optional — omit for commands that don’t target a user.<key-value>: the corresponding identifier.<command>: a string (case-insensitive). See list below.<arg…>: command-specific positional arguments.
A successful POST returns nothing; failures throw (the whole batch aborts on the first error).
Commands
User profile
["internal_id", "acct-987", "User profile", "first_name", "Alice", "custom_t_1", "VIP"]
After the command name, the args alternate field, value, field, value, …
Product interactions
["internal_id", "acct-987", "Product viewed", "SKU-1234"]
["internal_id", "acct-987", "Product added to cart", "SKU-1234", "quantity", 2]
["internal_id", "acct-987", "Product liked", "SKU-1234"]
["internal_id", "acct-987", "Product purchased", "SKU-1234", "quantity", 2, "amount", 259.98]
["internal_id", "acct-987", "Product removed from cart","SKU-1234"]
["internal_id", "acct-987", "Product unliked", "SKU-1234"]
After the SKU, optional key-value pairs: "quantity", "amount", "action_id", "transaction_time".
Article interactions
["email", "alice@example.com", "Article viewed", "how-to-personalize"]
["email", "alice@example.com", "Article liked", "how-to-personalize"]
["email", "alice@example.com", "Article commented","how-to-personalize"]
["email", "alice@example.com", "Article unliked", "how-to-personalize"]
["email", "alice@example.com", "Article goal", "how-to-personalize"]
Examples
# Tag a user as VIP
curl -X POST 'https://api:KEY@app.personyze.com/rest/do' \
-H 'Content-Type: application/json' \
-d '[["internal_id","acct-987","User profile","custom_t_1","VIP","first_name","Alice"]]'
# Log a purchase + a profile update in one round-trip
curl -X POST 'https://api:KEY@app.personyze.com/rest/do' \
-H 'Content-Type: application/json' \
-d '[
["email","alice@example.com","Product purchased","SKU-1234","quantity",2,"amount",259.98],
["email","alice@example.com","User profile","customer_segment","loyal"]
]'
internal_id / email) auto-create a stub users row if no user matches. For high-throughput interaction logging, prefer products_interactions (typed and indexed) or the SDK’s batched event API.coupons
Records codes of your coupons used at a checkout the tag did not see — your own order system, a till, a coupon engine’s callback — as redemptions: POST /rest/coupons/redeemed (or /rest/coupons). See Coupon Codes.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| — | ✅ | — | — |
Request shape
{"code": "SPRING-K7Q2MX", "time": 1790000000, "email": "ann@example.com", "order": "#1001"}
Or several at once: {"redemptions": [ … ]}, at most 500. Only code is required; time is unix seconds (default: now), email finds the shopper and order is kept with the use. The answer: recorded, already, unknown and unknown_codes.
Privacy: privacy-person, privacy-export, privacy-delete
Answer a person’s request to see or delete their data from your own systems: a privacy tool (OneTrust, Transcend, DataGrail), Zapier, Make, n8n or a script. These three objects do exactly what Settings → Data & privacy → Visitor requests does, and every call is written to its Request log, with the source API and the key’s fingerprint.
| Object | Method | Body | Answer |
|---|---|---|---|
privacy-person |
POST; also GET /where/email=… or /where/user_id=… |
q, by |
Every profile that matched, what it matched by, and a count per store. |
privacy-export |
POST | q, by, user_ids |
The export file itself, ready to hand to the person. A store with more than 1,000 rows for the person includes the first 1,000. |
privacy-delete |
POST | q, by, user_ids, suppress |
The receipt: what was deleted, what was kept and why, and what a deletion does not reach. |
privacy_person, privacy_export and privacy_delete work too. Send the person in a POST body rather than in the URL: URLs are written to access logs along the way. Personyze keeps neither the body nor the person’s address in its own REST logs for these objects.
Which key
Your account’s API key, from Settings → Integrations → Full-featured API — the key Zapier, Make and n8n connect with (see Authentication). A key issued for an integration — WordPress, Segment, Shopify or Magento — is refused with 403: it was issued to send data in, not to find or delete people.
Fields
| Field | Notes |
|---|---|
q |
Required. The person: an email address, a CRM id or a visitor id. For privacy-delete it is also the confirmation the panel asks you to type. |
by |
any (default) — the profile’s email, its CRM id, or its visitor id when q is a number; email — the profiles whose email address it is, never a CRM id that happens to be the same text; user_id — that one visitor id. About half of all visitor ids are negative: send the minus sign. |
user_ids |
Optional. Only these profiles, from the userIds that privacy-person returned; each must still match q. |
suppress |
privacy-delete only. Default true: the address goes on your suppression list, so a later import or CRM sync cannot email the person as a stranger. With false it is still added when the person had unsubscribed. |
user_ids, privacy-delete deletes every profile q matches at that moment. A deletion cannot be undone.Examples
# Who is this person, and what do we hold?
curl -X POST 'https://api:KEY@app.personyze.com/rest/privacy-person' \
-H 'Content-Type: application/json' \
-d '{"q":"ann@example.com"}'
# Everything held about one visitor id, as a file
curl -X POST 'https://api:KEY@app.personyze.com/rest/privacy-export' \
-H 'Content-Type: application/json' \
-d '{"q":"-1234567890","by":"user_id"}'
# Delete the profiles whose email address it is
curl -X POST 'https://api:KEY@app.personyze.com/rest/privacy-delete' \
-H 'Content-Type: application/json' \
-d '{"q":"ann@example.com","by":"email"}'
The receipt
privacy-delete answers with deleted (store by store, with counts), kept (the suppression list, soft bounces and SMS STOPs, kept so the person is never emailed or texted again), notReached (files exported earlier, your own import files, copies already sent to connected tools, report totals), requestId (the Request log row) and unfinished. Meeting bookings and orders lose their personal details and stay in your reports.
A deletion has a time budget of about 45 seconds. A person with years of visits may not be finished within it: then unfinished names the stores left. What was deleted stays deleted and logged — send the same request again until unfinished is empty.
Errors
| Status | When |
|---|---|
400 |
q is missing; by, user_ids or suppress is malformed; by: "user_id" with a q that is not a visitor id; or a profile in user_ids no longer matches q. |
401 |
The key is wrong or was revoked. |
403 |
The key was issued for an integration, or the request carries no API key. |
Full reference, with answer samples: REST privacy objects.
sessions_archive
One row per visitor session (a contiguous window of activity). Backed by the long-lived archive table — much wider than events, with location, device, screen, and browser metadata.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Identifying / housekeeping
| Column | Notes |
|---|---|
first_visit_id |
Primary key. The id of the first visit row in this session. |
user_id |
FK → users.user_id. Indexed. |
session_start_time |
Unix seconds. |
last_session_time |
Unix seconds. |
session_counter |
Which session number for this user (1, 2, 3, …). |
total_visits |
Pages viewed in the session. |
time_in_focus |
Seconds the tab was actually focused. |
time_total |
Seconds from start to last activity. |
Geo / locale / device
| Column | Notes |
|---|---|
time_zone |
Visitor’s TZ offset (hours). |
country_code, region_code, city |
Geo (from IP). city is joined from the shared lookup, so it’s a human-readable name (null if no match). |
lang_0, lang_1, lang_2 |
First three Accept-Language entries. |
screen_width, screen_height, screen_depth |
Pixels / bit-depth. |
Engagement counters
| Column | Notes |
|---|---|
total_goal_value, total_n_goals |
Goal aggregates for the session. |
page_click, page_right_mouse, page_key_up, page_scroll |
Per-event counts. |
Landing URL & referrer
| Column | Notes |
|---|---|
url_prefix, url_host_port, url_path, url_query, url_fragment |
First-page URL of the session, split into parts. url_prefix is the scheme+www encoding. |
referrer_prefix, referrer_host_port, referrer_path, referrer_query, referrer_fragment |
Same shape, for the referrer. |
referrer_type |
Numeric tag (search / social / direct / …). |
search_word |
Search query when arriving via a search engine. |
UTM / ad campaign
ad_campaign, ad_source, ad_medium, ad_term, ad_content — the standard UTM parameters as captured on landing.
Examples
# Sessions for a user, most recent first
curl 'https://api:KEY@app.personyze.com/rest/sessions_archive
/where/user_id=5712334
/columns/first_visit_id,session_start_time,total_visits,country_code,city
/order_by_desc/session_start_time
/limit/100'
# Single session by primary key
curl 'https://api:KEY@app.personyze.com/rest/sessions_archive
/where/first_visit_id=900000000123
/columns/user_id,session_start_time,total_visits,total_goal_value'
Indexed columns: first_visit_id, user_id, plus several others. Queries must filter on an indexed column or the request is rejected as a full-table scan.
user_interests
Per-user interests, categories, tags, and family/cross/upsale tags inferred by the tracker pipeline. One row per (user_id, value, class, time). Read-only.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Columns
| Column | Notes |
|---|---|
user_id |
FK → users.user_id. Indexed. |
value |
The interest token (e.g. category name, tag, keyword). |
class |
interest, category, tag, family, cross category, upsale category. |
rank |
Float. Relevance score within the class. |
n_times |
How many times this value was observed for the user. |
time |
Unix seconds — when the interest was last updated. Indexed. |
Indexed columns: user_id, time. Queries must filter on an indexed column.
Examples
# All interests for one user, strongest first
curl 'https://api:KEY@app.personyze.com/rest/user_interests
/where/user_id=5712334
/columns/value,class,rank,n_times,time
/order_by_desc/rank
/limit/100'
# Only categories, recently updated
curl 'https://api:KEY@app.personyze.com/rest/user_interests
/where/user_id=5712334&class=category
/order_by_desc/time
/limit/50'
products_stats_*
Per-product aggregated interaction counters maintained by the offline summary pipeline. Six rolling windows are exposed at separate paths — pick the one that matches your reporting horizon. All share the same column shape and indices; only the time window differs.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Endpoints
| Path | Window |
|---|---|
/rest/products_stats_1day |
last 1 day |
/rest/products_stats_2day |
last 2 days |
/rest/products_stats_4day |
last 4 days |
/rest/products_stats_week |
last 7 days |
/rest/products_stats_recent |
recent (rolling — pipeline-defined) |
/rest/products_stats_all |
lifetime |
Identifying
| Column | Notes |
|---|---|
internal_id |
Primary key. The product’s external identifier (catalog SKU / id you provided). Indexed. |
Per-product counters (count of interactions on this product within the window)
| Column | Notes |
|---|---|
n_viewed |
Number of view events. Indexed. |
n_delivered |
Number of recommendations delivered (shown). Indexed (composite with n_viewed). |
n_extra |
“Extra” interactions (e.g. add-to-cart). Indexed (composite with n_viewed). |
n_favorite |
Favorited / wishlisted. Indexed (composite with n_viewed). |
n_goal |
Goal completions (purchases). Indexed (composite with n_viewed). |
Catalog-wide distribution stats
The same value on every row — describes the whole catalog within this window. For each metric M ∈ {viewed, delivered, extra, favorite, goal}:
| Column | Notes |
|---|---|
overall_n_<M> |
Sum across all products. |
overall_avg_<M> |
Mean across all products. |
overall_avg_nonzero_<M> |
Mean across products that had at least one event. |
percentile_<M> |
This row’s percentile rank for the metric. |
Last 3 goal users (most recent purchasers of this product)
| Column | Notes |
|---|---|
last_goal_user_id_0, last_goal_user_id_1, last_goal_user_id_2 |
Indexed individually. |
last_goal_user_time_0, last_goal_user_time_1, last_goal_user_time_2 |
Unix seconds. |
Indexed columns
internal_id, n_viewed, n_delivered, n_extra, n_favorite, n_goal, last_goal_user_id_0, last_goal_user_id_1, last_goal_user_id_2. Queries must filter on (or order_by) one of these.
Examples
# Top 50 most-viewed products this week
curl 'https://api:KEY@app.personyze.com/rest/products_stats_week
/where/n_viewed>0
/columns/internal_id,n_viewed,n_delivered,n_extra,n_goal,percentile_viewed
/order_by_desc/n_viewed
/limit/50'
# Lookup one product's lifetime stats
curl 'https://api:KEY@app.personyze.com/rest/products_stats_all
/where/internal_id=SKU-12345'
# What a specific user purchased recently (matches against last 3 goal users)
curl 'https://api:KEY@app.personyze.com/rest/products_stats_recent
/where/last_goal_user_id_0=5712334
/columns/internal_id,n_goal,last_goal_user_time_0'
summary_actions
Daily aggregated KPIs per action — one row per (day, action_id) for actions bound to a specific campaign (condition_id). Read-only.
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
day is indexed. Every request must include where/day… — there’s no order_by-only escape hatch.Identifying
| Column | Notes |
|---|---|
day |
Unix timestamp (seconds) of 0:00 (12 AM) of the day on Greenwich (GMT+0000). |
action_name |
Action name. |
action_id |
Action ID. |
campaign_name |
Campaign name to which the action belongs. |
campaign_id |
Campaign ID to which the action belongs. |
Action exposure
| Column | Notes |
|---|---|
n_executed |
How many times executed (actions are considered executed even if the actual visual content is not yet shown). |
n_delivered |
How many times we received feedback from the browser page that the content became visible. |
n_extra |
Depends on action type. For HTML actions: number of clicks. For form actions: number of submissions. |
n_failed |
Only counted for email actions. How many times sending an email failed (e.g. invalid address). |
n_closed |
How many times the user clicked the “close” button after the action content became visible. |
n_sessions_executed |
In how many distinct sessions there was at least one n_executed for this action. |
n_sessions_delivered |
In how many distinct sessions there was at least one n_delivered. |
n_sessions_extra |
In how many distinct sessions there was at least one n_extra. |
n_sessions_failed |
In how many distinct sessions there was at least one n_failed. |
n_sessions_closed |
In how many distinct sessions there was at least one n_closed. |
Product attribution (when this action recommended products)
| Column | Notes |
|---|---|
products_goal_n_times |
How many products (across all visitors) reached “purchased” during a session in which this action was executed. Counts every product purchase event, so a single order with 3 items adds 3. |
products_goal_n_sessions |
In how many distinct sessions at least one product was purchased after this action was executed. |
products_goal_value |
Sum of monetary values of all purchased products counted in products_goal_n_times. |
products_recom_viewed_n_times |
How many times a product that this action recommended was subsequently viewed. |
products_recom_viewed_n_sessions |
In how many distinct sessions at least one recommended product was viewed. |
products_recom_extra_n_times |
How many times a recommended product was subsequently added to cart (or otherwise reached the “extra” interaction). |
products_recom_extra_n_sessions |
In how many distinct sessions at least one recommended product reached the “extra” interaction. |
products_recom_extra_value |
Sum of monetary values of all “extra”-interacted recommended products. |
products_recom_goal_n_times |
How many times a recommended product was subsequently purchased. |
products_recom_goal_n_sessions |
In how many distinct sessions at least one recommended product was purchased. |
products_recom_goal_value |
Sum of monetary values of all purchased recommended products. |
Article attribution
Same shape as product attribution but for articles: articles_recom_viewed_n_times, articles_recom_viewed_n_sessions, articles_recom_extra_n_times, articles_recom_extra_n_sessions, articles_recom_extra_value, articles_recom_goal_n_times, articles_recom_goal_n_sessions, articles_recom_goal_value.
Per-account custom goal events
An account can configure up to 12 goal events. For every event container configured in your account with a non-zero goal_event_index (N from 1 to 12), four extra columns appear in the response:
goal_event_N_name— Display name of the configured goal event. Returned as a literal string, the same on every row.goal_event_N_n_times— How many times this goal event fired during a session in which the action was executed.goal_event_N_n_sessions— In how many distinct sessions this goal event fired at least once after the action was executed.goal_event_N_value— Sum of monetary values reported for this goal event across the times counted ingoal_event_N_n_times(zero unless the goal-event container is configured to capture a value).
Examples
# Last 30 days, daily KPIs per action
curl 'https://api:KEY@app.personyze.com/rest/summary_actions
/where/day>1730000000
/columns/day,action_name,n_executed,n_delivered,n_extra,products_goal_value
/order_by_desc/day
/limit/1000'
# A specific action's lifetime
curl 'https://api:KEY@app.personyze.com/rest/summary_actions
/where/action_id=42&day>1700000000
/order_by/day
/limit/1000'
tracker_code
Returns the JS snippet you embed in your site to bootstrap the Personyze tracker. The contents are derived from your account’s settings (account ID, tracking host, async/no-hide flags).
| GET | POST | PUT | DELETE |
|---|---|---|---|
| ✅ | — | — | — |
Response
A plain text/html (or JS-in-<script>) snippet ready to paste into a <head>. The body is not JSON — this is the one REST endpoint that returns raw HTML.
Example
curl 'https://api:KEY@app.personyze.com/rest/tracker_code'
<script>(function(s){
s.async = true;
s.src = '//lcounter.personyze.com/stat-track-lib.js';
s.onload = function() {
_S_T.async = true;
_S_T.setup(5919, "example.com www.example.com");
};
(document.querySelector('head') || document.documentElement).appendChild(s);
}(document.createElement('script')))</script>
Next steps
where/columns/order_by/limit with all operators and examples. Read →