The workspace and its settings
A workspace is the whole of what you and your colleagues share: its collections, its pages, its databases, its fields, its members. Nothing crosses that boundary. Two workspaces on one account do not know about each other, a search in one never returns a page from the other, and being a member of one says nothing about the other.
One account can be in many of them, and the same person in two workspaces is two memberships — with two roles, two sets of shares and, if both are paid for, two subscriptions.
Several accounts on one browser
You can be signed in to more than one account at once and change between them without typing a password again. The name at the foot of the sidebar opens the list; pick another and the app reloads as that account.
- Adding one is the ordinary sign-in. Add account takes you to the usual form, and signing in there keeps the account you were already using rather than replacing it.
- Forgetting one is in Settings → Account, next to the account it belongs to. It signs that account out and leaves the one you are using alone.
- "Sign out" means all of them. The single button at the foot of the sidebar signs out of every account remembered on this browser, not only the active one.
- The list belongs to this address. Accounts you add here are Basalt's own. An app on another address keeps its own list, because a browser holds the accounts of one address apart from another's.
The workspace is in the address
Every page you open carries its workspace in the URL:
https://app.basaltapp.io/w/<workspace id>/p/quarterly-planning-<page id>
So a link you paste into a chat message always opens in the right workspace,
whatever the person receiving it had open a moment ago. The words in front of
the page id are decoration: only the trailing id identifies anything, so a
renamed page keeps every link that was ever made to it, and the address quietly
corrects itself once the new title has loaded. A database view sits under the
same workspace segment at /v/<view id> — that one carries no slug, only the
id.
Switching workspaces is the control at the top of the sidebar — the name and icon of the one you are in, and under it every workspace you are in, with a tick on the one you are looking at. New workspace… sits below the list. Creating one makes you its owner and gives it a single open collection to start writing in.
Settings is the one address that does not name a workspace.
/settings/members opens Members in whichever workspace you currently have
open, so a settings link is a link to a screen, not to a screen of a
particular workspace. Send somebody /settings/invitations and they land on
their own invitations. That address only exists when you arrive by it: follow a
/settings/<section> link and a reload comes back to the section and the back
button walks the sections you visited. The gear and the switcher menu open
settings as a window over what you already had open and leave the address
alone.
Each app is turned on per workspace
Your membership is shared across the apps on your account; the plan is not. A workspace is activated for one app at a time, and Basalt lists only the workspaces it has been turned on for. This is why a workspace you use elsewhere is missing from the switcher: not a permission problem, and nothing to do with your role.
Three things follow, and the app says each of them out loud rather than leaving you to work it out:
- The address still works. Open
/w/<id>for a workspace of yours that Basalt is off for, and the screen says Basalt is not turned on for “{name}” with a button, Turn on Basalt for this workspace. It asks the server before it says anything, because "this is not yours" and "this is yours and one button away" are opposite sentences and guessing shows half the readers the wrong one. - An account with nothing activated is not invited to start over. Where the whole list is empty, the screen says Basalt is not turned on for any of your workspaces and offers a button per workspace — rather than "create your workspace" to somebody who already has one.
- An address that is not yours at all reads This workspace does not exist, or you cannot open it. One sentence for both cases, deliberately: the server does not tell a stranger which of the two it is.
Nothing about the inside of a workspace travels across an app boundary. What that screen knows is the name, the icon and your role, and that is all it is given.
Turning an app on is administration — an admin or the owner. It is also, once billing is live, the act that starts a subscription, which is why it is not a member's button.
Two settings surfaces, not one list
The gear in the sidebar footer is settings for you. The workspace's own settings are reached from the workspace, through Workspace settings… in the switcher menu — the same way a collection's settings are reached from the collection's own row.
They are two surfaces rather than two headings in one window because they answer two different questions, and because a global control that hands out administration of an object is the wrong shape for a control that lives next to your name.
Thirteen sections in all: one is yours, twelve are the workspace's.
| Section | Surface | Who may change it | What is on it |
|---|---|---|---|
| Preferences | Yours | You | Profile picture, theme, language, code wrapping, tab icon, version |
| General | Workspace | Admin | Name, icon, export — and, for the owner alone, deletion |
| Plan and usage | Workspace | Nobody — it is a report | Plan, storage, members, guests, file cap, history window |
| Billing | Workspace | Admin | Subscription, billing details, invoices |
| Members | Workspace | Admin | The roster and its roles |
| Groups | Workspace | Admin | Named sets of people |
| Invitations | Workspace | Admin | Open invitation links |
| Collections | Workspace | Admin to create; full access on a collection to change it | Visibility and who is named on it |
| Fields | Workspace | Admin | The workspace field registry |
| Symbols | Workspace | Member | The shared icon library |
| Import | Workspace | Anyone, within what they may write | Import jobs and their reports |
| Access tokens | Workspace | Each person, their own | API credentials |
| Webhooks | Workspace | Member | Outbound endpoints |
A section your role may not administer is shown, not hidden. You open it and read Not available for your role with a sentence naming why. A tab that vanishes for some people makes the product look broken to them; a tab that says why it is closed teaches the model.
Note what is not gated, and it is deliberate in every case: Plan and usage is
open to everyone, because it is where somebody whose upload was just refused
finds the reason — including a guest, who can hold edit on a page and can
therefore hit the storage cap. Access tokens, Import and Symbols are open
for the same reason: the server decides what an individual may actually do
there, and hiding the screen would withhold what they are allowed to do because
of something they are not.
Preferences — the half that is yours
Everything on this screen except the picture is stored on this device, so it takes effect immediately and does not follow you to another browser:
- Theme — Light, Dark or System. System keeps following the operating system rather than taking a snapshot of it.
- Language — English, Deutsch or System. The options are written in their own language, so a screen you set to a language you cannot read still has a way back.
- Long code lines — whether they wrap. This is the lasting setting and it
covers every code block; the
⋯on a single block changes that one block for this session only. - Tab icon — whether the browser tab shows the open page's icon or Basalt's. The tab's title is not a choice and always follows the page: six tabs all reading "Basalt" tell you nothing.
- The version, last on the screen, because it is read once and it is not a setting.
The profile picture is the exception: it is an account fact, one picture across every workspace you are in, and the hint under it says who sees it — the people who share a workspace with you, and nobody else.
The workspace itself
General holds the name and the icon, both of which every member sees in the switcher, and both of which need an admin. The icon saves the moment you pick it; the name saves on submit.
Deleting the workspace is the owner's button and nobody else's. It takes every page, database, collection, invitation, membership and uploaded file with it. There is no trash for this, so it is behind a dialog that makes you type the workspace's name.
Export
Download export sits under the workspace's name on General, and it is offered to everyone — there is nothing here for a capability to protect, because the archive contains exactly what the person asking can already read.
You get a .zip named after the workspace, holding one Markdown file per page,
the files those pages use — every attachment, not only the images — and a JSON
file describing the collections and databases. Pages you cannot access are not
in it, and the screen says so before you download, so a thin archive is a fact
about your access rather than a sign that something was lost.
The archive is the workspace's, not this app's. Documents that belong to another of our apps come out too, each kind in a folder of its own, because an export is the account asking for its own data and half of it would be the wrong answer.
Export is never refused because of a quota. A workspace over its storage limit can still leave, attachments included. That is not politeness; a plan that made your own notes unreachable until you paid would have taken them from you.
Members
Members is the roster: who is in the workspace, what role they hold, and when they joined. Email addresses are shown to admins and owners only.
| Role | What it grants |
|---|---|
| Owner | Everything an admin can, plus deleting the workspace and handing ownership on. |
| Admin | Manages members, groups, invitations, fields and collections — and is the role that may delete content for good. |
| Member | Reads and edits according to collection visibility and the shares they have been given. |
| Guest | Sees only what has been shared with them explicitly. |
A role is not access to content. What each of these can actually open is decided by collection visibility and by the grants on a page, which are on their own page.
Four rules the screen enforces, each with a sentence rather than a grey button:
- Only an owner may grant or withdraw ownership. For everybody else the Owner option is simply not in the list, and a row that already is an owner is read-only.
- Nobody may raise their own role. Lowering it is allowed.
- A workspace always keeps at least one owner. The last owner can be neither demoted nor removed, and the row says so where the menu would otherwise be.
- A change that would strand a page is refused. If demoting or removing somebody would leave a restricted page with nobody holding full access, the answer names that and tells you to grant somebody else full access there first.
Handing over ownership is two steps, not a button. Make the other person an owner, then lower your own role. There is no single Transfer ownership action, and the two-step route is the whole of what exists.
Removing somebody withdraws their access immediately, along with every group membership and every share granted to them personally. Their pages stay — authorship is not access. Removing yourself is worded as what it is: Leave workspace, and coming back needs a new invitation.
Guests
A guest is not a cheap member. A guest has no workspace-wide reach at all: they cannot browse the tree, they reach no collection by default, and they see exactly the pages somebody explicitly shared with them. Their sidebar says Nothing has been shared with you yet rather than "No collections yet", because those are different statements about the same empty screen.
Guests are free and are never counted towards the price. They are still capped, and the cap is generous next to the member cap for a reason worth stating plainly: without one, the cheapest way to run a large company on the free plan would be to make almost everybody a guest.
Promoting a guest to member is therefore a billing event, and the seat check runs at that moment: if the plan's member limit is already reached, the promotion is refused and the guest stays a guest.
Groups
A group is a name for a set of people. Share with the group and everyone in it is covered; add somebody to the group later and they are covered too. Groups are flat — a group holds people, never other groups — and they belong to the workspace, so the same group can be named on a collection, on a page and on anything else that takes a subject.
Deleting a group withdraws the access people held only through it; the people themselves stay in the workspace. If the group is the last holder of full access somewhere, the deletion is refused with the same sentence a stranding role change gets.
Invitations
The link is the deliverable, not a receipt. You enter an email address, choose a role and get a link, and passing it on is your job. Where the instance can also send mail, it does, and a line appears saying which address it went to — but the link stays on screen either way, because the message that lands in a spam folder is exactly the case the link exists for.
The rest of the model, in the order you meet it:
- The token is shown exactly once. What the invitation stores is a one-way digest of it, and no later listing returns it. Lose it and the way back is to revoke the invitation and create a new one; inviting the same address again does that in one step, because an address only ever has one open invitation.
- Owner is not in the role picker. Ownership is transferred, not invited.
- An invitation is valid for 14 days, and the row says the date.
- The seat check runs twice — when the invitation is created and when it is accepted. A workspace that filled its last seat in between refuses the acceptance rather than going over.
- Accepted invitations fold away under Show N accepted invitations. They are history: the person is in Members now.
Symbols
The shared icon library: named images anyone in the workspace can pick as an icon for a page, a database or the workspace itself. It is a settings section rather than a mode inside the icon picker, because the picker exists to answer "give me an icon, now" and renaming or thinning a list everybody shares is housekeeping about the workspace.
Removing a symbol takes it out of the list and off nothing. Anything already wearing it keeps it. Adding and renaming need the member role; a guest sees the list and cannot curate it, and the screen says so.
Import
Import is a settings section rather than a paragraph somewhere, because an import is not a setting: it is a long-running job with a history, and its report has to be reachable by URL after the fact rather than only in the moment the upload finished. What each source costs, and what a re-run converges on, is its own page.
Plan and usage
A limit stops the next write of that kind. It never deletes, hides or locks anything you already have. That sentence is on the screen permanently rather than only when a meter is full — a reassurance that appears at the same moment as the bad news is worth nothing. The exceptions are in version history, and both are named below.
The limits
| Solo | Team | Business | Enterprise | |
|---|---|---|---|---|
| Storage | 2 GB | 100 GB | 1 TB | no limit |
| Largest single file | 5 MB | 25 MB | 100 MB | no limit |
| Members | 5 | 100 | no limit | no limit |
| Guests | 10 | 250 | no limit | no limit |
| Version history | 30 days | no time limit | no time limit | no time limit |
| Per member, per month | free | 5 € | 10 € | by arrangement |
Solo is the free plan, and the rest of this page — and the note about
version history under Sharing, comments and history — calls it that where what
matters is that nobody is paying for it. Both paid figures are the launch
prices; the pricing page names 6 € and 12 € as the regular ones. The API and the
operator's back office spell these plans free, pro, business and
enterprise — the same four things under the ids they were built with.
Two limits are in the table for different reasons and it matters which is which. Storage is a total and has a meter; the largest-file figure is a ceiling on one upload and has none. Either one alone leaves the other open: a 4 GB file is still one file, and four thousand one-megabyte files pass every per-file cap.
What going over a limit does, and does not
- Downgrading never trims storage and never removes members. It changes what the next upload or the next invitation is measured against.
- A member over the limit is not ejected. The workspace simply cannot add another one.
- Reading, searching and serving attachments are never gated on a quota, and neither is export.
- Version history is where things are deleted, and it happens in two ways. The plan's window is the first: on the free plan every version older than 30 days goes, checkpoints you saved by hand included, because a window a Save version click could step around would not be a window. Every paid plan keeps history with no time limit. Pruned is pruned — the alternative, keeping the versions and charging to look at them, is the pattern the rule above exists to forbid.
- The second way applies on every plan, including the paid ones, and it is thinning rather than an age limit: of the versions the app captures by itself, the newest twenty on a page survive whatever their age, and the older ones are thinned to one per day. Versions you saved by hand are never thinned. So "no time limit" means no age at which history is dropped, not one row per capture kept forever.
Storage is one pool for the whole workspace: a file uploaded from another of our apps counts towards the same total, because there is one workspace and one set of attachments underneath all of them. The plan that measures the pool is the most generous one the workspace holds, across every app it is turned on for — otherwise a plan you pay for in one app would still refuse an upload in the next. The plan named on this screen is the one this app is on, which is why the two can differ.
What the money is
The price is per billable member per month, and it is charged once a year. Owners, admins and members are billable; guests are not.
The number of seats is fixed at checkout and is not re-metered. A workspace that subscribes with two members and grows to a hundred is charged for two until somebody changes it — nothing on this platform updates that quantity on its own. The screen says this before you pay and again on the subscription card afterwards, and this page says it because it is the single most surprising thing about the bill.
Prices are shown as total prices including VAT at our own rate. Abroad the rate differs, so the exact amount is the one on the payment page.
Moving between plans
- Team and Business are the two you can buy. Enterprise is a conversation and is assigned rather than sold; a workspace on it is told so instead of being offered a checkout it could not complete.
- Billing details come first. An invoice needs a name, a full postal address with a country and an email address to be sent to. Saving the details takes less than buying does, so the form says which fields are still missing for a purchase.
- A VAT identification number is recorded and printed on the invoice. It does not change the amount today: this instance does not verify VAT numbers, so VAT is charged, and the field says exactly that rather than implying a check is pending.
- Moving to the free plan is a cancellation, and there is no self-service route for it. Nor is there one for changing the plan you are on, the number of seats, or cancelling. All four are a message to the operator of this instance.
Access tokens
A personal access token lets a script, an integration or an agent act as you over the API. It can never do more than you can, and it stops working when your access does — including automatically, the next time it is used after you have left the workspace.
Every member may hold one, a guest included: a token that carries its owner's authority and nothing more adds no reach, so refusing a guest one would narrow nothing.
A token belongs to the person who made it, and nobody else can list or revoke it — not even an admin. An admin does not need to: changing somebody's role narrows every token they hold on the very next request, and removing them from the workspace revokes their tokens outright. A second, per-credential control surface would add a screen without adding a power.
What the screen asks for, in order:
- A name. It is what tells one token from the next in the list.
- What it may do — Read content, Write content, Read administration, Change administration, at least one. The permissions cover the whole workspace, which is why they mention pages, databases and fields.
- How long it lives. 30, 90, 180 or 365 days; 90 is the default and 365 the maximum. Tokens always expire — there is no perpetual option, and the form says so.
A token is the account, not the app. It reads everything you may read in this workspace, including content this app does not show you because it belongs to another of our apps. That is a real property of the credential and not a rounding error, so treat a token as broader than the screen you created it on.
The token is shown once. It is stored as a one-way digest, so a value replaced before it was copied is gone for good — which is why the form refuses to mint a second token while the first is still uncopied on screen, and says why. The panel shows the workspace id beside it, copyable: every API path names the workspace, and that id is the other half of what a script needs.
Revoke stops anything using the token immediately, and cannot be undone. The wire details — the header, the error shapes, what a token may never reach — are on the API page.
Webhooks
Basalt can call a URL of yours whenever something changes here. The request says what changed and when, never the content itself, so a receiver that needs the page reads it back through the API.
Registering an endpoint needs the member role at least: it makes the server issue outbound HTTP, and a guest was given a corner of a workspace rather than the right to aim the server at an address. Like a token, an endpoint belongs to the person who registered it and appears in nobody else's list — which is also why it pauses itself when that person leaves the workspace.
You only receive events about content you can read. Two people watching the same workspace legitimately receive different events, and that is the filter doing its job rather than a delivery being lost.
Choosing what to hear about
The picker lists eleven kinds of thing: the workspace itself, collections, pages, fields, databases, views, rows, permissions, groups, invitations and comments. It lists nothing that belongs to another of our apps. An endpoint registered here carries this app with it and would never receive such an event, so offering the choice would mean an endpoint that looks configured and stays silent forever; the API refuses the same subscription for the same reason. To hear about a document that lives in another of our apps, register the endpoint there.
The endpoint's own row
- Public
httpsaddresses only. Private, loopback and cloud-metadata addresses are refused with a sentence, before anything is stored. - The signing secret is shown once, and unlike a token it can be replaced: New secret on the endpoint's row issues a new one and invalidates the old one the moment you confirm.
- Pause and Resume are yours to use. An endpoint can also pause itself, and the row says which happened: Paused by you, Paused — too many failed deliveries in a row, or Paused — you are no longer a member of this workspace.
- Recent deliveries hang under the row: queued, delivered or given up, with the attempt count, the HTTP status and when the next attempt is due.
- Delete takes the delivery history with it, and the confirmation names the URL — two endpoints on one host look identical in a truncated row.
A failed delivery is attempted eight times in all, backing off 10 s, 30 s, 2 min, 10 min, 30 min, 1 h and 2 h between them. Three given-up deliveries in a row pause the endpoint. A receiver that is down therefore costs a bounded amount of work and then stops costing anything, which is the whole point of the rule. Verifying a signature, and the shape of the body, are on the API page.
What the workspace cannot do yet
- No single-sign-on. No SAML, no OIDC, no "anyone at this domain joins automatically". Invitations are the only way in.
- No audit log you can read. Actions on a page have an activity feed; the administrative acts on this page — a role change, a token minted, an endpoint deleted — leave no record a customer can open.
- No self-service change of plan, seats or cancellation, and no way to move back to the free plan on your own. Each of those is a message to the operator of this instance.
- VAT identification numbers are recorded, not verified, so no invoice is issued as reverse charge yet. The field says so where you enter it.
- Your display name cannot be changed from the app. The profile picture can; the name is the one the account was created with.
- The "turn on Basalt" button is offered to everyone who can reach the screen, though only an admin or the owner may use it. A member who presses it gets That did not work. rather than a sentence naming the role — ask an admin to turn the app on.
- A workspace's own settings have no address of their own.
/settings/…opens the section in whichever workspace you have open, so a settings link cannot point a colleague at a particular workspace's members. Nor does opening settings from inside the app put anything in the address bar: the gear and the switcher menu open a window, and only a/settings/<section>link you follow makes the section something you can reload or link to. - No retention setting. How long version history is kept follows the plan and cannot be shortened or lengthened per workspace, and a workspace cannot be set to delete trashed pages on a schedule.
- A webhook cannot be filtered any finer than by kind. There is no way to hear only about one collection, or only about creations.
- A webhook registered here hears only about what this app can see. An endpoint cannot span our apps; a workspace switched on in two of them needs an endpoint registered in each.
- Nothing exports on a schedule. Download export is a button somebody presses; there is no nightly copy to a bucket of yours.