Before you install a Boosthis kit
A Boosthis kit runs inside your own application, in your own process, on your own domain. That is a lot of trust to ask for from a README, so these are the questions an evaluation actually turns on, answered in one sitting.
Every answer below is generated from the same source the kits and the install guides read, and checks on our build fail when one of them stops matching. Nothing here is a description of the product written separately from it.
- What does it send, and what is always on?
- What can it read inside my process?
- What appears on my users' pages?
- What does it put on my own domain?
- What do I have to allow through my Content-Security-Policy?
- What key does it need, and what happens if it leaks?
- How do I know the bytes I received are yours?
- What is the first network call, and when does it happen?
What does it send, and what is always on?
Everything below goes to one place: https://www.boosthis.com/api. An install with no project key configured sends nothing at all.
Sent by every registered install, in every runtime
- A random install identifier. A UUID generated on the machine your app runs on, the first time it registers. It is not derived from, or linked to, a device, a user, an IP address, a hostname or an account.
- Buckets describing a recurring performance problem. When the same performance pattern recurs, the kit sends the kind of problem it detected, a three-level severity bucket and a coarse occurrence-count bucket. The screen or route name is deliberately dropped.
- Buckets describing when one of those problems improves. When a tracked problem gets better, the kit sends the kind of rule and the before-and-after rating bucket — good, needs-work or poor. It is the fact that something improved, never the change that improved it.
- Error types with a redacted code location. When your app hits an uncaught error, the kit sends the error type, a redacted code location (function name, file basename and line number — never a path, URL, argument or value), a hash derived only from those code-defined tokens, and how many times it recurred.
- A short-lived crash-batch fingerprint. A current kit also sends a non-readable fingerprint for each crash batch so a retry after a lost response cannot add the same occurrences twice. It is operational duplicate-suppression metadata, not customer crash history: it is excluded from customer exports, retained for no more than 30 days and 1,024 receipts per install, and erased with the install.
- Anonymous notes about patterns we have no rule for yet. When the kit meets a slow or buggy pattern it has no rule for, it may send the runtime, a coarse category, a severity bucket, a timing bucket, a hash and a recurrence count. Buckets and a hash — never a screen name, a value or your source.
- The kit version and the runtime it runs in. For example, the Boosthis package version together with the language runtime, so a reading can be interpreted against the version that took it.
- The version of your own application. On a phone, the kit reads the version your app was built with — CFBundleShortVersionString on iOS, versionName on Android — and sends it alongside the Boosthis version, never merged into it, so a reading can be attributed to the release of YOUR app it came from. It is the version string you ship and nothing else: not the build's contents, not its signing identity, not a build number, not anything about the device.
- The names of scheduled jobs, and how each run went. If your app runs work on a schedule, the kit sends the job's name as written in your source, how long each run took, whether it succeeded, and — if your code states one — how often it should run. Never an argument, a payload, a result, a log line or anything the job touched.
Only because you switched it on
- If you switched on full performance details. Off unless your code calls enableTelemetry(). It stops the moment you call disableTelemetry(). Search your own source for enableTelemetry (or enable_telemetry). If it is not called, these per-route fields are not being sent. (The meter snapshot below has a second switch of its own, so check that separately.)
- If you switched on the page map, and full details or meter sharing is on. Off unless your own code asks for it — sendPageMap: true in the kit's options, and nothing we send back can turn it on. With it on, the map travels with the meter snapshot, so it also needs one of that snapshot's two switches: your code calling enableTelemetry(), or you switching on meter sharing for that project. disableTelemetry(), erasing the install, and BOOSTHIS_DISABLED=1 each stop it. Search your own source for sendPageMap. If it is not there, no map is being sent, whatever else is on. If it is, check the same two switches as for the meter snapshot: enableTelemetry (or enable_telemetry) in your source, and meter sharing on the project in your Boosthis dashboard — with sendPageMap on, either of those means the map is being sent.
- If full performance details OR meter sharing is switched on. Either switch uploads it: your code calling enableTelemetry(), or you switching on meter sharing for that project so a connected AI can read your live numbers. disableTelemetry(), erasing the install, and BOOSTHIS_DISABLED=1 each stop it. Two things to check, not one: search your own source for enableTelemetry (or enable_telemetry), and open the project in your Boosthis dashboard to see whether meter sharing is on. Either one on means the snapshot is being sent; only with both off is it not.
- If the route list is on (it rides the meter snapshot's switches). It travels only when the meter snapshot does — your code calling enableTelemetry(), or meter sharing switched on for that project — and it has a switch of its own on top of those: BOOSTHIS_ROUTE_LIST=0 on Node and Python, or setRouteListEnabled(false) in the browser and React Native kits. disableTelemetry(), erasing the install, and BOOSTHIS_DISABLED=1 each stop it with everything else. Two things decide it. First, is the meter snapshot being sent at all — search your source for enableTelemetry (or enable_telemetry), and check meter sharing for that project in your Boosthis dashboard. Then, if it is, open the project's map page: it names where each route came from, and says plainly when the list is switched off or when the kit could not ask your framework.
- If the control census is on (it rides the meter snapshot's switches). It travels only when the meter snapshot does — your code calling enableTelemetry(), or meter sharing switched on for that project — and it has a switch of its own on top of those: setControlCensusEnabled(false) in the browser and React Native kits, or BOOSTHIS_CONTROL_CENSUS=0. disableTelemetry(), erasing the install, and BOOSTHIS_DISABLED=1 each stop it with everything else. Only the browser and React Native kits answer this question at all; no server-side kit has a rendered interface to ask. Open the project's map page: it states the control count for the page the latest report was taken on, and says plainly when the census is switched off, when the kit could not read the page, and when a runtime has no interface to ask.
- If you switched a project into detailed crash mode. Off unless you turn it on for a specific project from your Boosthis dashboard. Open the project in your Boosthis dashboard: detailed crash mode is a per-project setting shown there.
- If your app is a React Native app. Decided by which kit you installed, not by a setting. Only the React Native kit sends any of it. The daily reach tag rides the always-on signals. The other three are collectors the kit starts itself when your code calls enableTelemetry(), with no setting to pass, and what they measure travels only when the meter snapshot does — full performance details, or meter sharing switched on for that project. Each of those three can be refused by name: autoWrapNetwork: false, trackUnhandledErrors: false, or trackImageWeight: false. A refused reading wires nothing and its meter says it is switched off in this build. disableTelemetry(), erasing the install, and BOOSTHIS_DISABLED=1 each stop all of it with everything else. It applies if you installed the React Native kit in a mobile app; no other runtime sends it. The three the kit starts itself are on unless your own enableTelemetry() call refuses them, so read the options you pass it — search your source for enableTelemetry. The kit's own panel and the project's meters then say, for each of the three, whether it is measuring or switched off in this build.
- If you switch on the React Native screen circuit. Off unless your code passes traceScreens to enableTelemetry(). With it absent or false, the kit behaves exactly as it did before: no screen spans, no call spans and no trace header. The separate Network meter is unchanged and remains blind — it still reads no URL, host, path or status. Search the app's enableTelemetry() call for traceScreens. true records the on-device circuit without passing headers anywhere. A propagateTo list additionally names the only hosts that may receive the trace header; with no named host, no host receives it.
- The name your app registers under, and the name you type for the project. An app sends a name only if your own code or build gives it one: the field is optional, and an install that sends none is listed by its identifier instead. The project name is not sent by anything — you type it on your Boosthis dashboard, and no kit ever sees it. Both are on your dashboard: the app's name on the install's own row, the project's name at the top of the project. Search your own source or build configuration for the name you pass to the kit; if you pass none, none is sent. Renaming a project renames it for every key in its rotation line, so an app still shipping an older key reports under the new name from its next handshake.
- If a developer uploads a build map so crash frames read as source. Nothing is uploaded unless a developer does it — by hand from the project page, or by a step added to your own build. No kit fetches a build map's contents, and Boosthis never asks your build system for one; a project that has uploaded none holds none. One kit asks a question about a map rather than for its contents: the browser kit's development-posture check makes one HEAD request to your own site for the first script's .map address and keeps only whether the answer was OK, as a 1 or a 0. Nothing is downloaded, and the address is neither stored nor sent. Upload one and your crash frames resolve to your own file and line; upload none and they read as the compiled position, which is the only difference. The project page lists every build map the project holds: which release, which generated file, when it arrived and the date it ages out. An empty list means none is held right now — either none was ever uploaded, or the ones that were have aged out. Each map is kept for 90 days from the day it arrived and is then deleted; re-uploading the same release replaces the map already held rather than adding a second, and restarts that clock.
Never sent, in any mode
- IP addresses. Never as part of telemetry, and never used to identify anyone or joined to telemetry. Like nearly every web service our server does briefly count requests per connecting address for rate limiting, and keeps short-lived operational request logs; both expire automatically.
- Anything that identifies one of your users. User IDs, email addresses, names, phone numbers, postal addresses, device IDs or any other identifier. A denylist blocks them on the device and again on our server, and a batch that trips it is rejected whole.
- The contents of requests and responses. Request bodies, response bodies, query strings and headers are never collected and never sent. Reading something inside your process and collecting it are two different things, and this is the whole of the first. The one exception is the AI-call meter: to tell repeated prompts apart it reads up to the first 4,096 characters of an outbound request body to an AI provider, inside your own process, and reduces it immediately to a single number — no body text is stored, uploaded or recoverable. Eight other bounded reads work the same way — inside your own process, reduced on the spot to a number, a flag or a label from a fixed list: the same meter reads the provider's reply as it streams back, holding at most 8,192 characters of a partial line at a time, to take the token counts the provider states in it; when a provider refuses a call, the meter takes its own copy of that error reply to say which kind of refusal it was — the Python kit stops accumulating at 8,192 characters, and in Node and the browser the runtime hands the reply over as one string, of which anything longer than 8,192 characters is dropped without being examined; the leak watch reads up to the first 8,192 bytes of an ERROR response your app is about to return, to see whether a stack trace or a secret-shaped string is about to reach one of your users; in the browser, and only if you switch it on, a copy of a JSON answer to one of your app's own calls is read to see whether it is error-shaped despite its 200: the copy is taken only where the server declared a length of 65,536 bytes or less, and because a declared length can understate what arrives, the copy the browser hands back is checked again and dropped unexamined past 65,536 characters; on an MCP endpoint your app serves, up to the first 64 KB of the JSON-RPC request is mirrored as your app reads it, to take the method name out of the envelope — never the arguments, and never a byte of what the app itself receives is changed; the cookie check reads the Set-Cookie headers your app sends — at most 20 per response, and at most 2,048 characters of the attribute tail on each, which is 2,048 bytes in the kits whose strings are bytes — for the Secure, HttpOnly and SameSite flags and the size, never the name and never the value; the Cookie header your users send is not read at all; a fixed list of headers is looked up by name and turned straight into a number or a fixed label: the content type, length and encoding, the Accept header your user's browser sent, whether your reply is marked as a download (Content-Disposition), the cache instructions and validators on your app's own reply (Cache-Control, ETag, Last-Modified), the elapsed-milliseconds offset a previous instrumented hop wrote, the queue-start timestamp a proxy adds, the presence (never the value) of a reverse proxy's forwarding headers (X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto, X-Real-IP), a hosting platform's cache verdict, an AI provider's rate-limit headroom, retry delay and service-side processing time, and whether an authorization header or an authentication challenge is present — never its value, and never a header nobody named: the list is the claim, and a kit that starts reading a header outside it fails our own build before it ships; and the query values the kit reads on its way OUT are the ones in URLs the kit itself builds for its own uploads, read key by key so the guard can refuse anything identifier-shaped before it leaves your process; your app's own query strings are cut off before a route label is made and are never read. One bounded read is not a reduction at all, because what it holds is your own page on its way to your own visitor: where the dashboard bubble is switched on, an HTML page is buffered so the one script tag can be written into it — up to 2 MB, 4 MB on .NET, past which the page is passed through untouched. Those bytes are handed back with one script tag added and nothing taken from them. One read is neither narrowed to a label from a fixed list nor limited in length, because the value IS the question being asked of the kit's own endpoint: the kit's own local read endpoints — the panel and the JSON reads it serves under its own path, behind their loopback or key gate — read the query of requests made TO THEM: how many rows to return, and which route name to filter to; the row count becomes a number, the route name is compared, exactly as the caller wrote it and with no limit on its length, against the route names the kit is already holding, so a name matching none of them simply returns nothing; neither value is recorded, and no other query string in your app is read. Nothing checks it against a list first, no cap is put on how long it may be, and nothing is derived from it or kept once the reply has gone. One bounded read does not stay inside your process, and the difference is set out here rather than left to be inferred: on a request arriving at your app, the kits on your servers read two headers for their VALUE rather than for a label — the trace id and the caller's span id that another Boosthis-instrumented service of yours wrote on it. A value is taken only if it is exactly the shape the kits mint (32 hexadecimal characters for the trace, 16 for the span), and anything else is discarded, the trace id replaced with a fresh random one. An adopted id then IS that request's trace id: it is put on the hops your app makes while handling the request, and it is uploaded with that request's timings, which is the only way one action crossing several of your services can be shown as one line rather than several unrelated ones. It is the one thing read here that leaves your process, it is an identifier the kits mint and nothing is derived from it, and no other header's value is read. One read is neither bounded nor reduced to a number, and you ask for it yourself: one endpoint the Python kit's panel serves takes a POST — the rule matcher — and it reads that request's body in full, because the code you paste in IS the question being asked: it is matched against the rule book inside your own process, behind the same loopback or key gate as the rest of the panel, the answer is a list of rule names, and neither the code nor any part of it is stored, logged or uploaded. Apart from a trace id another instrumented service already put on the request, none of what is read here is stored, uploaded or recoverable from what is uploaded, and the guard on the upload path refuses outright any payload carrying a request or response body, a header, a cookie or a query value — and that id is uploaded as a field of its own, never as the header it arrived in.
- Raw stack traces, raw error messages and log lines. A crash report carries a redacted code location and an error type — and, only in detailed crash mode, a first line that passed the guard. A meter that watches logged errors records how many and how often, never the line, the message, the logger or the level.
- Anything about the processes your app spawns. Command lines, arguments, environments and output are never sent. The subprocess meter records only how many spawns happened and how often.
- The names of the things the meters count. Threads, workers, modules, handles, timers, files, pools and queues are counted, never named. A meter reports how many and how long, never which.
- Your source code. Boosthis never reads your codebase. No kit opens, scans, indexes or uploads a source file, and no source text is stored on our servers — including from a build map, whose embedded copy of your source is discarded the moment the map arrives and is never written down. What we can say about a line of your code comes from what your own build already put in a stack frame.
- Your hostnames and your environment. Hostnames and environment variables are never sent. One environment variable is read inside your own process and does not leave it: the browser kit's development-posture check reads NODE_ENV to report whether a development build is running, as a 1 or a 0, never the value. File paths are never read from your machine — with one exception, named here rather than further down the page: a build map a developer uploads keeps its own original source paths, for as long as that map is kept. Nothing else carries one. A crash frame's file is a basename, and an absolute path is cut back before it leaves the device.
- Anything your users see or say. Screen contents, screenshots, video and audio are never captured.
The field-by-field version, in the words your own privacy policy needs, is on what Boosthis collects inside your app.
What can it read inside my process?
Reading something inside your process and collecting it are two different things. The one exception is the AI-call meter: to tell repeated prompts apart it reads up to the first 4,096 characters of an outbound request body to an AI provider, inside your own process, and reduces it immediately to a single number — no body text is stored, uploaded or recoverable. Eight other bounded reads work the same way — the token counts a provider states in its reply, which kind of refusal a provider's error reply is, a stack trace or a secret about to reach one of your users, an error-shaped JSON answer returned with a 200, the method name in a tool-call request your app serves, the flags on the cookies your app sets, a fixed list of named headers and the query of the kit's own upload URLs — each reduced on the spot to a number, a flag or a label from a fixed list, and each set out with its own limit in the Privacy Policy. One bounded read is not a reduction at all — the HTML page the dashboard bubble is written into — held only long enough for the one script tag to be written in, then handed back with nothing taken from it. One read is neither narrowed to a label from a fixed list nor limited in length — the query on requests to the kit's own read endpoints — used as the caller wrote it to pick which of the kit's own rows come back, then dropped with the reply. One bounded read does not stay inside your process — a trace id another instrumented service already put on the request — adopted only when it is exactly the shape the kits mint, then carried onward and uploaded with that request's timings so one action across your services reads as one. One read is neither bounded nor reduced to a number, and you ask for it yourself: the code you post to the kit's own rule matcher. Apart from a trace id another instrumented service already put on the request, none of what is read here is stored, uploaded or recoverable from what is uploaded, and the guard on the upload path refuses outright any payload carrying a request or response body, a header, a cookie or a query value — and that id is uploaded as a field of its own, never as the header it arrived in.
What appears on my users' pages?
The floating bubble is on by default in every environment, including production. BOOSTHIS_BUBBLE set to 0 hides it and the kit carries on measuring; BOOSTHIS_DISABLED stops the kit altogether. Each name is read from the environment where this runtime has one, and otherwise from a value of the same name on the host.
Kits that draw it: Node.js, Python, Go, Java, PHP, Ruby, .NET, Rust, Elixir, Browser / web, React Native / Expo, Flutter, Swift / iOS, Kotlin / Android. Kits that show your users nothing at all: Edge / V8 isolates.
What else the kit touches on the page
- One element, in a closed shadow root. The bubble is a single
divcarrying adata-boosthis-bubbleattribute, with a closed shadow root inside it. Its styles are onestyleelement inside that root, so none of them reach your page and none of your page's styles reach the bubble. Nothing else in your document is added, moved or restyled. - Web Storage, under one namespace. Every value the kit keeps is stored under the
boosthis:prefix inlocalStorage, falling back to memory where the store is unreachable. The kit reads no key outside its own prefix and enumerates none. - No cookies. The kit never reads or writes
document.cookie, and the uploads carry no credential of a visitor's — only the project key you configured. - A passive policy listener. The kit listens for the browser's own
securitypolicyviolationevent so it can print one console line if your policy is blocking it. The event only fires when something is actually blocked, so a page with no Content-Security-Policy sees no extra work and no probe request either way.
What does it put on my own domain?
A kit mounts addresses inside your application, on whatever domain you deploy to. Most answer local requests only. These are deliberately open, because the bubble is injected into your own pages and polls them from wherever your visitor is: /_boosthis, /_boosthis/, /_boosthis/panel, /_boosthis/pulse. None of them carries a credential, a route or screen label, a URL, a raw sample, or anything about one of your visitors.
The full inventory, per runtime, with what each address returns and what it deliberately omits, is on what Boosthis adds to your app.
What do I have to allow through my Content-Security-Policy?
One origin, https://www.boosthis.com, on connect-src and script-src. No wildcard is needed, no other host is contacted, and a page that sends no Content-Security-Policy at all needs nothing.
connect-src— needed by every browser install, however the kit got onto the page — this is the one that carries the uploads. Without it, the browser refuses each upload, the kit keeps running and measuring, and nothing ever arrives.script-src— needed by only pages that load the pre-built script tag. An install bundled through your own build step needs nothing here — the code is already yours. Without it, the script never loads at all, and nothing measures.style-src— met by only the on-page bubble, and only if you want it to look right. The bubble's styles are astyleelement the kit creates at runtime inside its own shadow root, and the kit takes no nonce, so a policy that refuses inline styles refuses that one too. Without it, the bubble draws unstyled — every reading is still taken, still uploaded and still on your dashboard. If you would rather not widenstyle-srcfor someone else's element, the honest fix is to turn the bubble off rather than to allow inline styles across your whole page.script-src-attr— met by nothing you need. The pre-built script tag carries anonerrorattribute whose only job is to print one console line when the kit file never arrives, and an inline handler is exactly what a strict policy refuses (script-srccovers this wherescript-src-attris not set). Without it, our console line never prints. A blocked or mistyped script then looks like a page with nothing installed, so read your own policy violation report instead — the browser's report names the script we could not tell you about.
In a policy, that is — schematically, because both directives are ones you almost certainly already have. Add the origin to the ones you have rather than pasting this as a policy of its own; the … stands for whatever sources you already allow, and a second script-src appended after your first one narrows the first rather than extending it.
connect-src … https://www.boosthis.com; script-src … https://www.boosthis.com;
Two more directives are worth knowing about and are deliberately NOT in that line, because neither is needed for a single reading to arrive: style-src and script-src-attr. Both would have to allow 'unsafe-inline', which is a real widening of your policy for someone else's code. We would rather tell you what keeping the policy costs.
The pre-built script tag, for pages with no build step, is served from https://www.boosthis.com/kit.js — the same origin.
Every address the kit posts to, under https://www.boosthis.com/api
/installs/consent— the install identifier, the runtime name, the kit version, the collection mode this build's code asked for, and the display name if one was set. The project key rides as a header. This is the first call./samples— individual timing readings, as numbers against a route label./snapshots— the periodic roll-up of this install's meters./crashes— crash and error reports, with the message and stack put through the kit's own denylist first./spans— trace spans — a method and a route label per span, never a URL or a body./candidates— candidate rules the kit noticed, as closed-vocabulary terms./resolutions— whether a previously reported problem stopped happening./job-runs— background job and scheduled-task timings, where the kit watches them. Server and device kits only./installs/forget— nothing but the install identifier and its own token — the erase lever, and the only one of these a person triggers deliberately.
A check on our build reads these addresses back out of the kit sources and fails when this list misses one, or names one no kit posts to.
What key does it need, and what happens if it leaks?
One project key, minted from the Project keys page of your Boosthis dashboard. Server-side kits read it from the environment — the shared BOOSTHIS_PROJECT_KEY where nothing more specific is wired in — so it never travels inside anything a user downloads.
the React Native kit, the browser kit, the Flutter kit, the Swift kit and the Kotlin kit are different: their key comes to rest inside a published build, where anyone holding a copy of the app can read it. We mint those with the narrowest scope we have, and say plainly what that leaves:
A key lifted out of a published build can still register installs under this project and send made-up readings into its meters, which is a real cost and the one this scope does not remove. What it cannot do is read those meters back — no measurements, traces, structure, coverage or exposure findings over the Boosthis AI connection — and it reaches no account, billing, team or other project.
A key placed in public can be revoked on its own from the Project keys page of the Boosthis dashboard, which leaves every other key on the account running.
How do I know the bytes I received are yours?
Be clear about what the check in front of you does — and run the one that matches what you downloaded, because the archives come in two shapes and the wrong command finds nothing to read.
Node.js, Python, Go, Java, PHP, Ruby, .NET, Rust, Elixir, Browser / web, Flutter, Swift / iOS, Kotlin / Android, Edge / V8 isolates
The archive ships a BOOSTHIS_CHECKSUMS.txt listing a SHA-256 for each file it carries. From the folder you unpacked into:
sha256sum -c BOOSTHIS_CHECKSUMS.txt
On macOS without GNU coreutils, shasum -a 256 -c BOOSTHIS_CHECKSUMS.txt does the same thing. It needs no network, no account and no Boosthis tooling.
React Native / Expo
That archive carries no checksum list. Its packer hashes every file it ships into a boosthis-kit-manifest.json at the archive root, and the same archive brings the tool that re-hashes them where you unpacked them:
./boosthis verify .
The same offline check against a different file. A sha256sum -c BOOSTHIS_CHECKSUMS.txt here would fail for the uninteresting reason that the file it wants is not in this archive.
What either check proves: every file the archive says it carries is on your disk, byte-for-byte as it was packed. It catches a truncated download, a file that failed to write, and an elision made by a transport in between — all of which otherwise produce wiring that looks installed and measures nothing. It says nothing about files the list does not name, so unpack into an empty folder: anything an older copy left behind is invisible to both checks.
What neither check proves: where the bytes came from. The list — or the manifest — travels inside the same archive it describes, so anyone able to alter the archive could alter its own record of itself with it. The kits are not code-signed, and this is a decision rather than an omission. A signing key held beside the deployment that serves the downloads would sign whatever that deployment served, including an attacker's bytes — it would add a ceremony that reads as provenance without being it. We would rather say this than let a checksum be mistaken for a signature.
What actually stands behind the bytes is the channel: you fetched them from our server, over TLS, authenticated with your own project key, and nowhere else serves them. If you received a kit any other way — pasted, forwarded, or handed over by an AI connection you did not open yourself — the check above tells you the copy is intact, and nothing tells you it is ours. Fetch it again from your own dashboard.
What is the first network call, and when does it happen?
A POST to https://www.boosthis.com/api/installs/consent, carrying the install identifier, the runtime name, the kit version, the collection mode this build's code asked for, and the display name if one was set. The project key rides as a header. This is the first call.
It fires on initialisation, not after any human action: there is no banner, no click and no consent dialog in front of it, because the call is the kit telling us that an install of your project exists. An install with no project key configured makes no call at all.
WHEN EACH KIT FIRST CHECKS IN (so quiet is not mistaken for broken): a browser page registers within a couple of seconds of the page loading, and a mobile-app kit registers shortly after launch — both show up almost immediately. A back-end kit registers on the service's FIRST REAL REQUEST instead: it consents lazily off the reporting path rather than at boot, so a back end that has been started but never called reports as never checked in, and that is the expected state rather than a fault.
If that did not settle it
- What Boosthis collects inside your app — every field, where it is processed, how long it is kept, and paste-able wording for your own privacy policy.
- What Boosthis adds to your app — the visible element and every address your app starts answering, per runtime.
- Privacy Policy and Terms of Service — the legal source. This page describes behaviour; those two govern it.
- support@boosthis.com — a question about your own deployment reaches a person.