Blog / Technical Guides
Automatic Timestamp When a Checkbox Is Ticked in Google Sheets
By Keyona Meeks, Founder, ReRev Labs · Oct 31, 2026 · 9 min read
The short answer: As far as I know, a formula alone cannot stamp the time once and keep it. A short Apps Script can. It uses an
onEdittrigger, which Google runs when a user changes a cell. When someone ticks a box in your checkbox column, the script writes the time in the next column. It leaves an existing time alone, so the first tick is the one that counts. I tested the script with a mock in Node. Nothing was run in Google. I could not read Google's method-table entry for the call that writes the cell, so test that part first.
By the end of this post, you'll be able to:
- Add checkboxes to a column.
- Stamp the time when a box is ticked.
- Choose what happens when a box is unticked.
- Know what this script cannot do.
We sell AI operations work, so weigh this post with that in mind.
How do you stamp the time when a checkbox is ticked?
Use an onEdit(e) function. Google's triggers page, as my tool returned it, says: "The onEdit(e) trigger runs automatically when a user changes the value of any cell in a spreadsheet." A function with that exact name runs on its own. You do not install it. My tool returned that page in parts, so check the quotes on the page.
The page also says simple triggers "can't run for longer than 30 seconds," and that they cannot use services that need authorization. Gmail is its example, so this script does not send email. It only reads and writes the same spreadsheet.
How do you add the checkboxes?
I could not confirm the menu steps for checkboxes in Google Sheets, so I give none. Use Google's own help. In code, Google describes Range.insertCheckboxes() this way: "Inserts checkboxes into each cell in the range, configured with true for checked and false for unchecked." Either way, the boxes go in one column. The script reads that column from the CHECK_COL number.
What does the script look like?
Paste this into the Apps Script project attached to the sheet. Set the tab name and the two column numbers at the top. The example watches column C and writes into column D.
// Writes a time next to a checkbox when someone ticks it. Runs by itself as a simple onEdit trigger. Needs no installation.
var TAB = 'Tasks'; // The tab to watch.
var CHECK_COL = 3; // The column that holds the checkboxes (3 = column C).
var TIME_COL = 4; // The column that gets the time (4 = column D).
var HEADER_ROWS = 1; // Rows at the top to ignore.
var CLEAR_ON_UNTICK = false; // Set to true to clear the time when a box is unticked. Your decision.
function onEdit(e) {
stampIfTicked(e);
}
function stampIfTicked(e) {
if (!e || !e.range) return 'no event';
var range = e.range;
var sheet = range.getSheet();
if (sheet.getName() !== TAB) return 'wrong tab';
var row = range.getRow();
if (row <= HEADER_ROWS) return 'header';
if (range.getColumn() !== CHECK_COL) return 'wrong column';
var timeCell = sheet.getRange(row, TIME_COL);
if (range.isChecked() === true) {
if (String(timeCell.getValue()) !== '') return 'already stamped';
var tz = Session.getScriptTimeZone();
timeCell.setValue(Utilities.formatDate(new Date(), tz, 'yyyy-MM-dd HH:mm'));
return 'stamped';
}
if (CLEAR_ON_UNTICK) {
timeCell.setValue('');
return 'cleared';
}
return 'left alone';
}
What the parts do, with Google's own descriptions as I read them in the method tables this session:
Range.getSheet(): "Returns the sheet this range belongs to."getRow(): "Returns the row position for this range."getColumn(): "Returns the starting column position for this range."Range.isChecked(): "Returns whether all cells in the range have their checkbox state as 'checked'."Sheet.getRange(row, column): "Returns the range with the top left cell at the given coordinates."getValue(): "Returns the value of the top-left cell in the range."Utilities.formatDate"Formats date according to specification described in Java SE SimpleDateFormat class."Session.getScriptTimeZone()"Gets the time zone of the script."Range.setValue(): I could not read its method-table entry. Google's triggers page namesRange.setValue()as an example of a script change that does not fireonEdit. So the call exists, and what it does is the part to test.
The script checks the tab, skips the header row, skips other columns, and stamps only when the box is ticked and the time cell is empty. The time goes in as text, for example 2026-10-31 14:05, in the script time zone. It is not a date value, so sort it as text.
Why does the script not stamp again when the cell is written?
Because Google's page says: "Script executions and API requests don't cause triggers to run." It gives Range.setValue() as an example. So the time the script writes does not start another onEdit. Edits you make by hand do start it.
What happens when someone unticks a box?
By default, nothing. The first time stays, so you keep a record of the first tick. If you want the time cleared when a box is unticked, set CLEAR_ON_UNTICK to true. That is your decision. A cleared time is a lost record.
What can this script not do?
- It does not fire for changes made by a script or an import. Google's page says script executions and API requests do not run triggers.
- It stamps only one row per edit. If someone pastes ticked boxes into many rows at once, only the first row is stamped. I could not confirm how to read every row of a pasted block, so I left it out.
- It does not say who ticked the box. I did not confirm a safe way to read the editor's name from a simple trigger, so I record the time only.
- The time is text. It is not a real date value.
Where does an LLM fit in this?
An LLM can help with the messy input. For example, it can read a long free-text notes column and suggest which rows look finished, so a person can tick them. A person decides, because an LLM can mark a row done that is not, and sound sure. The tick, the stamp and the skip rules are plain rules that do the same thing every time. My stance: AI writes the code, plain automation runs it, and an LLM shows up only where the input is messy and a person checks the result. For where to start with your own automations, see what to automate first. For background on the tool, see what Google Apps Script is.
How do you test it?
- Make a tab named
Taskswith headings in row 1. Put checkboxes in column C, rows 2 to 6. - Tick the box in C2. D2 should show the time.
- Untick and tick it again. D2 should keep the first time.
- Tick a box in another column, and tick one on another tab. Nothing should appear.
- Set
CLEAR_ON_UNTICKto true, untick C2, and check that D2 clears. Set it back if you want the record kept. - Delete the test data.
What did the test show?
I tested the script in Node with a mock of the sheet and the event. All 13 checks passed. They covered a first stamp, a second tick leaving the time alone, an untick leaving the time, the wrong tab, the header row, the wrong column, a missing event, clearing on untick, other column numbers, the onEdit entry point, an existing time being kept and a non-true value. The mock cannot show how Google passes the event. Nothing was run in Google.
Where this has limits
- Nothing was run in Google. The test was a mock in Node.
- I could not read the method-table entry for
Range.setValue(). Test that call first. - My tool returned Google's triggers page in parts. Check the quotes.
- I give no menu steps for checkboxes. I could not confirm them.
- One row per edit, no editor name, and the time is text.
- No ReRev prices and no promises about results.
If you want help turning this into a tracking system your team uses, see our AI operations service or tell us what your team ticks off. Do not send passwords or login details.
Frequently asked questions
Can a Google Sheets formula add a timestamp when a box is ticked?
As far as I know, not one that stays fixed. I did not test this, and I did not read Google's formula help. A script can write the time once.
Does the script need to be installed?
No. A function named onEdit runs as a simple trigger. Google's page says it runs when a user changes the value of any cell.
Will it stamp changes made by another script?
No. Google's page says script executions and API requests do not run triggers.
What if I untick the box?
By default the time stays. Set CLEAR_ON_UNTICK to true to clear it.
Does it record who ticked the box?
No. It records the time only.
Does the script use an LLM?
No. An LLM can help suggest which rows look finished, and a person ticks the boxes.
Read next: Send an email when a cell changes turns the same kind of edit into a notification.