Core ideas
Four words cover the whole product.
- Workspace
- Everything you track, plus your business name and currency. Elsewhere called: org, account
- Module
- One kind of thing you track: Contacts, Deals, Job Sites. Elsewhere called: object, entity
- Field
- One piece of information on a module: Email, Value, Stage. Elsewhere called: property, column
- Record
- One actual entry: a specific customer, a specific deal. Elsewhere called: row, card
The important difference from a traditional CRM: modules are yours to define. There is no fixed schema to work around. If your business runs on Job Sites and Callbacks rather than Leads and Opportunities, build those instead.
Your first five minutes
When you open Nimble Clerk for the first time you'll see the setup screen.
- Enter your business name and currency. Currency controls how every money field is displayed across the app. You can change both later.
- Pick your modules. Contacts, Deals and Tasks are pre-selected because most businesses want them. Tick anything else you need. You can add or remove modules at any time.
- Choose whether to include sample records. Handy for seeing how things look; easy to delete later.
- Click Create my CRM.
Two shortcuts on that screen
- Explore with demo data fills every module with a complete fictional business — 40 contacts, a populated deal pipeline, tasks, leads and notes. The best way to evaluate the app or run a demo without typing anything. It's added alongside whatever you already have, so it's safe to try.
- Start with a custom module instead skips the templates and takes you straight to the module builder.
Working with records
Add
Open a module from the sidebar and click Add. Required fields are marked with a red asterisk; the form won't save until they're filled. The dashboard also has a Quick add panel for the modules you use most.
Edit
Click any row — or any card on a board — to open it. Change what you need and click Save.
Email, phone and website cells are real links. Clicking directly on an email address opens your mail app rather than the record. Click anywhere else on the row to open the record.
Delete
Open the record and click Delete. This can't be undone, and on a team it deletes for everyone, so export a backup first if you're unsure. If someone shouldn't be able to delete, the Contributor role lets them add and edit without it.
Search
The search box filters as you type, matching against every field in the module — not just the visible columns. Clear the box to see everything again.
Table and board views
Every module has a table view: a dense, sortable list.
Sorting
Click any column header to sort by it. Click again to reverse, and a third time to return to the default order (most recently edited first). Sorting is type-aware: money and numbers sort numerically, dates chronologically, and dropdowns sort in pipeline order — so a Stage column sorts Lead → Qualified → Proposal → Won, not alphabetically. Empty values always sort last.
The board
Any module with a dropdown field also gets a board view — click the board icon next to the search box. Each dropdown option becomes a column, and you drag cards between columns to change that field. Dragging a deal from Proposal to Won updates its Stage immediately and permanently.
If your module has a money field, each board column shows its count and total — so a Deals board doubles as a pipeline value report.
Totals under a column
Under the table, every Number, Currency and Calculated column carries a total. It starts as a Sum, and the small menu in each footer cell changes it to Average, Minimum, Maximum, Filled (how many rows have a value in that column) or None. A column with nothing to add up — text, dates, dropdowns — simply has no total.
It totals what you can see: search for something, or narrow the due-date filter, and the totals follow — with a line underneath saying how many rows they cover, so a figure over part of the module cannot be mistaken for the whole of it.
An empty cell is skipped, not counted as zero, exactly as in a
calculated column. Only an Average can be moved by that, so only an average shows the
small ·4/6 telling you how many rows it divided by.
The choice is shared with your team — it is part of the module rather than a setting on your own device, so everybody reads the same number from the same rule. Only an owner can change it; everyone else sees the total with the operation named beside it.
A CSV export carries the rows, not the totals. Spreadsheets have their own
SUM, and a total row sitting inside the data is something you then
have to delete.
Grouping by week or by month
If a module has a date column, a Group by control sits above the table: Week or Month. The rows are gathered into periods, each period gets a heading saying how many rows are in it, and each period gets its own totals using the same choices you made in the footer. The footer underneath still shows the overall total. That turns a log into a report without a separate screen.
It says which column it used — with one date column the control reads Group by Month on Shift date, and with more than one you pick. A report aged on a date you cannot see is indistinguishable from a wrong one.
Newest period first, so the current week or month is at the top rather than at the end of a year of history. A week runs from whichever day your region starts weeks on — Monday in most of the world, Sunday in the US — and the heading names the actual dates, so you can see which you got.
Rows with that date empty get their own group at the bottom, named after the column. They are not dropped and not folded into a period, so the group totals always add up to the footer.
Grouping is yours, not the team's: it is how you are looking at the table right now, like the search box, so it is not shared with colleagues and it resets when you reload. The totals choice in the footer is the opposite — that one is shared, because it decides what a column means.
Building and changing modules
Click + next to MODULES in the sidebar, or Add module on the dashboard. Either one offers the prebuilt modules first, with Empty module at the top if you would rather start from nothing.
The prebuilt ones are always available, not only on your first day. If you skipped Renewals or Consent when you set the workspace up, add it whenever you want it — the picker marks the ones you already have, so it also answers “which of these did I take?”. A module added from a template is an ordinary module: you can rename it, change its fields and delete it exactly like one you built.
- Name it. Use the plural — "Projects", "Invoices", "Job Sites". Buttons elsewhere in the app automatically use the singular form.
- Pick an icon and colour. These appear in the sidebar and dashboard and make modules easy to tell apart at a glance.
- Define fields. For each one set a label and a type, then two checkboxes:
Reqmeans the record can't be saved without it, andListmeans the field appears as a column in table view. Up to six columns show; the rest are still on the record form. - Reorder or remove. Move fields with the ↑ button, remove them with ✕.
To change a module later, open it and click the pencil icon.
Renaming a field keeps its data. The label is what you see; the underlying key stays put, so renaming "Phone" to "Mobile" doesn't empty the column. Deleting a field, however, removes that field's values from every record in the module.
Recording why you hold someone's details
If you're in the UK or the EU, data protection law asks you to be able to say why you're allowed to hold each person's details, and to show it if asked. That's your call to make, not ours — but there's a starting point built in.
Pick Consent & lawful basis on the onboarding screen, or add it later from Add module → from a template. One row per person or company: who they are, why you hold them, what you use it for, where they came from, and — if the answer is consent — when they gave it and when they took it back.
The Lawful basis dropdown uses the six official names, so you can match a row against the ICO's own guidance. In plain terms:
| Basis | You'd pick this when |
|---|---|
| Consent | They actively agreed — ticked a box, signed up. They can withdraw it, and you must let them. |
| Contract | You need their details to do the thing they asked for: deliver an order, send an invoice, quote a job. |
| Legal obligation | The law makes you keep it — tax records, for example. |
| Legitimate interests | You have a genuine business reason and you've considered whether they'd object. This one asks the most of you; the ICO expects you to have weighed it. |
| Vital interests | Someone's life is at stake. Rare outside healthcare. |
| Public task | You're carrying out an official function. Rare outside the public sector. |
Most small businesses use the first three, and Contract covers more than people expect — you don't need consent to invoice a customer.
This is a place to write things down, not advice about what to write: if you're unsure which basis applies, the ICO's website is free and plain-spoken. And nothing links these rows to your Contacts automatically — you name the person in text, the same way Deals names a contact.
Tracking things that expire
Insurance certificates, trade licences, safety checks, vehicle inspections, background checks — the paperwork that is fine until the day it is not, and that nobody thinks about until a client asks for it.
Pick Renewals on the onboarding screen, or add it later from Add module → from a template. One row per certificate: who or what it covers, what kind it is, the policy number, who issued it, where the renewal has got to, and the date it expires.
The point of it is the date. Once the rows are in, two things you already have start working on them. The Due date filter on the module shows what lapses in the next 7, 14, 30 or 90 days — and everything already expired, however long ago. The daily digest counts the same rows into your team channel each morning; set Look ahead to 30 days and you are told a month before, which is usually enough time to actually renew something.
Keep Expires the only date column. The digest watches one date field per module — the first one shown in the table. Add a second date column, an Issued on say, and it may start counting that one instead, or stop mentioning the module altogether. Keep other dates out of the table view.
Two smaller things. The digest says overdue rather than expired — it is the same wording for every module and it means the same thing here. And the look-ahead is one setting for the whole workspace: if your deals want 7 days and your certificates want 30, pick the longer one, since the filter on each module is still per-module.
Field types
| Type | Use it for | Notes |
|---|---|---|
| Text | Names, references, short notes | — |
| Long text | Descriptions, meeting notes | Truncated in the table, full on the record |
| Number | Quantities, counts | Right-aligned, sorts numerically |
| Currency | Deal values, quotes, invoices | Formatted in your workspace currency; totalled on boards and the dashboard |
| Date | Due dates, close dates | Date picker; sorts chronologically |
| Dropdown | Stage, Status, Priority, Source | Enables board view. Options are comma-separated; their order is the board's column order |
| Checkbox | Done, Paid, Active | — |
| Email addresses | Becomes a clickable mail link | |
| Phone | Phone numbers | Becomes a clickable dial link |
| Link | Websites, shared documents | Opens in a new tab |
| Link to module | A Project's Client, a Deal's Company | Shows a picker listing records from the module you choose |
| Calculated | A total, an average or a difference across other columns in the same record | Read-only. Pick an operation and tick the Number or Currency fields it should use |
Columns that work something out for you
A Calculated field adds up, averages or compares other columns in the same record. Pick the operation, tick the fields it should use, and the column fills itself in — on the table, on the record, and in a CSV export.
It is read-only everywhere: there is nothing to type into, and it is not offered as a destination when you import a CSV. The figure is worked out fresh every time it is shown, so it can never be out of date with the columns it is made from.
An empty cell is skipped, not counted as zero. An average over three
columns where one was never filled in divides by two, not three — and the column says
so, with a small ·2/3 beside the figure.
The operations are Sum, Average, Minimum, Maximum, Count filled, Difference (a − b) and Ratio (a ÷ b). The last two take exactly two columns and the order matters; both need their columns filled in, so a missing second figure gives a dash rather than a number.
A calculation can only read Number and Currency
columns. If a column holds 2 hours rather than 2, change
its type to Number and move the unit into the heading — Down time (hours).
Text cannot be added up, and a column of text also sorts alphabetically, so
10 hours lands between 1 hour and 2 hours.
There is no formula box, so (a − b) ÷ c is not possible, and one
calculated column cannot use another. If you remove a column a calculation depends
on, the save is refused and the message names both — edit the calculation first.
The dropdown option order is your pipeline. Put them in the order work actually flows — Lead, Qualified, Proposal, Negotiation, Won, Lost — and both the board and the sorting will match how you think.
Importing from a spreadsheet
This is usually how a real business gets started: you already have a customer list in Excel, Numbers or Google Sheets.
- In your spreadsheet, make sure the first row contains column headings, then export or save as CSV.
- In Nimble Clerk, open the module you want to import into and click the upload icon in the header.
- Check the mapping screen: every column in your file, a sample value from it, and where it should go. Columns whose names resemble your fields are matched automatically.
- For each remaining column choose an existing field, skip this column, or create a new field for it.
- Choose whether to add the rows to what's there (the default) or replace everything in the module.
- Click Import.
What the importer handles for you
- Quoted fields containing commas, quotes and line breaks
- Files exported from Excel with a byte-order mark, and Windows line endings
- Money written as
$1,234.00or€1 234→ stored as a number - Negative amounts written as
(500)→ stored as-500 yes/y/true/1/x→ ticked checkboxes- Most written date formats → a proper date
- Dropdown values matched to your existing options regardless of capitalisation
- Completely blank rows are skipped rather than imported as empty records
You say which way round they are. 03/04/2026 is 3 April in the UK and 4 March in the US, and nothing in the file says which — so when your import contains dates like that, the mapping screen asks. If the file settles the question, the answer is already chosen and the screen says why: a 31/12/2026 anywhere in the file can only be day-first. If the file could genuinely be either, nothing is chosen and the import waits for you — one click beats half your dates quietly landing in the wrong month.
You see what your answer does before anything is imported ("03/04/2026 will be imported as 3 April 2026"), and it warns you when some values can't be read the way you picked — 13/04/2026 isn't a month-first date, so it would arrive empty.
Dates already written as 2026-04-03, or spelled out as 12 September 2026, say which number is the month by themselves. Those ask you nothing.
Run it on a copy of your data first, or export a backup from Settings → Export data, so you can undo it in one step. There is no per-import undo.
Exporting your data
One module, as CSV
Open the module and click the download icon. The export contains exactly what you're looking at: if a search filter or a sort is active, the file matches it. Every field is exported, including ones not shown as columns.
Everything, as JSON
Settings → Export data (JSON) gives you the complete workspace: all modules, all records, and your settings. It's the format the importer on the same page expects, and it's how you move a workspace between devices without an account.
Your data is yours. There is no lock-in and no export limit.
When someone asks what you hold about them
Settings → Data requests. Type their name — or part of it, or their email address — and press Search. It looks in every text field of every record, and reports three things worth knowing:
- Where they appear, module by module, so you can go and look.
- Names that only appear as a link. If a Deal points at a contact, that person is found even though their name is nowhere in the Deal's own fields.
- Values under fields you removed. Deleting a column offers to delete what was in it; if you chose Keep the data, those values are still in the workspace and still in every backup. They show here marked removed field.
Read the results before you send anything. A search matches text, so it can catch a different person with a similar name — and a record that mentions two people holds data about both. The screen shows what it found first; the download button is underneath.
The file is JSON, and it carries the limits of the search inside it, because whoever reads it next probably did not run it. The search does not find a different spelling or a nickname, a number stored in a Number or Currency field, anything on a colleague's device that has not synced, or deleted records — a deletion discards the contents, so there is nothing left to find.
Finding data you have stopped using
Settings → Data you have stopped using. Pick a window — 12 months, 2 years, 3 years or 5 years — and press Review. It lists records nobody has changed in that time, oldest first, with a count per module and a file you can download. Holding personal data for longer than you need it is the rule most small businesses drift past without noticing, and this is the review that answers it.
It is a list, not a bin. There is no delete button here, deliberately. Old is not the same as unwanted — a closed matter you must keep for six years looks exactly like an abandoned one, and nothing in the app can tell them apart. Deleting cannot be undone, and on a team it deletes for everybody.
Two things about the dates. Unchanged means the last edit recorded on this workspace — importing or restoring a record resets it, so a bulk import last month makes everything in it look new. And records that have never reached this device, from a colleague who is offline, are not counted.
The other question: who nobody has contacted
The same card asks a second thing, and it is not the same question. Switch the first dropdown from Records nobody has changed to People nobody has contacted. The difference is which date it reads:
| Mode | Reads | Answers |
|---|---|---|
| Records nobody has changed | when the record was last edited | how long have we been holding this? |
| People nobody has contacted | a date field you pick | who have we stopped talking to? |
That distinction matters more than it looks. A customer whose address you corrected last month counts as changed — and you still have not spoken to them in two years. Asked the other way round, a customer you phoned last week but never logged looks dormant. So the second question needs a date meaning we made contact, and only you know which field that is.
Pick the field, and the screen says which one it used. If the module has a date field named something like Last contacted it starts there; otherwise it opens on the module's first date field and you change it. The result always says Aged on <field> above the list, so you can see whether the answer means what you think. Two more controls appear as they become useful: which module (you want dormant customers, not dormant invoices), and narrowing to a dropdown value — so Contacts, tagged Retail, nobody has contacted in 2 years is one question.
Download it as CSV, not just JSON: this is the one report whose output goes into a mail tool. Both files carry the same caveat, because whoever opens the file did not run the report — "last contacted" is only as good as your habit of updating it, and somebody you phoned but did not log looks dormant.
If the module has no date field at all, the card says so and falls back to the last-changed date — which is the other question again. Add a date field called Last contacted and fill it in when you speak to somebody. Records with that field empty are counted separately and are not in the list: they are not dormant customers, they are customers nobody has logged at all.
Closing your account
Settings → Danger zone → Delete my account. Anyone can close their own account, whatever their role. You are told what it costs before anything happens, and the numbers come from the server rather than from this device: on your own, your workspace goes with the account and the confirmation says how many records and modules that is; on a team, the team keeps its workspace and you lose your access to it.
Two cases are refused, and you are told in advance rather than at the last step: you cannot close your account while you are the only owner of a team that still has other people in it — make someone else an owner first — or the only administrator of the whole deployment.
It cannot be undone, and it clears the workspace off this device too. Export a backup first if you might want your records.
Workspace settings
Open Settings from the bottom of the sidebar.
- Business name — shown at the top of the sidebar and on the dashboard.
- Currency — 30 currencies. Changing it reformats every money field everywhere, immediately.
- Time zone — which calendar day a date belongs to when the server works it out on your behalf. Your own screens already use this device's clock. Leave it unset and dates are treated as UTC.
Currency changes display, not the stored numbers — switching from USD to EUR relabels amounts, it does not convert them.
Click Save workspace to apply. All three are set by the team's owner; everyone else sees them as values rather than as a form.
Notifications (owners only)
An owner can point the workspace at a team chat channel from Settings, and send a test message to check it works. What it sends on its own is the daily digest, below.
Slack and Discord each give you a webhook URL to paste in. Telegram does not — it gives you a bot token instead, and the chat has to be looked up. Open Using Telegram? Set it up here under Notifications and:
- Message @BotFather, send
/newbot, and copy the token. - Decide where the messages should arrive — this step is what chooses. Privately, to you: open your new bot and press Start. To a team group: add the bot to that group. A bot cannot open a conversation, so one of these has to happen before it can see you at all.
- Paste the token, press Find my chat, and pick the chat from the list — each one says whether it is a private chat or a group.
If the list comes back empty, Telegram has simply forgotten — it only keeps the last day of activity. Message the bot again and press the button again.
The webhook URL works like a password, so it is never shown to you again after you save it, and it is never included in a backup. If your workspace is restored from one, an owner has to paste it again — the Notifications screen says so rather than looking as though nothing was ever set up, and notifications stay off until it is re-entered.
Chasing something that is overdue
Open an overdue record and there is a Chase by email button beside Save. It does not send anything — it writes the draft and hands it to your own email app, from your own address, with your own signature on it. That is what makes a payment reminder work: one from a stranger's system gets ignored.
It appears only when the record is past the date the module watches (the same date the filter uses) and an email address can be found. It looks on the record first, then follows a link — an invoice usually does not carry an address, but the customer it is linked to does. The preview says which it used, so you can check it rather than trust it. The draft names the record, the amount if the module has a currency field, the due date and how many days ago that was, and it ends with "If you have already paid, please disregard this message."
Read the preview before you send. The message is built from the record as it stands right now, so if the amount is out of date the reminder is wrong — and a demand sent to somebody who has already paid is worse than not sending one. Nothing here checks that for you.
Some email apps refuse a very long draft, so if yours is over the limit the end is cut and the screen says by how many characters before you press anything. Every role can do this, including view-only: it opens your own email app with an address you can already read off the record.
Sending it from the app instead
An owner can connect the workspace’s own email account — Settings → Sending reminders by email — by pasting a Resend or Postmark API key and the address reminders should come from. A Send it now button then appears in the preview beside Open in my email app, and one press sends it.
Setting it up, start to finish. You need an account with one of the two services; both have a free tier that is ample for chasing invoices.
- Sign up at resend.com or postmarkapp.com. Either is fine — pick on price and on which you find easier to read.
- Add and verify your sending domain with them. This is the step that takes real effort: they give you DNS records to add wherever your domain is managed, and it can take anything from minutes to a few hours to go through. Do this before anything else — it is the single most common reason a first send fails, and the failure arrives as a refusal from your provider rather than as anything wrong with the key.
- Create an API key in their dashboard, with permission to send. Copy it the moment it is shown; neither service will show it to you twice.
- Open Settings → Sending reminders by email. Paste the key, and type the address reminders should come from — it has to be at the domain you verified in step 2. Save.
- Send one to yourself. Open an overdue record, press Chase by email, and use Send it now. That first send is what proves the whole chain, and it is much better to discover a DNS record is still propagating on a reminder addressed to you than on one addressed to a customer.
If a send is refused, the message on screen is your provider’s own wording rather than ours — that is deliberate, because they are the only one that knows whether the problem is the key, the domain, or the recipient.
- It is your account with them, not ours. Your sending domain, your deliverability, your bill. We hold the key so the reminder can be sent and nothing else: it is never shown back to anybody, never sent to a browser, and never included in a backup.
- You do not pick the provider. We work out which service the key belongs to from the key itself.
- The address must be one your provider has verified, or it will refuse to send from it. We cannot check that when you save the key — proving an email key works means sending an email — so the card says the key has not been checked until your first real send, and that send reports any problem with it in your provider’s own words.
- Owners and members can send; contributors and viewers cannot. Sending is a rung above editing a record, because it leaves the building with your business’s name on it and cannot be recalled.
- Nothing sends on its own. There is no automatic escalation and no schedule — a person presses the button every time.
A restore cannot bring the key back. It works like a password, so it is never in a backup. After one, the card says the key needs re-entering rather than looking like a workspace that never had one — but until somebody does, reminders open as a draft instead of sending.
Disconnecting puts everything back to the draft, which never stopped working.
Knowing whether somebody has already chased it
Every reminder is recorded on the record. Once there is one, the button reads Chase again and the preview opens with a line naming the last one — who, when, and whether it was sent or only drafted.
Those two words mean different things and the app will not blur them. Sent means your provider accepted it. Drafted means somebody opened it in their own email app, which is not proof they pressed send — nothing outside their mail client can know that.
- It syncs like the rest of the record, so a colleague's chase reaches your device the way their edits do.
- Two people chasing the same record both leave a trace, even if one of them was offline. Neither entry overwrites the other.
- The last 20 are kept, oldest dropped; all of them are in the record's JSON export.
- Chasing counts as touching the record, so one you chased last week stops appearing in Data you have stopped using. That is deliberate — you have not stopped using it.
- A view-only account can draft a reminder and nothing is recorded, because a viewer cannot change a record. Their draft still opens normally.
The daily digest
With a webhook set, an owner can turn on a once-a-day message: a count of what is due or already overdue, per module — the same rows the Due date filter shows. Set how far to look ahead, the earliest hour it may go out (read in the workspace’s time zone), and whether to send it at all. It is off until you turn it on, and the settings screen shows you the exact message your team would get before you do.
- Counts, not names. “Invoices: 2 overdue, 3 due within 7 days” — never which ones. A chat channel often has more people in it than your CRM does.
- A quiet day sends nothing, so there is no daily “all clear” to learn to ignore.
- Once a day. Something that becomes due this afternoon is in tomorrow’s message.
Anything already overdue is always counted, however old it is. The look-ahead window only bounds the future side.
Accounts, sync and multiple devices
Nimble Clerk works fully without an account — everything is stored on the device you're using. Signing in adds sync.
To sign in, click Sign in to sync at the bottom of the sidebar and continue with Google. From then on:
- Work already done on this device is uploaded to your account.
- On a device with no data yet, your workspace is downloaded.
- Every change syncs automatically a moment after you make it.
What the chip above Settings is telling you
Signing out leaves your data on the device. It stops syncing; it doesn't erase anything.
Sync works one record at a time, and one field at a time within a record. Edit a contact on your laptop and a different contact on your phone and both survive. Change a contact's phone while a colleague changes their email and both survive too. Only when the same field is edited in two places does anything have to be chosen, and there the most recent edit wins.
Deleting a record deletes it everywhere, including on a device that was offline when you deleted it: the delete is remembered and travels like any other change, rather than the record quietly reappearing on the next sync.
Sync also sends only what changed, so an edit costs the same whether your workspace has fifty records or fifty thousand.
Anything you do before signing in stays on the device until you say otherwise. The first time you sign in, Nimble Clerk asks once what to do with it — bring it into your account, or leave it where it is. Nothing you typed is ever discarded without being asked.
Working as a team
An organisation is your team, and everyone on it shares one workspace: the same modules, the same records, kept in step by the same per-record sync that keeps your own laptop and phone together.
To invite someone (owners only): Settings → Invite a colleague. You get a private link — copy it and send it however you normally reach them. The link works once and stops working after a week, so it is safe to send in a message but not to post somewhere public.
When they open the link, they sign in and are asked one question: start on the team's workspace, or bring their own records with them. Anything they bring becomes visible to everyone on the team, and the prompt says so. Nothing they decline to bring is deleted — it stays in their own workspace.
Who can change what
Four roles, each doing everything the one below it does plus one more thing:
| Role | Can |
|---|---|
| Owner | Everything: module fields, adding and deleting modules, invites, and managing the team |
| Member | Create, edit and delete records |
| Contributor | Create and edit records, but not delete them |
| Viewer | Read only — and export |
A field rename changes what every record in the team means, so the schema belongs with whoever is accountable for the workspace. Anyone below owner opening the module builder sees the fields but cannot change them. The workspace’s name and currency are owner-only for the same reason: changing the currency relabels every amount in the team’s records rather than converting them.
What view-only looks like. It is a complete app for reading, not a restricted one for writing. A viewer sees every module and record, can search and sort, switch between table and board, open any record, and export to CSV or JSON — which is the whole job if they are an auditor or an investor doing due diligence. Records open as values rather than as a form, so there is no Save button to look for and nothing to type into by mistake. A quiet View only badge sits beside their name in the sidebar, and Settings says so once in plain words. Buttons that would create or delete something are simply not shown.
If someone's role changes while they are offline, work they did in the meantime that they are no longer allowed to do is undone when they reconnect, and the app says which rule stopped it rather than leaving them to guess.
Managing the team (Settings → Team, owners only): set anyone's role from the picker beside their name, remove them, and revoke an invite link that has not been used yet.
Removing someone keeps their sign-in and gives them a fresh, empty workspace of their own; the team's records stay with the team. The next time their device reaches the internet it drops its copy of the team's data by itself — though a device that never comes online again keeps whatever it already had, which is true of anything that works offline.
Leaving a team is on the same screen and needs nobody's permission. You get a fresh, empty workspace; the team keeps its records. The one exception: if you are the only owner and other people are on the team, make someone else an owner first — otherwise they would be left with a workspace nobody can administer.
Working offline and installing the app
Nimble Clerk is a Progressive Web App, so you can install it like a native one:
| Platform | How |
|---|---|
| Desktop (Chrome/Edge) | The install icon in the address bar, or Settings → Install on this device |
| iPhone / iPad (Safari) | Share → Add to Home Screen |
| Android (Chrome) | Menu → Install app |
Offline, everything still works. You can browse, search, add, edit and delete records with no connection. The sidebar shows Offline — changes saved locally, and anything you changed syncs automatically when you're back online. This is deliberate: the app never makes you wait for a server to reach your own data.
Light, dark, or whatever your device does
Settings → Appearance offers three choices:
- System — follow whatever your phone or computer is set to. This is the default, and it is what the app has always done.
- Light — always light, even on a device set to dark.
- Dark — always dark, even on a device set to light.
It applies to this device only. It is not part of your workspace, so it does not travel to your other devices and it is not shared with your team — a colleague on a dark screen and one on a light screen each keep their own. Anyone can change it, whatever their role, because it changes nothing about the data. The policy and terms pages follow it too, so the whole site is consistent rather than the app being dark and the policy page light.
Backups
Your records live in the browser's local database, and in your account if you've signed in. Two habits worth having:
- Export a JSON backup periodically — especially before a big import or before deleting anything substantial.
- Sign in, so a copy lives in your account rather than only on one device.
Clearing your browser's site data will erase a signed-out workspace. If that happens after you've signed in, just sign in again and your workspace comes back.
To restore: Settings → Import backup, choose the JSON file, and pick what should happen to what is already there:
- Merge (the default) adds everything in the file and leaves the rest of the workspace alone. This is almost always what you want — recovering one deleted module shouldn't touch anything added since.
- Replace additionally deletes anything the file doesn't contain. It tells you how many records that is before you confirm.
Replace's deletions reach everyone, because they sync like any other change. Merge is the default for exactly that reason.
For administrators
If your account has the administrator role, an Admin entry appears in the sidebar. Some of what follows is only visible to a platform administrator — the person who runs the deployment, as opposed to the owner of one team.
Metrics
Total accounts, accounts active in the last 7 days, workspaces containing data, and totals for records and modules built. Two charts show signups over the last 30 days and daily active users over the last 14. Hover any bar for the exact figure.
Deployment (platform administrators)
Three meters showing what the whole deployment is consuming against its free-tier ceilings:
- Database — what MongoDB actually reports as stored, including indexes and tombstones rather than an estimate from the record count.
- Memory — the container's resident memory, plus the peak seen since the last restart. Sampled when the page loads, so it catches a slow leak rather than a sudden spike.
- Bandwidth — response bodies sent this month. Headers aren't counted, so the real figure is a little higher.
Below the meters, New organisations: Allowed / Capped. Capping stops new tenants without freezing your existing customers: a colleague invited to a team that already exists still signs up and joins. That is why it is a separate switch from pausing signups.
Organisations (platform administrators)
Every team, heaviest first, with its people, records, stored bytes, share of the database, and last activity. Each row has one action: pause or resume writes.
A paused workspace can still be read and its data is untouched — it just can't sync changes up until you resume it. Nothing about it is irreversible.
Requests to join
People who signed in without an invite and asked. Approving lets them straight in: they sign in again with the same Google account and it works. Nothing is emailed.
Beta access
Whether signups are Invite only, Open or Paused, plus the beta codes and their remaining uses. The mode takes effect immediately with no redeploy, and outlives restarts. Send a test alert fires a webhook message and reports what every alert rule currently sees, so silence can be told apart from a broken webhook URL.
Problem reports
What testers sent from Settings → Report a problem, each with the app version, screen, browser, sync status, counts and recent console errors.
Accounts
Every account with its role, status, usage, join date and last activity. Search by name or email. For each account you can:
- Change the role — owner, member, contributor or viewer within a team; only a platform administrator can grant that role.
- Disable — the person is signed out immediately and can't sync until re-enabled. Their data is kept.
- Delete — removes the account and its synced data. This cannot be undone.
You can't disable, demote or delete your own account, so an instance can never be left without an administrator by accident. An org owner can't act on a platform administrator at all.
If a deployment names nobody in its ADMIN_EMAILS setting, the first person to sign in becomes the platform administrator — that's the bootstrap that stops a fresh deployment from being unusable. Once ADMIN_EMAILS names someone, that list decides, and the first visitor is an ordinary user like anyone else.
Troubleshooting
The app is slow to load the very first time
On free hosting the server sleeps when idle and takes 30–60 seconds to wake. The app itself loads instantly from your device and shows Connecting… while it waits — your data is usable the whole time. Before a demo or a meeting, open the URL a minute early to wake it up.
I signed in but my records are missing
Check the sidebar chip. If it says Offline or Connecting…, sync hasn't finished. If it says Synced and data is still missing, you may have signed in with a different email than before — each account has its own workspace.
My changes aren't syncing
The chip will show Sync error — retrying or Offline. Changes are safe on the device and upload automatically when the connection returns. Settings → Sync now forces an attempt.
The board view isn't available
Board view needs a dropdown field. Edit the module and add one — for example Stage or Status — with its options in pipeline order.
Import produced empty or wrong values
Almost always a mapping issue: re-run the import and check the Import as column on the mapping screen. If dates or amounts look wrong, confirm the spreadsheet column holds one consistent format.
I need to undo an import, or I deleted a module by mistake
Import your most recent JSON backup via Settings → Import backup. Deleting a module deletes its records too and can't be undone from inside the app — which is why exporting before a large change is worth the ten seconds.