The scenario
A space is the unit of isolation, of sharing, of configuration and of deletion. Split too finely and nothing can see anything else; too coarsely and you cannot share one part without sharing all of it. What this recipe shows that no other does: the space itself as a design decision, and the four calls that manage its lifecycle.The rule
Split by who may read it, never by what it is about. Topics are what search is for — two subjects in one space cost you nothing, because a query about one will not return the other. Audiences are what a space is for, and no query filter can retrofit an audience boundary. So: one space per readership. Within it, use scope keys for per-user separation and tags for topic.Step 1 — Create deliberately
Step 2 — See what you have
shared_by names the org that shared it with you, and is null for your own.
When a shared space collides with one of your own names, qualified_id gives
you the owner:name form to address it unambiguously.
Step 3 — Inspect one
Step 4 — Delete, and mean it
Evals
Before committing to a layout, test the two things that are expensive to change:- Can you share exactly one audience’s data without the others? If sharing the space would over-share, it is too coarse.
- Does any single question need to draw on two spaces at once? If yes, it is too fine — there is no cross-space query, and stitching results client-side loses the ranking that makes recall work.
Guardrails
- A space’s id is its name. There is no separate identifier to rename later, so a name with spaces is legal and means URL-encoding every path that uses it.
- Plans cap how many spaces you get;
max_spaces = -1means unlimited. - Scratch spaces are cheap and worth it. Tuning extraction against a real space leaves it with two eras of settings mixed together permanently.