Calmora

Privacy Policy

Effective date: October 2, 2026

Calmora is a scheduling assistant that turns plain language and schedule images into Google Calendar events, and shows you what your week actually has room for. It works on deeply personal data — your calendar — so this policy is written to be specific rather than broad: it names exactly what is collected, exactly where it goes, and exactly how long it exists. If a practice is not described here, the Service does not do it.

What changed on October 2, 2026

Route checking with Google’s Routes API, off unless the operator of a deployment switches it on — and then only for the operator’s own account. Where it is on, a trip between a shift or event you are checking and your commitment just before or after it can be checked with Google instead of being estimated from the distance. This is a new recipient of data:

  • What is sent, and when.Whenever a dated shift or event is previewed, or its times are edited, our server may send Google one request for each of its two journeys: the coordinates of the shift or event’s place (or of your workplace, when it has none) and of the commitment just before or after it (which can be your home), within a few hours, and the time you need to arrive or leave. Never your identity, an event’s title, or any address text. A request is retried once if Google’s server fails (Sections 3.5, 8).
  • How much.At most 4 trips checked for each check, however many shifts it holds, and by default at most 200 trips a day for each account on each server instance. A trip is one request, sent a second time only if Google’s server fails, and it still counts as one trip — so a check sends at most 8 requests. The week view’s own drawing never sends one (Section 3.5).
  • What is kept, and for how long. The answer, as numbers only — a travel time and the kinds of travel — in server memory, keyed to your account, to the two places on a 100-metre grid and to the time in 15-minute steps. It is not used after an hour (seven days for a trip with no set time; a failed check after one minute), and is deleted the next time route checking runs, or when the server restarts (Section 7).

What changed on September 28, 2026

A Trip room, off unless the operator of a deployment switches it on. Where it is on, a Trip tab plans a trip between two places you type. This is a new use of data:

  • The places you type are looked up.Our server sends the text of each place you type into the Trip room to the address-lookup service the operator chose (NYC GeoSearch or OpenStreetMap’s Nominatim) to find where it is — the same service and the same limits as for your calendar’s locations, now also for text you type there. Where address lookup is off, the Trip room looks nothing up and plans nothing (Sections 3.3, 3.5, 8).
  • The plan reads what the commute planner reads.Citi Bike’s public station feeds, the subway timetable kept on our server where that is on, and — for a plan with a Citi Bike leg — Open-Meteo’s forecast at a coordinate rounded to about 1 km. Your browser receives the place names, times and steps of the plan — and, only where the map below is also on, the rounded positions needed to draw it (Section 3.5).
  • A trip on a map, where the operator has also switched the map on. Each plan then also carries the positions of the two places you typed, rounded to three decimal places (about 100 metres), and, for a Citi Bike plan, of the two docks it uses, rounded to four (about 10 metres), with the straight lines between them — no names and no IDs. Nothing is loaded until you press “Show on map”; then your browser loads the map from OpenFreeMap (tiles.openfreemap.org), which receives what any website receives (your IP address, browser user agent and our site’s address) and which map tiles are loaded, which shows the area of your trip. The positions are drawn by our own code; OpenFreeMap never receives them, the places you typed, or anything about your account (Sections 3.5, 8).
  • Saved trip places stay in your browser.A place you choose to save is kept in this browser’s local storage, under calmora.trip.places.v1 — never on our servers (Sections 3.3, 9, 10).
  • Nothing reaches your calendar without a preview. Adding a trip shows you the event first and writes it only when you confirm (Section 3.5).

And the Service now counts page views.It did not measure itself at all before. Vercel Web Analytics records which page was opened, roughly where the visit came from, a coarse device type and country, and a visitor identifier Vercel works out on its own servers and changes every day. It sets no cookie, reads nothing from the page you are looking at — no event, place, or account — and is served from this site’s own address, so your browser contacts no other host for it. A “Do Not Track” or Global Privacy Control signal switches it off entirely (Sections 8, 9, 12).

Travel nudges, off unless the operator of a deployment switches them on — and then off for your account until you turn them on. Where they are on, the You tab offers “Travel nudges”: a notification when it is time to get ready, and when it is time to leave, for the journeys between your commitments, even with the app closed. This is a new use of data, and it applies only to an account that turns it on:

  • What our database keeps.That you turned nudges on; for each journey your week view shows arriving in the next 36 hours, the IDs of the two calendar events it joins, when you need to leave, when you arrive, the time zone, and which nudges have been sent — never an event’s title, place, description or guests; and a copy of the push subscription of each device where you have turned notifications on (Sections 3.5 and 7).
  • For how long. A journey is deleted once it is over. A device copy is kept until you turn nudges off, turn notifications off on that device or sign out there, or its push service reports it gone (Section 7).
  • What a nudge says.Only that it is time to get ready or to leave, and the time to leave by — no event title and no place. It is encrypted for your device and passes through your browser’s push service (Apple, Google, or Mozilla), which cannot read it (Section 8).
  • The scheduler.A script in the operator’s own Google account (Google Apps Script) asks our server every few minutes whether a nudge is due. It carries a shared password and gets back only counts; nothing about you passes through it (Section 8).
  • How to delete it. Turning nudges off on the You tab deletes all of it at once; or ask us (Section 10).

Keeping travel blocks current, off unless the operator of a deployment switches it on — and then off for your account until you turn it on. Where it is on, the You tab offers “Keep my travel blocks current” under Travel nudges, which it needs. This is a new automatic change to your calendar, made without a preview, and it applies only to an account that turns it on:

  • What it may change.Only a travel block the Service itself added between two of your commitments, and only its start time: when the latest plan for that journey says to leave earlier or later, the block’s start is moved to match, by more than 5 and at most 60 minutes, on the same day. Its end stays at your next commitment’s start, it never starts before the commitment before it ends, nothing else about the event changes, and Google is told not to email anyone (Sections 3.2.1 and 4).
  • What it never touches. An event you moved or changed in Google Calendar, one that changed after the move was worked out, one with guests, a repeating one, or anything the Service did not add as a travel block.
  • How and when. Our scheduler works out the move from your route and live train times — never your location — and your browser makes it, with your own sign-in, while your week is open in the app; the week view then says what moved (Section 4).
  • What our database keeps.For each journey nudges keep, the ID of the travel block the Service added, its start and end times and Google’s version tag for it, when the commitment before it ends, and the move waiting to be made; and a record of each move made or refused (an internal draft ID and the outcome of the checks) — never a title, place, description or guest (Section 7).
  • How to turn it off. Switch it off on the You tab, or turn travel nudges off: it stops at once and those times and records are deleted (Section 10).

Live location for travel, off unless the operator of a deployment switches it on — and then off for your account until you turn it on. Where it is on, the You tab offers “Live location for travel” under Travel nudges, which it needs, and the week view offers “Update from where I am” on a journey that starts within the next 3 hours. Until now the Service never used your device’s location; this is a new use of data, and it applies only to an account that turns it on:

  • What is collected, and when.Nothing, until you press “Update from where I am” — never when a page opens, never in the background. Then your browser asks your permission (the first time) and finds where you are, and your device turns that into the 100 metre square you are in before anything is sent. Our server receives only that square, when it was found, and which two events the journey joins — never your exact position (Section 3.5).
  • Where it goes.To our server, which works the journey out again from the middle of that square the same way the week view does, and sends back the new time to leave. The square is sent to no one else. Your browser finds your position its own way, which on some devices involves the browser’s or the device maker’s location service, under their own terms (Section 8).
  • What is kept, and for how long. Only if travel nudges are watching that journey: the square, when it was sent, and the time to leave worked out from it, in our database, for at most 30 minutes— used to time that journey’s nudge while it is under 15 minutes old. Otherwise nothing is kept. On the operator’s own account, nothing is kept when the square is within 250 metres of the home the operator configured (Sections 3.5 and 7).
  • How to stop and delete it.“Stop sharing” on the journey deletes what is kept at once; so does turning “Live location for travel” or travel nudges off. You can also block location for this site in your browser (Section 10).

Your guess answers now reach two more flows.The September 27 notice below says your “Yes” and “No” answers about the AI’s category guesses are sent with your week view and shift-check requests so the Service does not ask the AI about a title again. As of September 28, they are sent the same way with two more requests: checking a change you make to an event — or autopilot makes — for what it now runs into, and the email feed (Section 6.1) checking what turned up in the mail against your calendar. No new answers are collected; the two lists already disclosed on September 27 are just read by two more parts of the Service (Sections 3.3 and 5.3 describe all four).

What changed on September 27, 2026

Three things changed. Autopilot changed — these are new practices, and they apply only to an account that switches autopilot on:

  • Autopilot is now per account, off by default. It does nothing for your account until you switch it on from the You tab (Section 4).
  • Autopilot may now change and remove events it created. Where the operator has separately switched this on, it may move or remove an event the Service itself created, within the limits in Section 4. Before, it could only create.
  • Activity and undo.What autopilot changed or removed is listed under “Autopilot did this” on the You tab, where a removal can be put back; the server keeps only the event IDs, for at most 24 hours (Section 7).
  • A notification gate. An automatic change or removal happens only when the Service can send a notification to a device where you have turned notifications on; a removal or a serious change is sent there (Section 4).

The week view’s questions changed— how it asks about the AI’s guesses — and your “Yes” answers can now be remembered. This part also corrects statements in this policy that no longer matched how the Service works:

  • Your “Yes” answers are remembered in your browser. When the week view asks about a guess and you answer “Yes”, your browser keeps that title and the category you confirmed (the 100 most recently answered or on a week you viewed) and sends them with that browser’s requests, in a request header or body — never in the web address — so that when your week is shown or a shift is checked from that browser, the Service holds that time without asking the AI about the title again (Section 5.3 gives the limits). The list is not tied to your account, and signing out clears it (Sections 3.3, 5.3, 7, 9, and 10).
  • Fewer questions, nothing hidden.The week view now asks only about guesses whose answer would change how much of your day is reserved, once per title. Every other guess is still listed under the week: the AI’s guesses with its reason and a way to reject them, and guesses you confirmed with your answer and an Undo that brings the question back, where you can answer “No”. The Service also no longer sends the AI the titles of the tentative holds and travel blocks it wrote into your calendar (Section 5.3).
  • Corrected statements.The server’s title-category cache drops its oldest entry to make room for a new one rather than being cleared all at once, and it holds the AI’s one-line reason as well as the category (Section 7). On our server, the title-category cache, write-deduplication records, push subscriptions, and the autopilot activity list are keyed to a random identifier issued each time you sign in, not to your Google account ID; your saved commute and rate limiting are keyed to your email address (Sections 3.1, 3.3, 3.4, 5.3, and 7).

And this update adds a map of your week and a second address-lookup service, and your commute setup can now be saved to your account, so it follows you to any device you sign in on. Those three are new practices, and each is off unless the operator of a deployment switches it on. This part also corrects statements that no longer matched what the Service already does; those practices are not new, and live train times among them are on by default:

  • The week map— when it is switched on and you open it, our server sends your browser the positions of your own events for the week on screen, rounded to about 10 metres (Section 3.5), and your browser loads the map itself — map images, label lettering and icons — directly from OpenFreeMap (tiles.openfreemap.org). OpenFreeMap therefore receives your IP address, your browser’s user agent, our site’s address, and which part of the map you are looking at, which is the area around your events. It receives no calendar text, event times, or account details (Sections 3.5, 6, 8).
  • A new recipient: NYC GeoSearch, the New York City Department of City Planning’s address-lookup service, as an alternative to OpenStreetMap’s Nominatim. Where an operator turns it on, location text that matches no place the Service already knows is sent to it from our server to find its coordinates (Sections 3.5, 8).
  • Corrected promises about your browser. Sections 1, 5, 11, and 12 said your browser talks to nothing but our own site. That stays true except for the map-tile host, and only on a deployment where the map is switched on; those sections now say so. The Service still loads all of its code and its interface fonts from its own site.
  • A corrected promise about the MTA.Sections 3.5 and 8 said no request is ever made to the MTA. Since live train times arrived, that has not been true: by default, during live hours, our server reads the MTA’s public live feed for a trip with a subway ride. Those sections, and Sections 1 and 7, now say so, and say exactly what the request carries.
  • A corrected statement about weather checks.Section 3.5 said the week view never builds a live trip plan, and so never asks Open-Meteo about the weather. Since the week view gained live train times on September 27, 2026, that has not been true: during live hours it plans the trip about to happen live, and a live plan with a Citi Bike leg asks Open-Meteo for the forecast — with the same coordinate rounded to about 1 km, and nothing else, that Sections 1, 6, and 8 already describe. Only the operator’s own routes are ever planned this way. Section 3.5 now says exactly when.
  • A corrected statement about access logs.Sections 3.4 and 11 said the titles you mark “Not this” (Section 3.3) travel in a request’s web address, where the host’s standard access logs could record them. That has not been true since September 18, 2026: they travel in a request header or body, and no calendar title is put in a web address. Before then, the week view did put them in its web address, so the host’s access logs from that time may still hold some of them until the host’s own log retention removes them.
  • A database, for one thing.Where account storage is switched on, the commute answers you save while signed in are kept in a Postgres database, keyed to your account’s email address. No calendar data and no tokens are ever kept there (Sections 1, 3.3, 6, and 7).
  • The Service now counts its own use. Where that same database is switched on, two things are recorded that were not before. First, a single row per account holding your email address, when it was first and last seen, and how many times it has signed in — and nothing about what you did. Second, daily totals of how often the Service parsed a sentence, read a schedule photo, or added an event: counters only, in a table that has no column for an account at all, so they cannot be tied back to you. They exist so the operator can tell whether the Service is being used and how close it is to Google’s 100-account pre-verification limit. They are visible only to the operator, as numbers — never as a list of who signed up — and no third-party analytics or tracking service is involved (Sections 7, 8, 12).
  • A new service provider: Neon, Inc., which hosts that database (Section 8).
  • How to delete it:the commute setup’s “Delete my saved commute” button removes it from your account and your browser, or ask us. Signing out removes your browser’s copy but not the account’s (Section 10).

1. At a glance

  • You sign in with Google. There are no Calmora passwords, and we never see or store your Google password.
  • We request the narrowest Google Calendar permission that lets the app do its job (calendar.events), and we touch only your primary calendar.
  • We keep one small database, for your saved commute and — only where the operator offers travel nudges and you turn them on — for those nudges: if you save your commute setup while signed in, it is stored in a Postgres database hosted by Neon, keyed to your account’s email address, so it follows you to your other devices, and stays until you delete it. If you turn travel nudges on, the same database keeps, under the same key, the times and event IDs of your journeys for the next 36 hours and your devices’ notification subscriptions, until the journey is over or you turn nudges off; and, if you also turn on keeping travel blocks current, the ID and times of each travel block the Service added for those journeys and a record of each automatic move, until you turn that off; and, if you also turn on live location for travel, the 100 metre square you shared for a journey, for at most 30 minutes. It holds no event titles, places or descriptions, and no tokens (Sections 7 and 10). On a deployment where the operator has not switched account storage on, your commute stays in your browser only. Apart from that, the application writes no user data to disk on the server, with one exception that exists only if an operator switches it on (an address-lookup cache file, Section 3.5). What the server holds in memory is listed in this policy, item by item, with its bounds and lifetime.
  • To estimate travel between your commitments, the Service uses the location of your calendar events, any commute details you enter, the places you type into the Trip room where an operator has switched it on, and — only where live location for travel is on, you turned it on and you press “Update from where I am” — the 100 metre square your device is in. It works them out on our server; the outside services involved are Open-Meteo, which receives only a coordinate rounded to about 1 km for a weather check; the MTA, whose public live train feed our server reads during live hours, naming only a group of subway lines; OpenStreetMap’s Nominatim or NYC GeoSearch, only if an operator turns address lookup on; and Google’s Routes API, only if an operator turns route checking on and then only for the operator’s own account, which receives the coordinates of a trip’s two ends and a time (Section 3.5). Where an operator has switched the map on and you open the week map, or a trip’s map in the Trip room, your browser loads the map from OpenFreeMap (Section 3.5).
  • Your Google sign-in tokens are stored in an encrypted cookie in your own browser — not on our servers.
  • Specific, minimized pieces of data are sent to Anthropic, our AI provider, to power the features you see (Section 5 lists every such flow). Under Anthropic’s commercial terms, API data is not used to train Anthropic’s models.
  • No advertising, no analytics, no tracking pixels, no third-party scripts, no data sales, no data brokers.The Service loads all of its code and interface fonts from its own origin. The only outside host the page itself fetches anything from is OpenFreeMap — map images and map-label lettering — and only where the map is switched on and you open the week map or a trip’s map (Section 3.5).
  • Signing in never asks for access to your email.The one way the Service can read your mail is an optional mail view on the Standby Board: it is off unless the operator switches it on, and even then it reads nothing until you click “Connect Gmail” and grant Google’s separate, read-only Gmail permission. What it reads, and what it keeps (nothing), is in Section 6.1.
  • You can cut off all access at any time from your Google Account permissions page. Signing out of Calmora alone does not revoke the Google-side grant — Section 10 explains both steps.

2. Who we are, and what this policy covers

Calmora (the “Service”) is operated by Darwin Hu, an independent developer based in New York, United States (“we”, “us”, the “Operator”). You can reach us about anything in this policy at darwinhu64@gmail.com.

This policy covers the Calmora website and application, including its use of information received from Google APIs. It applies to everyone who visits or signs in. It does not cover Google’s own handling of your Google account and calendar (governed by the Google Privacy Policy) or Anthropic’s handling of API traffic (governed by Anthropic’s Commercial Terms), though Section 5 describes what we send to Anthropic and on what conditions.

3. Information the Service receives

3.1 Google account identity

When you sign in with Google, we receive your name, email address, profile picture URL, and Google account ID, along with OAuth tokens that let the Service call the Google Calendar API as you. Sign-in requests these scopes and nothing more: openid, email, profile, and https://www.googleapis.com/auth/calendar.events. We never request the broader full-calendar scope, and sign-in never requests any Gmail, Drive, Contacts, or other Google scope. The only other scope the Service can ask for is Gmail read-only (https://www.googleapis.com/auth/gmail.readonly), and only separately, when you choose “Connect Gmail” on the Standby Board where the operator has switched its mail view on (Section 6.1).

Your access and refresh tokens are placed inside an encrypted session cookie held by your browser (Section 7). The server keeps no copy. A random identifier issued each time you sign in — not your Google account ID — is used server-side as the key for the bounded, transient per-user records listed in Section 7 (the title-category cache, write-deduplication records, push subscriptions, and the autopilot activity list), and your email address as the key for your saved commute (Section 3.3) and for rate limiting (Section 3.4), so that one account’s data can never answer another account’s request.

3.2 Google Calendar data

With your permission, the Service reads events from your primary calendar only— it never lists or touches your other calendars — for the date ranges the feature needs: about a month plus a two-day margin per request for the week view; for shift checks, the span of the shifts you submitted (at most 31 days) plus a day’s margin on each side; the week on screen plus a two-day margin for the week map, when you open it; and the next 60 days for the Standby Board. For the week view, the week map, and shift checks, it extracts and uses only these fields from each event: the event ID, title, start and end times, status, whether the event is marked busy or free, your own response to it (accepted, tentative, declined, or not yet answered — never anyone else’s), its location text (used only for travel estimates and, if you open it, the week map, Section 3.5), a link back to the event in Google Calendar, and three of the private properties the Service itself may have written (Section 3.2.1): appDraftId, appHold and appTravel. The Standby Board reads the ID, title, times, status, location, and your own response, plus, where present, the event’s description (up to 2,000 characters, checked for deadline wording) and its video-call link; these go to your browser to lay out the board and nowhere else. For a travel block the Service added, these reads also note whether its times are still the ones the Service last wrote (appWrittenSpan), how many guests it has (a count) and its version tag. When previewing a change or a deletion, before autopilot changes or removes an event, or before a travel block is kept current (Section 4), the Service additionally reads the event’s version tag, recurrence rule, how many guests it has (a count, never who they are), and the start and end the Service last wrote on it (Section 3.2.1), so it can show you exactly what would be changed or removed, detect concurrent changes, and refuse to change or remove on its own an event other people are on. For a change or an automatic removal it also reads the event’s description, location, and reminders, and returns them to your browser alone, so the event can be shown, and put back, as it was. Before a change it also reads the busy times around the old and new time, the same way the week view does, to tell you whether the new time still fits.

An honest technical note: for the week view, the week map, and shift checks, Google’s API transmits full event records in its responses, which can include fields like descriptions and the full guest list. The Service discards everything except the fields listed above — from the guest list it reads only the entry that is you — uses nothing else, and retains none of the raw response after the request completes. The Standby Board asks Google for only the fields it uses, and drops any other guest’s details before anything reaches your browser.

3.2.1 What the Service writes into your calendar

When you confirm an event, the Service creates it in your primary calendar with the details you approved in the preview: title, times and time zone, and — when present in the draft — a description, a location, and a recurrence rule. Reminders are written too: yours when you set them, otherwise a sensible default based on the event’s category. Two additional things are worth knowing:

  • Names of people mentioned in your event are written as plain text inside the event description (a “With: …” line). The Service deliberately never adds Google attendees, so Google never emails invitations to anyone on your behalf.
  • Each created event carries app-private properties stored inside your own Google Calendar: appDraftId on every event, appWrittenSpan on every timed event (the start and end the Service last wrote, so a later update can tell an event you moved yourself from one it moved), plus appHold on tentative holds and appTravelon travel blocks (Section 3.5). They are invisible in the normal Google Calendar interface, readable via the API, and exist so the Service can recognize the events it wrote — which is what lets it refuse to delete anything that does not carry its own creation marker. Where a draft carries a source link — today that means a link the public-event research feature (Section 5.4) found for it — a small “Added by Calmora” source note with that link is attached. All of this lives in your Google account, not on our servers, and is removed with the event when the event is deleted.

Deleting through the Service uses a preview-then-confirm flow (or, only where autopilot may remove events, the automatic path in Section 4), only ever targets events carrying the hidden marker the Service wrote at creation, and tells Google not to send cancellation emails. Changing an event works the same way: a preview to confirm (or the automatic path in Section 4), only an event carrying that hidden marker, never a repeating one, and Google is told not to email anyone about it. A change you confirm moves the event’s time and, if you changed it in the preview, its place; an automatic change moves its time only. Where you have turned on keeping travel blocks current (Section 4), the Service may also move the start time of a travel block it added, without a preview: that write changes the block’s start and end fields (the end to the same time it already has) and the hidden record of the times it wrote, and nothing else. A one-tap update — the “Update calendar block to …” button on the commute panel, or “Change the time” under an event just added, where the button names the new times and pressing it is the confirmation — rewrites the event as the Service would write it now: its times, title, place, notes and reminder; it is refused if the event’s times are no longer the ones the Service last wrote, so an event you moved yourself in Google Calendar is left alone. Event reminders are delivered by Google, like any other calendar reminder. Separately, if you turn on push notifications in your browser, the Service sends one push message to your device after it writes an event, removes one automatically, or makes a serious change to one (Section 4), containing the event’s title and time — and, for a move, the time it was at and, if the place changed, the new place, plus, where they apply, how many guests can see it and the names of anything on your calendar the new time runs into — so the confirmation is useful. It goes through the push service your browser chose (Apple, Google, or Mozilla). It is off unless you enable it, and no push is sent to anyone but you. A removal you confirm yourself, and a routine change (one that is not serious), sends none. It also sends one when you press “Send a test notification”: that test message says only that notifications are working and contains nothing from your calendar. See Section 8. Travel nudges, where the operator offers them and you turn them on, are separate push messages that carry no event title or place (Section 3.5).

3.3 Content you give the Service directly

  • Typed event text. What you type into the input box (up to 2,000 characters), so it can be parsed into a draft event.
  • Schedule images.Images you upload or paste (PNG, JPEG, WebP, or GIF, up to 8 MB), an optional name to look for in them, and an optional free-text hint. Images are processed entirely in memory and are never written to disk or kept after the request. Be aware that a schedule image can show other people’s information (for example, coworkers on a shift roster); the Service may report the other names it saw, to you only, so you know what was in the image. Upload only images you have the right to share.
  • Corrections and confirmations.When you reject a category the AI guessed for one of your events (“No extra time” or “Not this”), that title is remembered in your own browser’s storage (the 50 most recent) and sent with that browser’s future requests so the Service stops guessing about it. When you confirm a guess (“Yes”), the title and the category you confirmed are remembered in your browser’s storage too (the 100 most recently answered or on a week you viewed, so an older answer about a title on the week you are looking at is kept ahead of a newer one that is not) and sent with that browser’s requests, so that when your week is shown or a shift is checked from that browser, or a change you make to an event is checked for what it now runs into (and the same for a change autopilot makes), or the email feed (Section 6.1) checks what turned up in the mail against your calendar, the Service holds the time that category reserves without asking the AI about the title again (Section 5.3 gives the limit: a confirmation that does not fit in a request can still be guessed about again). Both lists travel in a request header or in the request body — never in the web address — and neither is kept on our servers. Neither list is tied to your account: each applies to whoever uses that browser and does not follow you to another device. Signing out clears the confirmed list; it does not clear the rejected one.
  • Your commute.If you complete commute setup, your answers: where your usual trip starts and ends (each either a place the Service already knows or text you type, which may be a home or work address), a short name for each end, what kind of place you are going to (work, school, or other), and your buffer and get-ready times. They are kept in your own browser’s storage (Section 9) and sent with each trip you ask the Service to plan (Section 3.5). Where account storage is switched on and you are signed in, saving them also stores them in our database (a Postgres database hosted by Neon, Inc.), keyed to your account’s email address, so the same commute appears on any device you sign in on; that copy is readable and changeable only through your own signed-in account. If your browser already held a commute from before, the Service asks before copying it to your account — it is never uploaded without your say-so. The stored copy is kept until you delete it (Section 10).
  • Trip places.Where the operator has switched the Trip room on, the two places you type into it (each at most 120 characters, and often a street address) and the time you want to leave or arrive, sent with each trip you ask it to plan (Section 3.5). They are used for that one plan and not kept on our servers. If you save a place there, the short name you give it and the text you typed are kept in your own browser’s storage (at most 12 places, under calmora.trip.places.v1, Section 9) — never sent anywhere except as the text of a trip you plan, not tied to your account, and not on any other device.
  • Your time zone.Your browser’s IANA time zone is sent with requests so dates and times resolve correctly.

3.4 Technical and log data

  • Account address or IP address, in memory, for rate limiting.The Service keeps request counts in server memory to bound the cost of the parsing, trip-planning, and week-map endpoints. When you are signed in the count is kept against your account’s email address, so that one person’s usage is bounded rather than one network’s; when there is no session it falls back to the IP address. These counters live only in memory — for up to the life of the server process — and disappear on restart. They are a cost guardrail, not a tracking mechanism.
  • Application logs are metadata-only by construction. API requests log at most one structured line containing things like route name, duration, status code, item counts, model name, and token counts — never your text, your event titles, image bytes, email-derived content, or your name. The logging code cannot carry content without a code change.
  • Hosting-provider access logs.Like virtually every website, the infrastructure the Service runs on (Section 8) keeps standard access logs (requested URL, IP address, timestamps). Calendar titles are never put in a request’s web address: the corrections and confirmations of Section 3.3 travel in a request header or body, not in the requested URL that access logs record. We do not use access logs to profile anyone.

3.5 Locations and travel estimates

The Service estimates how long it takes to get between your commitments, so the week view and shift checks leave room for travel, and so the commute planner can tell you when to leave. The location information it uses is: the location text of your calendar events (Section 3.2), the location of a shift you submit for checking when the draft has one, your commute setup (Section 3.3), and, where the Trip room is switched on, the places you type into it (Section 3.3). It uses your device’s location only for live location for travel (below): only where the operator has switched it on and you have turned it on, only when you press “Update from where I am” on a journey, and then only as the 100 metre square your device is in. Here is what happens to that information:

  • Matched on our server first. Location text is compared, on our server, with a short built-in list of places and routes the Service already knows. That comparison involves no one else. Text that matches nothing gets a stated default travel time, labeled as a guess — unless address lookup is on (below).
  • Weather: Open-Meteo, on by default. When the Service builds a live trip plan and that plan includes a Citi Bike leg, our server asks Open-Meteo (api.open-meteo.com) for the hourly forecast where the bike leg starts, so it does not send you cycling into rain. The commute planner, shift checks and, where it is switched on, the Trip room build live trip plans. The week view builds them only during live hours (on weekdays, 7 AM–9 AM, 11 AM–1 PM and 3 PM–6 PM, New York time), and then only for at most two trips per reading of the week — trips to or from an event that starts or ends within the next two hours, along a route on the built-in list; every other trip in the week is worked out without a weather check. The built-in routes are the operator’s own commute, so on any other account the week view builds no live trip plan and asks Open-Meteo nothing. The request carries only a coordinate rounded to two decimal places (about 1 km): no time, no name, no account identifier, and no event text. An operator can switch weather checks off, and then Open-Meteo is never asked, by the week view or anything else; switching live train times off (below) does not switch weather checks off.
  • Citi Bike availability.Live trip plans also download Citi Bike’s public station feeds (gbfs.citibikenyc.com). This is a read of public data; nothing about you or your trip is sent.
  • Bike estimates between your own events: off unless an operator turns it on. Where an operator switches it on, and two of your commitments both have a location the Service already has coordinates for (from the built-in list, or from address lookup if that is on), with no route on file and no subway schedule answer between them, the Service may estimate that trip as a walk to a Citi Bike dock, a ride, and a walk from a dock — for a trip in the next few hours only. The commute planner may estimate a trip between the two places you give it in the same way. It is worked out on our server from the same public Citi Bike station feeds as above, downloaded whole: nothing new is sent to anyone, and no location, event text, time or account detail goes out with the request. No weather is requested for these estimates. Each one says it is modelled from live docks rather than measured, and the docks it chose stay on our server; your browser receives only the travel time and that sentence, and from the commute planner also notes in our own words that name no dock.
  • Subway schedules: worked out on our server, off unless an operator turns it on.Where an operator switches it on, a trip between two places the Service has coordinates for can be estimated by finding a route on the MTA’s published subway timetable. That timetable is a copy of the MTA’s public schedule data (its GTFS feed), downloaded by the operator ahead of time and stored with the Service; the route is worked out entirely on our server, and finding it sends nothing about you, your events or your trip to anyone. The times are the published schedule, not live train positions, and every such estimate says so. Subway schedule data: MTA New York City Transit, obtained from the MTA and stored on our own server; the MTA does not endorse the Service and makes no claim that the data is accurate, complete or timely.
  • Route checking: Google’s Routes API, off unless an operator turns it on — and then only for the operator’s own account.Where an operator switches it on, a trip between the shift or event being checked and the commitment just before or after it, within a few hours, that the Service has positions for — and that no route the Service already knows and no subway-schedule answer covers — can be checked with Google’s Routes API (routes.googleapis.com) instead of being estimated from the distance. That happens whenever a dated shift or event is previewed, and again when its times are edited; nobody has to ask for it. Each trip checked is one request from our server, retried once if Google’s server fails, carrying the trip’s two ends as coordinates — the shift or event’s place (or your workplace, when it has none) and the commitment just before or after it, which can be your home when that is where a commitment is — and the time you need to arrive or leave. Never your identity, an event’s title, or any address text. Checking one event, or all the shifts of a posted schedule, checks at most 4 trips; each account, by default, at most 200 trips a day on each server instance. A retry is the same trip sent again and is not counted again, so one check sends at most 8 requests. The week view’s own drawing never sends a request: it shows a checked route only when one is already held (below). No other account’s trips are ever checked. The key these requests are made with, what Google charges for them, and any spending limit are the operator’s.
  • Live train times: the MTA, on by default during live hours. When the Service builds a live trip plan that includes a subway ride, and the time is within live hours — on weekdays, 7 AM–9 AM, 11 AM–1 PM and 3 PM–6 PM, New York time — our server reads the MTA’s free public live-arrivals feed (GTFS-realtime, at api-endpoint.mta.info) so the wait for the train is the real one rather than one worked out from the published timetable. So the MTA receives our server’s request for its public live feed: the request names only which group of subway lines’ feed to read (for example, the A/C/E lines), which follows from the lines the trip would use. It carries no account identifier, no event text, no times and no places, so nothing in it says whose trip it was. Each server instance reads a given feed at most once every 5 minutes and shares that one answer with every trip it plans in that time. Outside live hours no request is made and waits come from the timetable. An operator can switch live train times off, and then the MTA is never contacted.
  • Address lookup: OpenStreetMap Nominatim, off unless an operator turns it on.The Service can be configured to send location text that matched nothing on the built-in list to OpenStreetMap’s Nominatim service (nominatim.openstreetmap.org) to find its coordinates, which gives a distance-based estimate instead of the default. It is off unless the operator of a deployment explicitly switches it on. When it is on, each lookup sends the location text alone (at most 200 characters, limited to U.S. results) from our server — never your identity, or an event’s title or time — and text the operator has listed as never-to-be-looked-up is withheld.
  • Address lookup: NYC GeoSearch, off unless an operator turns it on. As an alternative to Nominatim, an operator can choose NYC GeoSearch (geosearch.planninglabs.nyc), the New York City Department of City Planning’s search over the city’s official address directory. It works the same way and under the same limits: our server sends the location text alone (at most 200 characters) — never your identity, or an event’s title or time — withholds text the operator has listed as never-to-be-looked-up, and sends at most 12 lookups per request. It only knows New York City addresses, and the Service uses an answer only when it clearly matches what you wrote; anything else falls back to the stated default. Only one lookup service is ever in use at a time.
  • The Trip room: off unless an operator turns it on.Where it is on, the Trip tab plans a trip between two places you type. Our server first compares each place with the built-in list above (only the operator’s own account has places there), then sends the text to the address-lookup service the operator chose (below) — so the Trip room plans nothing where address lookup is off. The operator’s never-to-be-looked-up list is applied to the operator’s own text only; applied to anyone else’s, a refusal would reveal what is on that list. The trip is then worked out on our server as a subway journey on the published timetable (where that is on), or as a walk to a Citi Bike dock, a ride and a walk from a dock from Citi Bike’s public station feeds, or as a walk — and a plan with a Citi Bike leg asks Open-Meteo for the weather, as above. Your browser receives what you typed, the name the lookup matched it to, and the plan’s times, steps and the public names of the docks or stations it uses. Where the map is off, that is all — never a coordinate; where the operator has also switched the map on, the plan also carries the rounded positions described under “The Trip room’s map” below. Nothing about the trip is kept on our servers after the answer is sent, apart from the lookup cache described under “What is kept”.
  • The week map: off unless an operator turns it on, and nothing happens until you open it. On a deployment where it is switched on, the week view offers a map. When you open it, two things happen:
    • Our server looks up where your own events in the week on screen are — the same matching, and the same address lookup if one is on, as for travel estimates — and sends your browser, for each event it could place, the event’s ID and its position rounded to four decimal places (about 10 metres), plus whether the position came from an address lookup. It does not send the address text or a place’s name, and you only ever receive positions for your own events.
    • Your browser loads the map itself — map images (“tiles”), map-label lettering, and icons — directly from OpenFreeMap (tiles.openfreemap.org), a free map service built on OpenStreetMap data. Like any website, it receives your IP address, your browser’s user agent, and our site’s address; and because a tile is a piece of the map, it learns which area you are looking at and how closely — and the map opens on the area around your events. The pins are drawn by our own code on top of the tiles: no event text, time, position, or account detail is sent to OpenFreeMap.
    The lines drawn between your stops are straight lines between two positions, not routes. The map never uses your device’s location.
  • The Trip room’s map: only where both the Trip room and the map are switched on, and nothing is loaded until you open it. The same switch that turns the week map on lets the Trip room show a trip on a map. Where both are on:
    • Each plan our server sends your browser also carries the positions needed to draw it: the two places you typed, as the address lookup (or, for the operator’s own account, the built-in list) placed them, rounded to three decimal places (about 100 metres); for a Citi Bike plan, the two docks it uses, rounded to four decimal places (about 10 metres), and whether each is where you take the bike or return it; and the straight lines of the walks and the ride between those points. A subway plan carries only the two places. No address text, dock or station name, or ID is part of it, and the positions come only from the two places you typed and Citi Bike’s public station feed — never from anyone else’s places or settings. The operator’s home is never drawn: on the operator’s own account, a trip with any of those points within 250 metres of the home the operator configured comes without a map.
    • The map stays closed until you press “Show on map”. Then your browser loads the map from OpenFreeMap (tiles.openfreemap.org), exactly as for the week map above: OpenFreeMap receives your IP address, your browser’s user agent, our site’s address, and which map tiles are loaded — which shows the area of your trip. The start, the destination and the docks are drawn by our own code on top of the tiles: no position, place text, name, time or account detail is sent to OpenFreeMap.
    The lines are straight lines between those points, not the route you would take.
  • What is kept.Travel estimates and map positions are worked out per request and discarded when the response is sent (apart from the journey times kept for travel nudges if you turn them on, a square you share with live location for travel, and checked routes where route checking is on, below); your browser holds the positions only while the page is open. Weather forecasts are kept in server memory for 10 minutes, keyed by the rounded coordinate (Section 7). With address lookup on, results are held in memory for the request; if the operator also configures a cache file, each result — a normalized form of the location text, the coordinates found, and the place’s name — is written to that file on the server, so the same text is not sent twice. Found places stay in the file until it is deleted; not-found ones expire after 30 days. The file is not tied to any account. With route checking on, each checked trip’s travel time and the kinds of travel it used — numbers only, never Google’s description of the route — are held in server memory, keyed to your account, to the two places on a 100-metre grid and to the time in 15-minute steps, so the same trip is not sent twice. An answer is not used after an hour (seven days for a trip with no set time; a failed check after one minute), and is deleted the next time route checking runs, or when the server restarts. Each server instance also counts each account’s trips checked for the current day (UTC); a past day’s count is deleted the next time a trip is checked, or when the instance restarts.
  • Travel blocks.The commute planner, and the Trip room where it is on, can turn a plan into a “Travel to …” event on your calendar. Like any other event, it is shown to you as a preview and written only when you confirm (Section 3.2.1); a travel block added between two commitments may afterwards be kept current, if you turn that on (below).
  • Travel nudges: off unless the operator switches them on, and off for your account until you turn them on.Where they are offered, the You tab has a “Travel nudges” switch. While it is on, each time your week view shows the current week, your browser sends our server the journeys it shows arriving in the next 36 hours; the server checks each against your own calendar and keeps, in our database, the IDs of the two events a journey joins, when you need to leave, when you arrive, the time zone, whether you are the operator (for the operator’s own getting-ready lead), and which nudges have been sent — never a title, place, description or guest, and never your location unless you also turn on live location for travel (below). A scheduler then sends a push to your devices when it is time to get ready and when it is time to leave, saying only that and the time to leave by. A journey is deleted once it is over, or when your calendar no longer shows it; turning nudges off deletes every one (Sections 7 and 10). Nudges need notifications turned on for your device.
  • Keeping travel blocks current: off unless the operator switches it on, and off for your account until you turn it on.Where it is offered, it needs travel nudges on. While it is on, when your week view registers your journeys, the server also looks, on your own calendar, for the travel block the Service added between the two commitments of each journey, works out that journey’s current plan the same way the week view does — from your route and live train times, never your location — and keeps, beside the journey, the block’s event ID, its start and end times, Google’s version tag for it and when the commitment before it ends. Our scheduler compares the plan with the block and records a move for your browser to make (Section 4). Never a title, place, description or guest.
  • Live location for travel: off unless the operator switches it on, and off for your account until you turn it on.Where it is offered, it needs travel nudges on. While it is on, the week view offers “Update from where I am” on a journey that starts within the next 3 hours, and nothing else asks for your location:
    • Only when you press it, your browser finds where you are (asking your permission the first time; on some devices it uses the browser’s or device maker’s own location service to do so), and your device turns that into the 100 metre square it is in before sending anything. Our server receives, in the body of one request, only that square, when it was found and the IDs of the two events the journey joins — never your exact position. A request that puts a location in a web address is refused, because web addresses are written to access logs.
    • Our server checks both events are on your own calendar and the journey starts within 3 hours, then works the journey out again from the middle of the square, exactly as for the week view (the subway schedule and Citi Bike’s public station feed where those are on, and — where address lookup is on — your event’s location text, as in the rest of this section), and sends back the new time to leave and the minutes of travel. The square is sent to no one else, and is never written to a log.
    • Only if travel nudges are watching that journey, our database keeps, beside the journey, the square, when it was sent and the time to leave worked out from it, for at most 30 minutes; our scheduler uses that time for the journey’s nudge while it is under 15 minutes old, and your planned time otherwise. Nothing else about where you are is kept, and your browser keeps none of it. On the operator’s own account, nothing is kept when the square is within 250 metres of the home the operator configured, and the journey is worked out from that home instead.
    • “Stop sharing” on the journey, or turning live location for travel or travel nudges off, deletes what is kept at once (Section 10). Off by default.

None of this involves our AI provider: travel estimates are computed without Anthropic.

4. How we use information

We use the information above to do exactly the things the interface shows:

  • parse your text or image into draft events you review before anything is written;
  • show your week, with busy blocks and realistic free windows;
  • show the next 60 days of your calendar on the Standby Board;
  • estimate travel time between your commitments, and tell you when to leave for the commute you set up (Section 3.5);
  • where live location for travel is on and you turn it on, work out when to leave from where you are when you ask, and time that journey’s nudge from it (Section 3.5);
  • where the week map is switched on and you open it, show where your commitments are on a map (Section 3.5);
  • where the Trip room is switched on, plan a trip between two places you type — and, where the map is also on and you open it, show that trip on a map (Section 3.5);
  • check proposed work shifts against your existing commitments;
  • create, change and delete events in your primary Google Calendar — behind an explicit confirmation step, except for the automatic paths described below;
  • keep the Service working (deduplicate retried writes, enforce rate limits, debug failures from metadata-only logs).

Automatic writes (autopilot). Autopilot is off unless it is switched on. While it is off — the state the Service ships in — nothing reaches your calendar until you confirm a preview, apart from keeping travel blocks current (below), a separate switch that is also off unless you turn it on. While it is on, the Service may create (and, within the limits below, change or remove) an event without asking you first, and only when the parse cleared every one of these gates: high confidence, nothing flagged for review, no warnings, no unresolved research questions, and a complete date and time. Anything that fails a gate still comes to you as a preview. Whatever autopilot does is reported on screen when it happens, marked as done automatically, with the way back beside it: an event it created can be removed there, an event it moved can be changed back there, and an event it removed can be put back there.

Automatic removals.Autopilot removes an event on its own only where the operator of this deployment has switched that on separately, and then only an event the Service itself created: a single event (never a repeating one), with no guests, in a routine category (work, school, or study), named exactly as your message names it, on the day your message names. Anything short of that comes to you as a preview to confirm. An automated removal happens only when the Service can send a notification to a device where you have turned notifications on, and it is then sent to every such device, naming what was removed and when it was. The removal is listed under “Autopilot did this” on the You tab for as long as this server remembers it (at most 24 hours), where it can be put back; Google Calendar’s Trash keeps the removed event for thirty days either way.

Automatic changes.Under the same separate switch and the same limits, autopilot may change the time of, or remove, an event the Service itself created. A change moves only when the event happens, to the time your message names: a message that would also change its place or anything else, or whose new start leaves the event without an end that still fits, comes to you as a preview to confirm instead, as does a repeating event. An automatic change is also refused when the event’s times are no longer the ones the Service last wrote — an event you have moved yourself in Google Calendar is never moved again on its own — or when the event was added before the Service recorded the times it wrote. A serious change — a different day, a move of thirty minutes or more, a change of place (as well as a change of length of thirty minutes or more, a switch between all-day and timed, an event other people are on, a new time that runs into something else on your calendar, or a new time the Service could not check against the rest of your calendar) — is sent as a notification to every device where you have turned notifications on; a routine one is not; an automated change, like a removal, happens only when such a device can be reached. A change is listed on the You tab with the notification naming where it was; change it back in Google Calendar.

Keeping travel blocks current. Separate from autopilot, and off unless the operator of this deployment switches it on and you then turn on “Keep my travel blocks current” on the You tab (it needs travel nudges on). When the latest plan for a journey — worked out from your route and live train times, never your location — says to leave earlier or later than the travel block the Service added for it, the Service moves that block’s start time to match, without a preview. It does so only for a single travel block the Service itself added between two of your commitments, with no guests, whose times are still the ones the Service last wrote and have not changed since the move was worked out; only by more than 5 and at most 60 minutes; only on the same day; never so that the block starts before the commitment before it ends, and never in the past. The block’s end stays at your next commitment’s start, nothing else about the event changes, and Google is told not to email anyone. Our scheduler, which holds no access to your calendar, works the move out; your browser makes it, with your own sign-in, while your week is open in the app, and the week view then says what moved. A block that fails any check is left as it is, and that move is dropped rather than tried again. To undo a move, change the block in Google Calendar: the Service never moves a block you changed. It is per account, off by default, and turning it off (or turning travel nudges off) stops it at once.

Autopilot is per account and off by default. It does nothing for your account until you switch it on from the You tab, and it applies only to the browser you turned it on in, until you sign out, sign in again, or your sign-in expires.

We do not use your information for advertising, do not build profiles for any purpose other than the features above, and do not sell or rent any of it to anyone (Section 8).

5. AI processing — what is sent to Anthropic, exactly

The intelligence in Calmora comes from AI models operated by Anthropic, PBC (api.anthropic.com). This section is the complete list of what crosses that boundary when you use the Service (one additional flow exists that never involves your data: the operator-configurable email capability of Section 6.1). Three properties hold for every flow below:

  • All AI calls are made from our server.Your browser never talks to Anthropic, and the page’s security policy (Section 11) blocks it from talking to anything but the Service’s own origin — and, only where the map is switched on (the week map, and the Trip room’s map), the map-tile host (Section 3.5).
  • Your data is not used to train models.Anthropic’s Commercial Terms of Service provide that Anthropic may not train models on customer content from its API services (see Anthropic Commercial Terms), and we do not opt in to any data-sharing or training program. We request provider-side prompt caching only for our own fixed instructions — never for your content.
  • Untrusted content is fenced. Everything user-provided or external (your text, image contents, calendar titles, web results) is wrapped in explicit data-only delimiters and sanitized, and the instructions tell the model to treat it as data, never as commands. This is a prompt-injection defense, not a privacy control, but it shapes every request we send.

5.1 Typing an event

When you type an event and the AI parser is available, the Service sends Anthropic your typed text (up to 2,000 characters) together with the current date and your time zone. The model returns one structured draft event. If the AI parser is not configured at all, nothing is sent anywhere and an offline, deterministic parser handles your text with a visible “AI unavailable” notice; if a live AI call fails or times out, the same offline fallback and notice apply — in that case your text was transmitted in the failed attempt, but nothing further is sent.

5.2 Uploading a schedule image

When you upload a schedule image, the Service sends Anthropic the image itself, the current date and week boundaries, your time zone, your optional hint, and an identity block used to find your rows in a shared roster: the name being searched for, mechanically derived variants of it (initials, reversed order, first or last name alone, configured aliases), and — when you are signed in — your email address. We state that plainly because it is easy to miss: on this one flow, your account identifiers accompany the upload, so the model can tell which rows of a multi-person schedule are yours. If no confident match is found, the extractor is instructed to return no events; anything it returns anyway is shown unselected behind a prominent “could not confirm which row is yours” warning and is never added to your calendar without your explicit per-event confirmation.

5.3 Reading your week

Rendering your week, checking shifts, checking a change to an event (yours or autopilot’s) for what it runs into, and checking what turned up in the email feed (Section 6.1) against your calendar are mostly local arithmetic. The one AI-backed piece, in each of them: when an event title is too terse for the Service’s built-in rules to categorize (“Alesso” rather than “Alesso concert”), that title — and only the title — is sent to Anthropic to ask what kind of commitment it is. This flow is deliberately minimal:

  • only titles the local rules could not read are sent — anything recognizable never leaves;
  • duplicate titles are sent once, results are cached for your sign-in session (Section 7), and titles are truncated to 300 characters;
  • the titles of tentative holds and travel blocks the Service wrote into your calendar (Section 3.2.1) are never sent;
  • a title whose guess you confirmed (“Yes”, Section 3.3) is not sent again when your week is rendered, a shift is checked, a change to an event (yours or autopilot’s) is checked for what it runs into, or the email feed is checked against your calendar, from that browser: your browser sends the confirmed category with the request and the Service uses it as it is. Your browser sends as many confirmations as fit in the request, those most recently answered or on a week you viewed first; one that does not fit is guessed about again like any other title;
  • no name, email, or account identifier accompanies the title in the request;
  • event descriptions, attendees, and locations are never sent on this flow;
  • every guess the model made that appears in your week view is shown with the model’s reason and can be rejected; a guess you confirmed is listed with your answer and an Undo that brings the question back, where you can answer “No”; guesses that would not change how much of your day is reserved, and guesses you have confirmed, are listed under the week without a question rather than hidden. A title you rejected is not sent again when a shift is checked from that browser, and not when your week is rendered, a change to an event (yours or autopilot’s) is checked, or the email feed is checked against your calendar either, with one limit: for those three, your browser sends the most recent rejections that fit in the request; an older one that does not fit may be guessed about again, and the week view then shows it as not applied;
  • if the model is unsure or unavailable, the Service simply treats the event as uncategorized.

Because, under Google Calendar’s common default settings, invitations can be placed on your calendar by anyone who knows your email address, an unclassifiable title there may have been written by a third party; the fencing described above treats every title as untrusted for exactly that reason.

5.4 Looking up a public event (research)

When a parse needs facts the model should not guess (like a concert’s venue) and the research feature is enabled on the deployment you are using, the Service sends a search query built from the draft’s title, location name, and date to Tavily (api.tavily.com), a web-search API, and then sends the top results (short excerpts) plus the draft’s title and date to Anthropic to fill in missing fields. Research results can only ever fill blanks and add warnings — they can never overwrite what you typed or promote a draft past your review. When the research feature is not configured, no research request is made at all and the draft is returned unchanged, still marked as needing your verification, rather than guessed at.

5.5 What does NOT go to any AI provider

  • Your Google tokens, password, or any credential — never.
  • Your calendar as a whole. There is no bulk export, sync, or embedding of your calendar anywhere.
  • Your email. Nothing from your mailbox is sent to any AI provider. If you connect Gmail to the Standby Board, your mail is sorted on our server by fixed rules, with no AI call (Section 6.1).
  • Anything, when the corresponding feature is unconfigured — every AI call is gated on its key being present, and absent keys mean offline fallbacks or honest “unavailable” errors, never silent substitutes.

For completeness: the codebase contains an alternative adapter for OpenAI that is not wired into the running Service — no data is sent to OpenAI. If we ever switch or add AI providers, this policy will name them before the change takes effect.

6. Google user data — access, use, storage, sharing (Limited Use)

This section restates, in Google’s required frame, how the Service handles information received from Google APIs.

  • Access: identity basics (openid, email, profile) and read/write access to events on your primary calendar via the calendar.eventsscope, as described in Section 3; and, only if you choose “Connect Gmail” on the Standby Board where the operator has switched its mail view on, read-only access to your Gmail (Section 6.1).
  • Use: solely to provide the user-facing features that are prominent in the interface — parsing events you submit, rendering your week, your availability, and the Standby Board, estimating travel between your commitments, showing them on the week map when you open it, checking shifts, and creating, changing or deleting events on the terms set out in Section 4 (your confirmation; autopilot when it is switched on; or, if you turn it on, keeping the travel blocks the Service added current — each within the limits described there). Not for advertising. Not for credit-worthiness or lending decisions. Not to build databases about you.
  • Storage:Google calendar data is not stored durably on our servers. The one piece of Google user data kept durably is your Google account’s email address, and only if you save a commute while signed in: it is the key under which that commute is stored in our database (Section 7), so it can be returned to you and to no one else. No calendar content is stored there — with one exception you choose: where travel nudges are offered and you turn them on, the same database keeps, under the same email key, the IDs of the calendar events your next journeys join and their leave-by and arrival times, until each journey is over (Section 3.5); and, if you also turn on keeping travel blocks current, the ID and start and end times of the travel block the Service added for each of those journeys (with Google’s version tag for it), and a record of each automatic move made or refused (an internal draft ID and the outcome of the checks), until you turn it off (Sections 4 and 7); and, if you also turn on live location for travel, the time to leave worked out from where you were for a journey, for at most 30 minutes (Section 3.5). Never an event’s title, place, description or guests. Beyond that, no files are written except one that exists only if an operator switches it on: the address-lookup cache of Section 3.5, which can hold event location text (in normalized form, with its coordinates) and is not tied to any account (Section 7). Transient in-process memory (for example, the per-sign-in title-category cache) is enumerated in Section 7 with its bounds and lifetimes. Your tokens live encrypted in your own browser.
  • Sharing:the only transfers of Google user data to a third party are the AI flows itemized in Section 5 — narrowly scoped payloads sent to Anthropic (and, for research on public events, a query to Tavily) — and the travel lookups in Section 3.5: a coordinate rounded to about 1 km, which may be derived from an event’s location, sent to Open-Meteo for a weather check; during live hours, a request to the MTA naming only which group of subway lines’ public live feed to read, which may follow from the lines a trip between your events would use; and, only where an operator has turned address lookup on, an event’s location text sent to OpenStreetMap’s Nominatim service or to NYC GeoSearch to find its coordinates; and, only where an operator has turned route checking on and only for the operator’s own account, the coordinates of a trip’s two ends (the shift or event being checked, or the workplace, and the commitment just before or after it) and the time of the trip, sent to Google’s Routes API to check how long it takes. One further flow is indirect, and we state it so it is not missed: where the week map is switched on and you open it, your browser requests map tiles from OpenFreeMap for the area around your events, so OpenFreeMap can infer that area from which tiles were requested — though it receives no event text, times, positions, or account details. Where account storage is switched on, your email address is also held by Neon, Inc., the database host (Section 8), as the key of the commute you saved — and, if you turn travel nudges on, as the key of the event IDs and journey times they keep — stored for us, not shared for any use of Neon’s own. Each serves those same user-facing features. Google user data is never transferred to advertising platforms, data brokers, or information resellers, never sold, and never used for any purpose beyond the features you can see.
  • AI/ML restriction: Google user data sent to our AI provider is used only to produce the immediate, user-visible result and is not used — by us or, per its terms, by Anthropic — to create, train, or improve any machine-learning or artificial-intelligence model.
  • Human access:no one, including the Operator, reads your Google user data through the Service: no screen, route, or log line exposes one account’s calendar content to anyone else. The narrow exceptions Google’s policy contemplates apply here too — we may access data where you explicitly ask us to (for example, helping you debug with data you share), where necessary for security (investigating abuse), or where required by law.

Calmora’s use of information received from Google APIs will adhere to the Google API Services User Data Policy, including the Limited Use requirements. The use of information received from Google Workspace scopes will adhere to the Google User Data Policy, including the Limited Use requirements.

6.1 Email

Signing in requests no Gmail permission, and an account that never connects Gmail gives the Service no way to read its mailbox — the sign-in scopes are pinned by an automated test in the codebase. There are two email capabilities in the codebase, and each is off unless the operator switches it on.

The Standby Board’s mail view — your own mail, only if you connect it.Where the operator has switched it on, the Standby Board offers a “Connect Gmail” button. Nothing is read unless you click it and grant Google’s separate consent for the read-only Gmail scope (https://www.googleapis.com/auth/gmail.readonly) — never the scope that can change or send mail. Once granted, the board reads your own mailbox with your own grant: the sender, subject, date, labels and Google’s one-line preview of recent messages (up to 50 inbox messages from the last 7 days, and up to 40 messages from the last 45 days, sent or received, whose subject mentions an application, an interview, availability or next steps), never message bodies or attachments. It sorts them on our server by fixed rules — no AI provider is involved — and sends your browser only the sender, subject, date and thread ID; the preview line is used for that sorting and discarded when the response is sent. Nothing read from your mail is stored on the server or written to logs, which carry only counts; the one trace is a per-account request count in server memory for rate limiting, as in Section 3.4. The Gmail grant is kept in the same encrypted session cookie as your calendar grant (Section 7). Removing Calmora at your Google Account permissions page ends it (Section 10).

The operator’s own scanner — never your mail. The codebase also contains an email-scanning capability an operator can configure for the operator’s own mailbox: a scanner running inside the operator’s own Google account hands pre-filtered messages to that operator’s deployment, where excerpts of them (sender, subject, and message text) are sent to Anthropic to extract commitments — the operator’s own data, never yours. That capability is off unless the operator explicitly configures it, is not configured on the public Service as of the effective date, and — whatever its configuration — never reads the mailbox of anyone who signs in. What it extracts is shown only to the operator, in an email feed that checks each item against the operator’s own calendar the way Section 5.3 describes.

7. Where data lives, and for how long

The Service is deliberately built with as little storage as it can manage. The durable copies of your data live in systems youcontrol — your Google Calendar, your Google account, and your own browser — with three exceptions, all in our database: the commute setup you save while signed in, which lives there so it can follow you between devices; what travel nudges need, only if you turn them on where they are offered; and a single row recording that your account has signed in. Here is the complete inventory as the public Service runs (the operator email capability of Section 6.1, when an operator configures it, adds in-memory stores of the operator’s own email-derived proposals, message IDs, and extraction counters — bounded, and likewise erased on restart):

  • Google tokens and identity — your browser. Stored in the session cookie, encrypted with a server-held key, marked HttpOnly and Secure, expiring after about 30 days of inactivity or when you sign out. The server never persists them.
  • Your calendar — your Google account. The Service reads it per-request and keeps no copy. Events it creates (with the properties described in Section 3.2.1) live in your calendar under your control.
  • Rejected-category titles — your browser.One localStorage entry, the 50 most recent titles, kept until you clear your browser’s site data for the Service. It is not tied to an account, and signing out does not clear it.
  • Confirmed guesses — your browser.One localStorage entry: of the titles you confirmed, the 100 most recently answered or on a week you viewed, each with the category you confirmed. Sent with that browser’s requests (Section 3.3) and kept on none of our servers. Removed when you sign out on that browser or clear its site data for the Service.
  • Commute setup — our database, and your browser.Where account storage is switched on and you save your commute while signed in, one row in a Postgres database hosted by Neon, Inc. (Section 8) holds your commute answers (Section 3.3), your account’s email address as the row’s key, and the time it was last saved — nothing else. It is kept until you delete it with the commute setup’s “Delete my saved commute” button or ask us to (Section 10); saving again replaces it, and a server restart does not erase it. Your browser also keeps a localStorage copy (Section 9), kept until you change it, delete it, sign out (for a copy that came from your account), or clear your browser’s site data for the Service. Where account storage is not switched on, the browser copy is the only one.
  • That your account signed in — our database. Where account storage is switched on, one row per account holds your email address, the first and last time the Service saw you, and how many times you have signed in. It holds nothing about what you did, no calendar data, and no tokens. It is written when you sign in and kept until you ask us to delete it (Section 10); deleting your commute setup does not remove it, because it is a different row answering a different question.
  • How often the Service was used — our database, with no link to you. Daily totals of four things: sentences parsed, schedule photos read, events added, and automatic writes. The table storing them has no column for an account, so there is nothing in it to connect a count to a person — not your address, not an identifier, not an IP. Kept indefinitely as aggregate numbers, because once recorded there is nothing personal left in them to expire.
  • Typed text and uploaded images — request lifetime only. Processed in memory, never written to disk, gone when the response is sent.
  • Push subscriptions — server memory, only if you enable notifications. When you turn on push, your browser’s subscription (a device endpoint URL and the two keys needed to encrypt a message to it) is held in the server’s in-process memory so it can be reached when the Service writes an event, removes one automatically, or makes a serious change to one (Section 4), and when you press “Send a test notification”. No name or calendar content is stored with it; it is dropped when the server restarts or when the push service reports the subscription is gone, and you can end it by turning notifications off. Signing out also ends notifications on that browser: the Service asks the server to forget its subscription and tells the browser to drop it. If you have turned travel nudges on, a copy is also kept in our database (next item).
  • Travel nudges — our database, only if you turn them on.Where the operator offers travel nudges and you turn them on, the Postgres database hosted by Neon, Inc. (Section 8) keeps, keyed to your account’s email address: that you turned them on; for each journey your week view showed arriving in the next 36 hours, the IDs of the two calendar events it joins, when you need to leave, when you arrive, the time zone, whether you are the operator, and which nudges have been sent; and a copy of the push subscription (endpoint URL, the two encryption keys, and a device name such as “iPhone”) of each device, at most 10, where you have turned notifications on. No event title, place, description or guest is kept, and no location of yours unless you also turn on live location for travel (below). A journey is deleted once it is over, or when your week view no longer shows it. A device copy is kept until you turn nudges off, turn notifications off on that device or sign out there, or its push service reports it gone. Turning nudges off deletes all of it at once (Section 10); a server restart does not erase it.
  • Keeping travel blocks current — our database, only if you turn it on. Beside each journey above: the event ID of the travel block the Service added for it, the block’s start and end times, Google’s version tag for it (so a block you edited in any way since is left alone), when the commitment before it ends, when that was read, and the move waiting to be made (the new start and end, the minutes, and when it was worked out). These go with the journey. And, keyed to your account’s email address, a record of each automatic move made or refused: an internal draft ID (made of event IDs and a time), that it was this kind of automation, whether it was allowed and which checks stopped it, and when — never a title, place, description or guest. The records are kept until you turn keeping travel blocks current or travel nudges off (Section 10); if one cannot be written there, it goes to the server-memory buffer below instead.
  • Live location for travel — our database, 30 minutes at most, only if you turn it on.Beside a journey that travel nudges are watching, when you press “Update from where I am”: the 100 metre square your device was in (two whole numbers naming the square, never a latitude or longitude), when you sent it, and the time to leave worked out from it. Each is deleted 30 minutes after it was sent at the latest — every read of it refuses an older one and our scheduler clears older ones — and at once when you press “Stop sharing”, turn live location for travel or travel nudges off, or the journey is over. Nothing is kept for a journey nudges are not watching, and, on the operator’s own account, nothing near the home the operator configured. Never written to a log.
  • Title-category cache — server memory.Capped at roughly 500 entries per server process, keyed to an identifier issued at each sign-in, holding a title, its inferred category, and the model’s one-line reason. No fixed expiry: at the cap the oldest entry is dropped for each new one, and everything is erased on server restart.
  • Write-deduplication records — server memory, 10 minutes.After a confirmed write, the created event’s ID and its Google Calendar link are remembered briefly (at most 10 minutes) so a retried request cannot create a duplicate.
  • Write-decision records — server memory. Each confirmed, automatic, or refused calendar write adds a small content-free record (internal draft ID, the kind of write, decision, for an automatic change or removal how serious it was judged, and timestamp — never event details) to a buffer capped at 200 entries, kept for debugging the confirmation safeguards. For keeping travel blocks current, these records are kept in our database instead (previous items).
  • Autopilot activity — server memory, 24 hours. The IDs of events autopilot changed or removed for your account, at most 20, with no titles or times, so the You tab can list what happened and offer to put a removed event back. Each entry is dropped after 24 hours or when the server restarts, whichever comes first; no other account can read it.
  • Travel estimates and map positions — request lifetime only.Location text, the travel times worked out from it, and the rounded positions sent to your browser for the week map and the Trip room’s map (Section 3.5) are held while a request runs and discarded when the response is sent — apart from checked routes, below.
  • Weather forecasts — server memory, 10 minutes.Up to 200 hourly forecasts, each keyed by a coordinate rounded to about 1 km, with no account, name, or event attached. Each expires after 10 minutes.
  • Checked routes — server memory, an hour (seven days with no set time), only where an operator turns route checking on.For the operator’s own account only: each checked trip’s travel time and the kinds of travel it used, as numbers (never Google’s description of the route), keyed to the account’s email address, to the trip’s two places on a 100-metre grid, and to its time in 15-minute steps; bounded in number, and each is not used after an hour (seven days for a trip with no set time; a failed check after one minute) and is deleted the next time route checking runs, or when the server restarts. Alongside, each server instance keeps a count of each account’s trips checked for the current day (UTC), to enforce the daily limit; a past day’s count is deleted the next time a trip is checked, or when the instance restarts.
  • Live train feed — server memory, 5 minutes. Where live train times are on (Section 3.5), the last answer read from each of the MTA’s subway feeds is kept, keyed by that feed’s address, so every trip planned in that span shares one request. It is the MTA’s public data: no account, event, time, or place of yours is attached to it. Each copy expires after 5 minutes.
  • Address-lookup cache file — server disk, only if an operator configures it. Where address lookup is on and a cache file is configured (Section 3.5), looked-up location text, in normalized form, is stored with its coordinates and place name, not tied to any account. Found places stay until the file is deleted; not-found ones expire after 30 days.
  • Rate-limit counters — server memory.Request counts for the parsing, trip-planning, and week-map endpoints, keyed by your account’s email address when you are signed in and by IP address otherwise, swept opportunistically and cleared on restart.
  • Server restart clears everything server-side. Every structure above that lives in server memory is erased whenever the server process restarts. Nothing user-derived survives on our side, apart from your saved commute in the database, your travel-nudge data there if you turned nudges on (including, for at most 30 minutes, a square you shared with live location for travel), and the address-lookup cache file above where an operator has configured one.
  • Provider-side handling.Data sent to Anthropic under Section 5 is processed by Anthropic under its Commercial Terms and Data Processing Addendum and is not used for model training; retention on Anthropic’s side is governed by Anthropic’s published practices, not by us. The same structure applies to Tavily for the research queries described in Section 5.4, to Google for API traffic, to Open-Meteo and (where address lookup is on) the OpenStreetMap Foundation or the New York City Department of City Planning for the travel lookups in Section 3.5, to Google for the route checks in Section 3.5 (where an operator turns them on), to the MTA for the live-feed reads in Section 3.5 (which carry nothing about you), and (where the map is on) to OpenFreeMap for the map requests your browser makes. Neon, Inc. stores the database on our behalf; deleting your saved commute, or turning travel nudges off, deletes the rows, and Neon’s own backups of the database are retained and expire under Neon’s published practices.

8. Who we share data with — the complete list

We share data with no one except the service providers required to run the product, each receiving only what its role requires:

  • Google LLC— sign-in (OAuth) and the Calendar API itself. Google necessarily processes your requests to your own calendar. And, only on a deployment where the operator has turned route checking on, which is off unless explicitly configured (Section 3.5), and then only for the operator’s own account, its Routes API (routes.googleapis.com): the coordinates of a trip’s two ends — the shift or event being checked (or the workplace) and the commitment just before or after it — and the time of the trip, to check how long it takes. Never your identity, an event’s title, or address text.
  • Anthropic, PBC— the AI flows itemized in Section 5 (plus, on a deployment where an operator has configured the Section 6.1 email capability, the operator’s own email excerpts), under terms that prohibit training on the data.
  • Tavily, Inc. — only when the public-event research feature runs (Section 5.4): a search query derived from the draft event (title, location name, date). Never your identity, tokens, calendar contents, or images.
  • Open-Meteo(weather forecasts) — only when a live trip plan includes a Citi Bike leg (Section 3.5): a coordinate rounded to about 1 km, to get the hourly forecast there. Never your identity, the time of your trip, or any calendar text. On by default; an operator can switch it off.
  • OpenStreetMap Foundation(its Nominatim address-lookup service) — only on a deployment where the operator has turned address lookup on, which is off unless explicitly configured (Section 3.5): location text that matched no place the Service already knows — from your calendar, your commute setup, or the Trip room where that is on — to find its coordinates. Never your identity, or an event’s title or time.
  • New York City Department of City Planning (its NYC GeoSearch address-lookup service, geosearch.planninglabs.nyc) — only on a deployment where the operator has chosen it for address lookup, which is off unless explicitly configured (Section 3.5): location text that matched no place the Service already knows — from your calendar, your commute setup, or the Trip room where that is on — to find its coordinates, sent from our server. Never your identity, or an event’s title or time.
  • OpenFreeMap(Hyperknot Software Kft., Hungary; map tiles built from OpenStreetMap data) — only on a deployment where the operator has switched the week map on (the same switch lets the Trip room show a trip on a map), and only while you have the week map or a trip’s map open (Section 3.5). Your browser requests the map from tiles.openfreemap.orgdirectly, so OpenFreeMap receives your IP address, your browser’s user agent, our site’s address, and which map tiles you view — which reveals the area around your events, or around a trip you planned. Never your identity, calendar text, event times, event positions, or the places you typed into the Trip room or their positions. Its privacy policy states that it uses no cookies or tracking, keeps server logs without IP addresses except temporarily during a security incident, and may deliver content through Cloudflare.
  • Our hosting provider (currently Vercel, Inc. for the hosted Service) — runs the servers, terminates HTTPS, and keeps standard infrastructure access logs (Section 3.4). It also provides the page-view counting described in Section 12, and so receives, for each page opened: the path, the referrer, a coarse device type and country, and a visitor identifier it derives on its own servers and rotates daily. It receives no calendar data, no account, and no cookie — there is none to send.
  • Neon, Inc.(database hosting) — only where account storage is switched on: hosts the Postgres database, in the United States, that stores the commute setup you save while signed in (Section 7) — your commute answers and your account’s email address as their key — and, only if you turn travel nudges on where they are offered, the nudge data in Section 7 (event IDs and journey times, and your devices’ push subscriptions, and — if you turn live location for travel on — a 100 metre square for at most 30 minutes) — together with the sign-in record and the anonymous daily counters described in Section 7. Neon stores those on our behalf and receives nothing else: no event titles or places, no tokens, and none of your other requests.
  • The operator’s own scheduler— only on a deployment where travel nudges are switched on: a script in the operator’s own Google account (Google Apps Script) calls our server every few minutes with a shared password, and our server answers with counts (how many nudges were due and sent). Nothing about you is sent to it or through it.
  • The operator’s own scanner— only on a deployment where the Section 6.1 email capability is configured: the server exchanges a shared secret and message IDs with the scanner web app in the operator’s own Google account. Not applicable to the public Service.
  • Your browser’s push service(Apple, Google, or Mozilla, whichever your browser uses) — only if you turn on push notifications: after the Service writes an event, removes one automatically, or makes a serious change to one (Section 4), it hands that push service one message containing the event’s title and time — and, for a move, the time it was at and, if the place changed, the new place, plus, where they apply, how many guests can see it and the names of anything on your calendar the new time runs into — addressed to your device alone; and, when you press “Send a test notification”, one test message to each of your devices that says only that notifications are working, with nothing from your calendar. Where the operator offers travel nudges and you turn them on, it also carries each nudge: only that it is time to get ready or to leave, and the time to leave by. Every message is encrypted for your device, so the push service cannot read it. Off unless you enable it; the push service delivers it to you and to no one else.

For completeness: live trip plans, and the bike estimates between your events where those are switched on, also download Citi Bike’s public station feeds (Section 3.5). That is a read of public data — nothing about you is sent — so Citi Bike is not a recipient of your data. Subway schedule estimates (Section 3.5) likewise use a copy of the MTA’s public timetable kept on our server and send nothing. Live train times are different, and we list them so they are not missed: by default, during live hours (on weekdays, 7 AM–9 AM, 11 AM–1 PM and 3 PM–6 PM, New York time), a live trip plan with a subway ride makes our server read the MTA’s public live feed (api-endpoint.mta.info). The request names only which group of subway lines’ feed to read — which follows from the trip’s lines — and carries no identity, event text, times or places; each server instance reads a feed at most once every 5 minutes and shares that answer across the trips it plans. An operator can switch it off (Section 3.5). Live location for travel, where it is on and you use it, sends your position to no one but our server, and only as a 100 metre square: your browser finds where you are its own way — on some devices by asking the browser maker’s or device maker’s location service, under their own terms — and the Service receives only the square (Section 3.5).

We do not sell personal information, do not share it for advertising of any kind, and do not provide it to data brokers. If a legal demand for user data ever arrives, we will disclose only what the law compels after reviewing the demand’s validity, and — unless legally forbidden — will tell the affected user. If the Service is ever acquired or merged, Google user data would be transferred only with your explicit prior consent, as Google’s policy requires; for all other data, this policy would continue to apply and you would be notified before any new policy takes effect.

9. Cookies and local storage

The Service sets only the cookies that sign-in requires — there are no advertising, analytics, or tracking cookies of any kind. That stays true now that page views are counted (Section 12): the counting stores no identifier in your browser at all, so it has nothing to keep in a cookie. The complete list:

  • a session cookie (authjs.session-token, with a __Secure- prefix over HTTPS) — the encrypted container for your session and Google tokens; HttpOnly, SameSite=Lax, up to ~30 days;
  • a CSRF-protection cookie and a callback-URL cookie used by the sign-in flow, with the same protections;
  • short-lived (15-minute) cookies that exist only during the OAuth handshake itself.

Local storage holds at most five entries: the rejected-titles list and the confirmed-guesses list, both described in Section 3.3; if you complete commute setup, your commute answers (which may include an address you typed), also described there; when that commute came from or was saved to your account, a note of which account it belongs to (your email address), so the Service never shows one account’s commute to another account signed in on the same browser; and, if you save a place in the Trip room, your saved trip places (calmora.trip.places.v1: a short name and the text you typed for each, which may be an address, Section 3.3). If you turn on push notifications, your browser also installs the Service’s small background worker, which keeps a copy of the app’s own static files — code, icons, and an offline page — in your browser’s cache; none of that is personal. If you open the week map or a trip’s map, your browser’s ordinary web cache may also keep the map images and lettering it downloaded from OpenFreeMap, as it would for any website; neither map sets cookies or writes local storage. That is the entire client-side footprint.

10. Your choices and controls

  • Revoke Google access (the master switch). Visit myaccount.google.com/permissions and remove Calmora. This invalidates the Service’s ability to touch your calendar even if a session cookie still exists somewhere. We say this explicitly because signing out alone clears your cookie but does not revoke the Google-side grant; for a complete disconnect, do both.
  • Sign out.Destroys the session cookie in your browser — the only copy of your tokens — and removes the confirmed-guesses list from that browser. The rejected-titles list stays until you clear the browser’s site data.
  • Delete events. Events the Service just created can be removed in-app through its preview-and-confirm flow; any event it created can always be deleted directly in Google Calendar, which you control.
  • Delete your saved commute.Open the commute planner, press Change, then “Delete my saved commute”. That deletes it from your account (the database row, Section 7) and from this browser; your other devices lose their copy the next time they load. You can also change it at any time the same way. Signing out removes this browser’s copy of an account-saved commute but keeps it in your account, and revoking Google access does not delete it either — to remove it from our database, use the delete button (signed in) or email us.
  • Turn travel nudges off.Where they are offered, switching “Travel nudges” off on the You tab deletes, at once, everything they kept in our database for your account: your upcoming journeys, the copies of your devices’ push subscriptions, and the record that you turned them on (Section 7). Turning notifications off on a device, or signing out there, deletes that device’s copy. Turning nudges off also turns off keeping travel blocks current and deletes its records. There is no separate account-deletion button; to have everything deleted, use these switches or email us.
  • Turn off keeping travel blocks current.Where it is offered, switching “Keep my travel blocks current” off on the You tab stops it at once — no further move is worked out or made — and deletes the travel-block times, the moves waiting to be made and the record of past moves it kept for your account (Section 7). A block it already moved stays where it is; change it in Google Calendar if you want.
  • Stop sharing your location.Where live location for travel is offered, “Stop sharing” on the journey deletes, at once, every square and time to leave kept for your account; switching “Live location for travel” (or travel nudges) off on the You tab does the same and stops the button being offered. You can also block location for this site in your browser’s settings; then nothing can be sent.
  • Delete saved trip places.In the Trip tab, “Remove” deletes one saved place and “Remove all” deletes them all, from this browser — the only place they are kept. Signing out does not remove them.
  • Clear corrections and browser copies.Clearing the Service’s site data in your browser removes the rejected-titles list, the confirmed-guesses list, this browser’s copy of your commute, and your saved trip places. It does not touch a commute saved to your account.
  • Ask us. Email darwinhu64@gmail.com for access, deletion, or questions. The durable user data the server keeps is your saved commute, if you saved one, and your travel-nudge data, if you turned nudges on (we will send you a copy or delete them on request, from the address on your account), and the address-lookup cache file of Section 3.5, which, where one is in use, we will delete on request. Every other server-side trace of your use expires on its own or is erased when the server process restarts (Section 7); we will confirm, and will restart the server process to flush transient memory on request. For AI-provider-side data, we will relay requests to Anthropic where applicable.
  • Export. The durable copy of your calendar stays in your Google account, so Google Takeout exports everything, including events the Service created.

11. Security

What protects your data here, concretely:

  • all traffic is encrypted in transit (HTTPS, terminated and enforced by our hosting provider’s edge);
  • your Google tokens exist only inside an encrypted (JWE), HttpOnly, Secure cookie — there is no server-side token store to breach;
  • the database is reachable only from our server, over an encrypted connection, and each request can read or change only the signed-in account’s own rows — the key comes from your session, never from anything the browser sends; the one part of the server that reads across accounts is the travel-nudge scheduler, which answers only to a shared password sent in a request header, and reads only the journeys of accounts that turned nudges on;
  • a strict, per-request Content-Security-Policy confines the browser to the Service’s own origin: no third-party scripts can load (the map library, too, is served from our own origin), scripted requests can reach only the Service itself — plus, only on a deployment where the week map is switched on (the same switch serves the Trip room’s map), the map-tile host tiles.openfreemap.org — and the one off-origin form action the policy permits is the sign-in form submission to accounts.google.com;
  • security headers deny framing, MIME sniffing, and access to camera, microphone, and geolocation — the Service never asks your browser for any of those;
  • our application logs are structurally incapable of carrying your content (Section 3.4), and calendar titles are never placed in request URLs, so the host’s standard access logs do not record them either;
  • all user-provided and external text entering AI prompts is sanitized and fenced as untrusted data, and AI calls run with no tools and no ability to write to your calendar;
  • every write to your calendar requires your explicit confirmation, except where autopilot has been switched on and the draft cleared every safety gate (Section 4); a change or removal, confirmed or automatic, refuses to touch anything the Service did not itself create, and an automatic one additionally needs the operator’s separate switch and a device of yours to notify.

No internet service can promise perfect security, and we do not. What we can promise: the attack surface here is unusually small because so little is stored, and if we ever learn of a breach affecting your personal information we will notify you and the relevant authorities as applicable law (including New York’s SHIELD Act) requires, promptly and plainly.

12. Do Not Track, and tracking generally

The Service shows no advertising, does not follow you across other websites, and does not allow other parties to collect information about your activities through it. It does count page views, and this section says exactly what that is rather than leaving it to the word “analytics”.

What is counted. For each page you open: which page it was, the site you arrived from if any, a coarse device type and country, and a visitor identifier that Vercel (Section 8) works out on its own servers and changes every day— so visits on two different days cannot be joined together, and none of it names you. It reads nothing from the page in front of you: no event, no title, no place, no address, no account. It sets no cookie and stores nothing in your browser (Section 9). The script and the measurement it sends both come from this site’s own address, so your browser contacts no other host to do it.

Do Not Track does something here. If your browser sends a Do Not Track header or a Global Privacy Control signal, the measurement is discarded in your browser before anything is sent — not reduced, not anonymised further: not sent. That check runs for every page view rather than once when the page loads, so a signal you switch on mid-visit takes effect immediately.

Counting page views therefore adds no other party to the list: the script and its measurement are our own address, so your browser still speaks to nobody else — with one disclosed exception, unchanged by any of the above. Where the map is switched on and you open the week map or a trip’s map, the map-tile host (OpenFreeMap, Section 8) necessarily receives your browser’s requests for map tiles, as any web server receives the requests sent to it; by its own privacy policy it sets no cookies and uses no tracking technologies.

13. Children

The Service is not directed to children under 13, and we do not knowingly collect personal information from children under 13. If you believe a child has used the Service, contact us at darwinhu64@gmail.com and we will delete what little may exist (Section 7 describes why that is at most a saved commute).

14. United States processing, and regional notes

The Service is operated from the United States and its servers process data in the United States; the providers in Section 8 may process data in other locations under their own terms. If you use the Service from elsewhere, you are sending your data to the U.S.

California:we honor CalOPPA’s disclosure requirements throughout this policy (categories collected: identifiers, calendar/schedule content, and location information — event locations and the commute details you enter — Section 3; third parties: Section 8; change process: Section 15; effective date: above). We are an individual developer and believe we are far below every threshold that makes the CCPA/CPRA’s obligations apply — but as a matter of practice we honor access and deletion requests from anyone, from anywhere (Section 10), and we do not sell or share personal information as those laws define those terms.

15. Changes to this policy

When our practices change, this page changes first: we will update the policy and its effective date before the new practice takes effect, and material changes (a new data category, a new third party, a new use) will be called out prominently on this page. If a change would expand how Google user data is used beyond what this policy discloses, it will not ship until this policy — and where required, our Google verification — has been updated to cover it. Continued use after the effective date constitutes acceptance of the updated policy.

16. Contact

Darwin Hu — Operator, Calmora
darwinhu64@gmail.com
New York, United States

See also our Terms of Service.

Calmora

Privacy Policy

Effective date: October 2, 2026

Calmora is a scheduling assistant that turns plain language and schedule images into Google Calendar events, and shows you what your week actually has room for. It works on deeply personal data — your calendar — so this policy is written to be specific rather than broad: it names exactly what is collected, exactly where it goes, and exactly how long it exists. If a practice is not described here, the Service does not do it.

What changed on October 2, 2026

Route checking with Google’s Routes API, off unless the operator of a deployment switches it on — and then only for the operator’s own account. Where it is on, a trip between a shift or event you are checking and your commitment just before or after it can be checked with Google instead of being estimated from the distance. This is a new recipient of data:

  • What is sent, and when.Whenever a dated shift or event is previewed, or its times are edited, our server may send Google one request for each of its two journeys: the coordinates of the shift or event’s place (or of your workplace, when it has none) and of the commitment just before or after it (which can be your home), within a few hours, and the time you need to arrive or leave. Never your identity, an event’s title, or any address text. A request is retried once if Google’s server fails (Sections 3.5, 8).
  • How much.At most 4 trips checked for each check, however many shifts it holds, and by default at most 200 trips a day for each account on each server instance. A trip is one request, sent a second time only if Google’s server fails, and it still counts as one trip — so a check sends at most 8 requests. The week view’s own drawing never sends one (Section 3.5).
  • What is kept, and for how long. The answer, as numbers only — a travel time and the kinds of travel — in server memory, keyed to your account, to the two places on a 100-metre grid and to the time in 15-minute steps. It is not used after an hour (seven days for a trip with no set time; a failed check after one minute), and is deleted the next time route checking runs, or when the server restarts (Section 7).

What changed on September 28, 2026

A Trip room, off unless the operator of a deployment switches it on. Where it is on, a Trip tab plans a trip between two places you type. This is a new use of data:

  • The places you type are looked up.Our server sends the text of each place you type into the Trip room to the address-lookup service the operator chose (NYC GeoSearch or OpenStreetMap’s Nominatim) to find where it is — the same service and the same limits as for your calendar’s locations, now also for text you type there. Where address lookup is off, the Trip room looks nothing up and plans nothing (Sections 3.3, 3.5, 8).
  • The plan reads what the commute planner reads.Citi Bike’s public station feeds, the subway timetable kept on our server where that is on, and — for a plan with a Citi Bike leg — Open-Meteo’s forecast at a coordinate rounded to about 1 km. Your browser receives the place names, times and steps of the plan — and, only where the map below is also on, the rounded positions needed to draw it (Section 3.5).
  • A trip on a map, where the operator has also switched the map on. Each plan then also carries the positions of the two places you typed, rounded to three decimal places (about 100 metres), and, for a Citi Bike plan, of the two docks it uses, rounded to four (about 10 metres), with the straight lines between them — no names and no IDs. Nothing is loaded until you press “Show on map”; then your browser loads the map from OpenFreeMap (tiles.openfreemap.org), which receives what any website receives (your IP address, browser user agent and our site’s address) and which map tiles are loaded, which shows the area of your trip. The positions are drawn by our own code; OpenFreeMap never receives them, the places you typed, or anything about your account (Sections 3.5, 8).
  • Saved trip places stay in your browser.A place you choose to save is kept in this browser’s local storage, under calmora.trip.places.v1 — never on our servers (Sections 3.3, 9, 10).
  • Nothing reaches your calendar without a preview. Adding a trip shows you the event first and writes it only when you confirm (Section 3.5).

And the Service now counts page views.It did not measure itself at all before. Vercel Web Analytics records which page was opened, roughly where the visit came from, a coarse device type and country, and a visitor identifier Vercel works out on its own servers and changes every day. It sets no cookie, reads nothing from the page you are looking at — no event, place, or account — and is served from this site’s own address, so your browser contacts no other host for it. A “Do Not Track” or Global Privacy Control signal switches it off entirely (Sections 8, 9, 12).

Travel nudges, off unless the operator of a deployment switches them on — and then off for your account until you turn them on. Where they are on, the You tab offers “Travel nudges”: a notification when it is time to get ready, and when it is time to leave, for the journeys between your commitments, even with the app closed. This is a new use of data, and it applies only to an account that turns it on:

  • What our database keeps.That you turned nudges on; for each journey your week view shows arriving in the next 36 hours, the IDs of the two calendar events it joins, when you need to leave, when you arrive, the time zone, and which nudges have been sent — never an event’s title, place, description or guests; and a copy of the push subscription of each device where you have turned notifications on (Sections 3.5 and 7).
  • For how long. A journey is deleted once it is over. A device copy is kept until you turn nudges off, turn notifications off on that device or sign out there, or its push service reports it gone (Section 7).
  • What a nudge says.Only that it is time to get ready or to leave, and the time to leave by — no event title and no place. It is encrypted for your device and passes through your browser’s push service (Apple, Google, or Mozilla), which cannot read it (Section 8).
  • The scheduler.A script in the operator’s own Google account (Google Apps Script) asks our server every few minutes whether a nudge is due. It carries a shared password and gets back only counts; nothing about you passes through it (Section 8).
  • How to delete it. Turning nudges off on the You tab deletes all of it at once; or ask us (Section 10).

Keeping travel blocks current, off unless the operator of a deployment switches it on — and then off for your account until you turn it on. Where it is on, the You tab offers “Keep my travel blocks current” under Travel nudges, which it needs. This is a new automatic change to your calendar, made without a preview, and it applies only to an account that turns it on:

  • What it may change.Only a travel block the Service itself added between two of your commitments, and only its start time: when the latest plan for that journey says to leave earlier or later, the block’s start is moved to match, by more than 5 and at most 60 minutes, on the same day. Its end stays at your next commitment’s start, it never starts before the commitment before it ends, nothing else about the event changes, and Google is told not to email anyone (Sections 3.2.1 and 4).
  • What it never touches. An event you moved or changed in Google Calendar, one that changed after the move was worked out, one with guests, a repeating one, or anything the Service did not add as a travel block.
  • How and when. Our scheduler works out the move from your route and live train times — never your location — and your browser makes it, with your own sign-in, while your week is open in the app; the week view then says what moved (Section 4).
  • What our database keeps.For each journey nudges keep, the ID of the travel block the Service added, its start and end times and Google’s version tag for it, when the commitment before it ends, and the move waiting to be made; and a record of each move made or refused (an internal draft ID and the outcome of the checks) — never a title, place, description or guest (Section 7).
  • How to turn it off. Switch it off on the You tab, or turn travel nudges off: it stops at once and those times and records are deleted (Section 10).

Live location for travel, off unless the operator of a deployment switches it on — and then off for your account until you turn it on. Where it is on, the You tab offers “Live location for travel” under Travel nudges, which it needs, and the week view offers “Update from where I am” on a journey that starts within the next 3 hours. Until now the Service never used your device’s location; this is a new use of data, and it applies only to an account that turns it on:

  • What is collected, and when.Nothing, until you press “Update from where I am” — never when a page opens, never in the background. Then your browser asks your permission (the first time) and finds where you are, and your device turns that into the 100 metre square you are in before anything is sent. Our server receives only that square, when it was found, and which two events the journey joins — never your exact position (Section 3.5).
  • Where it goes.To our server, which works the journey out again from the middle of that square the same way the week view does, and sends back the new time to leave. The square is sent to no one else. Your browser finds your position its own way, which on some devices involves the browser’s or the device maker’s location service, under their own terms (Section 8).
  • What is kept, and for how long. Only if travel nudges are watching that journey: the square, when it was sent, and the time to leave worked out from it, in our database, for at most 30 minutes— used to time that journey’s nudge while it is under 15 minutes old. Otherwise nothing is kept. On the operator’s own account, nothing is kept when the square is within 250 metres of the home the operator configured (Sections 3.5 and 7).
  • How to stop and delete it.“Stop sharing” on the journey deletes what is kept at once; so does turning “Live location for travel” or travel nudges off. You can also block location for this site in your browser (Section 10).

Your guess answers now reach two more flows.The September 27 notice below says your “Yes” and “No” answers about the AI’s category guesses are sent with your week view and shift-check requests so the Service does not ask the AI about a title again. As of September 28, they are sent the same way with two more requests: checking a change you make to an event — or autopilot makes — for what it now runs into, and the email feed (Section 6.1) checking what turned up in the mail against your calendar. No new answers are collected; the two lists already disclosed on September 27 are just read by two more parts of the Service (Sections 3.3 and 5.3 describe all four).

What changed on September 27, 2026

Three things changed. Autopilot changed — these are new practices, and they apply only to an account that switches autopilot on:

  • Autopilot is now per account, off by default. It does nothing for your account until you switch it on from the You tab (Section 4).
  • Autopilot may now change and remove events it created. Where the operator has separately switched this on, it may move or remove an event the Service itself created, within the limits in Section 4. Before, it could only create.
  • Activity and undo.What autopilot changed or removed is listed under “Autopilot did this” on the You tab, where a removal can be put back; the server keeps only the event IDs, for at most 24 hours (Section 7).
  • A notification gate. An automatic change or removal happens only when the Service can send a notification to a device where you have turned notifications on; a removal or a serious change is sent there (Section 4).

The week view’s questions changed— how it asks about the AI’s guesses — and your “Yes” answers can now be remembered. This part also corrects statements in this policy that no longer matched how the Service works:

  • Your “Yes” answers are remembered in your browser. When the week view asks about a guess and you answer “Yes”, your browser keeps that title and the category you confirmed (the 100 most recently answered or on a week you viewed) and sends them with that browser’s requests, in a request header or body — never in the web address — so that when your week is shown or a shift is checked from that browser, the Service holds that time without asking the AI about the title again (Section 5.3 gives the limits). The list is not tied to your account, and signing out clears it (Sections 3.3, 5.3, 7, 9, and 10).
  • Fewer questions, nothing hidden.The week view now asks only about guesses whose answer would change how much of your day is reserved, once per title. Every other guess is still listed under the week: the AI’s guesses with its reason and a way to reject them, and guesses you confirmed with your answer and an Undo that brings the question back, where you can answer “No”. The Service also no longer sends the AI the titles of the tentative holds and travel blocks it wrote into your calendar (Section 5.3).
  • Corrected statements.The server’s title-category cache drops its oldest entry to make room for a new one rather than being cleared all at once, and it holds the AI’s one-line reason as well as the category (Section 7). On our server, the title-category cache, write-deduplication records, push subscriptions, and the autopilot activity list are keyed to a random identifier issued each time you sign in, not to your Google account ID; your saved commute and rate limiting are keyed to your email address (Sections 3.1, 3.3, 3.4, 5.3, and 7).

And this update adds a map of your week and a second address-lookup service, and your commute setup can now be saved to your account, so it follows you to any device you sign in on. Those three are new practices, and each is off unless the operator of a deployment switches it on. This part also corrects statements that no longer matched what the Service already does; those practices are not new, and live train times among them are on by default:

  • The week map— when it is switched on and you open it, our server sends your browser the positions of your own events for the week on screen, rounded to about 10 metres (Section 3.5), and your browser loads the map itself — map images, label lettering and icons — directly from OpenFreeMap (tiles.openfreemap.org). OpenFreeMap therefore receives your IP address, your browser’s user agent, our site’s address, and which part of the map you are looking at, which is the area around your events. It receives no calendar text, event times, or account details (Sections 3.5, 6, 8).
  • A new recipient: NYC GeoSearch, the New York City Department of City Planning’s address-lookup service, as an alternative to OpenStreetMap’s Nominatim. Where an operator turns it on, location text that matches no place the Service already knows is sent to it from our server to find its coordinates (Sections 3.5, 8).
  • Corrected promises about your browser. Sections 1, 5, 11, and 12 said your browser talks to nothing but our own site. That stays true except for the map-tile host, and only on a deployment where the map is switched on; those sections now say so. The Service still loads all of its code and its interface fonts from its own site.
  • A corrected promise about the MTA.Sections 3.5 and 8 said no request is ever made to the MTA. Since live train times arrived, that has not been true: by default, during live hours, our server reads the MTA’s public live feed for a trip with a subway ride. Those sections, and Sections 1 and 7, now say so, and say exactly what the request carries.
  • A corrected statement about weather checks.Section 3.5 said the week view never builds a live trip plan, and so never asks Open-Meteo about the weather. Since the week view gained live train times on September 27, 2026, that has not been true: during live hours it plans the trip about to happen live, and a live plan with a Citi Bike leg asks Open-Meteo for the forecast — with the same coordinate rounded to about 1 km, and nothing else, that Sections 1, 6, and 8 already describe. Only the operator’s own routes are ever planned this way. Section 3.5 now says exactly when.
  • A corrected statement about access logs.Sections 3.4 and 11 said the titles you mark “Not this” (Section 3.3) travel in a request’s web address, where the host’s standard access logs could record them. That has not been true since September 18, 2026: they travel in a request header or body, and no calendar title is put in a web address. Before then, the week view did put them in its web address, so the host’s access logs from that time may still hold some of them until the host’s own log retention removes them.
  • A database, for one thing.Where account storage is switched on, the commute answers you save while signed in are kept in a Postgres database, keyed to your account’s email address. No calendar data and no tokens are ever kept there (Sections 1, 3.3, 6, and 7).
  • The Service now counts its own use. Where that same database is switched on, two things are recorded that were not before. First, a single row per account holding your email address, when it was first and last seen, and how many times it has signed in — and nothing about what you did. Second, daily totals of how often the Service parsed a sentence, read a schedule photo, or added an event: counters only, in a table that has no column for an account at all, so they cannot be tied back to you. They exist so the operator can tell whether the Service is being used and how close it is to Google’s 100-account pre-verification limit. They are visible only to the operator, as numbers — never as a list of who signed up — and no third-party analytics or tracking service is involved (Sections 7, 8, 12).
  • A new service provider: Neon, Inc., which hosts that database (Section 8).
  • How to delete it:the commute setup’s “Delete my saved commute” button removes it from your account and your browser, or ask us. Signing out removes your browser’s copy but not the account’s (Section 10).

1. At a glance

  • You sign in with Google. There are no Calmora passwords, and we never see or store your Google password.
  • We request the narrowest Google Calendar permission that lets the app do its job (calendar.events), and we touch only your primary calendar.
  • We keep one small database, for your saved commute and — only where the operator offers travel nudges and you turn them on — for those nudges: if you save your commute setup while signed in, it is stored in a Postgres database hosted by Neon, keyed to your account’s email address, so it follows you to your other devices, and stays until you delete it. If you turn travel nudges on, the same database keeps, under the same key, the times and event IDs of your journeys for the next 36 hours and your devices’ notification subscriptions, until the journey is over or you turn nudges off; and, if you also turn on keeping travel blocks current, the ID and times of each travel block the Service added for those journeys and a record of each automatic move, until you turn that off; and, if you also turn on live location for travel, the 100 metre square you shared for a journey, for at most 30 minutes. It holds no event titles, places or descriptions, and no tokens (Sections 7 and 10). On a deployment where the operator has not switched account storage on, your commute stays in your browser only. Apart from that, the application writes no user data to disk on the server, with one exception that exists only if an operator switches it on (an address-lookup cache file, Section 3.5). What the server holds in memory is listed in this policy, item by item, with its bounds and lifetime.
  • To estimate travel between your commitments, the Service uses the location of your calendar events, any commute details you enter, the places you type into the Trip room where an operator has switched it on, and — only where live location for travel is on, you turned it on and you press “Update from where I am” — the 100 metre square your device is in. It works them out on our server; the outside services involved are Open-Meteo, which receives only a coordinate rounded to about 1 km for a weather check; the MTA, whose public live train feed our server reads during live hours, naming only a group of subway lines; OpenStreetMap’s Nominatim or NYC GeoSearch, only if an operator turns address lookup on; and Google’s Routes API, only if an operator turns route checking on and then only for the operator’s own account, which receives the coordinates of a trip’s two ends and a time (Section 3.5). Where an operator has switched the map on and you open the week map, or a trip’s map in the Trip room, your browser loads the map from OpenFreeMap (Section 3.5).
  • Your Google sign-in tokens are stored in an encrypted cookie in your own browser — not on our servers.
  • Specific, minimized pieces of data are sent to Anthropic, our AI provider, to power the features you see (Section 5 lists every such flow). Under Anthropic’s commercial terms, API data is not used to train Anthropic’s models.
  • No advertising, no analytics, no tracking pixels, no third-party scripts, no data sales, no data brokers.The Service loads all of its code and interface fonts from its own origin. The only outside host the page itself fetches anything from is OpenFreeMap — map images and map-label lettering — and only where the map is switched on and you open the week map or a trip’s map (Section 3.5).
  • Signing in never asks for access to your email.The one way the Service can read your mail is an optional mail view on the Standby Board: it is off unless the operator switches it on, and even then it reads nothing until you click “Connect Gmail” and grant Google’s separate, read-only Gmail permission. What it reads, and what it keeps (nothing), is in Section 6.1.
  • You can cut off all access at any time from your Google Account permissions page. Signing out of Calmora alone does not revoke the Google-side grant — Section 10 explains both steps.

2. Who we are, and what this policy covers

Calmora (the “Service”) is operated by Darwin Hu, an independent developer based in New York, United States (“we”, “us”, the “Operator”). You can reach us about anything in this policy at darwinhu64@gmail.com.

This policy covers the Calmora website and application, including its use of information received from Google APIs. It applies to everyone who visits or signs in. It does not cover Google’s own handling of your Google account and calendar (governed by the Google Privacy Policy) or Anthropic’s handling of API traffic (governed by Anthropic’s Commercial Terms), though Section 5 describes what we send to Anthropic and on what conditions.

3. Information the Service receives

3.1 Google account identity

When you sign in with Google, we receive your name, email address, profile picture URL, and Google account ID, along with OAuth tokens that let the Service call the Google Calendar API as you. Sign-in requests these scopes and nothing more: openid, email, profile, and https://www.googleapis.com/auth/calendar.events. We never request the broader full-calendar scope, and sign-in never requests any Gmail, Drive, Contacts, or other Google scope. The only other scope the Service can ask for is Gmail read-only (https://www.googleapis.com/auth/gmail.readonly), and only separately, when you choose “Connect Gmail” on the Standby Board where the operator has switched its mail view on (Section 6.1).

Your access and refresh tokens are placed inside an encrypted session cookie held by your browser (Section 7). The server keeps no copy. A random identifier issued each time you sign in — not your Google account ID — is used server-side as the key for the bounded, transient per-user records listed in Section 7 (the title-category cache, write-deduplication records, push subscriptions, and the autopilot activity list), and your email address as the key for your saved commute (Section 3.3) and for rate limiting (Section 3.4), so that one account’s data can never answer another account’s request.

3.2 Google Calendar data

With your permission, the Service reads events from your primary calendar only— it never lists or touches your other calendars — for the date ranges the feature needs: about a month plus a two-day margin per request for the week view; for shift checks, the span of the shifts you submitted (at most 31 days) plus a day’s margin on each side; the week on screen plus a two-day margin for the week map, when you open it; and the next 60 days for the Standby Board. For the week view, the week map, and shift checks, it extracts and uses only these fields from each event: the event ID, title, start and end times, status, whether the event is marked busy or free, your own response to it (accepted, tentative, declined, or not yet answered — never anyone else’s), its location text (used only for travel estimates and, if you open it, the week map, Section 3.5), a link back to the event in Google Calendar, and three of the private properties the Service itself may have written (Section 3.2.1): appDraftId, appHold and appTravel. The Standby Board reads the ID, title, times, status, location, and your own response, plus, where present, the event’s description (up to 2,000 characters, checked for deadline wording) and its video-call link; these go to your browser to lay out the board and nowhere else. For a travel block the Service added, these reads also note whether its times are still the ones the Service last wrote (appWrittenSpan), how many guests it has (a count) and its version tag. When previewing a change or a deletion, before autopilot changes or removes an event, or before a travel block is kept current (Section 4), the Service additionally reads the event’s version tag, recurrence rule, how many guests it has (a count, never who they are), and the start and end the Service last wrote on it (Section 3.2.1), so it can show you exactly what would be changed or removed, detect concurrent changes, and refuse to change or remove on its own an event other people are on. For a change or an automatic removal it also reads the event’s description, location, and reminders, and returns them to your browser alone, so the event can be shown, and put back, as it was. Before a change it also reads the busy times around the old and new time, the same way the week view does, to tell you whether the new time still fits.

An honest technical note: for the week view, the week map, and shift checks, Google’s API transmits full event records in its responses, which can include fields like descriptions and the full guest list. The Service discards everything except the fields listed above — from the guest list it reads only the entry that is you — uses nothing else, and retains none of the raw response after the request completes. The Standby Board asks Google for only the fields it uses, and drops any other guest’s details before anything reaches your browser.

3.2.1 What the Service writes into your calendar

When you confirm an event, the Service creates it in your primary calendar with the details you approved in the preview: title, times and time zone, and — when present in the draft — a description, a location, and a recurrence rule. Reminders are written too: yours when you set them, otherwise a sensible default based on the event’s category. Two additional things are worth knowing:

  • Names of people mentioned in your event are written as plain text inside the event description (a “With: …” line). The Service deliberately never adds Google attendees, so Google never emails invitations to anyone on your behalf.
  • Each created event carries app-private properties stored inside your own Google Calendar: appDraftId on every event, appWrittenSpan on every timed event (the start and end the Service last wrote, so a later update can tell an event you moved yourself from one it moved), plus appHold on tentative holds and appTravelon travel blocks (Section 3.5). They are invisible in the normal Google Calendar interface, readable via the API, and exist so the Service can recognize the events it wrote — which is what lets it refuse to delete anything that does not carry its own creation marker. Where a draft carries a source link — today that means a link the public-event research feature (Section 5.4) found for it — a small “Added by Calmora” source note with that link is attached. All of this lives in your Google account, not on our servers, and is removed with the event when the event is deleted.

Deleting through the Service uses a preview-then-confirm flow (or, only where autopilot may remove events, the automatic path in Section 4), only ever targets events carrying the hidden marker the Service wrote at creation, and tells Google not to send cancellation emails. Changing an event works the same way: a preview to confirm (or the automatic path in Section 4), only an event carrying that hidden marker, never a repeating one, and Google is told not to email anyone about it. A change you confirm moves the event’s time and, if you changed it in the preview, its place; an automatic change moves its time only. Where you have turned on keeping travel blocks current (Section 4), the Service may also move the start time of a travel block it added, without a preview: that write changes the block’s start and end fields (the end to the same time it already has) and the hidden record of the times it wrote, and nothing else. A one-tap update — the “Update calendar block to …” button on the commute panel, or “Change the time” under an event just added, where the button names the new times and pressing it is the confirmation — rewrites the event as the Service would write it now: its times, title, place, notes and reminder; it is refused if the event’s times are no longer the ones the Service last wrote, so an event you moved yourself in Google Calendar is left alone. Event reminders are delivered by Google, like any other calendar reminder. Separately, if you turn on push notifications in your browser, the Service sends one push message to your device after it writes an event, removes one automatically, or makes a serious change to one (Section 4), containing the event’s title and time — and, for a move, the time it was at and, if the place changed, the new place, plus, where they apply, how many guests can see it and the names of anything on your calendar the new time runs into — so the confirmation is useful. It goes through the push service your browser chose (Apple, Google, or Mozilla). It is off unless you enable it, and no push is sent to anyone but you. A removal you confirm yourself, and a routine change (one that is not serious), sends none. It also sends one when you press “Send a test notification”: that test message says only that notifications are working and contains nothing from your calendar. See Section 8. Travel nudges, where the operator offers them and you turn them on, are separate push messages that carry no event title or place (Section 3.5).

3.3 Content you give the Service directly

  • Typed event text. What you type into the input box (up to 2,000 characters), so it can be parsed into a draft event.
  • Schedule images.Images you upload or paste (PNG, JPEG, WebP, or GIF, up to 8 MB), an optional name to look for in them, and an optional free-text hint. Images are processed entirely in memory and are never written to disk or kept after the request. Be aware that a schedule image can show other people’s information (for example, coworkers on a shift roster); the Service may report the other names it saw, to you only, so you know what was in the image. Upload only images you have the right to share.
  • Corrections and confirmations.When you reject a category the AI guessed for one of your events (“No extra time” or “Not this”), that title is remembered in your own browser’s storage (the 50 most recent) and sent with that browser’s future requests so the Service stops guessing about it. When you confirm a guess (“Yes”), the title and the category you confirmed are remembered in your browser’s storage too (the 100 most recently answered or on a week you viewed, so an older answer about a title on the week you are looking at is kept ahead of a newer one that is not) and sent with that browser’s requests, so that when your week is shown or a shift is checked from that browser, or a change you make to an event is checked for what it now runs into (and the same for a change autopilot makes), or the email feed (Section 6.1) checks what turned up in the mail against your calendar, the Service holds the time that category reserves without asking the AI about the title again (Section 5.3 gives the limit: a confirmation that does not fit in a request can still be guessed about again). Both lists travel in a request header or in the request body — never in the web address — and neither is kept on our servers. Neither list is tied to your account: each applies to whoever uses that browser and does not follow you to another device. Signing out clears the confirmed list; it does not clear the rejected one.
  • Your commute.If you complete commute setup, your answers: where your usual trip starts and ends (each either a place the Service already knows or text you type, which may be a home or work address), a short name for each end, what kind of place you are going to (work, school, or other), and your buffer and get-ready times. They are kept in your own browser’s storage (Section 9) and sent with each trip you ask the Service to plan (Section 3.5). Where account storage is switched on and you are signed in, saving them also stores them in our database (a Postgres database hosted by Neon, Inc.), keyed to your account’s email address, so the same commute appears on any device you sign in on; that copy is readable and changeable only through your own signed-in account. If your browser already held a commute from before, the Service asks before copying it to your account — it is never uploaded without your say-so. The stored copy is kept until you delete it (Section 10).
  • Trip places.Where the operator has switched the Trip room on, the two places you type into it (each at most 120 characters, and often a street address) and the time you want to leave or arrive, sent with each trip you ask it to plan (Section 3.5). They are used for that one plan and not kept on our servers. If you save a place there, the short name you give it and the text you typed are kept in your own browser’s storage (at most 12 places, under calmora.trip.places.v1, Section 9) — never sent anywhere except as the text of a trip you plan, not tied to your account, and not on any other device.
  • Your time zone.Your browser’s IANA time zone is sent with requests so dates and times resolve correctly.

3.4 Technical and log data

  • Account address or IP address, in memory, for rate limiting.The Service keeps request counts in server memory to bound the cost of the parsing, trip-planning, and week-map endpoints. When you are signed in the count is kept against your account’s email address, so that one person’s usage is bounded rather than one network’s; when there is no session it falls back to the IP address. These counters live only in memory — for up to the life of the server process — and disappear on restart. They are a cost guardrail, not a tracking mechanism.
  • Application logs are metadata-only by construction. API requests log at most one structured line containing things like route name, duration, status code, item counts, model name, and token counts — never your text, your event titles, image bytes, email-derived content, or your name. The logging code cannot carry content without a code change.
  • Hosting-provider access logs.Like virtually every website, the infrastructure the Service runs on (Section 8) keeps standard access logs (requested URL, IP address, timestamps). Calendar titles are never put in a request’s web address: the corrections and confirmations of Section 3.3 travel in a request header or body, not in the requested URL that access logs record. We do not use access logs to profile anyone.

3.5 Locations and travel estimates

The Service estimates how long it takes to get between your commitments, so the week view and shift checks leave room for travel, and so the commute planner can tell you when to leave. The location information it uses is: the location text of your calendar events (Section 3.2), the location of a shift you submit for checking when the draft has one, your commute setup (Section 3.3), and, where the Trip room is switched on, the places you type into it (Section 3.3). It uses your device’s location only for live location for travel (below): only where the operator has switched it on and you have turned it on, only when you press “Update from where I am” on a journey, and then only as the 100 metre square your device is in. Here is what happens to that information:

  • Matched on our server first. Location text is compared, on our server, with a short built-in list of places and routes the Service already knows. That comparison involves no one else. Text that matches nothing gets a stated default travel time, labeled as a guess — unless address lookup is on (below).
  • Weather: Open-Meteo, on by default. When the Service builds a live trip plan and that plan includes a Citi Bike leg, our server asks Open-Meteo (api.open-meteo.com) for the hourly forecast where the bike leg starts, so it does not send you cycling into rain. The commute planner, shift checks and, where it is switched on, the Trip room build live trip plans. The week view builds them only during live hours (on weekdays, 7 AM–9 AM, 11 AM–1 PM and 3 PM–6 PM, New York time), and then only for at most two trips per reading of the week — trips to or from an event that starts or ends within the next two hours, along a route on the built-in list; every other trip in the week is worked out without a weather check. The built-in routes are the operator’s own commute, so on any other account the week view builds no live trip plan and asks Open-Meteo nothing. The request carries only a coordinate rounded to two decimal places (about 1 km): no time, no name, no account identifier, and no event text. An operator can switch weather checks off, and then Open-Meteo is never asked, by the week view or anything else; switching live train times off (below) does not switch weather checks off.
  • Citi Bike availability.Live trip plans also download Citi Bike’s public station feeds (gbfs.citibikenyc.com). This is a read of public data; nothing about you or your trip is sent.
  • Bike estimates between your own events: off unless an operator turns it on. Where an operator switches it on, and two of your commitments both have a location the Service already has coordinates for (from the built-in list, or from address lookup if that is on), with no route on file and no subway schedule answer between them, the Service may estimate that trip as a walk to a Citi Bike dock, a ride, and a walk from a dock — for a trip in the next few hours only. The commute planner may estimate a trip between the two places you give it in the same way. It is worked out on our server from the same public Citi Bike station feeds as above, downloaded whole: nothing new is sent to anyone, and no location, event text, time or account detail goes out with the request. No weather is requested for these estimates. Each one says it is modelled from live docks rather than measured, and the docks it chose stay on our server; your browser receives only the travel time and that sentence, and from the commute planner also notes in our own words that name no dock.
  • Subway schedules: worked out on our server, off unless an operator turns it on.Where an operator switches it on, a trip between two places the Service has coordinates for can be estimated by finding a route on the MTA’s published subway timetable. That timetable is a copy of the MTA’s public schedule data (its GTFS feed), downloaded by the operator ahead of time and stored with the Service; the route is worked out entirely on our server, and finding it sends nothing about you, your events or your trip to anyone. The times are the published schedule, not live train positions, and every such estimate says so. Subway schedule data: MTA New York City Transit, obtained from the MTA and stored on our own server; the MTA does not endorse the Service and makes no claim that the data is accurate, complete or timely.
  • Route checking: Google’s Routes API, off unless an operator turns it on — and then only for the operator’s own account.Where an operator switches it on, a trip between the shift or event being checked and the commitment just before or after it, within a few hours, that the Service has positions for — and that no route the Service already knows and no subway-schedule answer covers — can be checked with Google’s Routes API (routes.googleapis.com) instead of being estimated from the distance. That happens whenever a dated shift or event is previewed, and again when its times are edited; nobody has to ask for it. Each trip checked is one request from our server, retried once if Google’s server fails, carrying the trip’s two ends as coordinates — the shift or event’s place (or your workplace, when it has none) and the commitment just before or after it, which can be your home when that is where a commitment is — and the time you need to arrive or leave. Never your identity, an event’s title, or any address text. Checking one event, or all the shifts of a posted schedule, checks at most 4 trips; each account, by default, at most 200 trips a day on each server instance. A retry is the same trip sent again and is not counted again, so one check sends at most 8 requests. The week view’s own drawing never sends a request: it shows a checked route only when one is already held (below). No other account’s trips are ever checked. The key these requests are made with, what Google charges for them, and any spending limit are the operator’s.
  • Live train times: the MTA, on by default during live hours. When the Service builds a live trip plan that includes a subway ride, and the time is within live hours — on weekdays, 7 AM–9 AM, 11 AM–1 PM and 3 PM–6 PM, New York time — our server reads the MTA’s free public live-arrivals feed (GTFS-realtime, at api-endpoint.mta.info) so the wait for the train is the real one rather than one worked out from the published timetable. So the MTA receives our server’s request for its public live feed: the request names only which group of subway lines’ feed to read (for example, the A/C/E lines), which follows from the lines the trip would use. It carries no account identifier, no event text, no times and no places, so nothing in it says whose trip it was. Each server instance reads a given feed at most once every 5 minutes and shares that one answer with every trip it plans in that time. Outside live hours no request is made and waits come from the timetable. An operator can switch live train times off, and then the MTA is never contacted.
  • Address lookup: OpenStreetMap Nominatim, off unless an operator turns it on.The Service can be configured to send location text that matched nothing on the built-in list to OpenStreetMap’s Nominatim service (nominatim.openstreetmap.org) to find its coordinates, which gives a distance-based estimate instead of the default. It is off unless the operator of a deployment explicitly switches it on. When it is on, each lookup sends the location text alone (at most 200 characters, limited to U.S. results) from our server — never your identity, or an event’s title or time — and text the operator has listed as never-to-be-looked-up is withheld.
  • Address lookup: NYC GeoSearch, off unless an operator turns it on. As an alternative to Nominatim, an operator can choose NYC GeoSearch (geosearch.planninglabs.nyc), the New York City Department of City Planning’s search over the city’s official address directory. It works the same way and under the same limits: our server sends the location text alone (at most 200 characters) — never your identity, or an event’s title or time — withholds text the operator has listed as never-to-be-looked-up, and sends at most 12 lookups per request. It only knows New York City addresses, and the Service uses an answer only when it clearly matches what you wrote; anything else falls back to the stated default. Only one lookup service is ever in use at a time.
  • The Trip room: off unless an operator turns it on.Where it is on, the Trip tab plans a trip between two places you type. Our server first compares each place with the built-in list above (only the operator’s own account has places there), then sends the text to the address-lookup service the operator chose (below) — so the Trip room plans nothing where address lookup is off. The operator’s never-to-be-looked-up list is applied to the operator’s own text only; applied to anyone else’s, a refusal would reveal what is on that list. The trip is then worked out on our server as a subway journey on the published timetable (where that is on), or as a walk to a Citi Bike dock, a ride and a walk from a dock from Citi Bike’s public station feeds, or as a walk — and a plan with a Citi Bike leg asks Open-Meteo for the weather, as above. Your browser receives what you typed, the name the lookup matched it to, and the plan’s times, steps and the public names of the docks or stations it uses. Where the map is off, that is all — never a coordinate; where the operator has also switched the map on, the plan also carries the rounded positions described under “The Trip room’s map” below. Nothing about the trip is kept on our servers after the answer is sent, apart from the lookup cache described under “What is kept”.
  • The week map: off unless an operator turns it on, and nothing happens until you open it. On a deployment where it is switched on, the week view offers a map. When you open it, two things happen:
    • Our server looks up where your own events in the week on screen are — the same matching, and the same address lookup if one is on, as for travel estimates — and sends your browser, for each event it could place, the event’s ID and its position rounded to four decimal places (about 10 metres), plus whether the position came from an address lookup. It does not send the address text or a place’s name, and you only ever receive positions for your own events.
    • Your browser loads the map itself — map images (“tiles”), map-label lettering, and icons — directly from OpenFreeMap (tiles.openfreemap.org), a free map service built on OpenStreetMap data. Like any website, it receives your IP address, your browser’s user agent, and our site’s address; and because a tile is a piece of the map, it learns which area you are looking at and how closely — and the map opens on the area around your events. The pins are drawn by our own code on top of the tiles: no event text, time, position, or account detail is sent to OpenFreeMap.
    The lines drawn between your stops are straight lines between two positions, not routes. The map never uses your device’s location.
  • The Trip room’s map: only where both the Trip room and the map are switched on, and nothing is loaded until you open it. The same switch that turns the week map on lets the Trip room show a trip on a map. Where both are on:
    • Each plan our server sends your browser also carries the positions needed to draw it: the two places you typed, as the address lookup (or, for the operator’s own account, the built-in list) placed them, rounded to three decimal places (about 100 metres); for a Citi Bike plan, the two docks it uses, rounded to four decimal places (about 10 metres), and whether each is where you take the bike or return it; and the straight lines of the walks and the ride between those points. A subway plan carries only the two places. No address text, dock or station name, or ID is part of it, and the positions come only from the two places you typed and Citi Bike’s public station feed — never from anyone else’s places or settings. The operator’s home is never drawn: on the operator’s own account, a trip with any of those points within 250 metres of the home the operator configured comes without a map.
    • The map stays closed until you press “Show on map”. Then your browser loads the map from OpenFreeMap (tiles.openfreemap.org), exactly as for the week map above: OpenFreeMap receives your IP address, your browser’s user agent, our site’s address, and which map tiles are loaded — which shows the area of your trip. The start, the destination and the docks are drawn by our own code on top of the tiles: no position, place text, name, time or account detail is sent to OpenFreeMap.
    The lines are straight lines between those points, not the route you would take.
  • What is kept.Travel estimates and map positions are worked out per request and discarded when the response is sent (apart from the journey times kept for travel nudges if you turn them on, a square you share with live location for travel, and checked routes where route checking is on, below); your browser holds the positions only while the page is open. Weather forecasts are kept in server memory for 10 minutes, keyed by the rounded coordinate (Section 7). With address lookup on, results are held in memory for the request; if the operator also configures a cache file, each result — a normalized form of the location text, the coordinates found, and the place’s name — is written to that file on the server, so the same text is not sent twice. Found places stay in the file until it is deleted; not-found ones expire after 30 days. The file is not tied to any account. With route checking on, each checked trip’s travel time and the kinds of travel it used — numbers only, never Google’s description of the route — are held in server memory, keyed to your account, to the two places on a 100-metre grid and to the time in 15-minute steps, so the same trip is not sent twice. An answer is not used after an hour (seven days for a trip with no set time; a failed check after one minute), and is deleted the next time route checking runs, or when the server restarts. Each server instance also counts each account’s trips checked for the current day (UTC); a past day’s count is deleted the next time a trip is checked, or when the instance restarts.
  • Travel blocks.The commute planner, and the Trip room where it is on, can turn a plan into a “Travel to …” event on your calendar. Like any other event, it is shown to you as a preview and written only when you confirm (Section 3.2.1); a travel block added between two commitments may afterwards be kept current, if you turn that on (below).
  • Travel nudges: off unless the operator switches them on, and off for your account until you turn them on.Where they are offered, the You tab has a “Travel nudges” switch. While it is on, each time your week view shows the current week, your browser sends our server the journeys it shows arriving in the next 36 hours; the server checks each against your own calendar and keeps, in our database, the IDs of the two events a journey joins, when you need to leave, when you arrive, the time zone, whether you are the operator (for the operator’s own getting-ready lead), and which nudges have been sent — never a title, place, description or guest, and never your location unless you also turn on live location for travel (below). A scheduler then sends a push to your devices when it is time to get ready and when it is time to leave, saying only that and the time to leave by. A journey is deleted once it is over, or when your calendar no longer shows it; turning nudges off deletes every one (Sections 7 and 10). Nudges need notifications turned on for your device.
  • Keeping travel blocks current: off unless the operator switches it on, and off for your account until you turn it on.Where it is offered, it needs travel nudges on. While it is on, when your week view registers your journeys, the server also looks, on your own calendar, for the travel block the Service added between the two commitments of each journey, works out that journey’s current plan the same way the week view does — from your route and live train times, never your location — and keeps, beside the journey, the block’s event ID, its start and end times, Google’s version tag for it and when the commitment before it ends. Our scheduler compares the plan with the block and records a move for your browser to make (Section 4). Never a title, place, description or guest.
  • Live location for travel: off unless the operator switches it on, and off for your account until you turn it on.Where it is offered, it needs travel nudges on. While it is on, the week view offers “Update from where I am” on a journey that starts within the next 3 hours, and nothing else asks for your location:
    • Only when you press it, your browser finds where you are (asking your permission the first time; on some devices it uses the browser’s or device maker’s own location service to do so), and your device turns that into the 100 metre square it is in before sending anything. Our server receives, in the body of one request, only that square, when it was found and the IDs of the two events the journey joins — never your exact position. A request that puts a location in a web address is refused, because web addresses are written to access logs.
    • Our server checks both events are on your own calendar and the journey starts within 3 hours, then works the journey out again from the middle of the square, exactly as for the week view (the subway schedule and Citi Bike’s public station feed where those are on, and — where address lookup is on — your event’s location text, as in the rest of this section), and sends back the new time to leave and the minutes of travel. The square is sent to no one else, and is never written to a log.
    • Only if travel nudges are watching that journey, our database keeps, beside the journey, the square, when it was sent and the time to leave worked out from it, for at most 30 minutes; our scheduler uses that time for the journey’s nudge while it is under 15 minutes old, and your planned time otherwise. Nothing else about where you are is kept, and your browser keeps none of it. On the operator’s own account, nothing is kept when the square is within 250 metres of the home the operator configured, and the journey is worked out from that home instead.
    • “Stop sharing” on the journey, or turning live location for travel or travel nudges off, deletes what is kept at once (Section 10). Off by default.

None of this involves our AI provider: travel estimates are computed without Anthropic.

4. How we use information

We use the information above to do exactly the things the interface shows:

  • parse your text or image into draft events you review before anything is written;
  • show your week, with busy blocks and realistic free windows;
  • show the next 60 days of your calendar on the Standby Board;
  • estimate travel time between your commitments, and tell you when to leave for the commute you set up (Section 3.5);
  • where live location for travel is on and you turn it on, work out when to leave from where you are when you ask, and time that journey’s nudge from it (Section 3.5);
  • where the week map is switched on and you open it, show where your commitments are on a map (Section 3.5);
  • where the Trip room is switched on, plan a trip between two places you type — and, where the map is also on and you open it, show that trip on a map (Section 3.5);
  • check proposed work shifts against your existing commitments;
  • create, change and delete events in your primary Google Calendar — behind an explicit confirmation step, except for the automatic paths described below;
  • keep the Service working (deduplicate retried writes, enforce rate limits, debug failures from metadata-only logs).

Automatic writes (autopilot). Autopilot is off unless it is switched on. While it is off — the state the Service ships in — nothing reaches your calendar until you confirm a preview, apart from keeping travel blocks current (below), a separate switch that is also off unless you turn it on. While it is on, the Service may create (and, within the limits below, change or remove) an event without asking you first, and only when the parse cleared every one of these gates: high confidence, nothing flagged for review, no warnings, no unresolved research questions, and a complete date and time. Anything that fails a gate still comes to you as a preview. Whatever autopilot does is reported on screen when it happens, marked as done automatically, with the way back beside it: an event it created can be removed there, an event it moved can be changed back there, and an event it removed can be put back there.

Automatic removals.Autopilot removes an event on its own only where the operator of this deployment has switched that on separately, and then only an event the Service itself created: a single event (never a repeating one), with no guests, in a routine category (work, school, or study), named exactly as your message names it, on the day your message names. Anything short of that comes to you as a preview to confirm. An automated removal happens only when the Service can send a notification to a device where you have turned notifications on, and it is then sent to every such device, naming what was removed and when it was. The removal is listed under “Autopilot did this” on the You tab for as long as this server remembers it (at most 24 hours), where it can be put back; Google Calendar’s Trash keeps the removed event for thirty days either way.

Automatic changes.Under the same separate switch and the same limits, autopilot may change the time of, or remove, an event the Service itself created. A change moves only when the event happens, to the time your message names: a message that would also change its place or anything else, or whose new start leaves the event without an end that still fits, comes to you as a preview to confirm instead, as does a repeating event. An automatic change is also refused when the event’s times are no longer the ones the Service last wrote — an event you have moved yourself in Google Calendar is never moved again on its own — or when the event was added before the Service recorded the times it wrote. A serious change — a different day, a move of thirty minutes or more, a change of place (as well as a change of length of thirty minutes or more, a switch between all-day and timed, an event other people are on, a new time that runs into something else on your calendar, or a new time the Service could not check against the rest of your calendar) — is sent as a notification to every device where you have turned notifications on; a routine one is not; an automated change, like a removal, happens only when such a device can be reached. A change is listed on the You tab with the notification naming where it was; change it back in Google Calendar.

Keeping travel blocks current. Separate from autopilot, and off unless the operator of this deployment switches it on and you then turn on “Keep my travel blocks current” on the You tab (it needs travel nudges on). When the latest plan for a journey — worked out from your route and live train times, never your location — says to leave earlier or later than the travel block the Service added for it, the Service moves that block’s start time to match, without a preview. It does so only for a single travel block the Service itself added between two of your commitments, with no guests, whose times are still the ones the Service last wrote and have not changed since the move was worked out; only by more than 5 and at most 60 minutes; only on the same day; never so that the block starts before the commitment before it ends, and never in the past. The block’s end stays at your next commitment’s start, nothing else about the event changes, and Google is told not to email anyone. Our scheduler, which holds no access to your calendar, works the move out; your browser makes it, with your own sign-in, while your week is open in the app, and the week view then says what moved. A block that fails any check is left as it is, and that move is dropped rather than tried again. To undo a move, change the block in Google Calendar: the Service never moves a block you changed. It is per account, off by default, and turning it off (or turning travel nudges off) stops it at once.

Autopilot is per account and off by default. It does nothing for your account until you switch it on from the You tab, and it applies only to the browser you turned it on in, until you sign out, sign in again, or your sign-in expires.

We do not use your information for advertising, do not build profiles for any purpose other than the features above, and do not sell or rent any of it to anyone (Section 8).

5. AI processing — what is sent to Anthropic, exactly

The intelligence in Calmora comes from AI models operated by Anthropic, PBC (api.anthropic.com). This section is the complete list of what crosses that boundary when you use the Service (one additional flow exists that never involves your data: the operator-configurable email capability of Section 6.1). Three properties hold for every flow below:

  • All AI calls are made from our server.Your browser never talks to Anthropic, and the page’s security policy (Section 11) blocks it from talking to anything but the Service’s own origin — and, only where the map is switched on (the week map, and the Trip room’s map), the map-tile host (Section 3.5).
  • Your data is not used to train models.Anthropic’s Commercial Terms of Service provide that Anthropic may not train models on customer content from its API services (see Anthropic Commercial Terms), and we do not opt in to any data-sharing or training program. We request provider-side prompt caching only for our own fixed instructions — never for your content.
  • Untrusted content is fenced. Everything user-provided or external (your text, image contents, calendar titles, web results) is wrapped in explicit data-only delimiters and sanitized, and the instructions tell the model to treat it as data, never as commands. This is a prompt-injection defense, not a privacy control, but it shapes every request we send.

5.1 Typing an event

When you type an event and the AI parser is available, the Service sends Anthropic your typed text (up to 2,000 characters) together with the current date and your time zone. The model returns one structured draft event. If the AI parser is not configured at all, nothing is sent anywhere and an offline, deterministic parser handles your text with a visible “AI unavailable” notice; if a live AI call fails or times out, the same offline fallback and notice apply — in that case your text was transmitted in the failed attempt, but nothing further is sent.

5.2 Uploading a schedule image

When you upload a schedule image, the Service sends Anthropic the image itself, the current date and week boundaries, your time zone, your optional hint, and an identity block used to find your rows in a shared roster: the name being searched for, mechanically derived variants of it (initials, reversed order, first or last name alone, configured aliases), and — when you are signed in — your email address. We state that plainly because it is easy to miss: on this one flow, your account identifiers accompany the upload, so the model can tell which rows of a multi-person schedule are yours. If no confident match is found, the extractor is instructed to return no events; anything it returns anyway is shown unselected behind a prominent “could not confirm which row is yours” warning and is never added to your calendar without your explicit per-event confirmation.

5.3 Reading your week

Rendering your week, checking shifts, checking a change to an event (yours or autopilot’s) for what it runs into, and checking what turned up in the email feed (Section 6.1) against your calendar are mostly local arithmetic. The one AI-backed piece, in each of them: when an event title is too terse for the Service’s built-in rules to categorize (“Alesso” rather than “Alesso concert”), that title — and only the title — is sent to Anthropic to ask what kind of commitment it is. This flow is deliberately minimal:

  • only titles the local rules could not read are sent — anything recognizable never leaves;
  • duplicate titles are sent once, results are cached for your sign-in session (Section 7), and titles are truncated to 300 characters;
  • the titles of tentative holds and travel blocks the Service wrote into your calendar (Section 3.2.1) are never sent;
  • a title whose guess you confirmed (“Yes”, Section 3.3) is not sent again when your week is rendered, a shift is checked, a change to an event (yours or autopilot’s) is checked for what it runs into, or the email feed is checked against your calendar, from that browser: your browser sends the confirmed category with the request and the Service uses it as it is. Your browser sends as many confirmations as fit in the request, those most recently answered or on a week you viewed first; one that does not fit is guessed about again like any other title;
  • no name, email, or account identifier accompanies the title in the request;
  • event descriptions, attendees, and locations are never sent on this flow;
  • every guess the model made that appears in your week view is shown with the model’s reason and can be rejected; a guess you confirmed is listed with your answer and an Undo that brings the question back, where you can answer “No”; guesses that would not change how much of your day is reserved, and guesses you have confirmed, are listed under the week without a question rather than hidden. A title you rejected is not sent again when a shift is checked from that browser, and not when your week is rendered, a change to an event (yours or autopilot’s) is checked, or the email feed is checked against your calendar either, with one limit: for those three, your browser sends the most recent rejections that fit in the request; an older one that does not fit may be guessed about again, and the week view then shows it as not applied;
  • if the model is unsure or unavailable, the Service simply treats the event as uncategorized.

Because, under Google Calendar’s common default settings, invitations can be placed on your calendar by anyone who knows your email address, an unclassifiable title there may have been written by a third party; the fencing described above treats every title as untrusted for exactly that reason.

5.4 Looking up a public event (research)

When a parse needs facts the model should not guess (like a concert’s venue) and the research feature is enabled on the deployment you are using, the Service sends a search query built from the draft’s title, location name, and date to Tavily (api.tavily.com), a web-search API, and then sends the top results (short excerpts) plus the draft’s title and date to Anthropic to fill in missing fields. Research results can only ever fill blanks and add warnings — they can never overwrite what you typed or promote a draft past your review. When the research feature is not configured, no research request is made at all and the draft is returned unchanged, still marked as needing your verification, rather than guessed at.

5.5 What does NOT go to any AI provider

  • Your Google tokens, password, or any credential — never.
  • Your calendar as a whole. There is no bulk export, sync, or embedding of your calendar anywhere.
  • Your email. Nothing from your mailbox is sent to any AI provider. If you connect Gmail to the Standby Board, your mail is sorted on our server by fixed rules, with no AI call (Section 6.1).
  • Anything, when the corresponding feature is unconfigured — every AI call is gated on its key being present, and absent keys mean offline fallbacks or honest “unavailable” errors, never silent substitutes.

For completeness: the codebase contains an alternative adapter for OpenAI that is not wired into the running Service — no data is sent to OpenAI. If we ever switch or add AI providers, this policy will name them before the change takes effect.

6. Google user data — access, use, storage, sharing (Limited Use)

This section restates, in Google’s required frame, how the Service handles information received from Google APIs.

  • Access: identity basics (openid, email, profile) and read/write access to events on your primary calendar via the calendar.eventsscope, as described in Section 3; and, only if you choose “Connect Gmail” on the Standby Board where the operator has switched its mail view on, read-only access to your Gmail (Section 6.1).
  • Use: solely to provide the user-facing features that are prominent in the interface — parsing events you submit, rendering your week, your availability, and the Standby Board, estimating travel between your commitments, showing them on the week map when you open it, checking shifts, and creating, changing or deleting events on the terms set out in Section 4 (your confirmation; autopilot when it is switched on; or, if you turn it on, keeping the travel blocks the Service added current — each within the limits described there). Not for advertising. Not for credit-worthiness or lending decisions. Not to build databases about you.
  • Storage:Google calendar data is not stored durably on our servers. The one piece of Google user data kept durably is your Google account’s email address, and only if you save a commute while signed in: it is the key under which that commute is stored in our database (Section 7), so it can be returned to you and to no one else. No calendar content is stored there — with one exception you choose: where travel nudges are offered and you turn them on, the same database keeps, under the same email key, the IDs of the calendar events your next journeys join and their leave-by and arrival times, until each journey is over (Section 3.5); and, if you also turn on keeping travel blocks current, the ID and start and end times of the travel block the Service added for each of those journeys (with Google’s version tag for it), and a record of each automatic move made or refused (an internal draft ID and the outcome of the checks), until you turn it off (Sections 4 and 7); and, if you also turn on live location for travel, the time to leave worked out from where you were for a journey, for at most 30 minutes (Section 3.5). Never an event’s title, place, description or guests. Beyond that, no files are written except one that exists only if an operator switches it on: the address-lookup cache of Section 3.5, which can hold event location text (in normalized form, with its coordinates) and is not tied to any account (Section 7). Transient in-process memory (for example, the per-sign-in title-category cache) is enumerated in Section 7 with its bounds and lifetimes. Your tokens live encrypted in your own browser.
  • Sharing:the only transfers of Google user data to a third party are the AI flows itemized in Section 5 — narrowly scoped payloads sent to Anthropic (and, for research on public events, a query to Tavily) — and the travel lookups in Section 3.5: a coordinate rounded to about 1 km, which may be derived from an event’s location, sent to Open-Meteo for a weather check; during live hours, a request to the MTA naming only which group of subway lines’ public live feed to read, which may follow from the lines a trip between your events would use; and, only where an operator has turned address lookup on, an event’s location text sent to OpenStreetMap’s Nominatim service or to NYC GeoSearch to find its coordinates; and, only where an operator has turned route checking on and only for the operator’s own account, the coordinates of a trip’s two ends (the shift or event being checked, or the workplace, and the commitment just before or after it) and the time of the trip, sent to Google’s Routes API to check how long it takes. One further flow is indirect, and we state it so it is not missed: where the week map is switched on and you open it, your browser requests map tiles from OpenFreeMap for the area around your events, so OpenFreeMap can infer that area from which tiles were requested — though it receives no event text, times, positions, or account details. Where account storage is switched on, your email address is also held by Neon, Inc., the database host (Section 8), as the key of the commute you saved — and, if you turn travel nudges on, as the key of the event IDs and journey times they keep — stored for us, not shared for any use of Neon’s own. Each serves those same user-facing features. Google user data is never transferred to advertising platforms, data brokers, or information resellers, never sold, and never used for any purpose beyond the features you can see.
  • AI/ML restriction: Google user data sent to our AI provider is used only to produce the immediate, user-visible result and is not used — by us or, per its terms, by Anthropic — to create, train, or improve any machine-learning or artificial-intelligence model.
  • Human access:no one, including the Operator, reads your Google user data through the Service: no screen, route, or log line exposes one account’s calendar content to anyone else. The narrow exceptions Google’s policy contemplates apply here too — we may access data where you explicitly ask us to (for example, helping you debug with data you share), where necessary for security (investigating abuse), or where required by law.

Calmora’s use of information received from Google APIs will adhere to the Google API Services User Data Policy, including the Limited Use requirements. The use of information received from Google Workspace scopes will adhere to the Google User Data Policy, including the Limited Use requirements.

6.1 Email

Signing in requests no Gmail permission, and an account that never connects Gmail gives the Service no way to read its mailbox — the sign-in scopes are pinned by an automated test in the codebase. There are two email capabilities in the codebase, and each is off unless the operator switches it on.

The Standby Board’s mail view — your own mail, only if you connect it.Where the operator has switched it on, the Standby Board offers a “Connect Gmail” button. Nothing is read unless you click it and grant Google’s separate consent for the read-only Gmail scope (https://www.googleapis.com/auth/gmail.readonly) — never the scope that can change or send mail. Once granted, the board reads your own mailbox with your own grant: the sender, subject, date, labels and Google’s one-line preview of recent messages (up to 50 inbox messages from the last 7 days, and up to 40 messages from the last 45 days, sent or received, whose subject mentions an application, an interview, availability or next steps), never message bodies or attachments. It sorts them on our server by fixed rules — no AI provider is involved — and sends your browser only the sender, subject, date and thread ID; the preview line is used for that sorting and discarded when the response is sent. Nothing read from your mail is stored on the server or written to logs, which carry only counts; the one trace is a per-account request count in server memory for rate limiting, as in Section 3.4. The Gmail grant is kept in the same encrypted session cookie as your calendar grant (Section 7). Removing Calmora at your Google Account permissions page ends it (Section 10).

The operator’s own scanner — never your mail. The codebase also contains an email-scanning capability an operator can configure for the operator’s own mailbox: a scanner running inside the operator’s own Google account hands pre-filtered messages to that operator’s deployment, where excerpts of them (sender, subject, and message text) are sent to Anthropic to extract commitments — the operator’s own data, never yours. That capability is off unless the operator explicitly configures it, is not configured on the public Service as of the effective date, and — whatever its configuration — never reads the mailbox of anyone who signs in. What it extracts is shown only to the operator, in an email feed that checks each item against the operator’s own calendar the way Section 5.3 describes.

7. Where data lives, and for how long

The Service is deliberately built with as little storage as it can manage. The durable copies of your data live in systems youcontrol — your Google Calendar, your Google account, and your own browser — with three exceptions, all in our database: the commute setup you save while signed in, which lives there so it can follow you between devices; what travel nudges need, only if you turn them on where they are offered; and a single row recording that your account has signed in. Here is the complete inventory as the public Service runs (the operator email capability of Section 6.1, when an operator configures it, adds in-memory stores of the operator’s own email-derived proposals, message IDs, and extraction counters — bounded, and likewise erased on restart):

  • Google tokens and identity — your browser. Stored in the session cookie, encrypted with a server-held key, marked HttpOnly and Secure, expiring after about 30 days of inactivity or when you sign out. The server never persists them.
  • Your calendar — your Google account. The Service reads it per-request and keeps no copy. Events it creates (with the properties described in Section 3.2.1) live in your calendar under your control.
  • Rejected-category titles — your browser.One localStorage entry, the 50 most recent titles, kept until you clear your browser’s site data for the Service. It is not tied to an account, and signing out does not clear it.
  • Confirmed guesses — your browser.One localStorage entry: of the titles you confirmed, the 100 most recently answered or on a week you viewed, each with the category you confirmed. Sent with that browser’s requests (Section 3.3) and kept on none of our servers. Removed when you sign out on that browser or clear its site data for the Service.
  • Commute setup — our database, and your browser.Where account storage is switched on and you save your commute while signed in, one row in a Postgres database hosted by Neon, Inc. (Section 8) holds your commute answers (Section 3.3), your account’s email address as the row’s key, and the time it was last saved — nothing else. It is kept until you delete it with the commute setup’s “Delete my saved commute” button or ask us to (Section 10); saving again replaces it, and a server restart does not erase it. Your browser also keeps a localStorage copy (Section 9), kept until you change it, delete it, sign out (for a copy that came from your account), or clear your browser’s site data for the Service. Where account storage is not switched on, the browser copy is the only one.
  • That your account signed in — our database. Where account storage is switched on, one row per account holds your email address, the first and last time the Service saw you, and how many times you have signed in. It holds nothing about what you did, no calendar data, and no tokens. It is written when you sign in and kept until you ask us to delete it (Section 10); deleting your commute setup does not remove it, because it is a different row answering a different question.
  • How often the Service was used — our database, with no link to you. Daily totals of four things: sentences parsed, schedule photos read, events added, and automatic writes. The table storing them has no column for an account, so there is nothing in it to connect a count to a person — not your address, not an identifier, not an IP. Kept indefinitely as aggregate numbers, because once recorded there is nothing personal left in them to expire.
  • Typed text and uploaded images — request lifetime only. Processed in memory, never written to disk, gone when the response is sent.
  • Push subscriptions — server memory, only if you enable notifications. When you turn on push, your browser’s subscription (a device endpoint URL and the two keys needed to encrypt a message to it) is held in the server’s in-process memory so it can be reached when the Service writes an event, removes one automatically, or makes a serious change to one (Section 4), and when you press “Send a test notification”. No name or calendar content is stored with it; it is dropped when the server restarts or when the push service reports the subscription is gone, and you can end it by turning notifications off. Signing out also ends notifications on that browser: the Service asks the server to forget its subscription and tells the browser to drop it. If you have turned travel nudges on, a copy is also kept in our database (next item).
  • Travel nudges — our database, only if you turn them on.Where the operator offers travel nudges and you turn them on, the Postgres database hosted by Neon, Inc. (Section 8) keeps, keyed to your account’s email address: that you turned them on; for each journey your week view showed arriving in the next 36 hours, the IDs of the two calendar events it joins, when you need to leave, when you arrive, the time zone, whether you are the operator, and which nudges have been sent; and a copy of the push subscription (endpoint URL, the two encryption keys, and a device name such as “iPhone”) of each device, at most 10, where you have turned notifications on. No event title, place, description or guest is kept, and no location of yours unless you also turn on live location for travel (below). A journey is deleted once it is over, or when your week view no longer shows it. A device copy is kept until you turn nudges off, turn notifications off on that device or sign out there, or its push service reports it gone. Turning nudges off deletes all of it at once (Section 10); a server restart does not erase it.
  • Keeping travel blocks current — our database, only if you turn it on. Beside each journey above: the event ID of the travel block the Service added for it, the block’s start and end times, Google’s version tag for it (so a block you edited in any way since is left alone), when the commitment before it ends, when that was read, and the move waiting to be made (the new start and end, the minutes, and when it was worked out). These go with the journey. And, keyed to your account’s email address, a record of each automatic move made or refused: an internal draft ID (made of event IDs and a time), that it was this kind of automation, whether it was allowed and which checks stopped it, and when — never a title, place, description or guest. The records are kept until you turn keeping travel blocks current or travel nudges off (Section 10); if one cannot be written there, it goes to the server-memory buffer below instead.
  • Live location for travel — our database, 30 minutes at most, only if you turn it on.Beside a journey that travel nudges are watching, when you press “Update from where I am”: the 100 metre square your device was in (two whole numbers naming the square, never a latitude or longitude), when you sent it, and the time to leave worked out from it. Each is deleted 30 minutes after it was sent at the latest — every read of it refuses an older one and our scheduler clears older ones — and at once when you press “Stop sharing”, turn live location for travel or travel nudges off, or the journey is over. Nothing is kept for a journey nudges are not watching, and, on the operator’s own account, nothing near the home the operator configured. Never written to a log.
  • Title-category cache — server memory.Capped at roughly 500 entries per server process, keyed to an identifier issued at each sign-in, holding a title, its inferred category, and the model’s one-line reason. No fixed expiry: at the cap the oldest entry is dropped for each new one, and everything is erased on server restart.
  • Write-deduplication records — server memory, 10 minutes.After a confirmed write, the created event’s ID and its Google Calendar link are remembered briefly (at most 10 minutes) so a retried request cannot create a duplicate.
  • Write-decision records — server memory. Each confirmed, automatic, or refused calendar write adds a small content-free record (internal draft ID, the kind of write, decision, for an automatic change or removal how serious it was judged, and timestamp — never event details) to a buffer capped at 200 entries, kept for debugging the confirmation safeguards. For keeping travel blocks current, these records are kept in our database instead (previous items).
  • Autopilot activity — server memory, 24 hours. The IDs of events autopilot changed or removed for your account, at most 20, with no titles or times, so the You tab can list what happened and offer to put a removed event back. Each entry is dropped after 24 hours or when the server restarts, whichever comes first; no other account can read it.
  • Travel estimates and map positions — request lifetime only.Location text, the travel times worked out from it, and the rounded positions sent to your browser for the week map and the Trip room’s map (Section 3.5) are held while a request runs and discarded when the response is sent — apart from checked routes, below.
  • Weather forecasts — server memory, 10 minutes.Up to 200 hourly forecasts, each keyed by a coordinate rounded to about 1 km, with no account, name, or event attached. Each expires after 10 minutes.
  • Checked routes — server memory, an hour (seven days with no set time), only where an operator turns route checking on.For the operator’s own account only: each checked trip’s travel time and the kinds of travel it used, as numbers (never Google’s description of the route), keyed to the account’s email address, to the trip’s two places on a 100-metre grid, and to its time in 15-minute steps; bounded in number, and each is not used after an hour (seven days for a trip with no set time; a failed check after one minute) and is deleted the next time route checking runs, or when the server restarts. Alongside, each server instance keeps a count of each account’s trips checked for the current day (UTC), to enforce the daily limit; a past day’s count is deleted the next time a trip is checked, or when the instance restarts.
  • Live train feed — server memory, 5 minutes. Where live train times are on (Section 3.5), the last answer read from each of the MTA’s subway feeds is kept, keyed by that feed’s address, so every trip planned in that span shares one request. It is the MTA’s public data: no account, event, time, or place of yours is attached to it. Each copy expires after 5 minutes.
  • Address-lookup cache file — server disk, only if an operator configures it. Where address lookup is on and a cache file is configured (Section 3.5), looked-up location text, in normalized form, is stored with its coordinates and place name, not tied to any account. Found places stay until the file is deleted; not-found ones expire after 30 days.
  • Rate-limit counters — server memory.Request counts for the parsing, trip-planning, and week-map endpoints, keyed by your account’s email address when you are signed in and by IP address otherwise, swept opportunistically and cleared on restart.
  • Server restart clears everything server-side. Every structure above that lives in server memory is erased whenever the server process restarts. Nothing user-derived survives on our side, apart from your saved commute in the database, your travel-nudge data there if you turned nudges on (including, for at most 30 minutes, a square you shared with live location for travel), and the address-lookup cache file above where an operator has configured one.
  • Provider-side handling.Data sent to Anthropic under Section 5 is processed by Anthropic under its Commercial Terms and Data Processing Addendum and is not used for model training; retention on Anthropic’s side is governed by Anthropic’s published practices, not by us. The same structure applies to Tavily for the research queries described in Section 5.4, to Google for API traffic, to Open-Meteo and (where address lookup is on) the OpenStreetMap Foundation or the New York City Department of City Planning for the travel lookups in Section 3.5, to Google for the route checks in Section 3.5 (where an operator turns them on), to the MTA for the live-feed reads in Section 3.5 (which carry nothing about you), and (where the map is on) to OpenFreeMap for the map requests your browser makes. Neon, Inc. stores the database on our behalf; deleting your saved commute, or turning travel nudges off, deletes the rows, and Neon’s own backups of the database are retained and expire under Neon’s published practices.

8. Who we share data with — the complete list

We share data with no one except the service providers required to run the product, each receiving only what its role requires:

  • Google LLC— sign-in (OAuth) and the Calendar API itself. Google necessarily processes your requests to your own calendar. And, only on a deployment where the operator has turned route checking on, which is off unless explicitly configured (Section 3.5), and then only for the operator’s own account, its Routes API (routes.googleapis.com): the coordinates of a trip’s two ends — the shift or event being checked (or the workplace) and the commitment just before or after it — and the time of the trip, to check how long it takes. Never your identity, an event’s title, or address text.
  • Anthropic, PBC— the AI flows itemized in Section 5 (plus, on a deployment where an operator has configured the Section 6.1 email capability, the operator’s own email excerpts), under terms that prohibit training on the data.
  • Tavily, Inc. — only when the public-event research feature runs (Section 5.4): a search query derived from the draft event (title, location name, date). Never your identity, tokens, calendar contents, or images.
  • Open-Meteo(weather forecasts) — only when a live trip plan includes a Citi Bike leg (Section 3.5): a coordinate rounded to about 1 km, to get the hourly forecast there. Never your identity, the time of your trip, or any calendar text. On by default; an operator can switch it off.
  • OpenStreetMap Foundation(its Nominatim address-lookup service) — only on a deployment where the operator has turned address lookup on, which is off unless explicitly configured (Section 3.5): location text that matched no place the Service already knows — from your calendar, your commute setup, or the Trip room where that is on — to find its coordinates. Never your identity, or an event’s title or time.
  • New York City Department of City Planning (its NYC GeoSearch address-lookup service, geosearch.planninglabs.nyc) — only on a deployment where the operator has chosen it for address lookup, which is off unless explicitly configured (Section 3.5): location text that matched no place the Service already knows — from your calendar, your commute setup, or the Trip room where that is on — to find its coordinates, sent from our server. Never your identity, or an event’s title or time.
  • OpenFreeMap(Hyperknot Software Kft., Hungary; map tiles built from OpenStreetMap data) — only on a deployment where the operator has switched the week map on (the same switch lets the Trip room show a trip on a map), and only while you have the week map or a trip’s map open (Section 3.5). Your browser requests the map from tiles.openfreemap.orgdirectly, so OpenFreeMap receives your IP address, your browser’s user agent, our site’s address, and which map tiles you view — which reveals the area around your events, or around a trip you planned. Never your identity, calendar text, event times, event positions, or the places you typed into the Trip room or their positions. Its privacy policy states that it uses no cookies or tracking, keeps server logs without IP addresses except temporarily during a security incident, and may deliver content through Cloudflare.
  • Our hosting provider (currently Vercel, Inc. for the hosted Service) — runs the servers, terminates HTTPS, and keeps standard infrastructure access logs (Section 3.4). It also provides the page-view counting described in Section 12, and so receives, for each page opened: the path, the referrer, a coarse device type and country, and a visitor identifier it derives on its own servers and rotates daily. It receives no calendar data, no account, and no cookie — there is none to send.
  • Neon, Inc.(database hosting) — only where account storage is switched on: hosts the Postgres database, in the United States, that stores the commute setup you save while signed in (Section 7) — your commute answers and your account’s email address as their key — and, only if you turn travel nudges on where they are offered, the nudge data in Section 7 (event IDs and journey times, and your devices’ push subscriptions, and — if you turn live location for travel on — a 100 metre square for at most 30 minutes) — together with the sign-in record and the anonymous daily counters described in Section 7. Neon stores those on our behalf and receives nothing else: no event titles or places, no tokens, and none of your other requests.
  • The operator’s own scheduler— only on a deployment where travel nudges are switched on: a script in the operator’s own Google account (Google Apps Script) calls our server every few minutes with a shared password, and our server answers with counts (how many nudges were due and sent). Nothing about you is sent to it or through it.
  • The operator’s own scanner— only on a deployment where the Section 6.1 email capability is configured: the server exchanges a shared secret and message IDs with the scanner web app in the operator’s own Google account. Not applicable to the public Service.
  • Your browser’s push service(Apple, Google, or Mozilla, whichever your browser uses) — only if you turn on push notifications: after the Service writes an event, removes one automatically, or makes a serious change to one (Section 4), it hands that push service one message containing the event’s title and time — and, for a move, the time it was at and, if the place changed, the new place, plus, where they apply, how many guests can see it and the names of anything on your calendar the new time runs into — addressed to your device alone; and, when you press “Send a test notification”, one test message to each of your devices that says only that notifications are working, with nothing from your calendar. Where the operator offers travel nudges and you turn them on, it also carries each nudge: only that it is time to get ready or to leave, and the time to leave by. Every message is encrypted for your device, so the push service cannot read it. Off unless you enable it; the push service delivers it to you and to no one else.

For completeness: live trip plans, and the bike estimates between your events where those are switched on, also download Citi Bike’s public station feeds (Section 3.5). That is a read of public data — nothing about you is sent — so Citi Bike is not a recipient of your data. Subway schedule estimates (Section 3.5) likewise use a copy of the MTA’s public timetable kept on our server and send nothing. Live train times are different, and we list them so they are not missed: by default, during live hours (on weekdays, 7 AM–9 AM, 11 AM–1 PM and 3 PM–6 PM, New York time), a live trip plan with a subway ride makes our server read the MTA’s public live feed (api-endpoint.mta.info). The request names only which group of subway lines’ feed to read — which follows from the trip’s lines — and carries no identity, event text, times or places; each server instance reads a feed at most once every 5 minutes and shares that answer across the trips it plans. An operator can switch it off (Section 3.5). Live location for travel, where it is on and you use it, sends your position to no one but our server, and only as a 100 metre square: your browser finds where you are its own way — on some devices by asking the browser maker’s or device maker’s location service, under their own terms — and the Service receives only the square (Section 3.5).

We do not sell personal information, do not share it for advertising of any kind, and do not provide it to data brokers. If a legal demand for user data ever arrives, we will disclose only what the law compels after reviewing the demand’s validity, and — unless legally forbidden — will tell the affected user. If the Service is ever acquired or merged, Google user data would be transferred only with your explicit prior consent, as Google’s policy requires; for all other data, this policy would continue to apply and you would be notified before any new policy takes effect.

9. Cookies and local storage

The Service sets only the cookies that sign-in requires — there are no advertising, analytics, or tracking cookies of any kind. That stays true now that page views are counted (Section 12): the counting stores no identifier in your browser at all, so it has nothing to keep in a cookie. The complete list:

  • a session cookie (authjs.session-token, with a __Secure- prefix over HTTPS) — the encrypted container for your session and Google tokens; HttpOnly, SameSite=Lax, up to ~30 days;
  • a CSRF-protection cookie and a callback-URL cookie used by the sign-in flow, with the same protections;
  • short-lived (15-minute) cookies that exist only during the OAuth handshake itself.

Local storage holds at most five entries: the rejected-titles list and the confirmed-guesses list, both described in Section 3.3; if you complete commute setup, your commute answers (which may include an address you typed), also described there; when that commute came from or was saved to your account, a note of which account it belongs to (your email address), so the Service never shows one account’s commute to another account signed in on the same browser; and, if you save a place in the Trip room, your saved trip places (calmora.trip.places.v1: a short name and the text you typed for each, which may be an address, Section 3.3). If you turn on push notifications, your browser also installs the Service’s small background worker, which keeps a copy of the app’s own static files — code, icons, and an offline page — in your browser’s cache; none of that is personal. If you open the week map or a trip’s map, your browser’s ordinary web cache may also keep the map images and lettering it downloaded from OpenFreeMap, as it would for any website; neither map sets cookies or writes local storage. That is the entire client-side footprint.

10. Your choices and controls

  • Revoke Google access (the master switch). Visit myaccount.google.com/permissions and remove Calmora. This invalidates the Service’s ability to touch your calendar even if a session cookie still exists somewhere. We say this explicitly because signing out alone clears your cookie but does not revoke the Google-side grant; for a complete disconnect, do both.
  • Sign out.Destroys the session cookie in your browser — the only copy of your tokens — and removes the confirmed-guesses list from that browser. The rejected-titles list stays until you clear the browser’s site data.
  • Delete events. Events the Service just created can be removed in-app through its preview-and-confirm flow; any event it created can always be deleted directly in Google Calendar, which you control.
  • Delete your saved commute.Open the commute planner, press Change, then “Delete my saved commute”. That deletes it from your account (the database row, Section 7) and from this browser; your other devices lose their copy the next time they load. You can also change it at any time the same way. Signing out removes this browser’s copy of an account-saved commute but keeps it in your account, and revoking Google access does not delete it either — to remove it from our database, use the delete button (signed in) or email us.
  • Turn travel nudges off.Where they are offered, switching “Travel nudges” off on the You tab deletes, at once, everything they kept in our database for your account: your upcoming journeys, the copies of your devices’ push subscriptions, and the record that you turned them on (Section 7). Turning notifications off on a device, or signing out there, deletes that device’s copy. Turning nudges off also turns off keeping travel blocks current and deletes its records. There is no separate account-deletion button; to have everything deleted, use these switches or email us.
  • Turn off keeping travel blocks current.Where it is offered, switching “Keep my travel blocks current” off on the You tab stops it at once — no further move is worked out or made — and deletes the travel-block times, the moves waiting to be made and the record of past moves it kept for your account (Section 7). A block it already moved stays where it is; change it in Google Calendar if you want.
  • Stop sharing your location.Where live location for travel is offered, “Stop sharing” on the journey deletes, at once, every square and time to leave kept for your account; switching “Live location for travel” (or travel nudges) off on the You tab does the same and stops the button being offered. You can also block location for this site in your browser’s settings; then nothing can be sent.
  • Delete saved trip places.In the Trip tab, “Remove” deletes one saved place and “Remove all” deletes them all, from this browser — the only place they are kept. Signing out does not remove them.
  • Clear corrections and browser copies.Clearing the Service’s site data in your browser removes the rejected-titles list, the confirmed-guesses list, this browser’s copy of your commute, and your saved trip places. It does not touch a commute saved to your account.
  • Ask us. Email darwinhu64@gmail.com for access, deletion, or questions. The durable user data the server keeps is your saved commute, if you saved one, and your travel-nudge data, if you turned nudges on (we will send you a copy or delete them on request, from the address on your account), and the address-lookup cache file of Section 3.5, which, where one is in use, we will delete on request. Every other server-side trace of your use expires on its own or is erased when the server process restarts (Section 7); we will confirm, and will restart the server process to flush transient memory on request. For AI-provider-side data, we will relay requests to Anthropic where applicable.
  • Export. The durable copy of your calendar stays in your Google account, so Google Takeout exports everything, including events the Service created.

11. Security

What protects your data here, concretely:

  • all traffic is encrypted in transit (HTTPS, terminated and enforced by our hosting provider’s edge);
  • your Google tokens exist only inside an encrypted (JWE), HttpOnly, Secure cookie — there is no server-side token store to breach;
  • the database is reachable only from our server, over an encrypted connection, and each request can read or change only the signed-in account’s own rows — the key comes from your session, never from anything the browser sends; the one part of the server that reads across accounts is the travel-nudge scheduler, which answers only to a shared password sent in a request header, and reads only the journeys of accounts that turned nudges on;
  • a strict, per-request Content-Security-Policy confines the browser to the Service’s own origin: no third-party scripts can load (the map library, too, is served from our own origin), scripted requests can reach only the Service itself — plus, only on a deployment where the week map is switched on (the same switch serves the Trip room’s map), the map-tile host tiles.openfreemap.org — and the one off-origin form action the policy permits is the sign-in form submission to accounts.google.com;
  • security headers deny framing, MIME sniffing, and access to camera, microphone, and geolocation — the Service never asks your browser for any of those;
  • our application logs are structurally incapable of carrying your content (Section 3.4), and calendar titles are never placed in request URLs, so the host’s standard access logs do not record them either;
  • all user-provided and external text entering AI prompts is sanitized and fenced as untrusted data, and AI calls run with no tools and no ability to write to your calendar;
  • every write to your calendar requires your explicit confirmation, except where autopilot has been switched on and the draft cleared every safety gate (Section 4); a change or removal, confirmed or automatic, refuses to touch anything the Service did not itself create, and an automatic one additionally needs the operator’s separate switch and a device of yours to notify.

No internet service can promise perfect security, and we do not. What we can promise: the attack surface here is unusually small because so little is stored, and if we ever learn of a breach affecting your personal information we will notify you and the relevant authorities as applicable law (including New York’s SHIELD Act) requires, promptly and plainly.

12. Do Not Track, and tracking generally

The Service shows no advertising, does not follow you across other websites, and does not allow other parties to collect information about your activities through it. It does count page views, and this section says exactly what that is rather than leaving it to the word “analytics”.

What is counted. For each page you open: which page it was, the site you arrived from if any, a coarse device type and country, and a visitor identifier that Vercel (Section 8) works out on its own servers and changes every day— so visits on two different days cannot be joined together, and none of it names you. It reads nothing from the page in front of you: no event, no title, no place, no address, no account. It sets no cookie and stores nothing in your browser (Section 9). The script and the measurement it sends both come from this site’s own address, so your browser contacts no other host to do it.

Do Not Track does something here. If your browser sends a Do Not Track header or a Global Privacy Control signal, the measurement is discarded in your browser before anything is sent — not reduced, not anonymised further: not sent. That check runs for every page view rather than once when the page loads, so a signal you switch on mid-visit takes effect immediately.

Counting page views therefore adds no other party to the list: the script and its measurement are our own address, so your browser still speaks to nobody else — with one disclosed exception, unchanged by any of the above. Where the map is switched on and you open the week map or a trip’s map, the map-tile host (OpenFreeMap, Section 8) necessarily receives your browser’s requests for map tiles, as any web server receives the requests sent to it; by its own privacy policy it sets no cookies and uses no tracking technologies.

13. Children

The Service is not directed to children under 13, and we do not knowingly collect personal information from children under 13. If you believe a child has used the Service, contact us at darwinhu64@gmail.com and we will delete what little may exist (Section 7 describes why that is at most a saved commute).

14. United States processing, and regional notes

The Service is operated from the United States and its servers process data in the United States; the providers in Section 8 may process data in other locations under their own terms. If you use the Service from elsewhere, you are sending your data to the U.S.

California:we honor CalOPPA’s disclosure requirements throughout this policy (categories collected: identifiers, calendar/schedule content, and location information — event locations and the commute details you enter — Section 3; third parties: Section 8; change process: Section 15; effective date: above). We are an individual developer and believe we are far below every threshold that makes the CCPA/CPRA’s obligations apply — but as a matter of practice we honor access and deletion requests from anyone, from anywhere (Section 10), and we do not sell or share personal information as those laws define those terms.

15. Changes to this policy

When our practices change, this page changes first: we will update the policy and its effective date before the new practice takes effect, and material changes (a new data category, a new third party, a new use) will be called out prominently on this page. If a change would expand how Google user data is used beyond what this policy discloses, it will not ship until this policy — and where required, our Google verification — has been updated to cover it. Continued use after the effective date constitutes acceptance of the updated policy.

16. Contact

Darwin Hu — Operator, Calmora
darwinhu64@gmail.com
New York, United States

See also our Terms of Service.