Personyze Wiki Personyze Wiki docs
Open Personyze
Docs/ Developer Resources/ Server-side personalization and A/B testing
Developer Resources

Server-side personalization and A/B testing

Personyze is usually installed as a JavaScript snippet: it loads in the visitor’s browser, decides what to show, and renders it in the page. That is the right…

5 min read Updated 18 hours ago

Personyze is usually installed as a JavaScript snippet: it loads in the visitor’s browser, decides what to show, and renders it in the page. That is the right choice for most sites.

But the same decision engine answers over HTTP, so your own server can ask “what should this visitor see?” and render the answer itself. Nothing loads in the browser, and the page arrives already personalized.

Is this for you?

Use server-side personalization when:

  • You render pages on the server and don’t want the brief flash of default content before personalization applies. A server-rendered variant is simply the page — there is nothing to swap and nothing to hide.
  • You want to A/B test something invisible. A different ranking algorithm, a different price, a different API response. There is no element on the page to change, so a visual tool has nothing to work with.
  • There is no browser. A native app, a kiosk, a set-top box, an email pipeline, a support tool. Anything that can make an HTTPS request can be personalized.
  • The snippet is blocked. Ad blockers, strict content-security policies and corporate proxies all stop third-party scripts. A server-side call is your server talking to ours.

Stay with the browser snippet when you’re personalizing visible page elements on an ordinary website and want to build campaigns in the visual editor without involving a developer. You can also do both: server-side calls and browser sessions share one visitor profile and one A/B assignment, as long as both identify the person the same way.

How it works

One HTTPS endpoint does everything. You tell Personyze what the visitor just did, and it tells you what should happen next:

  1. Your server calls Personyze when it is about to render something — a page, a product list, an API response.
  2. Personyze answers with action IDs: the campaigns matching this visitor right now, and what they should see.
  3. Your code decides what each ID means. Action 88 might be “show the free-shipping banner” or “use ranking algorithm B”. You map IDs to behaviour in your own code, or read the ready-made content out of the response.
  4. You tell Personyze what you did. This is what makes reporting and A/B results real.

Everything you already configure in the panel still applies: audiences, targeting rules, scheduling, A/B splits, and the reports.

Running an A/B test

Set the test up in the panel exactly as you would for an on-site test — an A/B Testing campaign, an action for each variant, and your winner criteria. For a purely server-side test the actions need no content at all: the ID alone tells your code which branch to take.

Then, in your code: call Personyze at the decision point, branch on which action ID comes back, and report the outcome.

Personyze assigns visitors to arms — you must not. It holds the assignment and keeps each visitor in the same arm across visits and across devices, so long as you identify them consistently. If your code also splits traffic, the two systems disagree about who is in which arm and the results stop meaning anything.

Two things people miss, both worth checking before you launch:

  • Report that you rendered the variant. An action you never report looks like it never ran. Its arm doesn’t lose the test — it appears to have had no traffic at all, and the test can never conclude.
  • Report the outcome in the form your winner criterion measures. A test scored on purchases is not moved by reporting clicks. Match the signal to the criterion you chose, or the arm looks like it produced nothing.

Results appear in the panel exactly as they do for on-site tests — significance, improvement over control, and the winner — and can also be read programmatically if you want them in your own dashboard.

Official libraries

You can call the endpoint directly with any HTTP client. Libraries are available for the common stacks and handle the details that are easy to get wrong — keeping the session, timing out quickly, and never letting a personalization call take down the page it personalizes:

  • Node.js / TypeScriptnpm install @personyze/node, with helpers for Express and Next.js.
  • PHPcomposer require personyze/personyze.
  • Pythonpip install personyze, with helpers for Django and Flask.

Each one is a thin wrapper around the same endpoint, so nothing is hidden from you and you can drop to raw HTTP whenever you need to.

Performance and safety

A personalization call sits in the path of a page render, so the libraries default to a 1-second timeout and fail open: if Personyze is slow or unreachable, your code gets an empty answer and renders its default. Your page never waits on us, and never breaks because of us.

The call is authenticated with an API key over HTTPS. Keep it on your server — it has full access to your account, unlike the tracker snippet, which is public by design.

What you need to get started

  1. An API key. In the panel: Settings → Integrations → Full-featured API.
  2. A stable visitor ID. Your own user ID, a device ID, a hash — anything you can reproduce for the same person next time. This is what lets someone stay in one A/B arm across visits.
  3. Somewhere to keep a session. Personyze returns a session value with every answer; give it back on the next call. Wherever you already keep session state is the right place.

Next steps

The full technical documentation — request and response formats, the command vocabulary, the A/B recipe, and a worked example — is in the developer guide: Server-side personalization and A/B testing.

If you are not sure whether server-side is right for your case, contact support and describe what you are trying to personalize; it is often a short answer.

Did this page answer your question?
Thank you — that goes to whoever maintains this page.