curl -s -X POST $SUBSTRIO_URL/v1/_meta/collections -H "Authorization: Bearer $SUBSTRIO_KEY" \
-H 'content-type: application/json' -d '{"name":"notes"}'
# {"name":"notes","created":true,"acl_flags":0}
Collections
| Operation | Route | Scope |
|---|---|---|
collection.list |
GET /v1/_collections |
read-only |
collection.create |
POST /v1/_meta/collections |
curator |
collection.delete |
DELETE /v1/_meta/collections/{name} |
operator |
collection.stats |
GET /v1/{collection}/_stats |
read-only |
collection.create takes name (1 to 64 characters, not starting with an
underscore), an optional acl_flags (an integer bit set of access rules; 0,
the default, enforces none, and the owner-only bit gives each record's owner
read, write and delete), and an optional identity (field names whose values
make a record's key content-addressed). A name already in use answers 409.
Creating a collection declares no schema: use schema.update for that.
collection.delete removes a collection by name together with its records
and its index, vector, text and sparse trees. There is no undo; back up
first. A name starting with an underscore is refused with 400, and an
unknown collection answers 404.
collection.stats reads doc_count, indexes (each entry {"kind":"field", "field","unique"} for a declared field, or {"kind":"vector"|"text"| "sparse"} for a search index), index_count, and has_rag.
curl -s $SUBSTRIO_URL/v1/notes/_stats -H "Authorization: Bearer $SUBSTRIO_KEY"
# {"doc_count":42,"indexes":[{"kind":"field","field":"title","unique":false}],"index_count":1,"has_rag":false}
Schemas
schema.update (PATCH /v1/{collection}/_schema) replaces a collection's
schema. The collection must already exist (404 COLLECTION_NOT_FOUND
otherwise, so create it first).
| Field | Type | Default | Description |
|---|---|---|---|
rules |
array | required (at least one rule or constraint) | Each rule names a document field and its type |
constraints |
array | none | Cross-field rules evaluated on write |
strict |
boolean | true |
Refuse fields no rule names |
A rule's type is one of string, number, boolean, array, object,
datetime (an RFC 3339 date-time string, or an integer epoch in
milliseconds), secret (a string field left out of every read, result,
export and event; a filter, sort, group or projection naming it answers 400
SECRET_FIELD; read it from a function with db.secret), or any. A rule
may also set required, nullable, min, max, pattern (a regular
expression for strings), and enum (allowed strings). null counts as
absent: a field that is not required accepts null; a required one refuses
it unless nullable is true.
A constraint is {kind, ...}: exactly_one, at_least_one or
at_most_one with fields (two or more), or required_when with field,
equals, required and forbidden:
{"kind": "required_when", "field": "kind", "equals": "x", "required": ["a"], "forbidden": ["c"]}
Every field a constraint names needs a string, number, boolean or
datetime rule in the same schema. A write that breaks a constraint answers
400 SCHEMA_REFUSED naming the constraint's kind and fields (never a
value). If stored documents already break a new constraint, the declaration
is refused with 409 SCHEMA_VIOLATORS ({count, first: {_id}}); set
existing: "allow" to declare it anyway.
curl -s -X PATCH $SUBSTRIO_URL/v1/notes/_schema -H "Authorization: Bearer $SUBSTRIO_KEY" \
-H 'content-type: application/json' \
-d '{"rules":[{"field":"title","type":"string","required":true},{"field":"n","type":"number"}]}'
schema.get (GET /v1/{collection}/_schema) reads a collection's rules,
constraints and strict flag. schema.delete (DELETE /v1/{collection}/_schema) removes the schema.
Namespaces
namespace.list (GET /v1/{collection}/_namespaces) lists one collection's
namespaces. namespace.stats (GET /v1/{collection}/_namespaces/{name}/stats) reads one namespace's
statistics. namespace.delete (DELETE /v1/{collection}/_namespaces/{name}) removes a namespace by name.
Views
A view holds the result of a query, computed ahead of time so reading it
skips re-running that query. view.create (POST /v1/_views) takes:
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | The view's name |
collection |
string | required | The collection it reads |
query |
object | one of query/pipeline |
A query over the collection |
pipeline |
array | one of query/pipeline |
An aggregation pipeline |
mode |
string | scheduled |
scheduled or live |
cron |
string | */5 * * * * |
When a scheduled view refreshes |
ttl_seconds |
integer | 300 |
How long a refresh stays valid |
debounce_ms |
integer | 100 |
Minimum gap between refreshes |
curl -s -X POST $SUBSTRIO_URL/v1/_views -H "Authorization: Bearer $SUBSTRIO_KEY" \
-H 'content-type: application/json' \
-d '{"name":"top_notes","collection":"notes","query":{"where":{"n":{"$gt":2}}},"cron":"*/10 * * * *"}'
# {"name":"top_notes", ...}
view.create answers the view's id, which view.update, view.delete and
view.refresh take. view.list (GET /v1/_views) lists every view,
materialized and live. view.get (GET /v1/_views/{name}/data) reads a
materialized view's data. view.update (PATCH /v1/_views/{name}) takes
name and enabled to turn a view on or off. view.refresh (POST /v1/_views/{name}/refresh) recomputes one materialized view now. view.delete
(DELETE /v1/_views/{name}) removes a view by id; there is no undo.
A scheduled view materializes its result on cron and is read from that
stored copy until the next refresh or until ttl_seconds expires. Do not
assume a view read reflects the collection's current records.
Live views
A live view (live_view.create, POST /v1/_live_views) tracks a query over
one collection and keeps its result current as the collection changes.
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | The live view's name |
source_collection |
string | required | The collection it tracks |
query |
object | required | The tracked query |
min_interval_ms |
integer | 50 |
Minimum gap between recomputes |
live_view.get (GET /v1/_live_views/{name}/data) reads a live view's
current data. live_view.list (GET /v1/_live_views) lists live views by
name. live_view.update (PATCH /v1/_live_views/{name}) takes name and
enabled. live_view.delete (DELETE /v1/_live_views/{name}) removes one
by name.
Next
For the query shapes a view's query or a live view's query can hold, see
query-language.md and
chains-over-api.md.