Privacy Policy
Evenlot is scheduling software for small businesses. This page describes what the software stores, where it stores it, what it sends to other companies, and what it can and cannot delete. It was written by reading the code, and it is deliberately specific rather than reassuring.
1. Two different sets of people
There are two kinds of person in this product, and they are in very different positions:
- The business owner creates the account, chooses what to put into it, and pays for it.
- The staff on the roster are named, scheduled and clocked in and out by that business. Most of them never create an account with us, never see this page, and never agree to anything with us. Their employer decided to put their name here.
Evenlot holds staff records because a business put them there. What the business owes its own staff about that, and what Evenlot owes them directly, is not something this draft decides.
2. Who we are and how to reach us
Evenlot is run by one person and has no customers yet.
3. What the software stores
Everything a business puts in is stored as ordinary files on the server that runs the app, in one directory per business. There is no shared database table: one business's files are a different directory from another's, and which directory a request may touch is decided from the signed-in session, never from anything the browser sends.
Account and login
- A username, and the business it belongs to.
- A password, stored only as a PBKDF2-HMAC-SHA256 hash with a per-user random salt and 200,000 iterations. The password itself is never stored.
- An email address, if one was given. It is optional at signup.
- Whether the login is an owner or staff, which roster name it is linked to, whether it is disabled, and a counter used to sign every existing session out at once.
- Password-reset tokens, stored as hashes, expiring after one hour by default.
The business’s settings
- Opening hours, how many people each section needs and when, closing times, the business’s time zone and its currency.
- Overtime and pay-period settings, holidays, fairness preferences.
- A list of the names the owner has marked as being under 18, so the app can warn about hour limits for them.
- Stripe identifiers if the business has subscribed: a customer id, a subscription id, the subscription status and the date the current period ends.
The roster
For each person: their name, whether they are active, inactive or no longer employed, their role, which sections they can work, a maximum number of shifts, and a target number of weekly hours.
There is no field on the roster for a phone number, a date of birth, a home address, a national identification number, a photograph, or bank details. The software does not ask for any of them and has nowhere to put them.
Availability and time off
Which days each person cannot work, both as a recurring pattern and for specific weeks.
The schedule
- The previous schedule the owner uploaded, as a spreadsheet, CSV or PDF. It is stored exactly as it arrived and is never written back to or modified. Whatever is inside it is inside it.
- Every published week, archived week by week: who works which shift.
- Shifts the owner pinned by hand, and a profile of how their original spreadsheet was formatted so exports look like their own file.
Pay rates
Optional. If the owner enters hourly rates, each is stored as a whole number of minor currency units with the currency code it was entered in, in a file of its own that is separate from the roster. Nothing that feeds the schedule, the assistant or a staff member’s view of the rota reads that file.
The time clock
- One record per punch: the instant it happened in UTC, who it was for, and who took it. The date, the week, the hours and any rounding are worked out from that instant when a report is built, so nothing is stored twice.
- A correction is an additional record naming what it changed. A punch is never overwritten or deleted, so “the manager changed my hours” is answerable from the records.
- Kiosk PINs are stored only as hashes, in a separate file that is left out of the data export for the same reason a password would be.
Logs kept per business
- An activity log of what the in-app assistant proposed, what the owner approved, and what was refused. It contains staff names.
- If the assistant is switched on, a record per call of how many tokens it used and what that cost. It contains no message text.
- A record of any name that has been replaced by a pseudonym. See section 8, because this one holds the original name on purpose.
Server logs
The application writes one line per request: the method, the path, the status code, how long it took, and a random request id. It does not log IP addresses, browser user agents, query strings, request bodies or cookies, and values that look like credentials are replaced before anything is written.
IP addresses are used, but not stored: to rate-limit logins, signups and password resets, an address is reduced to a fixed-length hash held in the running process’s memory for sixty seconds. It is never written to disk.
4. What is deliberately not collected
- No analytics, no tracking pixels, no advertising identifiers, and no third-party scripts. The pages load nothing from any other company: every font and image is served from this site.
- No cookies except the one that keeps a person signed in, described in section 9.
- No card numbers. Card details are entered on Stripe’s own pages and never reach Evenlot.
- Nothing a customer puts in is used to train any model, sold, or shared with anyone other than the companies listed in section 6, and each of those only for the job it is there to do.
One honest qualification. Several fields are free text: a note beside a time-off request, a message typed at the assistant. If someone types a phone number, a medical reason or anything else into one of them, the software stores what was typed. It does not inspect free text and remove personal details from it.
5. The in-app assistant, and exactly what leaves this server
The assistant lets an owner type a sentence instead of clicking through forms: “Kaye resigned, rebuild next week”.
It is off unless an API key is configured. With no key, nothing leaves the server at all: the sentence is parsed by ordinary code on this machine.
When it is switched on, each message is sent to Anthropic’s API, and this is everything that is sent:
- The message the owner typed, exactly as typed.
- The last few turns of the same conversation, exactly as typed.
- The list of names on the roster. Staff names reach the model. They are sent so it can tell which person a sentence is about.
- The names of the business’s sections, today’s date in the business’s own time zone, and the Monday of the current week.
These things are not sent: pay rates, time-clock punches, availability and time off, published schedules, the uploaded spreadsheet, email addresses, passwords, and the identifier of the business itself.
Two further points, because they cut both ways. The model is never allowed to act: it may only choose from a fixed list of scheduling operations, its reply is validated before anything happens, nothing changes without the owner pressing confirm, and every sentence shown next to that confirm button is written by Evenlot’s own code rather than by the model. But the message itself is passed on as typed. Evenlot does not strip personal details out of it, so if an owner writes a staff member’s phone number or the reason they are in hospital, that sentence goes to Anthropic with the rest.
How many tokens each call used, and what it cost, is recorded locally. The message text is not.
6. Other companies involved
Only these, and each only when it has been configured. Nothing else is contacted by the server, and nothing at all is contacted by the browser.
- Anthropic: the assistant, as described above. Receives the owner’s message and the roster names. Optional; off without an API key.
- Stripe: subscription payments. Evenlot sends the identifier of the business, the price being bought and the pages to return to, and stores back the customer and subscription identifiers, the status and the period end date. Card details and the billing email are collected by Stripe on Stripe’s own pages. Optional; billing is off without Stripe keys.
- An email provider: for password resets, staff invitations and “the schedule is published” notices. This is Resend if it is configured, otherwise an SMTP server the operator configures. It receives the recipient address, the subject and the body. If neither is configured the message is written to a local file instead, and the body of a password-reset message is redacted rather than written there.
- Sentry: error reporting, if it is switched on. It is configured not to send personal data, cookies, authorization headers or query strings, and values that look like credentials are removed before an error is sent.
- The hosting provider: the machine the app runs on and the disk the files sit on. See the open question about naming it.
7. How long things are kept
This is the section most likely to be wrong in a policy written from optimism, so it is written from the code.
Nothing expires on its own. There is no scheduled job that deletes an old schedule, an old punch, a dormant account or a business that stopped paying. A business’s files stay on the server until somebody deletes them.
What does delete, today:
- Deleting the business. The owner can delete the whole business from Settings after re-entering their password. That removes the entire data directory, every login belonging to it, and any outstanding password reset tokens. It is immediate and cannot be undone.
- A staff member deleting their own login. This removes the login. It deliberately does not remove the person from the roster, because the roster is the business’s own scheduling record rather than the login.
- The demo. The sandbox a visitor can start from the marketing page is a temporary business filled with invented data. It is deleted one hour after it is created.
- Log rotation. The activity log, the assistant usage log, the mail file and the punch log each stop growing at 5 MB, keeping one previous generation. Older entries are dropped at that point. That is a size limit, not a retention policy, and it is not a promise that anything is gone by a particular date.
Backups. If nightly backups are running as the deployment ships, the whole data directory is archived once every 24 hours and the fourteen most recent archives are kept. So a business deleted today can still be inside those archives for about two weeks, and nothing removes one business or one person from an archive that has already been written.
8. Removing a name is not the same as erasing it
There is a feature for a departed worker: it replaces their name with a stable label like “Former staff #a1b2c3d4” across the roster, their availability, the business’s settings, pinned shifts, every published week, and the activity log, so the history keeps its shape without keeping the name. It also unlinks any login pointing at that person.
Two things about it are true and are easy to gloss over:
- The original name is kept, in a file that maps it to the label. It has to be, because the spreadsheet the owner uploaded is never rewritten, and that map is what stops the name reappearing the next time the app reads the file. This is a pseudonym replacing a name, not the name being destroyed.
- The uploaded spreadsheet still contains the name. The app tells the owner so, in the result of the operation, because they may be about to repeat our answer to the person who asked. Replacing it means uploading a file with the name already changed.
9. Cookies
One cookie, for signing in. It is set when someone logs in, is signed so it
cannot be edited, is marked HttpOnly so page scripts cannot read it, is
marked SameSite=Strict so it is never sent from another site,
and is served only over HTTPS in production. It lasts at most seven days, and
the server can invalidate every session for an account at once. A demo
session carries its own one-hour deadline and is cleared when it passes.
There are no analytics, advertising or third-party cookies, so there is nothing here for a consent banner to ask about.
10. Who can see what
- One business cannot reach another’s data. Which business a request belongs to always comes from the signed-in session.
- A staff login sees the rota and its own shifts. It does not see the management view: per-person pay-period hours and the reasons a shift was pinned are owner-only, partly because those reasons can identify which staff are under 18.
- Pay rates, the timesheet, other people’s punches and the kiosk PINs are owner-only.
Being straight about the other direction: anyone with administrative access to the server can read every business’s files, because they are files. Nothing in the software restricts that.
11. Getting a copy, and getting it out
- Any signed-in person can ask the app for everything it holds about their login, including which published weeks name them.
- An owner can download the whole business as a zip: settings, roster, availability, every archived week, pins, pay rates, the punch log, the formatting profile, the pseudonym map and the file they originally uploaded. The activity log, the usage log, the mail file and the kiosk PIN hashes are deliberately left out: a backup a customer emails to themselves must not be a credential store.
12. Security
What the software does, stated as controls rather than as a guarantee:
HTTPS in production; passwords hashed with PBKDF2-HMAC-SHA256 at 200,000
iterations; signed HttpOnly SameSite=Strict session cookies with
server-side revocation; a cross-site request token required on every change;
lockout after repeated failed logins and per-address rate limits on login,
signup and password reset; a content security policy that allows no inline
scripts and no third-party code; uploads size-capped and validated before
they are committed; and every file written atomically under a lock.
No system is secure because a page says so. This is a description of the controls that are in place, not a promise that they are sufficient.
13. Children
Evenlot is sold to businesses and is not intended for use by children. It does hold, on purpose, a list of the staff a business has marked as being under 18. That list is what makes the under-18 limits apply to them. When it builds or checks a schedule, Evenlot enforces the limits in that business’s own rules: a weekly hours cap, and per-shift limits for the earliest start, the latest end and the longest day.
It does not know any jurisdiction’s child labor law, does not check ages, and does not enforce school-day rules. The list is names somebody typed in, and the limits are numbers somebody typed in; neither is a legal determination. There is no date-of-birth field anywhere on the roster, which is why an age cannot be checked. See “The roster” in section 3.
14. Changes to this page
It is a draft; it will change. How a later change is announced to customers who have already signed up is one of the open questions below.
Open questions for review
Every point below is a decision the software cannot make and this draft refuses to guess.
- PRIV-1Effective date and versioning. This page carries only the date it was drafted. What is the effective date, is a version or changelog needed, and how must a later change be notified to existing customers?
- PRIV-2Controller or processor. Which party is which for the owner’s account details, and for the staff roster, availability, wages and punches? Does a data processing agreement have to be part of signing up, and does it have to exist before the first paying customer?
- PRIV-3Staff who never signed up. What notice does Evenlot owe a person whose name, hours and pay rate are here because their employer typed them in, and what may that person ask Evenlot for directly rather than through their employer?
- PRIV-4Identity and contact. The legal entity name, its registered address, the governing country, and an address for privacy requests. None of these exist anywhere in the product today.
- PRIV-5The host, and its own logs. The hosting provider is not named in the codebase. It has to be named as a sub-processor, the country the server is in has to be stated, and any logging the provider does on its own account has to be described. That logging can include IP addresses whatever the application does.
- PRIV-6Free text and special categories. Health, religion or union membership can arrive in a time-off note or an assistant message, and nothing filters them out. Must the policy forbid it, must the product warn at the box, or does handling it bring obligations we should avoid taking on?
- PRIV-7Anthropic. What the commercial API terms say about retention and training; whether a data processing agreement or a zero-retention arrangement is needed before a customer’s staff names go through it; whether the owner must be warned in the product; and whether an owner must be able to switch the assistant off for their own business.
- PRIV-8The sub-processor list. Every third party in section 6 is optional in the code. Which are actually switched on in production, does a public sub-processor list with advance notice of changes have to exist, and does each need a signed agreement before launch?
- PRIV-9International transfers. Anthropic, Stripe, Resend and Sentry are US companies. Where is the server, where are customers expected to be, and what has to be in place for the transfer?
- PRIV-10Retention and backups. Nothing expires today. What retention period are we prepared to state, and what maximum time to erasure is honest given fourteen nightly archives that nothing edits? Must backups be encrypted at rest or held for a shorter window?
- PRIV-11“Anonymise” is the wrong word. The feature keeps the original name in a mapping file that ships in the customer’s own export, so it is pseudonymisation. Is the current wording acceptable, must it be renamed in the product, and must a real erasure path be built before launch?
- PRIV-12Cookie consent. Confirm a sign-in cookie of this kind needs no consent banner in the markets we intend to sell in, and whether its seven-day lifetime is acceptable.
- PRIV-13Internal access. Anyone with administrative access to the server can read every business’s files. What must this page say about that, what controls or access logging does a lawyer want in place first, and does any commitment belong in the terms instead?
- PRIV-14Answering a formal request. Are the two export routes enough for an access or portability request, what is the response deadline, how is a request from a staff member with no login handled, and who is answerable for it?
- PRIV-15Breach notification. No process exists: no deadline, no template, no named person, and no log that would reliably establish scope afterwards. What must exist, and what must this page promise?
- PRIV-16Under-18 staff. The product records that a named person is under 18. Does that bring additional obligations, and may a staff login be issued to a minor at all?