Platform · Decisioning

Decide what each visitor sees, at the moment they ask.

Every page you render already makes a choice — a headline, an offer, a layout. qbrix makes that choice per request, from what you know about the visitor and what your experiments have learned so far.

Incoming request
The context that travels with it.
{
id: "u_8241",
metadata.plan: "growth",
properties.device: "mobile",
properties.cart_value: 84.00,
properties.returning: true,
}
Reached the learner
in the 100% rollout · no override rule matched
The decision
Sampled from what each variant has earned so far, then served.
social-proofserved this request
76.4%6.42%Served
controlheld back
12.1%4.81%
urgency-copyheld back
8.4%4.02%
discount-badgeheld back
3.1%3.44%
qbrix.agent.select(experiment_id, context) → "social-proof"No model server

Your checkout copy was chosen in March. Every visitor since has seen the same thing. Nobody has checked if it still works.

How it works today
decided · 4 marchsocial-proof
served to everyone, every request, for 214 days
mobile · returningsocial-proof
desktop · newsocial-proof
mobile · newsocial-proof
desktop · returningsocial-proof

Every visitor, the same answer.

With qbrix
TimeWhat you sentServed
14:32:07.881mobile · returning · cart €84social-proof
14:32:07.902desktop · new · cart €19discount-badge
14:32:07.913mobile · new · cart €31discount-badge
14:32:07.940desktop · returning · cart €212urgency-copy
14:32:07.958mobile · returning · cart €67social-proof
14:32:07.971tablet · new · cart €48control
14:32:08.004desktop · returning · cart €96social-proof
14:32:08.019mobile · new · cart €23urgency-copy

A new decision every time, for the visitor in front of you.

Two calls. That is the whole integration.

Ask which version to show. Later, say what happened. Nothing else in your stack moves — same renderer, same database, same deploy.

1.0The call
const { arm, requestId } = await qbrix.select("checkout-cta", {
id: userId,
properties: { device: "mobile", cartValue: 84 },
});
render(CTA[arm.name]); // → "social-proof"
// minutes later, when they check out
await qbrix.feedback(requestId, 1.0);
What does not move
Your rendererThe variant is a name. You already have a switch on it.
Your databaseqbrix never reads or writes yours.
Your deployChanging the experiment does not ship code.
Your fallbackIf the call is slow, your default renders instead.

It answers, or your page does.

The answer comes from what qbrix already knows — there is nothing else standing between the request and the response. And if it ever takes longer than you allow, the SDK stops waiting and your own default renders.

2.0The path
On the path
Your requestone call, in your renderer
Gate checkis this visitor taking part?
What it already knowsheld in memory, kept fresh
Variant returneda name, back to you
taking longer than you allowyour default renders
Not on the path
A database round tripA model server callA cross-region hopTraining

Learning runs somewhere else entirely. The loop that makes the next decision better is never the reason this one waits.

Send qbrix the outcomes. The next decision will be better.

When the visitor converts or doesn’t, send the outcome. qbrix will learn from all your user interactions and will improve its decisions.

3.0The loop
While your page renders
You ask for a variant
You render it
The visitor decides
you send the outcome
Afterwards, out of the way
The outcome is queued
Learned from in batches
What qbrix knows is updated
Every request after this one
…is answered with what it just learned. No code change, no wait.

Why did this visitor see that?

Adaptive does not mean unaccountable. Every decision, every outcome and every change to an experiment is logged — so any single request can be read back, months later, exactly as it happened.

4.0The record
Selectionevery variant served, and what you sent with the request
Outcomeevery reward you reported back, paired to its selection
Changewho changed an experiment, a gate or a key — and when
sel_9f2a41Selection12 june · 14:32:07.881
experimentcheckout-cta
visitoru_8241
what you sentdevice = mobile · returning · cart_value = 84.00
gateinside the 40% rollout · no override rule matched
servedsocial-proof
outcomeconverted · reward 1.0 · reported 14:41:02
Kept for 90 days, filterable by experiment, visitor or request id.

Shown: the Event Log in the console.