How it works
What happens between the editor and your visitor's browser, what Miniwall does and does not do, and what data it collects.
This page follows one screen from the editor to a visitor's browser. It also states plainly what Miniwall leaves to you.
Miniwall renders. It does not charge.
Miniwall draws screens and measures what visitors do with them. It does not process payments, hold prices or manage a product catalog.
- Prices come from your website. You pass a price for each package ID. Miniwall fills them into the screen text.
- Checkout is yours. When a visitor taps a buy button, the SDK calls your
onPurchasefunction with the package ID. You run Stripe, Paddle or your own backend, then tell the SDK whether it worked. - Miniwall plans are priced by views. Miniwall never takes a share of your revenue. See Plans and billing.
The three parts
| Part | What it does |
|---|---|
| Dashboard | Where you build screens in the visual editor, configure placements, read analytics and manage your team. |
| API | Stores your screens, versions, placements and events. It serves published screens to the SDK and checks every dashboard action against your role and plan. |
| Web SDK | A small script on your website. It fetches the published screen for a placement, draws it, runs your checkout and sends view events back. |
A screen is JSON
The editor saves each screen as a JSON document, the same format the SDK draws. It has three main parts:
default_locale the language used when no other matches, for example en_US
components_config
base the layout tree: stacks, text, images, plan cards, buttons
components_localizations
en_US every piece of text, by languageYou never edit this by hand. You can still download it: on the Screens page, open a card's menu and choose Download JSON.
Things that decide how and when a screen shows are not in the JSON. Format, trigger, audience, A/B test and schedule belong to the placement. That is why one screen can be a popup in one place and a banner in another.
From publish to the visitor
You publish
Publishing runs the same checks the editor runs, on the server, so a broken screen can never reach your site. If a check fails, the API refuses with a message that starts Cannot publish:. The checks are described in Validation.
Your site asks for a placement
The SDK sends a read-only request with your public key, for example GET /v1/sdk/placements/upgrade_button. Only published versions are ever returned. The answer holds the screen JSON, its package IDs, and the placement's display, trigger, audiences, frequency cap and holdout. If an A/B test is running, it holds both sides. The full shape is in the public API reference.
The SDK decides what to show
Audiences, the frequency cap, the holdout and the A/B split are applied in the visitor's browser. The attributes your site passes in for audiences never leave the browser. See Core concepts for the order of decisions.
The SDK draws the screen
The SDK renders the layout, fills in {{ product.* }} text from the prices you passed, and picks the visitor's language and light or dark mode. It sends a view event.
The visitor acts
Taps on a buy button call your onPurchase. Buttons set to Run your code call your onAction with the action ID you chose in the editor. Go to screen buttons load the next screen of a flow. Closing the screen sends a close event.
Speed and reliability
- Delivery responses are cached at the edge for about 30 seconds, so a new publish reaches visitors within about a minute.
- The SDK keeps its own copy of each response in the browser and revalidates it with an ETag. If the network fails, or the server answers with an error in the 500 range, it shows the last copy it saw.
- If the API takes longer than 8 seconds, the SDK gives up and uses the last copy, or reports an error. You can change this with the
timeoutMsoption. - The SDK never blocks your page on analytics. Events are sent in the background.
What Miniwall collects
For each screen event, Miniwall stores:
| Field | Meaning |
|---|---|
| Event type | One of view, close, purchase_click, purchase, purchase_cancel, purchase_error, restore, action, holdout, holdout_purchase, answer |
| Screen, version and placement | Which published screen was shown and where |
| Package ID | For purchase events, the plan the visitor chose |
| Action ID | For button presses on Run your code buttons |
| Field ID and option ID | For answers to choice questions, the IDs you set in the editor |
| Experiment and side | When an A/B test picked the screen |
| Visitor ID | A random ID the SDK keeps in the browser to count unique visitors |
| Time | When the event happened |
What Miniwall does not collect
- Visitor attributes. What you pass as
attributes(a plan name, a country) is used in the browser to pick an audience. It is never sent to Miniwall and never saved in events. - Typed text. Text a visitor types into a text field is never sent. Your own code receives it in
answers. Only chosen option IDs are counted. - Identity. The visitor ID is a random value, not an account ID or email. It is kept in the browser's local storage, so a cleared browser looks like a new visitor.
- Payment details. They never pass through Miniwall.
The SDK keeps a few things in the browser: the visitor ID, counters for the frequency cap (session storage and local storage), the last copy of each delivery response, and a pending purchase marker that lets reportPurchase find the right screen later. To stop events completely, call configure with analytics set to false. Frequency caps still work. See Events and privacy.
What counts as a view
One screen shown on your site is one view. Views are counted per calendar month in UTC against your plan. Previews from the dashboard and shared preview links are not counted. Placements that show nothing because of a frequency cap, an audience set to show nothing, or a holdout are not counted either.
If a month's views run out, your screens keep showing. See Plans and billing for what pauses and when.