The records of an app’s collections: which collections the caller may use and what they may do with each, listing with search, filter and sort, reading and writing records and reading their history, following changes live, and the details of the refusals specific to records.
Generated from the SDK’s own source. The SDK Reference is the narrative; this page is every member, in the order the SDK declares them.
CollectionsApi
The records of an app’s collections, reachable as client.collections: the
app’s own data model, written by a developer as a schema in the console and
read and written here with the caller’s role.
Every call is checked against the caller’s rights on the collection and,
for a collection that belongs to robots, against the robots the caller
reaches. A collection the caller may not read at all rejects
collection_not_found, exactly as one that does not exist; one the caller
may read but not write rejects forbidden. The refusals specific to
records keep the cloud’s codes, with error.details in the shape each
exported schema describes:
required_missing(400):requiredMissingDetails— the required fields left empty.reference_invalid(400):referenceInvalidDetails— the reference field and why it was refused.record_changed(409):recordChangedDetails— the revision the record is at now.record_referenced(409):recordReferencedDetails— the collections that still point at the record, with counts.validation_error(400) andplan_limit(409) as elsewhere.rate_limited(429):RateLimitDetails—retry_after_ms, how long to wait before writing again. Surfaced, never retried.
definitions()
definitions(): Promise<CollectionDefinitions>
The collections the caller may read, with their field definitions and
what the caller may do with each — what a screen needs to draw a list or
a form without hard-coding the schema — and the schema version they
belong to. collections is [] for an app that has published none, or
whose roles grant this caller none.
The schema can change under a running app; a realtime subscription’s
onSchemaPublished says when to read this again, and hands over the
version to compare with.
Returns Promise<CollectionDefinitions>.
References: CollectionDefinitions
list()
list(collection: string, options?: CollectionListOptions): Promise<CollectionPage>
One page of a collection’s records, filtered, searched and sorted by the cloud. In a collection that belongs to robots the caller sees only the records of robots they reach.
Rejects invalid_option, before anything is sent, for a filter that is
not plain JSON.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
options |
CollectionListOptions |
no |
Returns Promise<CollectionPage>.
References: CollectionListOptions, CollectionPage
get()
get(collection: string, id: string, options?: { expand?: string[] }): Promise<CollectionRecord>
One record by id. Rejects not_found when there is no such record or
the caller may not see it. expand embeds reference fields, one hop.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
id |
string |
yes |
|
options |
{ expand?: string[] } |
no |
Returns Promise<CollectionRecord>.
References: CollectionRecord
get(collection: string, by: { robot: string }, options?: { expand?: string[] }): Promise<CollectionRecord>
The record of one robot in a one_per_robot collection, which always
has exactly one. Rejects robot_not_attached when the robot is not
attached to the app or the caller does not reach it, and not_found
when the collection holds no record for it. Use it on a one_per_robot
collection only: on a per_robot collection, which holds many records
per robot, it returns the first of them.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
by |
{ robot: string } |
yes |
|
options |
{ expand?: string[] } |
no |
Returns Promise<CollectionRecord>.
References: CollectionRecord
create()
create(collection: string, values: Record<string, unknown>, options?: { robot?: string }): Promise<CollectionRecord>
Creates a record. values holds the fields by key and must set every
required one. A collection that belongs to robots takes robot, the id
of the robot the record belongs to, which cannot change afterwards.
Rejects required_missing, reference_invalid or validation_error
for values the schema refuses, and plan_limit when the organization is
at its record or storage limit. A one_per_robot collection takes no
creates (validation_error): the platform keeps one record for every
attached robot already.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
values |
Record<string, unknown> |
yes |
|
options |
{ robot?: string } |
no |
Returns Promise<CollectionRecord>.
References: CollectionRecord
update()
update(collection: string, id: string, values: Record<string, unknown>, options?: { expectedRevision?: number }): Promise<CollectionRecord>
Changes the fields in values and leaves the others alone; a null
clears a field. With expectedRevision (the revision you last read)
the write is refused with record_changed if the record has moved on, so
two editors do not silently overwrite each other.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
id |
string |
yes |
|
values |
Record<string, unknown> |
yes |
|
options |
{ expectedRevision?: number } |
no |
Returns Promise<CollectionRecord>.
References: CollectionRecord
delete()
delete(collection: string, id: string): Promise<void>
Deletes a record; its history is kept. Rejects record_referenced while
a record of another collection points at it with on_delete: prevent.
A one_per_robot collection takes no deletes (validation_error).
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
id |
string |
yes |
Returns Promise<void>.
history()
history(collection: string, id: string, options?: CollectionHistoryOptions): Promise<CollectionHistoryPage>
A record’s history, newest revision first. Needs the right to update the record.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
id |
string |
yes |
|
options |
CollectionHistoryOptions |
no |
Returns Promise<CollectionHistoryPage>.
References: CollectionHistoryOptions, CollectionHistoryPage
subscribe()
subscribe(collection: string, options: CollectionSubscribeOptions, onEvent: (event: CollectionEvent) => void): () => void
Follows a collection’s changes live over the client’s realtime channel:
onEvent is called for every record that is created, updated, deleted,
or comes into or leaves the view of this subscription (see
CollectionEvent). options.robot and options.filter narrow it; the
caller’s rights are checked on every event, not only when subscribing.
There is no first snapshot, but the cloud confirms the subscription.
Once it has accepted and registered it, options.onReady is called, and
from then on every change reaches onEvent. To show the records that
exist, list in onReady, so that no change can fall between the list
and the events; then apply the events to what the list returned. A
refusal is answered through options.onError and onReady is not called.
Opens the channel if it is not open, and subscribes again by itself after
every reconnect. Changes made while the connection was down are not
replayed, but onReady is called again once the cloud has confirmed the
subscription on the new connection: the same list in the same place
refreshes what the app holds.
Returns the function that ends the subscription. It is safe to call more than once, and after the cloud ended the subscription itself.
Throws invalid_option, before anything is sent, for a filter that is
not plain JSON, and for a subscription whose frame, with its filter, is
larger than the 16,384 bytes the cloud takes.
| Parameter | Type | Required | Description |
|---|---|---|---|
collection |
string |
yes |
|
options |
CollectionSubscribeOptions |
yes |
|
onEvent |
(event: CollectionEvent) => void |
yes |
Returns () => void.
References: CollectionSubscribeOptions, CollectionEvent
CollectionDefinitions
What collections.definitions resolves with: collections, the collections
the caller may read (see CollectionDefinition), and version, the schema
version they belong to, null while the app has published none. Compare it
with the version onSchemaPublished hands over to tell whether what you hold
is current.
The wire shape is contracts’ collectionDefinitionsResponse.
The API Schemas page lists its two fields, version and collections.
CollectionDefinition
A collection as the caller may use it, from collections.definitions:
key, label, description, binding (global, per_robot or
one_per_robot), the display template, every field’s definition under
fields, and can, what the caller may do with the records (read,
create, and for update and delete 'all', 'own' or false) — the
answer to “which buttons do I draw”.
The wire shape is one entry of collections in contracts’
collectionDefinitionsResponse.
The API Schemas page lists its fields as the items of collections.
CollectionField
One field definition, discriminated on type. The schema document lists the options each of the nine field types takes.
CollectionBinding
How a collection relates to robots: global, per_robot or one_per_robot. App Data says what each means.
CollectionRecord
The collection-record wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
One record of a collection: its system fields (id, robot_id, who made
it and when, revision), display (the collection’s display template
filled in for this record), missing_required (required fields that are
empty because the schema changed after the record was written; absent when
nothing is missing) and values, the record’s own fields by key. A field
without a value is absent from values. With expand, a reference field
holds the referenced record in this same shape instead of its id, when the
caller may read that collection.
The wire shape is contracts’ collectionRecord; the alias exists so the
reference can describe it.
CollectionActor
The collection-actor wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
CollectionListOptions
What collections.list reads. Every field is optional; the wire names are
snake_case or encoded (filter is JSON text, sort and expand are
comma-separated) and this SDK spells them the way its other options are
spelt, leaving out whatever the caller did not set.
| Property | Type | Required | Description |
|---|---|---|---|
search |
string |
no |
Words that must all occur, in any letter case, in at least one searchable field of the record. At most 10 words, separated by whitespace. |
filter |
Record<string, unknown> |
no |
A filter: { "<field>": { "<op>": value } }, combined with { and: [...] } and { or: [...] }. The operators are eq, ne, lt, lte, gt, gte, contains, in and empty. A field is a field key, reference.field to go one hop through a reference field, or one of the system fields id, robot_id, created_at, updated_at and created_by. Nested at most 3 levels, 50 conditions in all. A filter the cloud cannot read rejects validation_error naming the part that is wrong. The filter has to be plain JSON; a reactive proxy (Vue, Svelte, MobX) is fine, and a value JSON cannot hold (a BigInt, a function, a number that is not finite, a cycle) rejects invalid_option before anything is sent. |
sort |
string[] |
no |
Up to 3 fields to sort by, a leading - for descending, for example ['-created_at']. Ties are broken by id, so a page boundary is exact. |
limit |
number |
no |
How many records to return, 1 to 500; absent means 50. Above the cap the cloud refuses with validation_error rather than trimming. |
cursor |
string |
no |
The previous page’s nextCursor. Send it back rather than computing one; it stays valid while records are written. |
count |
boolean |
no |
true makes the page carry total, the number of records that match. |
expand |
string[] |
no |
Reference fields to embed as records instead of ids, one hop. A record is embedded only when the caller may read its collection; otherwise the id stays. |
robot |
string |
no |
Only the records of this robot, in a collection that belongs to robots. |
deleted |
boolean |
no |
true lists deleted records instead, newest deletion first. Needs the right to create records in the collection. |
CollectionPage
One page of collections.list.
Page until nextCursor is null, never until a page looks short. The
cloud only knows a page is the last one when there is nothing behind it.
| Property | Type | Required | Description |
|---|---|---|---|
records |
CollectionRecord[] |
yes |
The records of this page, in the requested order. |
nextCursor |
string | null |
yes |
Pass it as cursor to read the next page; null on the last page. |
total |
number |
no |
The number of records that match the whole query. Present only when the call asked for it with count: true. |
References: CollectionRecord
CollectionHistoryOptions
The window of collections.history: both fields optional, newest revisions first.
| Property | Type | Required | Description |
|---|---|---|---|
limit |
number |
no |
How many revisions to return, 1 to 500. |
beforeSeq |
number |
no |
The previous page’s nextBeforeSeq: only revisions older than this seq. |
CollectionHistoryPage
One page of a record’s history, newest revision first. purged is set when
an organization owner removed the older part of the history: it starts with
a note saying which revisions went, who removed them and when.
| Property | Type | Required | Description |
|---|---|---|---|
revisions |
CollectionRevision[] |
yes |
The revisions of this page, newest first. |
nextBeforeSeq |
number | null |
yes |
Pass it as beforeSeq to read older revisions; null when there are none. |
purged |
{ before: string; by: { kind: "fleetless" | "developer" | "server_key" | "app_user"; id: string; label: string }; at: string } | null |
yes |
The removal of the older history, or null when none happened. by is the owner who removed it, an actor with a label like a record’s created_by. |
References: CollectionRevision
CollectionRevision
The collection-revision wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
One change in the history of a record: seq (the position to page and
restore by), the operation (create, update, delete or restore), the
actor, reason (schema v5, import, restore v4, or null for an
ordinary write), the record’s revision afterwards, changes (each touched
field with its old and new value) and, on a delete, the whole record.
The wire shape is contracts’ collectionRevision.
CollectionSubscribeOptions
What collections.subscribe takes besides the collection and the change
callback. Every field is optional.
| Property | Type | Required | Description |
|---|---|---|---|
robot |
string |
no |
Only the records of this robot, in a collection that belongs to robots. |
filter |
Record<string, unknown> |
no |
Only records matching this filter are delivered. It is the filter of collections.list — the same grammar, at most 3 levels and 50 conditions — and a record that stops matching is announced once as removed. The SDK keeps a copy, so changing the object afterwards changes nothing; a reactive proxy (Vue, Svelte, MobX) is fine. The filter has to be plain JSON: a value JSON cannot hold (a BigInt, a function, a number that is not finite, a cycle) makes subscribe throw invalid_option before anything is sent. The whole subscription frame, filter included, may be at most 16,384 bytes (UTF-8): the cloud closes the connection for a larger one. A filter of a few dozen conditions fits; many long values in in lists may not. subscribe throws invalid_option for a frame over that, before anything is sent, so narrow the filter or follow the collection by robot. |
onError()
onError?(error: FleetlessError): void
Optional — a caller need not implement it.
Called when the cloud refuses the subscription (collection_not_found
for a collection that does not exist or that the caller may not read,
forbidden, robot_not_attached, validation_error for a filter it
cannot read, internal_error when it could not check), and when a
running one ends: collection_removed after a publish removed the
collection, or forbidden / robot_not_attached when a role change or a
detached robot no longer allows it. The subscription is over then and
delivers nothing more; subscribe again to follow the collection.
Also called, without ending the subscription, when the channel cannot
authenticate at all (no_session, for instance) and when the cloud ends
the connection because its credential is no longer valid
(token_revoked). Nothing reconnects after that, and the subscription
stays registered: if the app opens the channel again (by signing in and
making a new subscription or command), it is sent again and onReady
is called once the cloud has confirmed it.
| Parameter | Type | Required | Description |
|---|---|---|---|
error |
FleetlessError |
yes |
Returns void.
References: FleetlessError
onReady()
onReady?(): void
Optional — a caller need not implement it.
Called each time the cloud has confirmed the subscription: the first time
it is accepted, and again after every reconnect, once the subscription
was sent again on the new connection and accepted. From that moment on
every change the subscription covers reaches onEvent, so this is the
place to read the records that exist: call collections.list here and
show its result, then apply the events to it. An event can arrive while
the list is still being read, and may or may not be in its result; a
record’s revision tells a newer state from an older one, so apply an
event only when it is newer than what the list returned for that id.
The same code serves the first load and every later one. The cloud does not replay what changed while the connection was down, so after a reconnect the records the app holds may be stale: read them again here and replace them.
Not called before the cloud has answered, for a subscription it refuses
(that is onError), for one that ended (unsubscribe, or onError for
an ended one), nor when the app ends the subscription before the answer
arrives. A cloud that does not know this answer never calls it.
Returns void.
onSchemaPublished()
onSchemaPublished?(version: number): void
Optional — a caller need not implement it.
Called with the schema version now in force when a developer publishes or
restores the app’s collections. Rights, fields and collections may have
changed: read collections.definitions again.
| Parameter | Type | Required | Description |
|---|---|---|---|
version |
number |
yes |
Returns void.
CollectionEvent
One change to a record, as collections.subscribe hands it to its
callback.
eventiscreated,updatedordeletedwhen the record was written, andremovedorenteredwhen it left or came into view of this subscription without being deleted or created: its values stopped or started matching the subscription’s filter, the caller’s role lost or gained the right to read it, or its robot was detached or attached.idis the record’s id.recordis the whole record: as it is now forcreated,updated,enteredandremoved, and as it was fordeleted. It is absent only on aremovedevent for a record the caller may no longer read, so that its values are not told; theidstill is.
The wire frame is contracts’ collectionEvent; the SDK hands over the
change itself, without the frame’s type and request_id.
The realtime collection_event frame without its type and request_id, which the SDK keeps to itself; App Data lists the events.
RequiredMissingDetails
The required-missing-details wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
requiredMissingDetails
The details of a 400 required_missing refusal: every required field the write would leave empty.
const requiredMissingDetails: ZodType<RequiredMissingDetails>
References: RequiredMissingDetails
ReferenceInvalidDetails
The reference-invalid-details wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
referenceInvalidDetails
The details of a 400 reference_invalid refusal: which reference field, and why its value was refused.
const referenceInvalidDetails: ZodType<ReferenceInvalidDetails>
References: ReferenceInvalidDetails
RecordChangedDetails
The record-changed-details wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
recordChangedDetails
The details of a 409 record_changed refusal: the revision the record is at now, for the caller to read it again.
const recordChangedDetails: ZodType<RecordChangedDetails>
References: RecordChangedDetails
RecordReferencedDetails
The record-referenced-details wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.
recordReferencedDetails
The details of a 409 record_referenced refusal. Counts only: the caller
may not be allowed to read the records that point here, so neither their
ids nor their values are told. Nor is the key of a collection the caller may
not read, for the reason collection_not_found is answered for one: the list
names only collections the caller may read, and it is empty when every
collection that points here is one they may not.
const recordReferencedDetails: ZodType<RecordReferencedDetails>
References: RecordReferencedDetails