TOTP time window calculator
At Unix time 1700000000 with a 30-second period, you are in window 56666666 with 10 seconds left before the counter moves on. Enter a period and a timestamp to debug codes that seem to expire early, with no secret involved. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Period
- 30
- Current time
- 1,700,000,000
- Seconds remaining
- 10
- Window index
- 56,666,666
This TOTP time window calculator turns a period length and a Unix timestamp into two practical values: the index of the active time window and the number of whole seconds left before the next one begins. It is useful when building, testing, or diagnosing time-based one-time password systems, especially when a code appears to expire earlier than expected. The calculation is deterministic, uses no secret key, generates no password, and never reads the device clock for you, so the same input always produces the same result.
Understand what a TOTP time window represents
A TOTP system divides Unix time into consecutive windows of equal length. Thirty seconds is a common period, but the calculation works with any positive whole number of seconds. The window index is the Unix timestamp divided by the period and rounded down.
Every timestamp that produces the same quotient belongs to the same window, so an authenticator and a server can independently select the same moving counter. This calculator exposes that counter directly without asking for a shared secret or generating an authentication code. It also reports how many whole seconds remain before the counter advances.
At the exact first second of a window, the full period remains; at the final second, one second remains. That boundary convention makes countdown displays useful and avoids presenting zero while the current window is still active.
Choose inputs and interpret the result
Set period to the configured lifetime of one TOTP step, expressed as a positive integer in seconds. The index is zero-based from the Unix epoch and normally becomes a large integer for present-day timestamps. It is not a code and should not be compared with the digits shown by an authenticator.
Instead, compare window indexes when checking whether two components agree about time, or use the remaining value to decide when a test should wait for the next boundary. The function does not apply clock-skew tolerance, adjacent-window acceptance, leap-second corrections, or network delay. Those are policy choices for a verifier.
This result describes only the mathematically active window for the supplied timestamp and period, which keeps automated tests predictable and makes disagreements easier to isolate.
Use the calculator safely in testing and operations
Use this capability when you need timing information but do not want to expose a TOTP seed. In integration tests, fixed timestamps let you verify behavior immediately before, at, and after a boundary without mocking a hidden system clock inside this calculator. Remember that a matching window does not prove that a submitted one-time password is valid.
Verification still requires the shared secret, the agreed hash and digit settings, replay protection, and an explicit tolerance policy. Avoid logging secrets alongside these timing diagnostics; the period, timestamp, index, and countdown are sufficient for investigating most synchronization problems.
What you can do with it
Debug authenticator clock alignment
Compare the calculated window indexes for recorded client and server timestamps to identify a clock or period mismatch without sharing a TOTP seed.
Build a rollover countdown
Show how many whole seconds remain before the active TOTP counter advances and a newly generated code belongs to the next window.
Test exact window boundaries
Use fixed Unix timestamps immediately before and at a boundary to make authentication timing tests deterministic and repeatable.
FAQ
What does this capability cost?
The browser version can perform the same deterministic calculation locally.
Does it generate or verify a TOTP code?
No. It calculates timing metadata only and never accepts a shared secret or one-time password.
Why is the full period returned at an exact boundary?
The new window has just begun, so none of its whole seconds have elapsed and the complete period remains.
Should I enter the time in seconds or milliseconds?
In whole Unix seconds, never milliseconds. A millisecond value would point to a window far in the future. Using an explicit timestamp also lets you repeat the result later in tests, logs or incident notes.
If two systems share the same window, is the code valid?
Not necessarily. A matching window only shows that both sides agree on time. Checking a code still needs the shared secret, the agreed settings, protection against reuse and a clear tolerance for clock drift.
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/security/otp-time-window-calc \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"period":30,"current_time":1700000000}'const res = await fetch("https://api.kit.forhosting.com/security/otp-time-window-calc", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"period": 30,
"current_time": 1700000000
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/security/otp-time-window-calc",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"period": 30,
"current_time": 1700000000
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/security/otp-time-window-calc", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"period":30,"current_time":1700000000}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"period":30,"current_time":1700000000}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/security/otp-time-window-calc", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"period": 30,
"current_time": 1700000000
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "security.otp_time_window_calc",
"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
Understand what a TOTP time window represents
Enter the timestamp explicitly as Unix seconds, not milliseconds, so the result can be reproduced in logs, tests, and incident notes without depending on the clock of the browser or API worker.
Choose inputs and interpret the result
Then provide current_time as a non-negative Unix timestamp in whole seconds. The response contains seconds_remaining and window_index. For example, if a thirty-second period has ten seconds elapsed inside its current window, seconds_remaining is twenty.
Use the calculator safely in testing and operations
A monitoring job can calculate the current index from a recorded timestamp, while a user interface can use seconds_remaining to warn that a code is close to rollover. API calls cost $0.002 each, while the browser version can run locally.
Technical questions
Should current_time be in seconds or milliseconds?
Use whole Unix seconds. Convert a millisecond timestamp to seconds before submitting it.
What happens when the period is zero or negative?
The request fails with an invalid_input error because a TOTP time window must have a positive length.