Spaces
A space is a general-purpose file store on novem: folders and files of any type, with sharing, quotas, and a change journal built in.
AI-assisted, human-approvednovem uses AI to review and keep our documentation up to date.
Note: Spaces are an early-access feature. The endpoints below are
gated behind a per-account feature flag and return 404 unless it's enabled
on your account. Reach out to us if you'd like to try them.
A space stores files and folders, subject to your plan's storage quota. Use the HTTP API to upload, download, list, move, delete, and share files. A job can also mount a space as a folder.
Structure
Like every novem resource, a space is a small folder hierarchy:
project_data => Space name
├── content => Your files and folders live here
│ └── ... => Arbitrary nesting, up to 64 levels deep
├── changes => Change journal (for sync clients)
├── config
│ └── access
│ ├── ssh => Reserved for upcoming access protocols
│ └── web => Reserved for upcoming access protocols
├── description => Description (meta)
├── name => Display name (meta)
├── summary => Short summary (meta)
├── shortname => Auto-generated short id
├── url => The space's URL
├── shared => Who can see / edit the space
└── tags => Tags
The content/ folder holds your file tree. Other paths control metadata,
sharing, and configuration. See the
spaces API reference for the supported requests.
Creating a space
A space is created with an HTTP PUT to
https://api.novem.io/v1/code/spaces/SPACE_NAME:
novem --put /code/spaces/project_dataDELETE on the same path removes the space, and PATCH renames it: the
standard novem resource verbs.
Working with files
Files live under content/. The verbs follow the novem convention: PUT
creates a container (a folder), POST writes content (a file's bytes):
# make a folder
novem --put /code/spaces/project_data/content/reports
# upload a (text) file; parent folders are created automatically
novem --post /code/spaces/project_data/content/reports/q1.csv "$(cat q1.csv)"
# read it back
novem --get /code/spaces/project_data/content/reports/q1.csvA GET on a folder (or on content itself) returns a JSON listing in the
same shape as every other novem directory. PATCH renames or moves a file or
a whole folder tree; moves update paths without copying file contents. DELETE removes a file; deleting a non-empty
folder requires an explicit ?recursive=true.
Every file carries an ETag that changes on every write, and the write
verbs honor If-Match / If-None-Match preconditions, so concurrent
editors and scripts can detect conflicts instead of silently overwriting each
other. The full verb-by-verb behavior, including status codes and conditional
headers, is in the spaces API reference.
File names
The store is case-preserving but case-insensitive: Report.csv keeps its
casing, but you cannot create report.csv next to it. Names may use spaces,
unicode and mixed case; a small set of characters that cannot exist on every
platform (< > : " / \ | ? *, control characters, Windows reserved names
like CON, trailing dots or spaces) is rejected at write time. Paths can
nest up to 64 levels and 1024 bytes.
Tracking changes
Every mutation in a space (create, update, move, delete) is recorded in an
append-only journal with a per-space sequence number. GET .../changes?since=N
returns everything that happened after cursor N, including delete
tombstones and both sides of moves. Use the cursor to retrieve changes incrementally:
novem --get "/code/spaces/project_data/changes?since=0"Sharing
A space is shared like any other novem resource, by creating entries under
shared/. The grantee's group role determines what they can do:
- read access — list and download everything under
content/, and read thechangesjournal. - write access — full control of
content/: create, modify, move and delete. Files written by a collaborator count against the owner's quota.
Spaces cannot be made public yet; content is only ever visible to the owner and explicit shares.
Quotas
Space storage is tied to your subscription plan:
| Limit | Free | Basic | Premium | Enterprise |
|---|---|---|---|---|
| Spaces per user | 1 | 5 | 20 | 20 |
| Max single file size | 100 MB | 100 MB | 100 MB | 100 MB |
| Max space size | 5 GB | 5 GB | 5 GB | 5 GB |
Writes that would exceed a limit are rejected with 413. A space can hold at
most 1,000,000 files and folders.
The space page shows how much of both a space is using, and so does
GET .../:space/usage.
Using a space from a job
A job can mount a space and work with it as ordinary
files, instead of calling the API. Map a name to the space in the job's
config/spaces and it appears as a folder inside the run:
data_in => /u/alice/s/project_a,ro
scratch => /u/alice/s/scratch,rw
Mounts default to read-only, and changes under a rw mount reach the space as
the job writes them, not in one batch when the run ends — a run that fails
keeps whatever it had already written. See
job spaces for the file format, access rules
and limits.
Next steps
- Spaces API reference — every endpoint, verb and status code on the spaces surface.
- Job spaces — attaching a space to a job.
- Jobs and Repos — run code that reads and writes files.