Owner's guide

The backend

Every request the server answers and every job it runs while nobody is looking. This page is generated from the running code, so a missing entry is a defect, never an oversight.

What is hereFour things: the requests the server answers, the jobs it runs, where your data sits, and who else it talks to

All of it is read from the running code, so a missing entry is a defect rather than an oversight. If you only read one section, read the outside services — it is the only place that says what leaves this machine.

The APIEverything the app, your Claude and your scripts can ask this server for

Grouped by the part of the app it serves. The check column says a screen in the app makes that request. A row without one is served for scripts and operators. The one-line explanations are the code's own.

Two families are named for the store rather than the menu. documents serves the Notes tab and goals serves Goals. The Aug 2026 rename changed the words on screen and left every route, table and identifier as it was, so a bookmark from before it still resolves.

The journalWriting, reading back, search, recordings, and the device signals behind the morning sleep entry.

RequestWhat it doesApp
GET /api/journalA day's entries, in the order things happened.✓
POST /api/journalWrite an entry: a moment, a span, or a running time log.✓
GET /api/journal/activeThe running time log, if one is running.
POST /api/journal/mediaStore a recording or photograph; the key it returns is what an entry holds.✓
POST /api/journal/media/chunkOne piece of a long upload; the final piece assembles the file.✓
GET /api/journal/searchFind something written on any day, in the words or a transcript.✓
DELETE /api/journal/{entry_id}Remove an entry.✓
GET /api/journal/{entry_id}One entry by id, the way a change row names it (LC-221).✓
PUT /api/journal/{entry_id}Edit what an entry says or where it is filed; words cannot be saved away to nothing.✓
PATCH /api/journal/{entry_id}/sleepSay when you slept and woke. The recomputed entry keeps your numbers.✓
POST /api/journal/{entry_id}/stopClose the running time log at this moment.✓
POST /api/journal/{entry_id}/tasksPoint an entry at tasks; the task takes over its area until unlinked.✓
PATCH /api/journal/{entry_id}/timesMove an entry in the day; an end before its start is refused.✓
POST /api/journal/{entry_id}/transcribeWrite up a recording that has no transcript yet, for an entry the job never saw.✓
POST /api/signalNote a device signal: proof somebody was awake at a moment.

TasksThe open list, check-off, deferral, your status words, and the chores that come back.

RequestWhat it doesApp
GET /api/areasEvery area you have ever filed a task under, with open counts; empty ones stay.✓
GET /api/recurringThe chores that come back, and their cadences.✓
POST /api/recurringDefine something that comes back on a cadence.✓
POST /api/recurring/generateWrite today's recurring tasks now rather than waiting for the tick.
DELETE /api/recurring/{rid}Stop a definition. The tasks it already made stay.✓
PATCH /api/recurring/{rid}Change a recurring task's words, cadence, or whether it runs.✓
GET /api/task-statusesYour status words in their categories, seeded on first read.✓
POST /api/task-statusesAdd a status of your own to one of the four categories.✓
DELETE /api/task-statuses/{status_id}Remove a status; rows still wearing it move somewhere visible first.✓
PATCH /api/task-statuses/{status_id}Rename, recolor or reorder a status; a rename reaches every task wearing it.✓
GET /api/task-typesThe type words on your tasks, busiest first.✓
POST /api/tasksAdd a task.✓
GET /api/tasks/closedRecently closed, newest first: the record, and the way back from a mis-tap.✓
GET /api/tasks/openEverything still on your plate, in your order; deferred-today stays hidden.✓
POST /api/tasks/reorderPut a task where he dragged it, section and all, and keep it there.✓
GET /api/tasks/searchUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/tasks/search✓
DELETE /api/tasks/{task_id}Remove a task.✓
GET /api/tasks/{task_id}One task, whole. A goal id is refused — its page is the stream's.✓
PATCH /api/tasks/{task_id}Edit a task's fields.✓
POST /api/tasks/{task_id}/deferHide a task for one date; it returns the next day unchanged.✓
GET /api/tasks/{task_id}/journalWhat has been written against this task, newest first.✓
POST /api/tasks/{task_id}/keepAdopt a task the assistant added. It stops being a suggestion and joins the list with everything else.✓
POST /api/tasks/{task_id}/promoteMake a task a goal, keeping its id and taking its subtasks with it.✓
PATCH /api/tasks/{task_id}/statusMove a task to one of your statuses; a word you do not use is refused.✓
GET /api/tasks/{task_id}/subtasksThe steps under a task, open and finished apart.✓

Life areasThe parts of your life things are filed under, in your words and colours.

RequestWhat it doesApp
GET /api/life-areasYour areas, in your order, with your words for each.✓
POST /api/life-areasName a new part of your life.✓
PUT /api/life-areas/orderUNDESCRIBED — add a sentence to PAGE_COPY for PUT /api/life-areas/order✓
PATCH /api/life-areas/{area_id}Rename, recolor, or rewrite what an area is; a rename reaches everything filed under it.✓

The DayThe timeline, what changed, and the Google Calendar connection.

RequestWhat it doesApp
GET /api/calendar/configWhether a calendar is connected, and which ones are chosen.✓
GET /api/calendar/day/{date}Everything on one day: appointments and dated tasks, on one timeline.✓
POST /api/calendar/eventsPut an appointment on the calendar by hand.
DELETE /api/calendar/events/{event_id}Take a hand-made appointment off the calendar, with its decisions.
PATCH /api/calendar/events/{event_id}/intentDecide about one occurrence; each verb also moves the task and the log.✓
POST /api/calendar/placeholder-titlesWhich calendar titles are placeholders rather than meetings, so they keep their block on the day and never become tasks.
GET /api/changesA day's changes, or everything after a cursor.✓
GET /api/changes/latestThe newest change id, which is where a full export sets its cursor.
GET /api/changes/streamServer-Sent Events: the backlog after `since`, then the log as it grows.
POST /api/gcal/syncPull a window of the connected calendar in, safely repeatable.
GET /api/google/auth-urlThe Google sign-in link for this account, with a signed state.✓
GET /api/google/calendarsThe calendars your Google account offers, and which sync today.✓
POST /api/google/calendarsChoose which calendars sync and their areas, then pull them in at once.✓
GET /api/google/callbackWhere Google sends the browser back once you allow the calendar connection.
POST /api/google/disconnectForget the Google connection; the events already synced stay.✓
GET /api/google/statusWhether this instance can offer Google Calendar, and whether yours is connected.✓

NotesThe Notes tab's notes, the editor's stored bodies, and search inside them.

RequestWhat it doesApp
GET /api/documentsThe notes, newest first by the date each one shows.✓
POST /api/documentsStart a note.✓
GET /api/documents/searchFind a note by its title, its description, or the words inside it.✓
DELETE /api/documents/{doc_id}Remove a note and its body; the journal entry pointing at it keeps its words.✓
GET /api/documents/{doc_id}One live note; an archived one answers 404, which the app reads as shelved.✓
PATCH /api/documents/{doc_id}Rename a note, refile it, or move it on or off the shelf.✓
POST /api/documents/{document_id}/promoteMake a note a goal, carrying its title, its area and its words.✓
GET /api/page-body/{entity_id}The stored editor blocks, or the same body as markdown (LC-221).✓
PUT /api/page-body/{entity_id}Save the whole body, as editor blocks or as markdown; words for search are derived from it.✓
GET /api/page-body/{entity_id}/historyEverything the History panel draws, including how fresh the trail is.✓
POST /api/page-body/{entity_id}/historySeal what it says right now, on request.✓
GET /api/page-body/{entity_id}/history/{state_id}One past state, for reading it without putting it back.✓
POST /api/page-body/{entity_id}/history/{state_id}/restorePut a past state back. What is on screen now is sealed first, always.✓

GoalsThe streams you are working toward, with counts and movement computed from the work.

RequestWhat it doesApp
GET /api/goalsEvery goal, longest untouched first, with counts computed from the work.✓
GET /api/goals/{goal_id}One goal, for its own page.✓
GET /api/goals/{goal_id}/documentsThe writing filed under a goal, newest first.✓
GET /api/goals/{goal_id}/filesA goal's files, newest first, each with a fresh link.✓
POST /api/goals/{goal_id}/filesKeep a file beside a goal; the answer is the row, link and all.✓
DELETE /api/goals/{goal_id}/files/{file_id}Take a file off a goal, bytes and all.✓
GET /api/goals/{goal_id}/journalWhat has been written against this goal, newest first.✓
GET /api/goals/{goal_id}/linksWhat this goal points at and what points at it, in one list.✓
POST /api/goals/{goal_id}/linksPoint this goal at another one, with words for what the arrow means.✓
GET /api/goals/{goal_id}/tasksThe work under a goal, open and finished apart.✓
POST /api/initiativesStart a goal.✓
DELETE /api/initiatives/orderForget the dragged order, so goals read by status, then longest untouched.✓
DELETE /api/initiatives/{goal_id}Remove a goal; its tasks stay.✓
PATCH /api/initiatives/{goal_id}Change a goal; renaming reaches the tasks that name it.✓
POST /api/initiatives/{goal_id}/reorderPut a goal where he dragged it, section and all, and keep it there.✓

ChaptersThe stretches of days you lived under one name, and what covers a given day.

RequestWhat it doesApp
GET /api/chaptersEvery chapter, in reading order: running, then coming, then over.✓
POST /api/chaptersName a chapter. A name is enough; dates can come later.✓
GET /api/chapters/highlightedUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/chapters/highlighted✓
GET /api/chapters/on/{date}The chapters a given day falls inside.
DELETE /api/chapters/{chapter_id}Remove a chapter. The days it covered keep everything written on them.✓
GET /api/chapters/{chapter_id}One chapter, with its dates read in the account's own zone.✓
PATCH /api/chapters/{chapter_id}Change a chapter's name, its span, where it sits, or how it is marked.✓
GET /api/chapters/{chapter_id}/documentsThe live notes filed under this chapter, in the index's own order.✓
GET /api/chapters/{chapter_id}/journalWhat has been written on this chapter, newest first.✓
POST /api/chapters/{chapter_id}/moveMove an event and everything inside it by a number of days, in one write.✓
GET /api/chapters/{chapter_id}/tasksThe work filed under this chapter, open and finished apart.✓

RemindersTimes you asked to be nudged at, including ones that repeat.

RequestWhat it doesApp
GET /api/remindersYour reminders, soonest first; active means still waiting on you.✓
POST /api/remindersSet a nudge for a time, once or on a repeat.✓
DELETE /api/reminders/{reminder_id}Remove a reminder entirely.✓
PATCH /api/reminders/{reminder_id}Change a reminder's words, its time, or its repeat.✓
POST /api/reminders/{reminder_id}/ackDeal with a reminder; a repeating one rolls to its next time.✓
POST /api/reminders/{reminder_id}/snoozePush a reminder out by some minutes.✓

Your phonesWhich phones a reminder can ring, and the one-off test that proves it.

RequestWhat it doesApp
GET /api/devicesWhich phones this account can be reached on. The answer to "why did nothing arrive".✓
POST /api/devicesSay where a push notification can reach this account.✓
POST /api/devices/testSend one push right now, so "does this reach my phone" has an answer.✓
DELETE /api/devices/{token}Stop pushing to one phone.✓

Your accountWho you are to the app, every switch you can flip, the web login, and taking your data with you.

RequestWhat it doesApp
GET /api/auth/claimUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/auth/claim
POST /api/auth/claimSet the web login on an instance that has none yet. The second attempt is refused, so this stops being a way in the moment it is used.
POST /api/auth/signinTrade your username and password for a token. The phone's way in, so an access token never has to move between devices.
GET /api/auth/statusWhether this account has set a web login yet, and how long its password has to be.✓
POST /api/auth/verifyWhether a username and password are this account's web login.✓
GET /api/export/archiveEvery RECORD this account holds, as a zip.✓
POST /api/settings/aiTurn AI on or off for this account.✓
POST /api/settings/ai-jobTurn one AI job on or off, and hand back the stored list.✓
POST /api/settings/ai-job-modelChoose which model one AI job runs on. Only the models that job declares are accepted.✓
POST /api/settings/ai-job-promptEdit the prompt one AI job runs with, or clear the edit to get the shipped one back.✓
POST /api/settings/assistant-acts-as-meUNDESCRIBED — add a sentence to PAGE_COPY for POST /api/settings/assistant-acts-as-me✓
GET /api/settings/backup-statusWhen your data was last copied, and whether copies leave this machine.✓
POST /api/settings/barPut these apps in one bar, in this order. The phone's bottom row holds four and the wide window's top row holds twelve, and fewer is allowed.✓
POST /api/settings/device-zoneSay where this phone or laptop is, and adopt that timezone only if it moved.✓
POST /api/settings/homeMake one app, or the Apps page itself, the page the web and the phone open on. An app has to be switched on first.✓
POST /api/settings/loginSet this account's web login, replacing any it already had.
POST /api/settings/moduleSwitch one app on or off. An app switched off leaves the bar and stops being the home page in the same write.✓
POST /api/settings/passwordChange this account's web password, proving the old one first.✓
GET /api/settings/phone-tokenWhether a phone has ever been set up from here.✓
POST /api/settings/phone-tokenA fresh token for a phone, minted from a laptop somebody is logged into.✓
POST /api/settings/service-keyStore your own key for an outside service. Once stored it is never read back out, so the settings page can only say whether one is set.✓
POST /api/settings/sleepSay whether the morning sleep reading is taken at all.✓
GET /api/settings/sleep-areaWhich area the morning reading files under, and what it is called now.✓
POST /api/settings/sleep-areaFile the morning reading under one of your areas, or under none.✓
POST /api/settings/tasks-advancedTurn the richer task tier on or off.✓
POST /api/settings/themeSet some palette colours for this account, or take the shipped palette back.✓
POST /api/settings/timezoneStore the timezone every date resolves through.✓
GET /api/whoamiWho you are to the app, and every switch as it is stored.✓

RecordingsReading back a stored video, audio or photograph through an expiring link.

RequestWhat it doesApp
GET /api/media/{key}A recording, for a link that has not expired.

Running the instanceHealth, provisioning, and the operator's manual controls.

RequestWhat it doesApp
GET /api/accountsEvery account and every grant, the person-agent links among them.✓
GET /api/accounts/crossingsUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/accounts/crossings✓
PUT /api/accounts/grantsOpen one account to another, or change how; answers with the whole table.✓
DELETE /api/accounts/grants/{viewer_id}/{target_id}Take a grant back; the viewer's next request into that account is refused.✓
POST /api/admin/area-filing/resweepAsk the classifier again about every note and task it declined to file.
POST /api/admin/chapters/importBring an account's legacy chapters across, as often as anybody runs it.
GET /api/admin/crossingsUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/admin/crossings
GET /api/admin/grantsUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/admin/grants
PUT /api/admin/grantsUNDESCRIBED — add a sentence to PAGE_COPY for PUT /api/admin/grants
DELETE /api/admin/grants/{viewer_id}/{target_id}UNDESCRIBED — add a sentence to PAGE_COPY for DELETE /api/admin/grants/{viewer_id}/{target_id}
POST /api/admin/jobs/{name}/runRun one background job now, for every account. The operator's manual trigger.
POST /api/admin/provisionMake an account: a row, a partition, and a fresh token.
DELETE /api/admin/tenants/{uid}Retire an account: it can no longer sign in, and its data is set aside, not deleted.
PATCH /api/admin/tenants/{uid}Correct an account's name or email, when it was provisioned with the wrong one.
POST /api/admin/tenants/{uid}/change-log/clearEmpty one account's Changes lane, and say how many rows went.
GET /api/assistant/messagesThe conversation so far, oldest first.✓
POST /api/assistant/messagesSay something; the answer comes back on this same request.✓
POST /api/assistant/messages/streamUNDESCRIBED — add a sentence to PAGE_COPY for POST /api/assistant/messages/stream✓
GET /api/boardsEvery board, the most recently changed first, without its drawing.✓
POST /api/boardsStart a board: a blank canvas, or a FigJam board shown from its share link.✓
DELETE /api/boards/{board_id}Remove a board and its drawing.✓
GET /api/boards/{board_id}One board with its drawing.✓
PATCH /api/boards/{board_id}Give a board a new name; a blank one is Untitled board.✓
PUT /api/boards/{board_id}/sceneThe drawing as it is now, whole. 413 when it is over the ceiling.✓
GET /api/buildThe marker of the upload that is serving, or "unknown" for a build deploy.sh did not make.
POST /api/captureOne line typed or spoken, filed as a task or a journal entry, and the answer says which. With AI off it is always the journal.✓
GET /api/connector/sessionsThe connections seen in the last `days`, newest first, with what each wrote.✓
DELETE /api/connector/sessions/{connection_id}Disconnect one assistant: take back its key, and keep its calls on record.✓
GET /api/connector/sessions/{connection_id}One connection and every call it made, oldest first.✓
GET /api/developmentWhat the development board holds and which commit each tier last deployed, for the phone's Development screen. The web tier reads GitHub itself; the phone asks here.✓
GET /api/goal-kindsYour kind words in your order, seeded on first read.✓
POST /api/goal-kindsAdd a kind of your own; it goes on the end of the list.✓
DELETE /api/goal-kinds/{kind_id}Remove a kind; goals still wearing it move to a kind you name first.✓
PATCH /api/goal-kinds/{kind_id}Rename, recolor or reorder a kind; a rename reaches every goal wearing it.✓
GET /api/goal-linksEvery arrow at once, both ends named — the whole map in one read.✓
DELETE /api/goal-links/{link_id}Rub out one arrow. Both goals stay.✓
PATCH /api/goal-links/{link_id}Change what an arrow says; it keeps its direction and its ends.✓
GET /api/healthLiveness. The phone's recovery poll hits this with no session, so it takes no token.
GET /api/jobsWhen each background job last finished, for this account.
GET /api/pushUNDESCRIBED — add a sentence to PAGE_COPY for GET /api/push✓
PUT /api/push/kinds/{kind}Say whether one kind of news may interrupt this account.✓
POST /api/push/receiptsAsk Apple, through the relay, what happened to the pushes it took.✓

The background jobs12 jobs run on their own clocks, and each one is a switch

Your Claude can turn any of them off for this instance. A stopped job raises no error. Things simply stop appearing, so every run leaves a heartbeat — and a job crossing between working and failed sends one email each way, so a stop is news once, not a thousand times.

JobHow oftenWhat it does
remindersevery minutefires the reminders whose moment has arrived
push_receiptsevery 5 minutes
recurringevery 15 minuteswrites today's recurring tasks, once
sleepevery 15 minutesreads last night from the marks you left and writes the morning entry
calendarevery 15 minutespulls your Google Calendar into the day
classifyevery 2 minutesfiles a fresh capture into one of your life areas, marked as the classifier's choice
document_areasevery 5 minutesfiles a note that has no life area, reading its name, kind, description and text
task_areasevery 2 minutesgives a task under a stream that stream's area, then files what is left by reading the task's words
area_descriptionsevery 2 minutes
transcodeevery 5 minutescompresses new video recordings to web size, keeping the original until the swap is safe
backupdailytakes a consistent copy of your data and hands it to offsite storage
body_consolidationhourlyturns each note's raw save trail into versions where the writing really moved, and writes the line saying what changed

Where a Claude connectsThe same backend answers claude.ai, through a door with a lock

These addresses are not in the table above because they are not the app's: they are the MCP surface a Claude connects to, serving the same nineteen tools over your same data. Without a signed-in token the door answers 401 and points at the OAuth flow. Signing in IS your web login, on this backend's own page.

AddressWhat it is
/.well-known/oauth-authorization-serverThe metadata document naming the endpoints above, read first.
/.well-known/oauth-protected-resource/mcpNames which authorization server protects /mcp.
/authorizeOAuth: where claude.ai sends the browser to ask permission.
/mcpThe MCP endpoint itself: nineteen tools over your journal, tasks, notes, days and goals. Requires a bearer token. Without one it answers 401 with the pointer that starts the OAuth flow.
/registerOAuth: where a client introduces itself before asking.
/tokenOAuth: exchanges a finished sign-in for an ordinary access token.

Where your data isFour stores, and only one of them is yours

Your journal, tasks, notes, calendar and settings are rows in a single SQLite file that belongs to your account alone — not a shared table with your name in a column. Recordings sit beside it as plain files. The whole thing leaves with you through the export on the account page, as readable JSON plus a full SQL copy of the database.

StoreWhat is in itWhere
core.dbEverything you write and everything the app keeps for you: entries, tasks, notes, the day's calendar, your life areas, streams, reminders and settings.

area_classifications, area_corrections, area_description_drafts, assistant_messages, boards, calendar_config, calendar_events, change_log, chapters, connector_calls, connector_sessions, device_signals, devices, document_area_classifications, document_area_corrections, documents, event_intents, gcal_sync_state, goal_files, goal_kinds, goal_links, google_tokens, job_heartbeats, journal_entries, journal_entry_tasks, journal_writeups, life_areas, media_posters, media_transcodes, page_bodies, page_body_raw_saves, page_body_versions, push_deliveries, push_preferences, recurring_task_instances, recurring_tasks, reminders, sleep_config, task_area_classifications, task_area_corrections, task_deferrals, task_statuses, tasks

one file per account
users/{id}/core.db
system.dbThe accounts themselves — who exists, their login, and the tokens that let a device or a Claude connect. Everything you write is in the other file, never this one.

account_crossings, account_grants, auth_tokens, oauth_clients, oauth_codes, oauth_txns, users, web_logins

one file for the instance
system.db
RecordingsThe video, audio and photographs attached to entries. Kept as ordinary files, not blobs in the database — a compressed copy for playback, and the original until that swap is known good.on disk beside the databases
media/
Offsite copyThe nightly backup and, where configured, the recordings. This is the only store that is not on the machine running the app.a private Cloudflare R2 bucket
see the outside services

The outside servicesWhat leaves this machine, and who else is involved

Every one of these is optional, and the instance runs without all of them. Turning one on is a decision about trust, so the row says exactly what gets sent, what turns it on, and what you give up by leaving it off. This list is the whole of it — everything else the backend does stays on the machine.

ServiceWhat it does, and what we sendTurned on by
Anthropic

api.anthropic.com

Filing a captured entry into one of your life areas.

The text of an unfiled entry and the names of your life areas, and that is the whole payload. Your other entries, your tasks and your account details stay here.

Without it: Captures stay unfiled until you file them. Everything else works the same, and no other feature depends on this one.

a key in Settings → Integrations
ElevenLabs

api.elevenlabs.io

Turning a recording into a transcript.

The recording itself, and nothing else. The transcript comes back here, and the write-up of it is a separate call to Anthropic that sends only the transcript.

Without it: A recording is stored and plays, with no transcript and no write-up. It never leaves this machine, and nothing else changes.

a key in Settings → Integrations
Google Calendar

accounts.google.com, oauth2.googleapis.com, www.googleapis.com

Pulling your calendar onto the Day timeline.

Requests to read your calendars and the events on them, on the calendar.readonly and calendar.events scopes. Your events come in. This instance writes back one thing only, your own answer to an invitation, and only when you press Cancel & Decline on a meeting. That sets your attendance to declined and changes nothing else. Google emails nobody about it. The write sets sendUpdates to none, so no invitation mail goes out. This instance never edits, moves or deletes anything in your calendar, and sends it none of your writing.

Without it: The Day shows what you wrote and nothing from Google. The connect button says it is not configured.

GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
GOOGLE_REDIRECT_URI
Cloudflare R2

api.cloudflare.com

Offsite storage for recordings and for the nightly backup.

Your recordings and photographs, and a copy of your database. Into a private bucket - the app hands out links that expire rather than making anything public.

Without it: Recordings stay on this machine's disk, and the backup has nowhere offsite to go. The instance runs local-only, which is a supported way to run it and a real risk to accept.

R2_ACCOUNT_ID
R2_API_TOKEN
Resend

api.resend.com

Emailing you when a background job breaks or recovers.

Your alert address, and the name of the job plus its error. The contents of what you write stay here.

Without it: A job can stop and nobody is told. The heartbeats still record it, so the jobs page shows the failure - but only if somebody looks.

a key in Settings → Integrations
LIFEOPS_ALERT_EMAIL
LIFEOPS_ALERT_FROM
GitHub

api.github.com

Reading the development board for the phone's Development page.

A read of the open issues on the repositories named in the environment, with the read token. It sends nothing of yours.

Without it: The phone's Development page says the instance has not been told where its repositories are, and draws no board; the last deploy of each tier still shows, since that comes from the tiers themselves. The web tier's own copy of the page reads GitHub with its own environment and is unaffected.

LIFEOPS_DEV_REPOS
LIFEOPS_DEV_OWNER_LOGIN
LIFEOPS_DEV_GH_TOKEN
Expo push notifications

exp.host

Ringing your phone when a reminder comes due.

The words of the reminder itself, and the push address of the phone it is going to. Expo relays it to Apple using the notification key that already belongs to this app's Apple team. The rest of your account stays on this machine.

Without it: A reminder still fires and still shows in an open browser tab, but nothing reaches a phone in a pocket. This turns itself on when a phone registers and needs no key of its own. Set LIFEOPS_PUSH=0 to keep reminder text on this machine.

LIFEOPS_PUSH