Control the system. Keep the trail.
Countmill scopes every record to a business, locks a period once it's closed, and puts a reference on every failure. This is how the access model, the ledger and the error surface actually behave — no certifications claimed, just what the product does.

What actually enforces control.
Six mechanisms, all live in the product today.
RBAC per app scope
Roles grant access app by app — a role that can see Books doesn’t automatically see People. Scopes are checked on every route.
Record ownership & sharing
Every record has one owner. Sharing widens who can read or act on it — the owner never changes, and there is never a second copy.
Per-business isolation
Every record is scoped to a business. Nothing crosses into another business by accident, whether you’re in a single entity or the consolidated view.
Reconciliation locks & period close
Once a bank period is reconciled or the books are closed, those entries lock. Reopening is an explicit, logged action, not an accidental edit.
Audit trail on every posting
Every ledger posting carries who, when and what changed. The audit trail is a first-class record, not a debug log.
Soft delete + Trash with restore
Deleting a record moves it to Trash, recoverable until it’s purged. Nothing disappears from a single click.
Every failure is findable.
A system that can't explain its own failure is unfinished, however well it works the rest of the time.
A quotable request id is stamped once per request and shown on the error the user sees.
"Not found" and "not permitted" are logged and surfaced as two different things, never one blank page.
Logs are redacted at every depth before they leave the system, so more logging never means more exposure.
Something went wrong loading this record
The team can look this up immediately from the reference below.
Your data is yours.
Export everything, or read it back through the API — both scoped to your business, never a wider slice.

Export everything
CSV export is available from every module — deals, invoices, tickets, inventory, ledger entries — no module withholds its own data.
Brand-scoped API v1
Every API v1 credential is issued against one business. A call against it returns that business's records — never the group's.
Parent org → business → record
One login sits over a parent org; each business under it owns its own records; every record has one owner and an explicit share list.
Controls, not promises.
What a typical SaaS ships versus what Countmill actually enforces today.
- Per-seat pricing that punishes access
- One role for everyone
- Deleted means gone
- An error page with no reference
- Exports on request
- Unlimited seats, RBAC per app and per business
- Record ownership and sharing
- Soft delete with Trash and restore
- A quotable reference id on every error
- CSV and brand-scoped API v1, always
Common questions.
How is access controlled?
RBAC is scoped per app — CRM, Support, Commerce, Books, People and Analytics are each their own permission surface, checked on every route a user can reach.
Can one business see another business’s records?
No. Every record — deals, invoices, tickets, inventory — is scoped to one business. The consolidated "All businesses" view rolls figures up without exposing another business’s underlying records to someone who isn’t permitted to see them.
What happens when something fails?
Every error carries a request reference the user can read back and support can look up immediately, and the system distinguishes a record that’s genuinely not found from one that exists but is out of scope for that user.
Can we get our data out?
Yes. Export as CSV from any module, or pull it programmatically through the brand-scoped API v1 — every response is scoped to the business the calling credential belongs to.
Walk through the access model with us.
Bring your role structure and your business list — we'll show you exactly how it scopes.

