Bounce rate calculator
250 single-page sessions out of 1,000 visits is a 25% bounce rate, which leaves 750 visits that went past the first page. Enter the two counts from your analytics report for any page or week. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Single page sessions
- 250
- Total sessions
- 1,000
- Bounce rate
- 25
- Engaged sessions
- 750
- Non bounce rate
- 75
Website bounce rate is the share of visits that never go past the first page. Product, marketing, and analytics teams use it as a first-look health metric: a landing page that loses most of its sessions is a conversion problem, not a traffic problem. This bounce rate calculator takes two session counts — single-page sessions (bounces) and total sessions — and returns the rate as a percentage using the same identity every analytics suite publishes: bounce rate equals single-page sessions divided by total sessions, times one hundred.
What bounce rate measures and how the percentage is formed
Bounce rate is the percentage of sessions that contain only one page view — the visitor arrived, saw a single document, and left without a second hit. In the classic analytics definition those visits are single-page sessions, and the rate is that count divided by total sessions, then scaled to a percent. Two hundred fifty bounces out of one thousand sessions is twenty-five percent; one bounce out of three sessions is thirty-three point three repeating percent, returned here rounded half-up to six decimal places so goldens stay byte-stable across runtimes.
A bounce count equal to total sessions is also legitimate: every visit was a single-page session and the rate is one hundred percent. What is not legitimate is a zero or negative total, because dividing by zero does not produce a rate, and a bounce count larger than the session total, because you cannot bounce more visits than you had.
What you can do with it
Landing-page health checks
Turn a week's single-page sessions and total sessions into the bounce rate you can put next to the page in a growth review.
FAQ
What happens if total sessions are zero?
Bounce rate is undefined when there are no sessions to divide by, and the failure is not billed.
Is this the same bounce rate as classic web analytics?
Yes for the textbook identity: a bounce is a single-page session, and the rate is that count over total sessions as a percent. It does not apply later engagement-time or conversion-event rules.
Can the bounce rate be 0% or 100%?
Yes, both are valid. Zero single-page sessions means every visitor reached at least a second page, so the rate is 0%. If every session was a single page, the rate is 100%.
What is the non-bounce rate?
It is the share of visits that went past the first page: 100 minus the bounce rate. The engaged sessions are total sessions minus single-page sessions, so the two rates always add up to 100.
Why is a bounce count higher than the total sessions rejected?
Because a page cannot lose more visits than it had. If that happens, the two numbers usually come from different reports or different date ranges, so take both from the same report and period.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/fin/bounce-rate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"single_page_sessions":250,"total_sessions":1000}'const res = await fetch("https://api.kit.forhosting.com/fin/bounce-rate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"single_page_sessions": 250,
"total_sessions": 1000
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fin/bounce-rate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"single_page_sessions": 250,
"total_sessions": 1000
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fin/bounce-rate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"single_page_sessions":250,"total_sessions":1000}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"single_page_sessions":250,"total_sessions":1000}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fin/bounce-rate", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"single_page_sessions": 250,
"total_sessions": 1000
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fin.bounce_rate",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
When total sessions are zero the ratio is undefined, so the task fails with invalid_input and is not billed.
What bounce rate measures and how the percentage is formed
The complement is equally useful: engaged_sessions is total sessions minus single-page sessions, and non_bounce_rate is one hundred minus bounce_rate, so the two rates always sum to one hundred. A zero bounce count is a legitimate outcome — every session reached at least a second page — and returns bounce_rate of zero rather than an error. This endpoint does not ingest a raw hit log, does not classify engagement the way a later analytics product might (time on page, conversion events, session-duration thresholds), and does not sample. It prices and returns the textbook ratio on two counts you already have from your warehouse, your tag, or a weekly export.
Input contract, response shape, and error behaviour
Rates are rounded half-up to six decimal places; session counts are returned as the finite numbers you sent. POST a JSON body with two required finite numbers. single_page_sessions is the bounce count in the reporting window; aliases bounced_sessions, bounces, and bounced map to the same field so a warehouse column can keep its name. total_sessions is every session in that same window; aliases sessions and total are accepted. Each field may arrive as a JSON number or as a numeric string. Missing fields, empty strings, and non-finite values fail with invalid_input naming the field. If single_page_sessions is negative the request fails. If single_page_sessions is greater than total_sessions the request fails because a bounce cannot outnumber the visits it is taken from. Those failures are not billed. On success the body echoes single_page_sessions and total_sessions, then reports bounce_rate as a percentage, engaged_sessions as the complement count, non_bounce_rate as one hundred minus bounce_rate, and a formula string restating the identity. Example: two hundred fifty single-page sessions and one thousand total sessions yield bounce_rate twenty-five, engaged_sessions seven hundred fifty, and non_bounce_rate seventy-five. Pair the JSON with your own date grain if you need a weekly series; this endpoint computes one window at a time and does not emit charts.
Where a bounce rate calculator earns its keep
Growth and product teams use a bounce rate calculator when a landing page, a campaign, or a locale is accused of leaking traffic: they already have session totals in a sheet and need the same percentage their analytics product would print, without waiting on a UI export. Failed validation does not consume balance. Agencies re-run the two counts per creative and per device so a weekly deck can compare bounce_rate across variants with one shared rounding rule. Finance partners who allocate paid-media spend against session quality drop single_page_sessions and total_sessions from the warehouse and pin bounce_rate in a model that must not call a proprietary analytics API. This is a different search and a different job from computing click-through rate or conversion rate: those ratios use clicks or conversions in the numerator, while bounce rate uses single-page sessions against all sessions. Keep total_sessions strictly positive, keep the bounce count inside the session total, pin the rounded percentage in tests, and you get a reproducible website bounce rate for dashboards, LMS plugins, and edge workers without standing up an analytics engine of your own.
Integration use cases
Campaign and creative comparison
Recompute bounce_rate per ad, locale, or device from two warehouse counts so every variant shares the same percentage and rounding.
Paid-media quality models
Pin bounce_rate in a spend-allocation sheet without calling a proprietary analytics API for a ratio you already have the inputs for.
Technical questions
How is website bounce rate calculated?
Send finite numbers single_page_sessions (bounces) and total_sessions. The API returns bounce_rate = (single_page_sessions / total_sessions) × 100, plus engaged_sessions and non_bounce_rate.
Can the bounce count be larger than total sessions?
No. single_page_sessions must be between zero and total_sessions inclusive. A larger bounce count is rejected as invalid_input.
What does the bounce rate calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.