Documentation
¶
Index ¶
- Constants
- func CheckMetaEntry(key string, v any, nilOK bool) string
- type ACLAcceptRequest
- type ACLAddAccount
- type ACLAddRequest
- type ACLChangePermissionsRequest
- type ACLDeclineRequest
- type ACLOwnershipRequest
- type ACLPermissionChange
- type ACLRemoveRequest
- type APIError
- type AccessCodeRequest
- type AccessCodeResponse
- type AccountDiscoveryStatus
- type AccountMetadata
- type AccountResponse
- type AddDatasetFieldResponse
- type AddDatasetResponse
- type AddPartResponse
- type AddPropertyRequest
- type AddPropertyResponse
- type AggregateResponse
- type AuthAccount
- type AuthCapabilities
- type AuthRequest
- type AuthResponse
- type AuthStatusResponse
- type BacklinksAllResponse
- type BacklinksResponse
- type BlockCreateRequest
- type BlockNav
- type BlockPatchRequest
- type Bundle
- type BundleChildRequest
- type BundleChildResponse
- type BundleEnsureRequest
- type BundleEnsureResponse
- type BundleGetResponse
- type BundleListResponse
- type BundleResolveRequest
- type CRDTVersionState
- type CatalogBundle
- type CatalogCollection
- type CatalogListResponse
- type CatalogSetupBundle
- type CatalogSetupRequest
- type CatalogSetupResponse
- type CatalogType
- type CatalogUsecase
- type ChatAgentMeta
- type ChatAttachment
- type ChatEditRequest
- type ChatMessageContext
- type ChatMessageControl
- type ChatSendRequest
- type CollectionInfo
- type CollectionPatchRequest
- type CollectionsCreateRequest
- type CollectionsCreateResponse
- type CollectionsListResponse
- type DatasetDefResponse
- type DatasetDraftRequest
- type DatasetFieldDef
- type DatasetFieldDraft
- type DatasetFieldPatchRequest
- type DatasetFieldShape
- type DatasetPatchRequest
- type DatasetSchema
- type DatasetSearchFields
- type DatasetsResponse
- type DeleteRecordsRequest
- type DerivedSpaceInfo
- type DerivedSpaceListResponse
- type DeviceActivateRequest
- type DeviceActiveClaim
- type DeviceInfo
- type DeviceUpdateRequest
- type DevicesListResponse
- type ErrorEnvelope
- type Event
- type EventLinksUpdatedData
- type EventPublishRequest
- type EventPublishResponse
- type EventSender
- type FileCacheFreeRequest
- type FileCacheFreeResult
- type FileCacheInfo
- type FileInfo
- type FileListResponse
- type FileStats
- type FileStatus
- type GlobalP2PStatus
- type HealthResponse
- type HistoryChange
- type HistoryDatasetDiff
- type HistoryDiffResponse
- type HistoryFieldDiff
- type HistoryListResponse
- type HistoryRecordDiff
- type HistoryRecordResponse
- type HistoryTouchedRecord
- type HistoryViewDataset
- type HistoryViewResponse
- type IdentitiesListResponse
- type IdentityEventPayload
- type IdentityInfo
- type InviteCreateResponse
- type InviteInfo
- type InvitesListResponse
- type JoinRequest
- type JoinRequestsResponse
- type Link
- type LinkSource
- type LinkTarget
- type LinksResponse
- type LocalAggregateRequest
- type LocalAggregateResponse
- type LocalCollection
- type LocalCollectionInfo
- type LocalDeleteRequest
- type LocalDeleteResponse
- type LocalDiscoveryRequest
- type LocalDiscoveryResponse
- type LocalDocsRequest
- type LocalEnsureRequest
- type LocalEnsureResponse
- type LocalGetRequest
- type LocalIdsResponse
- type LocalImportResponse
- type LocalIndex
- type LocalIndexesRequest
- type LocalIndexesResponse
- type LocalListResponse
- type LocalMetaResponse
- type LocalQueryRequest
- type LocalRecordResponse
- type LocalUpdateRequest
- type LocalUpdateResponse
- type MarkdownContent
- type MarkdownEdit
- type MarkdownEditRequest
- type MarkdownSetResponse
- type Member
- type MemberEventPayload
- type MembersListResponse
- type ModifyResult
- type ObjectCreateRequest
- type ObjectDebugResponse
- type ObjectGetResponse
- type ObjectSyncStatusResponse
- type ObjectsCreateResponse
- type Op
- type OpRejection
- type P2PPeerStatus
- type P2PStatusResponse
- type PartDefResponse
- type PartDraftRequest
- type PartPatchRequest
- type PeerSyncStats
- type Process
- type ProcessCancelRequest
- type ProcessError
- type ProcessFinishRequest
- type ProcessListResponse
- type ProcessProgressRequest
- type ProcessRegisterRequest
- type PropertiesGetResponse
- type PropertiesListResponse
- type PropertiesSetRequest
- type PropertyDef
- type PropertyPatchRequest
- type PushSubscription
- type PushSubscriptionsResponse
- type PushTokenSetRequest
- type PushTokenStatus
- type QueryBodyParams
- type QueryResponse
- type QuerySubscribeEvent
- type QuerySubscribeRecord
- type QuerySubscribeSnapshot
- type RecordModify
- type RemovedRecord
- type SearchHit
- type SearchPassage
- type SearchRequest
- type SearchResponse
- type SearchText
- type SpaceAggregateObjectsRequest
- type SpaceAggregateRequest
- type SpaceBacklinks
- type SpaceCreateRequest
- type SpaceDebugResponse
- type SpaceInfo
- type SpaceJoinRequest
- type SpaceListQueryRequest
- type SpaceListResponse
- type SpaceModifyRequest
- type SpaceOneToOneRequest
- type SpacePushKeys
- type SpaceQueryObjectsRequest
- type SpaceQueryRequest
- type SpaceRegisterIncomingRequest
- type SpaceSettingsPatchRequest
- type SpaceSyncStatusResponse
- type SpaceUpdateRequest
- type SubscribeClosed
- type SubscribeEventOp
- type SubscribeReady
- type SyncStatusLagged
- type SyncStatusReady
- type TypeDatasetsListResponse
- type TypeInfo
- type TypePartsListResponse
- type TypePatchRequest
- type TypesCreateRequest
- type TypesCreateResponse
- type TypesListResponse
- type UpsertRecord
- type UpsertRejection
- type UpsertRequest
- type UpsertResult
Constants ¶
const ( LinkKindMention = "mention" LinkKindLink = "link" LinkKindCard = "card" LinkKindEmbed = "embed" LinkKindRelation = "relation" )
Link kinds — the established vocabulary.
const ( ErrBlockNotFound = "blocks.not_found" ErrBlockTypeMissing = "blocks.type_required" ErrBlockRejected = "blocks.rejected" )
Error code namespace for block endpoints.
const ( // ErrBundleNotFound — no live record for the bundle id. ErrBundleNotFound = "bundle.not_found" // ErrBundleNotReady — the winning root's tree has not reached this // device yet, so its id is not writable. Retryable. ErrBundleNotReady = "bundle.not_ready" // ErrBundleNotLoser — the resolve target is the current winner, or // was never claimed for this bundle. ErrBundleNotLoser = "bundle.not_loser" // ErrBundleLoserNotReady — the losing root is still syncing or // still inside the quiescence window, so what is stored locally is // not yet the whole of it. Retryable. ErrBundleLoserNotReady = "bundle.loser_not_ready" // ErrBundleReserved — the id is under the server's `system:` prefix; // only the server's own catalog installs there. ErrBundleReserved = "bundle.reserved" // ErrDatasetModuleReserved — a part or dataset draft names a module // reserved to the server's own installs. ErrDatasetModuleReserved = "dataset.module_reserved" )
Bundles-registry error codes.
const ( ErrChatTextRequired = "chat.text_required" ErrChatTextTooLong = "chat.text_too_long" ErrChatReplyIdInvalid = "chat.reply_id_invalid" ErrChatAgentInvalid = "chat.agent_invalid" ErrChatEmojiInvalid = "chat.emoji_invalid" ErrChatUnknownField = "chat.unknown_field" ErrChatNotAuthor = "chat.not_author" ErrChatNotFound = "chat.not_found" ErrChatRejected = "chat.rejected" ErrChatAttachmentsInvalid = "chat.attachments_invalid" ErrChatContextInvalid = "chat.context_invalid" ErrChatControlInvalid = "chat.control_invalid" )
Error code namespace for chat endpoints.
const ( // EventScopeDevice — this process only: delivered to local // subscribers, never leaves the machine. EventScopeDevice = "device" // EventScopeAccount — every device of this account. EventScopeAccount = "account" // EventScopeSpace — every member of the space named by SpaceId. EventScopeSpace = "space" )
Event Scope values — a closed set.
const ( EventUIOpenSpace = "ui.open_space" EventUIOpenObject = "ui.open_object" )
UI event types — the device-scope vocabulary UI windows subscribe to for navigation. Data carries {spaceId, objectId?, source?}: spaceId is the *target* space to open (independent of the envelope's scope routing), objectId is required for EventUIOpenObject, source is a free-form publisher hint (UI display only). An open set — new UI operations add a new type with no server change; unknown types are ignored client-side.
const ( // FileStateDurable — verified network receipt recorded (or inline). FileStateDurable = "durable" // FileStateInFlight — registered, backup not confirmed yet. FileStateInFlight = "inflight" // FileStateLimited — the network refused backup (storage limit); // retried on a slow cadence and on POST .../retry. FileStateLimited = "limited" )
File durability states — FileStatus.State.
const ( // ErrFileNotFound — unknown fileId, unknown objectId on attach, or // a files query against an object with no files attached yet. ErrFileNotFound = "file.not_found" // ErrFileNotDurable — offload refused: the local bytes are the only // copy (file not backed up yet). 409. ErrFileNotDurable = "file.not_durable" // ErrFileNotAvailable — content download refused: the bytes are not // local and cannot be fetched yet (file not durable, or the network // advertises no public read base). Retryable resource state — for a // freshly synced row, retry once the row shows networkSign (the // files/query/subscribe update event). 409. ErrFileNotAvailable = "file.not_available" // ErrFileVariantInvalid — variant/variantOf pairing broken, or the // variant original lives on a different object. 400. ErrFileVariantInvalid = "file.variant_invalid" )
Error code namespace for file endpoints.
const ( ErrMarkdownNoMatch = "markdown.no_match" // 400 — oldText not found in the current rendering ErrMarkdownAmbiguous = "markdown.ambiguous_match" // 400 — >1 occurrences without replaceAll ErrMarkdownOverlap = "markdown.overlapping_edits" // 400 — two edits matched intersecting text )
Error code namespace for the markdown edit endpoint.
const ( MemberStatusUnknown = "unknown" MemberStatusJoining = "joining" MemberStatusActive = "active" MemberStatusRemoved = "removed" MemberStatusDeclined = "declined" MemberStatusRemoving = "removing" MemberStatusCanceled = "canceled" )
Member status string values. Mirror space.MemberStatus 1:1.
const ( MemberEventKindAdded = "added" MemberEventKindChanged = "changed" MemberEventKindRemoved = "removed" )
Member event kinds — wire values for MemberEvent.Kind.
const ( ProcessStateRunning = "running" ProcessStateDone = "done" ProcessStateFailed = "failed" ProcessStateCancelled = "cancelled" )
Process State values — a closed set. Only running processes are heartbeat-kept; terminal states linger briefly in the view and then expire.
const ( EventProcessStarted = "process.started" EventProcessProgress = "process.progress" EventProcessDone = "process.done" EventProcessFailed = "process.failed" EventProcessCancelled = "process.cancelled" EventProcessCancel = "process.cancel" )
Process event types — the `process.*` corner of the event bus vocabulary the helper endpoints emit (envelope target = process id). EventProcessCancel is a directive addressed at the owner, not a state change: the owner reacts and emits the terminal event.
const ( PushPlatformIOS = "ios" PushPlatformAndroid = "android" )
Push platform wire values (mirror space.PushPlatform).
const ( SearchModeHybrid = "hybrid" SearchModeFTS = "fts" SearchModeVector = "vector" )
Search modes. Hybrid runs both legs and fuses by reciprocal rank; fts / vector run one leg only.
const ( // VectorStatusUsed: the vector leg ran and contributed to ranking. VectorStatusUsed = "used" // answer for this query — unreachable, or not within the query // budget — retry later may differ. Hybrid degraded to FTS; // mode=vector would have returned 503. VectorStatusUnavailable = "unavailable" // VectorStatusDisabled: no embedder is configured on this server — // vector search can never run until config changes. VectorStatusDisabled = "disabled" // VectorStatusSkipped: vector was not attempted although available // on this server — the caller asked for mode=fts, or the Filter // matched no object so no leg ran. VectorStatusSkipped = "skipped" )
VectorStatus values — the search response tells the consumer (often an agent deciding how much to trust recall) what happened to the vector leg, not just that it silently fell back to lexical search.
const ( SpaceStatusUnknown = "unknown" SpaceStatusActive = "active" SpaceStatusJoining = "joining" SpaceStatusLeaving = "leaving" SpaceStatusDeleted = "deleted" SpaceStatusRemoteDead = "remote_dead" // SpaceStatusOneToOnePending is an incoming 1-1 (direct) space // awaiting local approval — not yet materialized or synced. Discover // these via GET /v1/spaces?status=one_to_one_pending (hidden from the // active-only default list), then accept/decline. Device-local. SpaceStatusOneToOnePending = "one_to_one_pending" // SpaceStatusOneToOneDeclined is a 1-1 the user declined — a synced, // account-wide sticky marker. Hidden from the default list like // deleted; an explicit POST /v1/spaces/one-to-one overrides it. SpaceStatusOneToOneDeclined = "one_to_one_declined" // SpaceStatusInvitePending is a regular space another account added // this account to directly (ACL add by identity). Already a full // member; approval is a local gate — nothing is downloaded until // accepted. Synced account-wide. Discover via // GET /v1/spaces?status=invite_pending, then // POST /v1/spaces/:spaceId/invite/accept or .../invite/decline. SpaceStatusInvitePending = "invite_pending" // SpaceStatusInviteDeclined is a direct-add invite the user declined // — synced, sticky, non-terminal (accept overrides). Hidden from the // default list like deleted. SpaceStatusInviteDeclined = "invite_declined" // SpaceStatusGuestRevoked is a guest-key (public-access) space whose // shared guest identity was removed from the ACL — the owner revoked // public access. The local copy stays readable; new content no longer // arrives. Remove with DELETE /v1/spaces/:spaceId. SpaceStatusGuestRevoked = "guest_revoked" )
Space status string values exposed on the wire. Mirror the space.Status enum 1:1.
const ( SpacePermissionNone = "none" SpacePermissionReader = "reader" SpacePermissionGuest = "guest" SpacePermissionWriter = "writer" SpacePermissionAdmin = "admin" SpacePermissionOwner = "owner" )
Space permission string values for SpaceInfo.OwnRole. Mirror the space.Permission enum 1:1. Pre-staged for the ACL/Members endpoints that still return 501.
const ( // SubscribeClosedServerShutdown — the server is exiting (signal or // POST /v1/shutdown). Reconnect when the server is back up. SubscribeClosedServerShutdown = "server_shutdown" // torn down in place (DELETE /v1/auth, or a POST /v1/auth switch to // another account) while the server stays up. Re-read GET /v1/auth // before resubscribing: the server is unauthorized or serving a // different account. SubscribeClosedDeauthorized = "deauthorized" // SubscribeClosedSDKClosed — the SDK released the underlying // subscription channel (typically because the space or SDK closed). // Reconnect after re-resolving the space. SubscribeClosedSDKClosed = "sdk_closed" // SubscribeClosedOverflow — only on query/subscribe streams. The // per-sub mailbox filled before the consumer could drain it; the // SDK closes the subscription rather than dropping events. Recovery // is resubscribe (which re-Snapshots). SubscribeClosedOverflow = "overflow" // SubscribeClosedDrifted — only on query/subscribe streams. More // than DriftBudgetPercent of the held window left without // replacements; the SDK closes the subscription rather than // re-Query the database on the hot path. Recovery is resubscribe. SubscribeClosedDrifted = "drifted" )
Reason values for SubscribeClosed. Stable strings; clients should switch on these rather than message text. Shared across every SSE family — query/subscribe, sync-status/subscribe, members/subscribe.
const ( MutableNever = "never" MutableByAuthor = "author" MutableByAnyone = "any" StampCreator = "creator" StampCreateTime = "createTime" StampModifyTime = "modifyTime" IdRuleAuto = "auto" IdRuleUser = "user" DeleteByAnyone = "anyone" DeleteByAuthor = "author" )
Wire labels for the dataset-schema behavioral vocabulary. Mirror the SDK enums 1:1 (space.Mutability / Stamp / IdRule / DeletePolicy).
const ( ModuleRecords = "records" ModuleEditor = "editor" ModuleChat = "chat" )
Module slugs a dataset declaration may name. `records` is the SDK's built-in generic module (a schema-enforced dataset the declaration fully describes); `editor` and `chat` are this server's compiled-in modules — the module owns their schema, so a declaration carries no fields.
const ( CollectionEditorBlocks = "editor_blocks" CollectionChatMessages = "chat_messages" )
Canonical collections of the compiled-in modules — what a shared dataset of the module is, and the default the editor CLI writes.
const ( PropertyKindString = "string" PropertyKindNumber = "number" PropertyKindBoolean = "boolean" PropertyKindNull = "null" PropertyKindArray = "array" PropertyKindObject = "object" // PropertyKindDatetime is an instant: `{"$date": "<RFC 3339>"}` on // the wire in both directions (writes also accept // `{"$date": <unix millis>}`). The kind the `date` / `datetime` // formats imply — see docs/03-api.md § Types. PropertyKindDatetime = "datetime" )
PropertyKind* are the wire-string forms of space.PropertyKind. Mirror the SDK enum 1:1; expand when the SDK adds new kinds.
const ControlTokenHeader = "X-Any-Control-Token"
ControlTokenHeader carries the managed-mode control token. A managed server accepts POST/DELETE /v1/auth and POST /v1/shutdown only with the token its spawning host holds; a standalone server refuses those operations regardless (docs/03-api.md § Auth).
const DefaultSearchMaxData = 512
DefaultSearchMaxData is the Data window applied when a request leaves MaxData unset: enough for a one-line preview or an agent to judge the match, and a bounded reply whatever the record size — the full record stays one dataset query away.
const (
// ErrCatalogNotFound — no usecase with that id in the catalog.
ErrCatalogNotFound = "catalog.not_found"
)
Catalog error codes.
const EventLinksUpdated = "links.updated"
EventLinksUpdated is the device-scope event the link index publishes after a page changed edges: data is EventLinksUpdatedData.
const MaxEventLinksTargets = 200
MaxEventLinksTargets caps EventLinksUpdatedData.Targets.
const MaxSearchPassages = 10
MaxSearchPassages caps SearchRequest.Passages.
const MetaKeyMaxBytes = 64
MetaKeyMaxBytes bounds a meta key on a type or a collection.
Variables ¶
This section is empty.
Functions ¶
func CheckMetaEntry ¶ added in v0.2.2
CheckMetaEntry validates one entry of a definition's meta bag: a single-level key (no '.', no '$', at most MetaKeyMaxBytes) and a scalar value — string, bool or number. nilOK admits a nil value, the clear on PATCH. Returns "" when the entry is fine, otherwise the reason, worded for the caller's error message.
Types ¶
type ACLAcceptRequest ¶
type ACLAcceptRequest struct {
RequestRecordId string `json:"requestRecordId"`
Permission string `json:"permission"`
}
ACLAcceptRequest is the body of POST /v1/spaces/:spaceId/acl/accept. `permission` is granted on accept; valid values are the SpacePermission* constants minus SpacePermissionOwner.
type ACLAddAccount ¶
type ACLAddAccount struct {
Identity string `json:"identity"`
Permission string `json:"permission"`
Metadata AccountMetadata `json:"metadata,omitempty"`
}
ACLAddAccount is one entry in an AddAccounts batch.
type ACLAddRequest ¶
type ACLAddRequest struct {
Accounts []ACLAddAccount `json:"accounts"`
}
ACLAddRequest is the body of POST /v1/spaces/:spaceId/acl/add.
type ACLChangePermissionsRequest ¶
type ACLChangePermissionsRequest struct {
Changes []ACLPermissionChange `json:"changes"`
}
ACLChangePermissionsRequest is the body of POST /v1/spaces/:spaceId/acl/permissions.
type ACLDeclineRequest ¶
type ACLDeclineRequest struct {
Identity string `json:"identity"`
}
ACLDeclineRequest is the body of POST /v1/spaces/:spaceId/acl/decline.
type ACLOwnershipRequest ¶
type ACLOwnershipRequest struct {
NewOwner string `json:"newOwner"`
OldOwnerPerm string `json:"oldOwnerPerm"`
}
ACLOwnershipRequest is the body of POST /v1/spaces/:spaceId/acl/ownership.
type ACLPermissionChange ¶
type ACLPermissionChange struct {
Identity string `json:"identity"`
Permission string `json:"permission"`
}
ACLPermissionChange is one entry in a ChangePermissions batch.
type ACLRemoveRequest ¶
type ACLRemoveRequest struct {
Identities []string `json:"identities"`
}
ACLRemoveRequest is the body of POST /v1/spaces/:spaceId/acl/remove.
type AccessCodeRequest ¶
type AccessCodeRequest struct {
// Code is the invite code as typed; compared upper-cased with
// whitespace removed.
Code string `json:"code"`
}
AccessCodeRequest is the body of POST /v1/account/access-code.
type AccessCodeResponse ¶
type AccessCodeResponse struct {
// Status is "accepted" (limits are being granted) or
// "already_redeemed" (this account redeemed a code before).
Status string `json:"status" enums:"accepted,already_redeemed"`
RedemptionId string `json:"redemptionId,omitempty"`
}
AccessCodeResponse relays the invite service's answer.
type AccountDiscoveryStatus ¶ added in v0.2.3
type AccountDiscoveryStatus struct {
Enabled bool `json:"enabled"`
// Relays are the configured pkarr relays, as hosts.
Relays []string `json:"relays"`
// Devices is how many sibling devices the record names.
Devices int `json:"devices"`
// OwnEntry — the record names this device with its current relay.
OwnEntry bool `json:"ownEntry"`
LastResolved *time.Time `json:"lastResolved,omitempty"`
LastPublished *time.Time `json:"lastPublished,omitempty"`
// LastError is the last failed cycle; empty after a good one.
LastError string `json:"lastError,omitempty"`
// ClockAheadMs is how far the relays' record was dated past this
// device's clock — a sibling whose clock runs ahead. Zero when it
// was not.
ClockAheadMs int64 `json:"clockAheadMs,omitempty"`
}
AccountDiscoveryStatus is the pkarr record through which this account's own devices find each other — including a device that holds nothing but the mnemonic. Disabled when no pkarr relay is configured; devices then know each other only through the records of the spaces they share.
type AccountMetadata ¶
type AccountMetadata struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
}
AccountMetadata mirrors space.AccountMetadata.
type AccountResponse ¶
type AccountResponse struct {
Id string `json:"id"`
Metadata *AccountMetadata `json:"metadata,omitempty"`
// TechSpaceId is the account's tech space — the :spaceId for
// account-level bundles (see docs/03-api.md § Bundles).
TechSpaceId string `json:"techSpaceId"`
}
AccountResponse is the body of GET /v1/account. Metadata is the locally-stored profile (read from tech-space); omitted when no profile has ever been written on this device. Symmetric with the PUT /v1/account/metadata write path — readback is deterministic, no coordinator round-trip, no 60-second watcher tick.
type AddDatasetFieldResponse ¶
type AddDatasetFieldResponse struct {
FieldDefId string `json:"fieldDefId"`
}
AddDatasetFieldResponse is the body returned by POST …/datasets/:defId/fields.
type AddDatasetResponse ¶
type AddDatasetResponse struct {
DatasetDefId string `json:"datasetDefId"`
// Collection is the computed collection name the new dataset's
// records live in.
Collection string `json:"collection"`
}
AddDatasetResponse is the body returned by POST …/parts/:partId/datasets.
type AddPartResponse ¶
type AddPartResponse struct {
PartId string `json:"partId"`
}
AddPartResponse is the body returned by POST …/types/:typeId/parts.
type AddPropertyRequest ¶
type AddPropertyRequest struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
// XKey is the property's handle — an alias, not a storage key
// (values live under the content-addressed propId). Unique within
// the type (409 property.xkey_conflict); mutable via PATCH.
XKey string `json:"xKey,omitempty"`
Kind string `json:"kind"`
// Meta holds the consumer flags the server interprets — today only
// meta["index"] = "<scope>" | "none" for the search indexer
// (docs/13-index.md). Any other key is rejected; descriptive
// metadata lives under xFormat.
Meta map[string]string `json:"meta,omitempty"`
// XFormat is the property's descriptor: everything descriptive
// beyond the kind — the semantic slug, icon, ordering key, option
// set, relation targets, per-format config (docs/27-descriptors.md).
// An object; the server validates the keys it interprets (type,
// icon, pos, options, relation, config, links) against the vocabulary and
// the slug against kind, stores vendor-namespaced keys verbatim,
// and reserves validate / compute. Every path under it is mutable
// via PATCH.
XFormat json.RawMessage `json:"xFormat,omitempty"`
// Scope is the property's write/sync class: "synced" (default,
// everyone in the space), "account" (this account's devices only),
// or "local" (this device only, never synced). "derived" is
// reserved for built-ins and rejected. Pinned by the first write,
// like kind — changing a property's scope means defining a new
// property. Property VALUE writes auto-route by the declared scope
// (POST /v1/spaces/:spaceId/properties/:objectId/set/:typeId).
Scope string `json:"scope,omitempty"`
}
AddPropertyRequest is the body of POST /v1/spaces/:spaceId/types/:typeId/properties. Kind is the wire string from PropertyKind* below and is required — nothing is defaulted from the descriptor. Items / Properties / Required from space.PropertyDraft are not exposed in v1.
type AddPropertyResponse ¶
type AddPropertyResponse struct {
PropId string `json:"propId"`
}
AddPropertyResponse is the body returned by AddProperty.
type AggregateResponse ¶
type AggregateResponse struct {
Records []json.RawMessage `json:"records,omitzero"`
Plan *string `json:"plan,omitempty"`
}
AggregateResponse is the body of POST /v1/spaces/:spaceId/aggregate and POST /v1/spaces/:spaceId/objects/aggregate — both use Agg.All (or Agg.Explain with explain=true) under the hood.
Records are pipeline RESULT documents, not dataset rows: a $group doc carries the group key as `id` (never `_id`), a $count doc is `{<name>: N}` with no id at all. Rendered the same way as QueryResponse records (anyenc → FastJson → RawMessage).
Plan replaces Records when the request set explain=true. It is the pushed prefix's access plan plus the in-pipeline stage list — diagnostic only, NOT a stable format; don't parse it. Records uses omitzero, not omitempty: the result path always sends a non-nil slice (so an empty result is `"records": []`, matching QueryResponse), while the explain path leaves it nil and the field disappears entirely.
type AuthAccount ¶
type AuthAccount struct {
// Id is the StrKey account address ("A…"). Empty for a default
// root wallet whose id can't be derived without a passkey.
Id string `json:"id,omitempty"`
// Default marks the legacy flat-layout wallet at the data-dir root.
Default bool `json:"default,omitempty"`
}
AuthAccount is one locally-available account in AuthStatusResponse.
type AuthCapabilities ¶
type AuthCapabilities struct {
Deauthorize bool `json:"deauthorize"`
// SwitchAccount: POST /v1/auth with replace:true switches accounts
// in place.
SwitchAccount bool `json:"switchAccount"`
// Shutdown: POST /v1/shutdown stops the server.
Shutdown bool `json:"shutdown"`
}
AuthCapabilities are the lifecycle operations this server accepts. Clients branch on these bits, never on the mode string, so a future mode does not break them.
type AuthRequest ¶
type AuthRequest struct {
// Mnemonic restores (or first-creates) the account derived from
// this BIP-39 phrase.
Mnemonic string `json:"mnemonic,omitempty"`
// AccountId selects an account that already has a local wallet
// (standalone only).
AccountId string `json:"accountId,omitempty"`
// Index is the account derivation index for Mnemonic. Omitted
// means 1, the `any` default; pass 0 explicitly to restore an
// anytype-derived (or pre-index-1 any) account.
Index *uint32 `json:"index,omitempty"`
// Replace switches a managed server from its current account to
// the one this request names, tearing the current engine down
// first. Without it a different account is refused. Never implied.
Replace bool `json:"replace,omitempty"`
}
AuthRequest is the POST /v1/auth body. Mnemonic and AccountId are mutually exclusive; with neither set a fresh account is generated.
type AuthResponse ¶
type AuthResponse struct {
AccountId string `json:"accountId"`
// Created is true when this account had no local state before this
// call (fresh generation or first restore on this device).
Created bool `json:"created"`
// Mnemonic is returned exactly once: when the server generated a
// fresh account (no mnemonic/accountId in the request). The caller
// must surface it to the user for backup.
Mnemonic string `json:"mnemonic,omitempty"`
// AlreadyAuthorized reports that the request named the account the
// server already runs: nothing was booted. With a mnemonic this
// confirms the phrase derives to the running account; with an
// accountId it confirms only that the id matches.
AlreadyAuthorized bool `json:"alreadyAuthorized,omitempty"`
}
AuthResponse is the POST /v1/auth reply.
type AuthStatusResponse ¶
type AuthStatusResponse struct {
Authorized bool `json:"authorized"`
AccountId string `json:"accountId,omitempty"`
// Mode is the server's ownership mode, fixed at launch.
Mode string `json:"mode" enums:"standalone,managed"`
// Capabilities lists which lifecycle operations this server
// accepts; every bit is false on a standalone server.
Capabilities AuthCapabilities `json:"capabilities"`
// Accounts are the wallets on disk (standalone only — a managed
// server holds no keys and reports an empty list; the client owns
// the account list there).
Accounts []AuthAccount `json:"accounts"`
}
AuthStatusResponse is the GET /v1/auth reply.
type BacklinksAllResponse ¶
type BacklinksAllResponse struct {
Spaces []SpaceBacklinks `json:"spaces"`
}
BacklinksAllResponse is the body of GET /v1/backlinks?target=… — the edges pointing at one target from every space this device indexes. Spaces without an edge are omitted; never null.
type BacklinksResponse ¶
type BacklinksResponse struct {
Object []Link `json:"object"`
Parts []Link `json:"parts"`
// Truncated reports that the read hit its cap (`limit`, max 500)
// before the split into Object / Parts; there is no continuation.
Truncated bool `json:"truncated,omitempty"`
}
BacklinksResponse is the body of GET /v1/spaces/:spaceId/objects/:objectId/backlinks. Object holds the edges pointing at the object itself; Parts the edges pointing at one of its records or property values (a block link stays a block link — the parent is not counted twice). When the read is narrowed to one part (`?record=` / `?prop=`), Object holds the edges to that part and Parts is empty. Neither is ever null.
type BlockCreateRequest ¶
type BlockCreateRequest struct {
Type string `json:"type"`
Style map[string]any `json:"style,omitempty"`
Text string `json:"text,omitempty"`
}
BlockCreateRequest is the body of POST .../blocks. `type` is required; everything else is optional with safe defaults.
If `nav.pos` is empty the server allocates the next lexid after the current max for `nav.parentId`. If `nav.parentId` is omitted the new block is top-level.
type BlockNav ¶
type BlockNav struct {
}
BlockNav is the per-record sibling-ordering namespace. parentId references another block's id; pos is a lexid that sorts siblings.
type BlockPatchRequest ¶
type BlockPatchRequest struct {
Set map[string]json.RawMessage `json:"set,omitempty" swaggertype:"object"`
Unset []string `json:"unset,omitempty"`
}
BlockPatchRequest is the body of PATCH .../blocks/:blockId.
- `set` maps a dotted field path to its new JSON value. Each entry becomes one $set op against that path. Empty/omitted == no $set ops.
- `unset` is a list of dotted field paths to $unset. Empty/omitted == no $unset ops.
Both lists may be supplied together; the handler emits them as one atomic record-modify (single DAG change). Empty patch is a no-op that still returns the record's current _ver.
type Bundle ¶
type Bundle struct {
// Id is the stable bundle identifier — the record id. Permanent:
// a successor install takes a new id (record deletes are refused,
// so a reused id could never be reclaimed).
Id string `json:"id"`
// Name is the display name, stamped as `any.name` on the root by
// whichever device installed it.
Name string `json:"name,omitempty"`
// RootId is the winning root object id. Setup objects are derived
// from it, so this one id names the whole install. Provisional
// until the space syncs.
RootId string `json:"rootId"`
// Roots is every root ever claimed for this bundle — the add-only
// audit trail. A resolved loser stays listed; its death is
// recorded by the deletion of its tree.
Roots []string `json:"roots,omitempty"`
// Losers is the live conflict set: claimed roots that are neither
// the winner nor already deleted. Non-empty means two devices
// installed concurrently — merge what matters out of each, then
// resolve it.
Losers []string `json:"losers,omitempty"`
// Derived reports that the winner is the root derived from the
// bundle id: the same id on every device, so this install cannot
// fork — and cannot be uninstalled, a derived object being
// undeletable. Absent means an ordinary created root.
Derived bool `json:"derived,omitempty"`
}
Bundle is one row of a space's bundles registry.
type BundleChildRequest ¶
type BundleChildRequest struct {
// Seed derives the child deterministically under the bundle's
// current winner. Permanent — a successor object takes a new seed.
Seed string `json:"seed"`
// Type is the child's one type, set on first materialization —
// required (400 request.missing_field), `page` for a plain
// document; Collections the child lacks are added on every call.
Type string `json:"type"`
Collections []string `json:"collections,omitempty"`
}
BundleChildRequest is the body of POST /v1/spaces/:spaceId/bundles/:bundleId/children.
type BundleChildResponse ¶
type BundleChildResponse struct {
ObjectId string `json:"objectId"`
}
BundleChildResponse carries the derived child's object id.
type BundleEnsureRequest ¶
type BundleEnsureRequest struct {
// Id is the bundle identifier. Required.
Id string `json:"id"`
// Name is the display name, written on install.
Name string `json:"name,omitempty"`
// RootType is the type of the root Ensure mints (its one type,
// `any.type`): required when the body declares nothing (every
// object has a type; `page` for a plain document), refused next to
// a declaration — a declaring root carries its marker there.
// RootCollections are the collections the root is filed under at
// birth (a `miniapp` root is an app root). Both ride the root's
// first change.
RootType string `json:"rootType,omitempty"`
RootCollections []string `json:"rootCollections,omitempty"`
// RootProperties seeds the root's property values, keyed
// owner → propId → value (same shape as POST /objects), written
// with the membership; an owner that is neither rootType nor the
// root's own declaration is added to rootCollections.
RootProperties map[string]map[string]any `json:"rootProperties,omitempty"`
// Derived installs the bundle on the root derived from its id
// rather than a created one. Every device computes that id
// offline, so the install never forks and never waits for the
// registry to converge — which is the only way both sides of a
// 1-1 (where nobody is the owner) can install while apart.
//
// Permanent in both directions: a derived root cannot be deleted,
// so the bundle can never be uninstalled, and an existing install
// on a created root is adopted rather than migrated. Ask for it
// for a space's chat; not for anything a user may remove.
Derived bool `json:"derived,omitempty"`
// Parts declares the root's parts with their datasets (same shape
// as POST …/types/:typeId/parts); the root becomes a type
// definition, typeId = rootId, and — a definition implements
// itself — the records are written through POST …/upsert /
// …/modify on the root (dataset = the computed collection,
// `<rootId>_<key>` for a namespaced one). Declared once on install;
// later evolution goes through the …/types/:rootId/parts routes.
// Parts or properties are required on the tech space. Refused with
// `collection`.
Parts []PartDraftRequest `json:"parts,omitempty"`
// Properties declares property definitions on the root (same shape
// as POST …/types/:typeId/properties, xKey REQUIRED and unique):
// the root becomes a type (or, with `collection`, a collection)
// objects use, and each property's id is derived from (rootId,
// xKey) so two devices installing while apart mint one column per
// handle. Resolve xKey → propId through GET …/types/:rootId/
// properties (or …/collections/:rootId/properties). Declared once
// on install (an adopt fills in only definitions the root lacks);
// later evolution goes through the …/properties routes.
Properties []AddPropertyRequest `json:"properties,omitempty"`
// XKey is the root definition's handle (same meaning as on POST
// …/types): what a client resolves it by, and what
// relation.targetTypes in other declarations name. Unique within
// the space among listed types and collections (409
// type.xkey_conflict). An xKey alone declares a MARKER — a type, or
// with `collection` a collection, with no properties and no parts.
// Written on install. A writer's adopt fills in a handle the root
// lacks (an install that predates it); an existing handle is never
// changed.
XKey string `json:"xKey,omitempty"`
// Layout seeds the root type's rendering slice (same shape as POST
// …/types; refused with `collection`); Hidden keeps the definition
// out of the default listings. Both are written on install only —
// an adopt never patches them. Hidden is explicit: a root that only
// hosts its bundle's records should ask for it (a listed type is
// one a client may set on other objects, granting them the bundle's
// collections); a root that is a definition other objects use stays
// listed.
Layout json.RawMessage `json:"layout,omitempty"`
Hidden bool `json:"hidden,omitempty"`
// Collection makes the declaration a COLLECTION instead of a type:
// the root carries `__collection__` in any.type, properties are its
// columns, and objects are filed under it through any.collections.
// Parts and layout are refused with it.
Collection bool `json:"collection,omitempty"`
}
BundleEnsureRequest is the body of POST /v1/spaces/:spaceId/bundles.
type BundleEnsureResponse ¶
type BundleEnsureResponse struct {
// Bundle is the converged registry row.
Bundle Bundle `json:"bundle"`
// Installed reports whether THIS call registered the install.
// False means an existing one was adopted — which for a derived
// bundle may still materialize the root's tree on this device,
// since that id is one every device can mint.
//
// For a derived install it reports what THIS DEVICE did: both
// sides of a partition can report true for the one root they
// share.
Installed bool `json:"installed"`
}
BundleEnsureResponse is the reply to an Ensure call.
type BundleGetResponse ¶
type BundleGetResponse struct {
Bundle Bundle `json:"bundle"`
// Synced: see BundleListResponse.Synced.
Synced bool `json:"synced"`
}
BundleGetResponse is the reply to GET /v1/spaces/:spaceId/bundles/:bundleId.
type BundleListResponse ¶
type BundleListResponse struct {
Bundles []Bundle `json:"bundles"`
// Synced reports whether the registry converged before this read
// (the read-side lock): true means an absent bundle is definitively
// not installed; false (the wait expired — cold offline device)
// means absence is provisional.
Synced bool `json:"synced"`
}
BundleListResponse is the reply to GET /v1/spaces/:spaceId/bundles.
type BundleResolveRequest ¶
type BundleResolveRequest struct {
// LoserRootId is the losing root to delete, cascading to its
// derived children. Call it only once whatever mattered has been
// merged out — the server never merges for you.
LoserRootId string `json:"loserRootId"`
}
BundleResolveRequest is the body of POST /v1/spaces/:spaceId/bundles/:bundleId/resolve.
type CRDTVersionState ¶
type CRDTVersionState struct {
Supported int `json:"supported"`
Stored int `json:"stored"`
Newer bool `json:"newer"`
}
CRDTVersionState mirrors the SDK's account CRDT-version state.
type CatalogBundle ¶
type CatalogBundle struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
// Derived installs the bundle on the root derived from its id —
// never forks, never deletable. The general chat only.
Derived bool `json:"derived,omitempty"`
// Hidden keeps the root's definition out of pickers; needs `type`,
// `collection` or `parts`.
Hidden bool `json:"hidden,omitempty"`
// RootType is the root's type when the bundle declares nothing (a
// bare app root): a registered type id, `page` for a plain
// document. Required then, refused next to a declaration.
RootType string `json:"rootType,omitempty"`
// Type declares the type the root defines; Collection the
// collection. Exclusive. A root hosting its own records (parts)
// needs no flag: a definition implements itself.
Type *CatalogType `json:"type,omitempty"`
Collection *CatalogCollection `json:"collection,omitempty"`
// Miniapp is a value map on the built-in `miniapp` collection the
// root is filed under: `bundle` is this bundle's id (filled when
// omitted), any other key must be a property the built-in declares.
Miniapp map[string]any `json:"miniapp,omitempty"`
// Parts declare records datasets on the root (the
// POST …/types/:typeId/parts draft shape).
Parts []PartDraftRequest `json:"parts,omitempty"`
// Supersedes names bundles of the same usecase this one stands in
// for. A space that has any of them installed keeps them and never
// receives this bundle; every other space receives this bundle and
// never the ones it names. A superseded bundle may share its xKey
// with the bundle that supersedes it — the two never meet in a space.
Supersedes []string `json:"supersedes,omitempty"`
// Superseded marks a bundle another one of the usecase supersedes:
// kept where a space already has it, never what a new space
// receives. Derived from the other bundles' `supersedes` — the
// listing reports it, a catalog source does not declare it.
Superseded bool `json:"superseded,omitempty"`
}
CatalogBundle is one bundle of a usecase: one created root under a `system:<name>/v<n>` id. What the root IS follows from what it declares — a type objects have (`type`), a collection objects are filed under (`collection`), the object a client opens (`miniapp`), records on the root (`parts`) — in any combination but type with collection, or collection with parts.
type CatalogCollection ¶
type CatalogCollection struct {
XKey string `json:"xKey"`
Properties []AddPropertyRequest `json:"properties,omitempty"`
// Meta is the definition's open bag of consumer flags (see
// CollectionsCreateRequest): one string, bool or number per
// single-level key, opaque to the server. Setup writes each key the
// installed definition lacks and never overwrites one it carries.
Meta map[string]any `json:"meta,omitempty"`
}
CatalogCollection is the collection a catalog bundle declares on its root: a handle and columns, no parts, no layout.
type CatalogListResponse ¶
type CatalogListResponse struct {
Usecases []CatalogUsecase `json:"usecases"`
}
CatalogListResponse is the body of GET /v1/catalog.
type CatalogSetupBundle ¶
type CatalogSetupBundle struct {
// Usecase is the entry the bundle belongs to (the requested one or
// a dependency).
Usecase string `json:"usecase"`
// Id is the bundle id.
Id string `json:"id"`
// Bundle is the converged registry row.
Bundle Bundle `json:"bundle"`
// Installed reports whether THIS call registered the root.
Installed bool `json:"installed"`
// TypeId is the root's id when the bundle declares a type — the
// namespace of its property values (`<typeId>.<propId>`).
TypeId string `json:"typeId,omitempty"`
// CollectionId is the root's id when the bundle declares a
// collection.
CollectionId string `json:"collectionId,omitempty"`
// Properties maps each declared property's xKey to its id.
Properties map[string]string `json:"properties,omitempty"`
// Miniapp is the value map the catalog declares on the built-in
// `miniapp` collection, `bundle` included — what an install writes and an
// adopt by a writer fills in where absent. Read the root for what it
// carries.
Miniapp map[string]any `json:"miniapp,omitempty"`
}
CatalogSetupBundle is one install a setup ensured.
type CatalogSetupRequest ¶
type CatalogSetupRequest struct {
SpaceId string `json:"spaceId"`
}
CatalogSetupRequest is the body of POST /v1/catalog/:usecaseId/setup.
type CatalogSetupResponse ¶
type CatalogSetupResponse struct {
// Usecase is the id that was asked for.
Usecase string `json:"usecase"`
// Bundles are the installs in setup order.
Bundles []CatalogSetupBundle `json:"bundles"`
}
CatalogSetupResponse is the reply to a setup: every bundle the call touched, dependencies first, the requested usecase's bundles last.
type CatalogType ¶
type CatalogType struct {
// XKey is the type's handle — what clients resolve it by and what
// relation.targetTypes name. Unique across the catalog, types and
// collections together.
XKey string `json:"xKey"`
// Layout is the rendering slug, `{type, config?}`.
Layout json.RawMessage `json:"layout,omitempty"`
// Properties are the columns (the POST …/types/:typeId/properties
// draft shape); each carries an xKey, the property id derives from
// it.
Properties []AddPropertyRequest `json:"properties,omitempty"`
}
CatalogType is the type a catalog bundle declares on its root.
type CatalogUsecase ¶
type CatalogUsecase struct {
// Id is the usecase slug — the `:usecaseId` path segment. Never
// enters a space.
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
// Requires lists the usecases set up before this one, transitively.
Requires []string `json:"requires,omitempty"`
// Bundles are the usecase's own installs, in setup order.
Bundles []CatalogBundle `json:"bundles"`
}
CatalogUsecase is one catalog entry as the catalog declares it.
type ChatAgentMeta ¶
type ChatAgentMeta struct {
Name string `json:"name"`
DebugLink string `json:"debugLink,omitempty"`
Done bool `json:"done"`
// Outcome says how the run behind a done:true message ended when
// it did not end normally — `interrupted` (the user stopped it),
// `error` (it died). Absent on a normal reply. Opaque to the
// server; clients key their rendering (a stop mark, a warning) on
// it instead of parsing the text.
Outcome string `json:"outcome,omitempty"`
}
ChatAgentMeta marks a message as agent-authored. `Name` is the display label; like the old fromAgent tag it is NOT verified against any identity / signature — `creator` stays the change signer. `DebugLink` is an opaque drill-down link into the run's debug page, by convention `any://<spaceId>/<debugLogObjectId>[#turn_<n>]`. `Done` is liveness: false means the run that produced this message is still going (clients show a typing indicator until a done:true message lands). The whole group is create-only and immutable.
type ChatAttachment ¶
ChatAttachment is one entry in a message's attachments map. `Type` is an open enum — known values are "link" and "image"; clients fall back to rendering `Link` as a plain anchor for unknown types. `Link` is the URL (any:// for in-space references, https:// or similar for out-of-space resources). Attachments are immutable post-create.
type ChatEditRequest ¶
type ChatEditRequest struct {
Text string `json:"text"`
}
ChatEditRequest is the body of PATCH .../messages/:msgId. Only `text` is editable post-creation — replyToMessageId is intentionally stable so thread structure doesn't shift. Edit by non-author returns 403 chat.not_author.
type ChatMessageContext ¶
type ChatMessageContext struct {
SpaceId string `json:"spaceId"`
ObjectId string `json:"objectId,omitempty"`
View string `json:"view,omitempty"`
}
ChatMessageContext is where the sender was when they sent the message — the page on screen, stamped by the client. `SpaceId` is the space in view (required), `ObjectId` the open object / collection / record when there is one, `View` the client's view kind (an open string: "object", "collection", "mail", …). Optional on send, create-only and immutable; an agent reading the chat takes "here"/"this page" from it. No timestamp: the message's createdAt is when the user was there.
type ChatMessageControl ¶
ChatMessageControl is a client's signal to the agent serving the chat, carried on a message of its own (text may be empty). `Kind` is an open string the agent interprets — `break` asks the run in flight to stop; `Hard` = now (vs. wrap up at the next turn). Create-only, immutable; a client renders it as a marker, not a bubble.
type ChatSendRequest ¶
type ChatSendRequest struct {
Text string `json:"text"`
ReplyToMessageId string `json:"replyToMessageId,omitempty"`
Agent *ChatAgentMeta `json:"agent,omitempty"`
Attachments map[string]ChatAttachment `json:"attachments,omitempty"`
Context *ChatMessageContext `json:"context,omitempty"`
Control *ChatMessageControl `json:"control,omitempty"`
}
ChatSendRequest is the body of POST /v1/spaces/:spaceId/objects/:objectId/messages. `text` is a markdown-formatted string; rendering is the client's problem. Server stamps creator, createdAt, modifiedAt.
`agent` is optional and marks the message as written by an agent acting on behalf of the signer (vs typed by the signer directly).
`attachments` is a map keyed by short opaque ids (≤ 64 chars, [A-Za-z0-9_-]+) carrying {type, link, order?}. Create-only.
`context` is the sender's view at send time (ChatMessageContext). Optional, create-only.
`control` is a signal to the agent (ChatMessageControl) — the one case where `text` may be empty. Optional, create-only.
type CollectionInfo ¶
type CollectionInfo struct {
Id string `json:"id"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
XKey string `json:"xKey,omitempty"`
BuiltIn bool `json:"builtIn,omitempty"`
Hidden bool `json:"hidden,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
CollectionInfo mirrors space.CollectionInfo on the wire. Registered collections report xKey = id, like registered types.
type CollectionPatchRequest ¶
type CollectionPatchRequest struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
IconCID *string `json:"iconCid,omitempty"`
Hidden *bool `json:"hidden,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
CollectionPatchRequest is the body of PATCH /v1/spaces/:spaceId/collections/:collectionId — the display and listing metadata, same rules as TypePatchRequest. At least one field is required.
type CollectionsCreateRequest ¶
type CollectionsCreateRequest struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
XKey string `json:"xKey,omitempty"`
Hidden bool `json:"hidden,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
CollectionsCreateRequest is the body of POST /v1/spaces/:spaceId/collections. A collection is a type without parts or layout: a column group objects are filed under (`any.collections`) next to their one type. Mirrors space.CollectionCreateParams; xKey, hidden and meta follow the type rules (TypesCreateRequest).
type CollectionsCreateResponse ¶
type CollectionsCreateResponse struct {
CollectionId string `json:"collectionId"`
}
CollectionsCreateResponse is the body returned by POST /v1/spaces/:spaceId/collections.
type CollectionsListResponse ¶
type CollectionsListResponse struct {
Collections []CollectionInfo `json:"collections"`
}
CollectionsListResponse is the body of GET /v1/spaces/:spaceId/collections.
type DatasetDefResponse ¶
type DatasetDefResponse struct {
Id string `json:"id"`
// Key is the slug inside the type; collection is the name reads and
// writes address (`dataset` on /query, /modify, /upsert …) — the
// module's canonical collection when shared, `<typeId>_<key>`
// otherwise. Server-computed, never client-set.
Key string `json:"key"`
Collection string `json:"collection"`
Module string `json:"module"`
// PartId is the owning part's id.
PartId string `json:"partId"`
DisplayName string `json:"displayName,omitempty"`
Description string `json:"description,omitempty"`
Dynamic bool `json:"dynamic,omitempty"`
IdRule string `json:"idRule"`
IdPattern string `json:"idPattern,omitempty"`
IdMaxLen int `json:"idMaxLen,omitempty"`
DeleteBy string `json:"deleteBy"`
SkipHistory bool `json:"skipHistory,omitempty"`
Search *DatasetSearchFields `json:"search,omitempty"`
Fields []DatasetFieldDef `json:"fields"`
// Invalid marks a definition whose folded declaration fails
// validation (invalidReason says why) — a records fold missing a
// creator stamp behind an author rule, an unknown module, a shared
// rule violation. Invalid definitions never register or accept data
// but stay listed so they can be repaired or removed.
Invalid bool `json:"invalid,omitempty"`
InvalidReason string `json:"invalidReason,omitempty"`
}
DatasetDefResponse mirrors space.DatasetDef — the compiled view of one dataset definition.
type DatasetDraftRequest ¶
type DatasetDraftRequest struct {
// Key is the dataset's slug inside its type ([a-z][a-z0-9_]*, ≤ 64)
// — pinned. A namespaced dataset lives in the collection
// `<typeId>_<key>`; a shared dataset's key is its module's canonical
// collection name and may be omitted.
Key string `json:"key,omitempty"`
// Module is the serving module: "records" (the default) or
// "editor". "chat" is reserved to the server (400
// dataset.module_reserved) — the catalog's general-chat usecase is
// its one declaration.
Module string `json:"module,omitempty"`
// Shared makes the type participate in the module's canonical
// collection (editor_blocks) instead of a namespaced one, so two
// types sharing the editor give an object carrying both a single
// body. Editor: either; records: never.
DisplayName string `json:"displayName,omitempty"`
Description string `json:"description,omitempty"`
// Dynamic keeps a free-form keyspace next to the declared fields.
Dynamic bool `json:"dynamic,omitempty"`
// IdRule: "auto" (default — ids derived from the change) or "user"
// (caller-supplied ids, constrained by idPattern/idMaxLen; the id
// doubles as the upsert idempotency key).
IdRule string `json:"idRule,omitempty"`
IdPattern string `json:"idPattern,omitempty"`
IdMaxLen int `json:"idMaxLen,omitempty"`
// DeleteBy: "anyone" (default) or "author" (requires a
// stamp:creator field among fields).
DeleteBy string `json:"deleteBy,omitempty"`
// SkipHistory keeps the dataset out of the version-history index.
SkipHistory bool `json:"skipHistory,omitempty"`
// Search is the optional search-extraction annotation (x-search):
// which record fields feed the search index's title/text, and
// optionally which index scope the entries land under.
Search *DatasetSearchFields `json:"search,omitempty"`
// Fields are the initial field definitions (records datasets only —
// a module owns its schema). Declare required fields here — fields
// added later cannot be required.
Fields []DatasetFieldDraft `json:"fields,omitempty"`
}
DatasetDraftRequest is one dataset declaration — an element of PartDraftRequest.Datasets or the body of POST /v1/spaces/:spaceId/types/:typeId/parts/:partId/datasets. Mirrors space.DatasetDraft. The behavioral parts (key, module, shared, idRule/idPattern/idMaxLen, deleteBy, skipHistory, field kinds/flags) are pinned for the definition's life — remove and re-add to change them; display parts (displayName, description, search leaves) patch via PATCH …/datasets/:defId.
type DatasetFieldDef ¶
type DatasetFieldDef struct {
// Id is the field definition record's id — the identity
// PATCH / DELETE …/fields/:fieldId target.
Id string `json:"id"`
Key string `json:"key"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Kind string `json:"kind"`
// Shape is the full declared value shape (kind plus items /
// properties) when one was declared beyond the bare kind.
Shape *DatasetFieldShape `json:"shape,omitempty"`
Scope string `json:"scope"`
Required bool `json:"required,omitempty"`
MutableBy string `json:"mutableBy"`
Stamp string `json:"stamp,omitempty"`
// XFormat is the field's descriptor as stored; absent when none was
// declared.
XFormat json.RawMessage `json:"xFormat,omitempty"`
}
DatasetFieldDef mirrors space.DatasetFieldDef.
type DatasetFieldDraft ¶
type DatasetFieldDraft struct {
// Key is the on-record field name — pinned.
Key string `json:"key"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
// Kind is a PropertyKind* wire string. Required unless stamp
// implies one (creator ⇒ string, createTime/modifyTime ⇒ datetime).
Kind string `json:"kind,omitempty"`
// Shape optionally refines array/object values.
Shape *DatasetFieldShape `json:"shape,omitempty"`
// Scope: "synced" (default) or "local"; "derived" is implied by
// stamp and rejected otherwise.
Scope string `json:"scope,omitempty"`
// Required: field must be present on create. Incompatible with stamp.
Required bool `json:"required,omitempty"`
// MutableBy: "never" (default — write-once), "author", "any".
// "author" requires a stamp:creator field in the dataset.
MutableBy string `json:"mutableBy,omitempty"`
// Stamp: "creator" | "createTime" | "modifyTime" — value derived at
// apply time, client writes rejected.
Stamp string `json:"stamp,omitempty"`
// XFormat is the field's descriptor — the same object a property
// definition carries (AddPropertyRequest.XFormat), validated the
// same way against the field's kind. Mutable via
// PATCH …/fields/:fieldId.
XFormat json.RawMessage `json:"xFormat,omitempty"`
}
DatasetFieldDraft is one field declaration — input to a records dataset draft and POST …/datasets/:defId/fields. Mirrors space.DatasetFieldDraft.
type DatasetFieldPatchRequest ¶
type DatasetFieldPatchRequest struct {
Set map[string]json.RawMessage `json:"set,omitempty" swaggertype:"object"`
Unset []string `json:"unset,omitempty"`
}
DatasetFieldPatchRequest is the body of PATCH /v1/spaces/:spaceId/types/:typeId/datasets/:defId/fields/:fieldId — a per-path patch over one field definition's mutable leaves (space.TypesAPI.PatchDatasetField): name, description (strings) and every path under xFormat (the property PATCH rules — a set targets a leaf, a container can only be unset). The behavioral declaration (key, kind, shape, scope, required, mutableBy, stamp) is pinned and rejected with 400 dataset.immutable. At least one entry across Set/Unset required.
type DatasetFieldShape ¶
type DatasetFieldShape struct {
Kind string `json:"kind"`
Items *DatasetFieldShape `json:"items,omitempty"`
Properties map[string]*DatasetFieldShape `json:"properties,omitempty"`
}
DatasetFieldShape is a recursive JSON-Schema-subset value shape (handler.FieldShape on the wire): a kind plus optional items / properties refinement.
type DatasetPatchRequest ¶
type DatasetPatchRequest struct {
Set map[string]json.RawMessage `json:"set,omitempty" swaggertype:"object"`
Unset []string `json:"unset,omitempty"`
}
DatasetPatchRequest is the body of PATCH /v1/spaces/:spaceId/types/:typeId/datasets/:defId — a per-path patch over a dataset definition's mutable leaves (space.DatasetDefPatch).
Mutable paths: description, displayName, search.title, search.text, search.scope (string leaves; a whole `search` replace is pinned). Everything else — the key, module, shared flag, id rule, delete gate, field kinds/flags — is pinned and rejected with 400 dataset.immutable. At least one entry across Set/Unset required.
type DatasetSchema ¶
type DatasetSchema struct {
Name string `json:"name"`
Schema json.RawMessage `json:"schema"`
// Owners are the types that declare the dataset: one for a
// registered-type or namespaced dataset, every type sharing the
// module for a canonical collection (empty while nothing declares
// it), none for space-level built-ins. Records exist only on objects
// carrying one of them; consumers gate indexing/eviction on it.
Owners []string `json:"owners,omitempty"`
// Module is the serving module ("records", "editor", "chat"; empty
// for built-ins and registered-type datasets); Shared marks a
// module's canonical collection.
Module string `json:"module,omitempty"`
}
DatasetSchema is the wire shape for space.DatasetSchema — one dataset's field declaration rendered as a standard JSON Schema document. Schema is carried as RawMessage so the JSON Schema (which the SDK already marshals) isn't double-encoded into a string.
The JSON Schema object looks like:
{"type":"object",
"properties":{"<field>":{"type":"string","title":"…","x-scope":"synced"}},
"additionalProperties":<dynamic>}
The `x-scope` extension keyword on each property carries the field's class: "synced" (user/DAG-written, synced across devices), "derived" (handler-computed, read-only to writers), or "local" (device-local, never synced). `additionalProperties:true` marks a dynamic dataset whose undeclared keys are permitted and treated as synced.
Datasets with behavioral schema declarations (runtime-defined ones, and built-ins that declare them) carry further extension keywords: per-field `x-mutable-by` ("author"/"any"; absent = write-once) and `x-stamp` ("creator"/"createTime"/"modifyTime" — derived at apply, client writes rejected); doc-level standard `required`, `x-delete-by` ("author"; absent = anyone), `x-id` ("user" with `x-id-pattern` / `x-id-max-length`; absent = auto-derived ids), and `x-search` ({title, text, scope} — the record fields feeding the search index and the index scope its entries land under; scope absent = "basic").
type DatasetSearchFields ¶
type DatasetSearchFields struct {
Title string `json:"title,omitempty"`
// Text accepts a bare field-key string OR a non-empty array of
// unique field keys; a single key always reads back as the bare
// string. The generated schema can only show the array form — the
// string form is equally valid on the wire.
Text SearchText `json:"text,omitempty"`
Scope string `json:"scope,omitempty"`
}
DatasetSearchFields mirrors space.SearchFields — the x-search mapping. Title/text may be empty (either alone suffices). Scope is the index scope slug the dataset's entries land under (index. ValidScope); empty = the indexer's default scope ("basic").
type DatasetsResponse ¶
type DatasetsResponse struct {
Datasets []DatasetSchema `json:"datasets"`
}
DatasetsResponse is the body of GET /v1/spaces/:spaceId/datasets and GET /v1/datasets — the JSON-Schema description of every dataset the space (or the account's tech-space system objects) hosts, for consumer discovery.
type DeleteRecordsRequest ¶
type DeleteRecordsRequest struct {
ObjectId string `json:"objectId"`
Dataset string `json:"dataset,omitempty"`
RecordIds []string `json:"recordIds"`
TraceIds []string `json:"traceIds,omitempty"`
}
DeleteRecordsRequest documents the body of POST /v1/spaces/:spaceId/delete-records.
type DerivedSpaceInfo ¶
type DerivedSpaceInfo struct {
Name string `json:"name"`
SpaceId string `json:"spaceId"`
Created bool `json:"created"`
Status string `json:"status,omitempty"`
}
DerivedSpaceInfo is one row of GET /v1/spaces/derived — a registry entry resolved against the account: the deterministic spaceId the entry derives to, and whether a usable space row exists (materialized here or on any of the account's devices). Resolving ids never creates anything; materialize with POST /v1/spaces/derived/:name. Status is the raw row status when a row exists (omitted otherwise); a "deleted" row — wedged before the permanence guard existed — reports created=false and refuses materialization.
type DerivedSpaceListResponse ¶
type DerivedSpaceListResponse struct {
Spaces []DerivedSpaceInfo `json:"spaces"`
}
DerivedSpaceListResponse is the body of GET /v1/spaces/derived.
type DeviceActivateRequest ¶
type DeviceActivateRequest struct {
App string `json:"app"`
}
DeviceActivateRequest is the body of POST /v1/devices/activate — claim the active role for one app slug on THIS device.
type DeviceActiveClaim ¶
DeviceActiveClaim is one device's claim to be the active instance of one app slug. Seq is a writer-supplied monotonic counter (claim = max of all visible seqs + 1); At is the claim's unix-seconds timestamp. Deliberately NOT a CRDT version id: versionIds are peer-locally allocated, so they cannot arbitrate across devices — the claim data itself is what every reader resolves on.
type DeviceInfo ¶
type DeviceInfo struct {
PeerId string `json:"peerId"`
Name string `json:"name,omitempty"`
OS string `json:"os,omitempty"`
Version string `json:"version,omitempty"`
Apps map[string]map[string]any `json:"apps,omitempty"`
ActiveClaims map[string]DeviceActiveClaim `json:"activeClaims,omitempty"`
}
DeviceInfo is the wire shape of one row in the account's tech-space `devices` dataset: one row per device (peer), row id = peerId. The registry is member-replicated across the account's devices; each device upserts its own row (name/os/version stamped server-side on boot and via PUT /v1/devices/me).
Apps is an open slug set (same convention as index scopes and UI command actions): presence of a slug means "installed on this device"; the per-slug object carries free-form app metadata (conventionally a `version` string). Nothing app-specific is baked into the server.
ActiveClaims carries this device's per-app claim to be the app's active instance. Winners are resolved reader-side — see DevicesListResponse.Active and docs/23-devices.md § Election.
type DeviceUpdateRequest ¶
type DeviceUpdateRequest struct {
Name string `json:"name,omitempty"`
Apps map[string]map[string]any `json:"apps,omitempty"`
}
DeviceUpdateRequest is the body of PUT /v1/devices/me — the restricted self-row upsert. peerId / os / version are stamped server-side and cannot be supplied; the body carries only the caller-owned fields, and only present fields are written (empty name = leave as-is). Apps entries merge per slug; an explicit null value uninstalls that slug (`{"apps": {"bao": null}}`).
type DevicesListResponse ¶
type DevicesListResponse struct {
Devices []DeviceInfo `json:"devices"`
Active map[string]string `json:"active,omitempty"`
Self string `json:"self"`
}
DevicesListResponse is the body of GET /v1/devices.
Active maps app slug → the peerId of that app's active device, resolved server-side by the canonical election rule (highest claim Seq, tiebreak highest At, final tiebreak lexicographically-largest peerId, candidates limited to devices whose row still carries the app slug). Both the UI and agent runtimes MUST consume this field rather than reimplementing the rule — one implementation, no divergent winners. A slug is absent when no installed device has claimed it.
Self is THIS server's own peerId — how a consumer (UI, agent runtime) tells whether it is the active device without a separate identity call.
type ErrorEnvelope ¶
type ErrorEnvelope struct {
Error APIError `json:"error"`
}
type Event ¶
type Event struct {
Type string `json:"type"`
Scope string `json:"scope"`
SpaceId string `json:"spaceId,omitempty"`
Target string `json:"target,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
Sender *EventSender `json:"sender,omitempty"`
}
Event is one envelope on the account-wide ephemeral event bus (POST /v1/events → GET /v1/events/subscribe). At-most-once: nothing is stored, there is no replay, a subscriber only sees events published after it connects. See docs/21-events.md.
Type is an open dotted slug set (e.g. "process.progress", "ui.open_space") — new kinds need no server change. Scope routes delivery: EventScopeDevice fans out in-process only; account and space ride the SDK's pub/sub to the account's devices / the space's members. SpaceId is required iff Scope == EventScopeSpace. Target optionally narrows the subject (objectId, runId, processId, …) and is filterable on subscribe. Data is the free-form payload.
Sender is server-stamped, never client-supplied: Identity is the publishing account (signature-verified for network scopes), Self is true when the event came from this account (any of its devices).
A sessionId field is reserved for a future per-connection identity; not implemented.
type EventLinksUpdatedData ¶
type EventLinksUpdatedData struct {
SpaceId string `json:"spaceId"`
Targets []string `json:"targets"`
Truncated bool `json:"truncated,omitempty"`
}
EventLinksUpdatedData is the payload of EventLinksUpdated: the canonical targets (object references, or the identity / file URI) whose backlinks changed in spaceId. Targets is capped at MaxEventLinksTargets; Truncated says more changed than listed — a panel showing an unlisted target re-reads too.
type EventPublishRequest ¶
type EventPublishRequest struct {
Type string `json:"type"`
Scope string `json:"scope"`
SpaceId string `json:"spaceId,omitempty"`
Target string `json:"target,omitempty"`
// Data is free-form: any JSON value, capped at 64 KiB marshaled.
// The generated schema can only show the object form — a scalar or
// an array is equally valid on the wire.
Data json.RawMessage `json:"data,omitempty"`
}
EventPublishRequest is the body of POST /v1/events — Event minus the server-stamped sender. Strict-bound: unknown top-level keys (including "sender") answer 400 request.unknown_field.
type EventPublishResponse ¶
type EventPublishResponse struct {
Subscribers int `json:"subscribers"`
}
EventPublishResponse is the body of POST /v1/events. Subscribers is how many local subscribers matched the event (0 = nobody listening). A valid publish always succeeds — the bus is fire-and-forget.
type EventSender ¶
EventSender identifies the publisher of an Event. Stamped by the server; a sender field inside a publish body is rejected.
type FileCacheFreeRequest ¶
type FileCacheFreeRequest struct {
Bytes int64 `json:"bytes"`
}
FileCacheFreeRequest is the body of POST /v1/files/cache/free.
type FileCacheFreeResult ¶
type FileCacheFreeResult struct {
Freed int64 `json:"freed"`
}
FileCacheFreeResult reports the bytes actually reclaimed — less than requested when nothing else is safely evictable.
type FileCacheInfo ¶
type FileCacheInfo struct {
Size int64 `json:"size"`
}
FileCacheInfo is the body of GET /v1/files/cache — local bytes held by file content across all spaces (complete + partial copies).
type FileInfo ¶
type FileInfo struct {
FileId string `json:"fileId"`
ObjectId string `json:"objectId"`
// RootCid is the content address of the encrypted file. Empty for
// inline-tier files (bytes ride the CRDT row itself).
RootCid string `json:"rootCid,omitempty"`
// Size is the plaintext byte size.
Size int64 `json:"size"`
// Inline reports the inline tier (no rootCid, no backup needed).
Inline bool `json:"inline"`
// Durable reports a verified network-custody receipt (inline files
// are durable by construction). False right after attach is normal:
// backup runs in the background — watch /files/subscribe or re-GET.
Durable bool `json:"durable"`
// Cached reports a complete local copy (always true for inline).
Cached bool `json:"cached"`
Name string `json:"name,omitempty"`
Mime string `json:"mime,omitempty"`
Variant string `json:"variant,omitempty"`
VariantOf string `json:"variantOf,omitempty"`
}
FileInfo describes one attached file — the unsealed member view. Name / Mime / Variant / VariantOf come from the sealed (member-only) part of the payloads row and are empty for a keyless reader.
type FileListResponse ¶
type FileListResponse struct {
Files []FileInfo `json:"files"`
}
FileListResponse is the body of GET /v1/spaces/:spaceId/files.
type FileStats ¶
type FileStats struct {
Total int `json:"total"`
Durable int `json:"durable"`
InFlight int `json:"inflight"`
Limited int `json:"limited"`
}
FileStats are the space's aggregate durability counts (GET /v1/spaces/:spaceId/files/stats).
type FileStatus ¶
type FileStatus struct {
FileId string `json:"fileId"`
ObjectId string `json:"objectId"`
State string `json:"state"`
Cached bool `json:"cached"`
// Attempts counts failed background attempts since the last
// success/enqueue; 0 when no work is pending.
Attempts int `json:"attempts,omitempty"`
LastErr string `json:"lastErr,omitempty"`
}
FileStatus is the point-in-time durability + availability view of one file. Also the payload of the per-space `status` SSE frames on GET /v1/spaces/:spaceId/files/subscribe.
type GlobalP2PStatus ¶ added in v0.2.3
type GlobalP2PStatus struct {
Enabled bool `json:"enabled"`
// EndpointId is this device's iroh endpoint id (its device key).
EndpointId string `json:"endpointId"`
// Ticket is what this device publishes for others to dial; empty
// until the relay session is up. Relay-only by construction — it
// never carries this device's IP addresses.
Ticket string `json:"ticket,omitempty"`
// HomeRelay is the relay URL inside Ticket.
HomeRelay string `json:"homeRelay,omitempty"`
// RelayConnected — the session to the home relay is up. Until it
// is, this device can dial out but cannot be reached.
RelayConnected bool `json:"relayConnected"`
// Peers are the peers known through records, connected or not —
// except any in the disabled tier, which the SDK drops from this
// list. A device silent for 30 days is therefore absent here, not
// listed as disabled.
Peers []P2PPeerStatus `json:"peers"`
// Account is the account-level discovery record (pkarr).
Account AccountDiscoveryStatus `json:"account"`
}
GlobalP2PStatus is the internet-wide layer: this device's iroh endpoint, its relay session, and every peer known through records.
type HealthResponse ¶
type HealthResponse struct {
Status string `json:"status"`
Version string `json:"version"`
StartedAt time.Time `json:"startedAt"`
// NetworkId is the any-sync network this server joins: the networkId
// of the nodeconf it started with. Set whether or not an account is
// authorized. The server names no networks; clients map well-known
// ids to names themselves.
NetworkId string `json:"networkId"`
Account string `json:"account"`
// Bootstrapping is true while the booted SDK's background boot pass
// (eager space loading + offline catch-up) is still running. The
// server serves throughout; per-space convergence is /sync-status.
// False when unauthorized and after the pass completes.
Bootstrapping bool `json:"bootstrapping"`
// CRDTVersion is the account's CRDT data-model version state
// (absent when unauthorized): the version this server's SDK
// supports, the one recorded on the account's tech space, and
// `newer` — true when the recorded one is above the supported one,
// which makes the account read-only until the server is upgraded
// (every synced write answers 409 sdk.crdt_version_newer).
CRDTVersion *CRDTVersionState `json:"crdtVersion,omitempty"`
}
type HistoryChange ¶
type HistoryChange struct {
Version string `json:"version"`
Author string `json:"author"`
Timestamp int64 `json:"timestamp"` // author clock, Unix seconds — display-only
Dataset string `json:"dataset"`
TraceIds []string `json:"traceIds,omitempty"`
Touched []HistoryTouchedRecord `json:"touched,omitempty"`
// Truncated is RESERVED (always false today): the SDK keeps full
// history locally. It becomes meaningful with the future
// snapshot-horizon contract.
Truncated bool `json:"truncated,omitempty"`
GroupSize int `json:"groupSize"`
}
HistoryChange is one listed change, or one coalesced group of consecutive same-author changes (groupSize > 1) whose handle is the group's newest ChangeId.
type HistoryDatasetDiff ¶
type HistoryDatasetDiff struct {
Dataset string `json:"dataset"`
Records []HistoryRecordDiff `json:"records"`
}
HistoryDatasetDiff groups record diffs of one dataset.
type HistoryDiffResponse ¶
type HistoryDiffResponse struct {
Base string `json:"base,omitempty"`
Version string `json:"version"`
Datasets []HistoryDatasetDiff `json:"datasets"`
}
HistoryDiffResponse is GET .../history/diff. Base is empty for a per-change effect diff (version diffed against its DAG parents).
type HistoryFieldDiff ¶
type HistoryFieldDiff struct {
Path []string `json:"path"`
// Before / After are leaf values — usually a string, number or
// boolean. The generated schema can only show the object form.
Before json.RawMessage `json:"before,omitempty"`
After json.RawMessage `json:"after,omitempty"`
}
HistoryFieldDiff is one leaf-level field difference; absent side is omitted. Peer-local bookkeeping (_ver etc.) never appears.
type HistoryListResponse ¶
type HistoryListResponse struct {
Changes []HistoryChange `json:"changes"`
// Cursor resumes the next page; empty = history exhausted.
Cursor string `json:"cursor,omitempty"`
}
HistoryListResponse is one page of GET /spaces/{spaceId}/objects/{objectId}/history.
type HistoryRecordDiff ¶
type HistoryRecordDiff struct {
Id string `json:"id"`
Kind string `json:"kind"`
Fields []HistoryFieldDiff `json:"fields,omitempty"`
}
HistoryRecordDiff is one record's difference. Kind is one of "added", "removed", "changed", "deleted".
type HistoryRecordResponse ¶
type HistoryRecordResponse struct {
Version string `json:"version"`
Dataset string `json:"dataset"`
RecordId string `json:"recordId"`
Exists bool `json:"exists"`
Deleted bool `json:"deleted,omitempty"`
Record json.RawMessage `json:"record,omitempty"`
}
HistoryRecordResponse is GET .../history/{version}/datasets/ {dataset}/records/{recordId}: one record at a version. Exists=false when the record was not present at that cut; Deleted=true when it was tombstoned (Record then carries the tombstone row).
type HistoryTouchedRecord ¶
type HistoryTouchedRecord struct {
Dataset string `json:"dataset"`
RecordId string `json:"recordId"`
Ops []string `json:"ops,omitempty"`
}
HistoryTouchedRecord names one record a change touched with its op kinds (e.g. "$set", "delete").
type HistoryViewDataset ¶
type HistoryViewDataset struct {
Dataset string `json:"dataset"`
Records []json.RawMessage `json:"records"`
}
HistoryViewDataset is one dataset's records at a version. Records are raw dataset rows (same shape as /query results).
type HistoryViewResponse ¶
type HistoryViewResponse struct {
Version string `json:"version"`
Datasets []HistoryViewDataset `json:"datasets"`
}
HistoryViewResponse is GET /spaces/{spaceId}/objects/{objectId}/history/{version}: the object's live records as of that version, grouped by dataset. Synced scope only — local/account values have no history and are excluded.
type IdentitiesListResponse ¶
type IdentitiesListResponse struct {
Identities []IdentityInfo `json:"identities"`
}
IdentitiesListResponse is the body of GET /v1/identities.
type IdentityEventPayload ¶
type IdentityEventPayload struct {
Added []IdentityInfo `json:"added,omitempty"`
Updated []IdentityInfo `json:"updated,omitempty"`
Removed []string `json:"removed,omitempty"`
}
IdentityEventPayload is the data payload of an `event: identities` frame on the identities subscribe SSE stream — one frame per directory change batch, mirroring space.IdentityListEvent. Added/Updated carry the post-event row; Removed carries the identity strings that left the directory.
type IdentityInfo ¶
type IdentityInfo struct {
Identity string `json:"identity"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
SpaceIds []string `json:"spaceIds"`
}
IdentityInfo is the wire shape of space.IdentityInfo — one row in the account-global identities directory: every account identity this account has encountered (across spaces, 1-1s, inbox invites). It is a device-local, persistent cache.
Name / Description / IconCID are the last identityRepo profile resolved for this identity and are OMITTED until resolved: profiles are encrypted, so a known identity surfaces id-only until its decryption key arrives (via a shared space's ACL or a 1-1 invite) and the background fetch completes. Clients must tolerate an empty name.
SpaceIds is the set of spaces where this identity is currently seen (pruned when we leave/offload a space). The directory carries NO per-space rights — roles (owner/admin/writer/reader) live on the members list (GET /v1/spaces/:id/members), which is the authoritative per-space roster.
type InviteCreateResponse ¶
type InviteCreateResponse struct {
SpaceId string `json:"spaceId"`
InviteToken string `json:"inviteToken"`
}
InviteCreateResponse is the body returned by POST /v1/spaces/:spaceId/invites. `inviteToken` is the share-friendly base58 token (space.EncodeInvite) — the only piece a joiner needs to call POST /v1/spaces/join.
type InviteInfo ¶
type InviteInfo struct {
RecordId string `json:"recordId"`
// Permission is "none" for the request-to-join invites v1 mints —
// the role is chosen at accept time, not carried by the invite.
Permission string `json:"permission"`
// InviteToken is the same share token POST /invites returned at
// mint time, recovered from the minting account's synced custody.
// Present only on that account's devices — other members (any
// role) never held the private key and get no token. Also omitted
// for invites minted before custody shipped (regenerate once to
// make the token durable) and for custody gone stale (invite
// replaced or revoked on another device).
InviteToken string `json:"inviteToken,omitempty"`
}
InviteInfo mirrors space.InviteInfo. RecordId is what the DELETE /v1/spaces/:spaceId/invites/:recordId path expects.
type InvitesListResponse ¶
type InvitesListResponse struct {
Invites []InviteInfo `json:"invites"`
}
InvitesListResponse is the body of GET /v1/spaces/:spaceId/invites.
type JoinRequest ¶
type JoinRequest struct {
RecordId string `json:"recordId"`
Identity string `json:"identity"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
}
JoinRequest mirrors space.JoinRequestInfo.
type JoinRequestsResponse ¶
type JoinRequestsResponse struct {
Requests []JoinRequest `json:"requests"`
}
JoinRequestsResponse is the body of GET /v1/spaces/:spaceId/members/requests.
type Link ¶
type Link struct {
Source LinkSource `json:"source"`
Kind string `json:"kind"`
Target LinkTarget `json:"target"`
}
Link is one edge. Kind is the edge kind: mention, link, card, embed, relation (an open set — see docs/13-index.md § Links).
type LinkSource ¶
type LinkSource struct {
SpaceId string `json:"spaceId"`
ObjectId string `json:"objectId"`
Dataset string `json:"dataset"`
RecordId string `json:"recordId"`
// TypeId is the type declaring a property value's source (`prop`
// edges only): the value lives at record[typeId][recordId].
TypeId string `json:"typeId,omitempty"`
// Field is the record field the reference was read from, for a
// runtime record with link-bearing fields; absent for a block or
// message text and for a property value.
Field string `json:"field,omitempty"`
}
LinkSource is where an edge was found: the object, the collection (a module or runtime collection, or the virtual `prop` for a property value) and the record (the property id under `prop`).
type LinkTarget ¶
type LinkTarget struct {
Uri string `json:"uri"`
Kind string `json:"kind"`
SpaceId string `json:"spaceId"`
ObjectId string `json:"objectId,omitempty"`
Dataset string `json:"dataset,omitempty"`
RecordId string `json:"recordId,omitempty"`
PropId string `json:"propId,omitempty"`
Identity string `json:"identity,omitempty"`
FileId string `json:"fileId,omitempty"`
}
LinkTarget is the canonical any:// target, parsed. Uri is the canonical string (docs/19-links.md); Kind is the URI kind (o, p, m, f); the id fields are populated per kind.
type LinksResponse ¶
type LinksResponse struct {
Links []Link `json:"links"`
// Truncated reports that the read hit its cap.
Truncated bool `json:"truncated,omitempty"`
}
LinksResponse is the body of GET /v1/spaces/:spaceId/objects/:objectId/links — the edges whose source is the object (or the one record / property it was narrowed to). Never null.
type LocalAggregateRequest ¶
type LocalAggregateRequest struct {
Coll LocalCollection `json:"coll"`
Pipeline []map[string]any `json:"pipeline"`
GroupLimit *int `json:"groupLimit,omitempty"`
AccumArrayLimit *int `json:"accumArrayLimit,omitempty"`
MemoryLimitBytes *int `json:"memoryLimitBytes,omitempty"`
Explain bool `json:"explain,omitempty"`
}
LocalAggregateRequest is the body of POST /v1/local/aggregate. The stage vocabulary is GET /v1/local/meta's `stages`. $out / $merge / $lookup name collections by StorageName and must name LOCAL ones (400 local.bad_sink_target otherwise); a sink pipeline answers `written` instead of `records`.
type LocalAggregateResponse ¶
type LocalAggregateResponse struct {
Records []json.RawMessage `json:"records,omitzero"`
Plan *string `json:"plan,omitempty"`
Written *int `json:"written,omitempty"`
}
LocalAggregateResponse is the body of POST /v1/local/aggregate: exactly one of Records (result docs), Plan (explain=true) or Written (a $out / $merge pipeline — documents written to the target).
type LocalCollection ¶
type LocalCollection struct {
// Scope is "account" or "space".
Scope string `json:"scope"`
// SpaceId binds a space-scoped collection; required iff scope is
// "space". Nothing drops the collection when the space goes away.
SpaceId string `json:"spaceId,omitempty"`
// Name: ^[a-z0-9][a-z0-9_-]{0,63}$.
Name string `json:"name"`
}
LocalCollection addresses one local collection on the wire.
type LocalCollectionInfo ¶
type LocalCollectionInfo struct {
LocalCollection
// StorageName is the collection's any-store name (the "l_"-tagged
// form). It is what a pipeline's $out / $merge `into` / $lookup
// `from` must name — those stages take raw collection names.
StorageName string `json:"storageName"`
Count int `json:"count"`
Indexes []LocalIndex `json:"indexes"`
}
LocalCollectionInfo describes an existing local collection.
type LocalDeleteRequest ¶
type LocalDeleteRequest struct {
Coll LocalCollection `json:"coll"`
Ids []string `json:"ids,omitempty"`
// Filter is omitzero, not omitempty: `{}` (delete everything) must
// survive marshalling; only a nil map is absent.
Filter map[string]any `json:"filter,omitzero"`
}
LocalDeleteRequest is the body of POST /v1/local/delete: exactly one of Ids / Filter. Filter deletes are collected under one read and removed in chunks of 256 — NOT atomic per call; a concurrent writer can interleave.
type LocalDeleteResponse ¶
type LocalDeleteResponse struct {
// Deleted counts documents actually removed (an id that was already
// gone is not counted, not an error).
Deleted int `json:"deleted"`
}
LocalDeleteResponse is the body of POST /v1/local/delete.
type LocalDiscoveryRequest ¶ added in v0.2.3
type LocalDiscoveryRequest struct {
// Enabled false stops announce and browse within seconds and keeps
// them stopped; true starts them at once. Required: an absent value
// is 400 request.missing_field rather than a silent off. Held for
// the process lifetime, across logout and account switches; a host
// restates it after a restart, and may state it before the first
// POST /v1/auth.
Enabled *bool `json:"enabled"`
}
LocalDiscoveryRequest is the body of PUT /v1/local-discovery: whether this device announces and browses on the local network (mDNS). The QUIC listener and the global p2p layer are unaffected.
type LocalDiscoveryResponse ¶ added in v0.2.3
type LocalDiscoveryResponse struct {
Enabled bool `json:"enabled"`
}
LocalDiscoveryResponse is the switch state: what the live engine reports, or, with no engine up, what the next boot will start with.
type LocalDocsRequest ¶
type LocalDocsRequest struct {
Coll LocalCollection `json:"coll"`
// Docs are JSON objects. A missing `id` is minted server-side
// (insert and upsert alike); it must be a string when present.
Docs []map[string]any `json:"docs"`
}
LocalDocsRequest is the body of POST /v1/local/insert and POST /v1/local/upsert. At most 1000 docs per request; written in chunks of 256 per transaction, so a failure mid-way leaves earlier chunks committed.
type LocalEnsureRequest ¶
type LocalEnsureRequest struct {
LocalCollection
// Indexes to ensure on the collection (idempotent).
Indexes []LocalIndex `json:"indexes,omitempty"`
}
LocalEnsureRequest is the body of PUT /v1/local/collections.
type LocalEnsureResponse ¶
type LocalEnsureResponse struct {
Collection LocalCollectionInfo `json:"collection"`
Created bool `json:"created"`
}
LocalEnsureResponse is the body of PUT /v1/local/collections: 201 when this call created the collection, 200 when it already existed.
type LocalGetRequest ¶
type LocalGetRequest struct {
Coll LocalCollection `json:"coll"`
Id string `json:"id"`
}
LocalGetRequest is the body of POST /v1/local/get.
type LocalIdsResponse ¶
type LocalIdsResponse struct {
Ids []string `json:"ids"`
}
LocalIdsResponse is the body of insert / upsert: the ids of every written document, in request order.
type LocalImportResponse ¶
type LocalImportResponse struct {
Collections []LocalCollectionInfo `json:"collections"`
}
LocalImportResponse is the body of POST /v1/local/import: every collection the file carried, as it stands after the import (in file order). The export itself, GET /v1/local/export, has no JSON body — it streams the file.
type LocalIndex ¶
type LocalIndex struct {
// Name is derived from Fields when empty (e.g. "kind,-at").
Name string `json:"name,omitempty"`
// Fields are field paths, "-" prefix for descending.
Fields []string `json:"fields"`
Unique bool `json:"unique,omitempty"`
Sparse bool `json:"sparse,omitempty"`
}
LocalIndex is one range index on a local collection.
type LocalIndexesRequest ¶
type LocalIndexesRequest struct {
Coll LocalCollection `json:"coll"`
Ensure []LocalIndex `json:"ensure,omitempty"`
// Drop names indexes to remove (a missing name is not an error).
Drop []string `json:"drop,omitempty"`
}
LocalIndexesRequest is the body of POST /v1/local/indexes.
type LocalIndexesResponse ¶
type LocalIndexesResponse struct {
Indexes []LocalIndex `json:"indexes"`
}
LocalIndexesResponse is the body of POST /v1/local/indexes: the collection's indexes after the change.
type LocalListResponse ¶
type LocalListResponse struct {
Collections []LocalCollectionInfo `json:"collections"`
}
LocalListResponse is the body of GET /v1/local/collections.
type LocalMetaResponse ¶
type LocalMetaResponse struct {
Stages []string `json:"stages"`
Accumulators []string `json:"accumulators"`
}
LocalMetaResponse is the body of GET /v1/local/meta: the aggregation grammar as any-store advertises it.
type LocalQueryRequest ¶
type LocalQueryRequest struct {
Coll LocalCollection `json:"coll"`
Filter map[string]any `json:"filter,omitempty"`
Sort []string `json:"sort,omitempty"`
// Limit defaults to 100, capped at 1000.
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
IncludeTotal bool `json:"includeTotal,omitempty"`
// Projection shapes the records that come back — the same
// mongo-style grammar the dataset query endpoints take (docs/09-
// query.md § Projection): field paths to 1 (include) or -1
// (exclude), `id` always present. A local record carries no `_ver`
// and no delivery counters, so the protocol-field rules there are
// simply inert here. `$project` inside /v1/local/aggregate is the
// equivalent for a pipeline.
Projection map[string]int `json:"projection,omitempty"`
}
LocalQueryRequest is the body of POST /v1/local/query. The reply is QueryResponse; `total`/`hasNext` ride includeTotal as on /query.
type LocalRecordResponse ¶
type LocalRecordResponse struct {
Record json.RawMessage `json:"record"`
}
LocalRecordResponse is the body of POST /v1/local/get.
type LocalUpdateRequest ¶
type LocalUpdateRequest struct {
Coll LocalCollection `json:"coll"`
Id string `json:"id"`
// Modifier is a mongo-style modifier ($set / $unset / $inc / …).
Modifier map[string]any `json:"modifier"`
// Upsert creates the document from the modifier when the id is
// absent instead of answering 404 local.doc_not_found.
Upsert bool `json:"upsert,omitempty"`
}
LocalUpdateRequest is the body of POST /v1/local/update.
type LocalUpdateResponse ¶
type LocalUpdateResponse struct {
// Modified reports whether the modifier changed the document.
Modified bool `json:"modified"`
// Record is the document after the update.
Record json.RawMessage `json:"record"`
}
LocalUpdateResponse is the body of POST /v1/local/update.
type MarkdownContent ¶
type MarkdownContent struct {
Content string `json:"content"`
}
MarkdownContent documents the body of GET/PUT .../editor/markdown.
type MarkdownEdit ¶
type MarkdownEdit struct {
OldText string `json:"oldText"`
NewText string `json:"newText"`
ReplaceAll bool `json:"replaceAll,omitempty"`
}
MarkdownEdit is one targeted replacement against an object's rendered markdown: oldText is matched against the bytes GET .../editor/markdown returns and must be unique unless replaceAll. See docs/03-api.md § Objects for the matching rules.
type MarkdownEditRequest ¶
type MarkdownEditRequest struct {
Edits []MarkdownEdit `json:"edits"`
}
MarkdownEditRequest is the body of PATCH .../editor/markdown. All edits match against the original document independently and must not overlap; any failing edit rejects the whole request.
type MarkdownSetResponse ¶
type MarkdownSetResponse struct {
Inserted []string `json:"inserted"`
Updated []string `json:"updated"`
Deleted []string `json:"deleted"`
Unchanged int `json:"unchanged"`
}
MarkdownSetResponse documents the response of PUT .../editor/markdown.
type Member ¶
type Member struct {
Identity string `json:"identity"`
Permission string `json:"permission"`
Status string `json:"status"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
RequestRecordId string `json:"requestRecordId,omitempty"`
}
Member is the wire shape of space.Member. Permission and Status are rendered as strings; identityRepo-decoded profile fields surface when populated.
type MemberEventPayload ¶
type MemberEventPayload struct {
Kind string `json:"kind"`
Member Member `json:"member"`
Previous *Member `json:"previous"`
}
MemberEventPayload is the data payload of an `event: member` frame on the members subscribe SSE stream. Kind discriminates the change; Member carries the post-event state; Previous carries pre-event state (nil for Added).
type MembersListResponse ¶
type MembersListResponse struct {
Members []Member `json:"members"`
}
MembersListResponse is the body of GET /v1/spaces/:spaceId/members.
type ModifyResult ¶
type ModifyResult struct {
VersionId string `json:"versionId"`
ChangeId string `json:"changeId"`
RecordIds []string `json:"recordIds"`
Rejections []OpRejection `json:"rejections,omitempty"`
}
ModifyResult is the response shape for Space.Modify, Space.Delete, and PropertiesAPI.Set. Always includes versionId/changeId/recordIds — clients use RecordIds[0] to read auto-derived ids when they submitted a record with empty Id.
Rejections is the partial-success list: ops the handler refused at apply time (kind mismatch, unknown property, immutable field…). The change still committed with this versionId/changeId, but those ops did not land. Empty / omitted means everything took.
type ObjectCreateRequest ¶
type ObjectCreateRequest struct {
// Type is the object's one type — what it IS: its parts, its layout
// and one column group. Required (400 request.missing_field);
// `page` is the plain document. Nothing is stamped server-side.
Type string `json:"type"`
// Collections lists the collections the object is filed under at
// create — column groups without parts (docs/28-well-known-bundles.md:
// an object is in a space's wiki tree only when it is in the wiki
// collection).
Collections []string `json:"collections,omitempty"`
// InitialProperties carries the object's starting property values,
// keyed by owner (the type or a collection) then property id — the
// ONLY home for them: {"initialProperties": {"any": {"name":
// "Dune"}}}. A top-level name/description/group key is rejected.
InitialProperties map[string]map[string]any `json:"initialProperties,omitempty"`
}
ObjectCreateRequest documents the body of POST /v1/spaces/:spaceId/objects. AUTHORITATIVE like QueryBodyParams: the server derives its strict unknown-field rejection from these json tags — this is the whole create vocabulary.
type ObjectDebugResponse ¶
type ObjectDebugResponse struct {
ObjectId string `json:"objectId"`
// SyncState is one of: unknown, offline, syncing, synced, error.
// Pending is the set of heads the per-space syncstatus tracker is
// waiting for a responsible-node HeadsApply on; empty means
// converged with the last sender we trust.
SyncState string `json:"syncState"`
Pending []string `json:"pending"`
LastSyncAt time.Time `json:"lastSyncAt"`
// Heads / HeadsCount: current tree heads. HeadsCount > 1 means the
// object is diverged across concurrent writers right now.
// BranchCount counts every DAG branch that ever existed —
// merged-in lineages (one per extra parent on a merge) plus
// still-open ones (HeadsCount - 1). TreeLen is total change count.
// Snapshots is the number of changes carrying IsSnapshot; costs a
// full IterateRoot walk.
Heads []string `json:"heads"`
HeadsCount int `json:"headsCount"`
BranchCount int `json:"branchCount"`
TreeLen int `json:"treeLen"`
Snapshots int `json:"snapshots"`
// LatestVersionId is the lexid-max OrderId across Heads. Empty
// when the tree has no heads (root-only / transient cold-restore).
// Local to this peer — VersionIds don't match across peers.
LatestVersionId string `json:"latestVersionId"`
// MaxAddSeq is the controller's delivery-order watermark — the
// highest AddSeq the apply path has seen. Exposed here as a
// sanity check that the controller is keeping up with the tree;
// not a cross-peer primitive.
MaxAddSeq uint64 `json:"maxAddSeq"`
}
ObjectDebugResponse is the wire shape of Space.Debug().Object(objectId). The tree-structure fields are gathered under the object tree mutex so they form a jointly-consistent snapshot; the read blocks local writes for the duration of the IterateRoot walk.
Diagnostic-only: this surface mirrors the SDK's DebugAPI, which is explicitly not stable. Production UI should subscribe to the per-space /sync-status endpoints once the SDK lands them.
type ObjectGetResponse ¶
type ObjectGetResponse struct {
ObjectId string `json:"objectId"`
Record json.RawMessage `json:"record"`
}
ObjectGetResponse is the body of GET /v1/spaces/:spaceId/objects/:objectId: the object's row from the space's objects collection (any.type, any.collections and property values, meta included), rendered as JSON.
type ObjectSyncStatusResponse ¶
type ObjectSyncStatusResponse struct {
ObjectId string `json:"objectId"`
State string `json:"state"`
LastSyncAt time.Time `json:"lastSyncAt"`
}
ObjectSyncStatusResponse is the wire shape of Space.SyncStatus().Object(objectId). Unknown ids return State = "unknown" with a zero LastSyncAt — same contract as the SDK.
type ObjectsCreateResponse ¶
type ObjectsCreateResponse struct {
ObjectId string `json:"objectId"`
}
ObjectsCreateResponse is the body returned by POST /v1/spaces/:spaceId/objects. The SDK currently surfaces only the new object id; a richer info object will follow when the SDK exposes one.
type Op ¶
type Op struct {
Type string `json:"type" enums:"$set,$unset,$inc,$addToSet,$pull"`
Path string `json:"path,omitempty"`
Value any `json:"value,omitempty"`
}
Op documents one operation in a modify batch.
type OpRejection ¶
type OpRejection struct {
RecordIndex int `json:"recordIndex"`
RecordId string `json:"recordId,omitempty"`
OpIndex int `json:"opIndex"`
Reason string `json:"reason"`
}
OpRejection mirrors space.OpRejection 1:1 on the wire. RecordIndex and OpIndex are positional; RecordId resolves the auto-derived id for empty-id records; Reason is human-readable text from the handler. OpIndex == -1 means the whole record was rejected (BeforeCreate / BeforeDelete).
type P2PPeerStatus ¶
type P2PPeerStatus struct {
PeerId string `json:"peerId"`
SpaceIds []string `json:"spaceIds"`
Connected bool `json:"connected"`
// Sources that know the peer: "lan", "global" (a space's records),
// "account" (this account's own device record), in any
// combination. A peer in the top-level list always carries at
// least "lan", and one in global.peers may also carry it — a
// device on the same LAN that a space's records also name appears
// in both lists, so presence under global is not proof that
// traffic is relayed.
Sources []string `json:"sources,omitempty"`
// LastSeen is the newest liveness evidence — a record heartbeat or
// a local connection. Zero for LAN-only peers.
LastSeen *time.Time `json:"lastSeen,omitempty"`
// Tier derived from LastSeen: active, stale, dormant, disabled. It
// sets how often the peer is dialed. Empty for LAN-only peers.
Tier string `json:"tier,omitempty"`
// Failures counts consecutive failed global dials.
Failures int `json:"failures,omitempty"`
}
P2PPeerStatus is one discovered peer. SpaceIds is the union over every source that knows the peer: for a LAN-only peer, the spaces it PROVED it shares in the space exchange (the handshake reveals only the intersection of the two space sets, not everything the peer holds); for a peer also known through records, the spaces those records name as well. Read Sources before treating the set as the LAN handshake's proof.
type P2PStatusResponse ¶
type P2PStatusResponse struct {
// PeerId is THIS device's peer id. Devices of one account must
// each have a distinct peerId — devices sharing one cannot pair.
PeerId string `json:"peerId"`
Enabled bool `json:"enabled"`
ListenerStarted bool `json:"listenerStarted"`
Port int `json:"port"`
Possibility string `json:"possibility"`
State string `json:"state"`
Peers []P2PPeerStatus `json:"peers"`
// LocalDiscovery is the mDNS switch (PUT /v1/local-discovery): false
// means announce and browse are off and Possibility reads `disabled`.
// Distinct from Enabled, the p2p.enabled config opt-out fixed at
// boot, which also takes the QUIC listener down.
LocalDiscovery bool `json:"localDiscovery"`
// Global is the internet-wide layer (iroh over the relays).
Global GlobalP2PStatus `json:"global"`
}
P2PStatusResponse is the wire shape of SDK.P2PStatus() — the account-wide snapshot of both direct layers: the local network (the top-level fields) and the internet-wide one (global). Diagnostic; the per-space p2p state lives in SpaceSyncStatusResponse (p2p / localPeers).
Possibility is one of: unknown, possible, nointerfaces, restricted, disabled. State is one of: unknown, notpossible, notconnected, connected, restricted; it is connected when ANY direct peer is, LAN or global.
type PartDefResponse ¶
type PartDefResponse struct {
Id string `json:"id"`
Key string `json:"key"`
Name string `json:"name,omitempty"`
Icon string `json:"icon,omitempty"`
Pos string `json:"pos,omitempty"`
Hidden bool `json:"hidden,omitempty"`
UI json.RawMessage `json:"ui,omitempty"`
Uses []string `json:"uses,omitempty"`
Datasets []DatasetDefResponse `json:"datasets"`
}
PartDefResponse mirrors space.PartDef — the compiled view of one part.
type PartDraftRequest ¶
type PartDraftRequest struct {
// Key is the part's slug ([a-z][a-z0-9_]*, ≤ 64), unique within the
// type — pinned.
Key string `json:"key"`
// Name / Icon / Pos are the display slice; clients sort parts by
// pos. Hidden parts are not shown by default but stay revealable.
Name string `json:"name,omitempty"`
Icon string `json:"icon,omitempty"`
Pos string `json:"pos,omitempty"`
Hidden bool `json:"hidden,omitempty"`
// UI is the widget descriptor — {type, config} in the xFormat shape
// (v1 slugs: document, chat, table, list, board, gallery, chart,
// properties; open set, an unknown slug renders the module default).
// Written whole.
UI json.RawMessage `json:"ui,omitempty"`
// Uses names other datasets OF THIS TYPE the part renders without
// owning them (dataset keys).
Uses []string `json:"uses,omitempty"`
// Datasets are the part's initial dataset declarations.
Datasets []DatasetDraftRequest `json:"datasets,omitempty"`
}
PartDraftRequest is the body of POST /v1/spaces/:spaceId/types/:typeId/parts and one element of a bundle ensure's `parts`. Mirrors space.PartDraft: a display unit of the type owning one or more datasets. The key is pinned; the display slice patches via PATCH …/parts/:partId; datasets evolve via POST …/parts/:partId/datasets.
type PartPatchRequest ¶
type PartPatchRequest struct {
Set map[string]json.RawMessage `json:"set,omitempty" swaggertype:"object"`
Unset []string `json:"unset,omitempty"`
}
PartPatchRequest is the body of PATCH /v1/spaces/:spaceId/types/:typeId/parts/:partId — a per-path patch over the part's mutable leaves: name, icon, pos (strings), hidden (boolean), ui (an object, replaced whole), uses (an array of dataset keys). The key is pinned → 400 dataset.immutable. At least one entry across Set/Unset required.
type PeerSyncStats ¶
type PeerSyncStats struct {
PeerId string `json:"peerId"`
LastSyncAt time.Time `json:"lastSyncAt"`
New int `json:"new"`
Changed int `json:"changed"`
LastErr string `json:"lastErr,omitempty"`
}
PeerSyncStats mirrors space.PeerSyncStats. New + Changed are post-deletionState counts handed to the SDK's TreeSyncer (trees we'll actually pull / push). LastErr is omitted when the last round succeeded.
type Process ¶
type Process struct {
Identity string `json:"identity"`
Self bool `json:"self"`
Id string `json:"id"`
Kind string `json:"kind"`
Title string `json:"title"`
Scope string `json:"scope"`
SpaceId string `json:"spaceId,omitempty"`
Target string `json:"target,omitempty"`
State string `json:"state"`
Done int64 `json:"done"`
Total int64 `json:"total,omitempty"`
Message string `json:"message,omitempty"`
Error *ProcessError `json:"error,omitempty"`
StartedAt int64 `json:"startedAt"`
UpdatedAt int64 `json:"updatedAt"`
}
Process is one row of the live process view (GET /v1/processes) — the server's last-event-wins picture of a long-running operation built from `process.*` events on the event bus. Nothing is persisted: a server restart forgets every process, remote processes materialize from their periodic broadcasts, and entries expire when their owner stops heartbeating. See docs/22-processes.md.
Processes are keyed (identity, id): id uniqueness is publisher-local, and identity comes from the server-stamped (for network scopes signature-verified) event sender — a remote peer can neither collide with nor spoof another publisher's process. Self is true when the process belongs to this account (any of its devices).
Scope/SpaceId/Target mirror the registering envelope: scope is where the process broadcasts (device/account/space), Target is the process's subject (objectId, runId, …) — distinct from the envelope target, which carries the process id. State is one of the ProcessState* values; Error is set when State is failed. Done/Total are the owner's progress counters (Total 0 = unknown).
StartedAt/UpdatedAt are unix seconds of local observation — this device's clock, not the owner's. Display/expiry quality only.
type ProcessCancelRequest ¶
type ProcessCancelRequest struct {
Identity string `json:"identity,omitempty"`
}
ProcessCancelRequest is the body of POST /v1/processes/:id/cancel. Identity disambiguates when more than one publisher runs a process with the same id (the composite key); with a single match it may be omitted. Strict-bound.
type ProcessError ¶
ProcessError is the terminal failure payload of a process — carried by the process.failed event and surfaced on the failed Process row.
type ProcessFinishRequest ¶
type ProcessFinishRequest struct {
Status string `json:"status"`
Error *ProcessError `json:"error,omitempty"`
}
ProcessFinishRequest is the body of POST /v1/processes/:id/finish. Status is done, failed or cancelled; Error is required iff failed. Strict-bound.
type ProcessListResponse ¶
type ProcessListResponse struct {
Processes []Process `json:"processes"`
}
ProcessListResponse is the body of GET /v1/processes — the live view, expired entries swept.
type ProcessProgressRequest ¶
type ProcessProgressRequest struct {
Done *int64 `json:"done,omitempty"`
Total *int64 `json:"total,omitempty"`
Message *string `json:"message,omitempty"`
}
ProcessProgressRequest is the body of POST /v1/processes/:id/progress. Every field is optional: an absent field keeps its current value (the server folds the stored state into the emitted frame), an explicit value sets it — total 0 back to unknown, message "" blank. A bare {} is therefore a pure heartbeat. Done/Total are free-unit counters; Message is a short human-readable status line. Owners re-POST progress at least every 15s even when idle — a running process not heard from for 45s expires from the view. Strict-bound.
type ProcessRegisterRequest ¶
type ProcessRegisterRequest struct {
Id string `json:"id"`
Kind string `json:"kind"`
Title string `json:"title"`
Scope string `json:"scope"`
SpaceId string `json:"spaceId,omitempty"`
Target string `json:"target,omitempty"`
}
ProcessRegisterRequest is the body of POST /v1/processes. Id names the process (publisher-local uniqueness; the event-target grammar [A-Za-z0-9._-]{1,128} applies — it becomes a topic segment). Re-registering an id restarts the process view. Scope routes the broadcasts (device/account/space; SpaceId required iff space); Target optionally names the process's subject. Strict-bound.
type PropertiesGetResponse ¶
type PropertiesGetResponse struct {
Record json.RawMessage `json:"record"`
}
PropertiesGetResponse is the body of GET /v1/spaces/:spaceId/properties/:objectId. Record is the property record rendered as JSON — *anyenc.Value converted via FastJson(arena).MarshalTo. Carried as RawMessage so it is not double-encoded.
type PropertiesListResponse ¶
type PropertiesListResponse struct {
Properties []PropertyDef `json:"properties"`
}
PropertiesListResponse is the body of GET /v1/spaces/:spaceId/types/:typeId/properties.
type PropertiesSetRequest ¶
PropertiesSetRequest documents the body of POST /v1/spaces/:spaceId/properties/:objectId/set/:typeId.
type PropertyDef ¶
type PropertyDef struct {
Id string `json:"id"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
XKey string `json:"xKey,omitempty"`
Kind string `json:"kind"`
// Meta is the consumer flag map (meta["index"] for the search
// indexer).
Meta map[string]string `json:"meta,omitempty"`
// Scope is the property's write/sync class (synced / derived /
// account / local). Definitions written before scopes existed
// read back as "synced".
Scope string `json:"scope,omitempty"`
Items *PropertyDef `json:"items,omitempty"`
Properties []PropertyDef `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
// XFormat is the descriptor as stored — absent for a property that
// never declared one, which renders structurally from Kind.
XFormat json.RawMessage `json:"xFormat,omitempty"`
}
PropertyDef mirrors space.PropertyDef on the wire. Recursive Items / Properties fields and Required are emitted only when populated.
type PropertyPatchRequest ¶
type PropertyPatchRequest struct {
Set map[string]json.RawMessage `json:"set,omitempty" swaggertype:"object"`
Unset []string `json:"unset,omitempty"`
}
PropertyPatchRequest is the body of PATCH /v1/spaces/:spaceId/types/:typeId/properties/:propId — a generic per-path patch to a property definition (space.PropertyPatch). Set assigns values at dotted field paths; Unset removes them (a whole option subtree, e.g. "xFormat.options.high", is unset by naming it).
Mutable paths: name, description, xKey, meta.index, and every path under xFormat. A set targets a leaf — never an object, so a container (options, options.<key>, relation, config, the whole bag) can only be unset, not replaced. Pinned paths (kind, scope, items, properties) are rejected with 400 property.immutable. At least one entry across Set/Unset required.
type PushSubscription ¶
PushSubscription is one row of GET /v1/push/subscriptions: the base58-encoded space push PUBLIC key (the push server's space identifier — not a spaceId) and the subscribed topic string. Signatures are never returned by the server.
type PushSubscriptionsResponse ¶
type PushSubscriptionsResponse struct {
Subscriptions []PushSubscription `json:"subscriptions"`
}
PushSubscriptionsResponse is the body of GET /v1/push/subscriptions — the account's topic set as the push server holds it.
type PushTokenSetRequest ¶
PushTokenSetRequest is the body of POST /v1/push/token: this device's mobile push transport ("ios" | "android" — the push server's platform enum has no desktop entry, so desktop/headless servers are send-only) and the opaque APNs/FCM token the shell obtained. Re-POST on token rotation; DELETE on logout.
type PushTokenStatus ¶
type PushTokenStatus struct {
Registered bool `json:"registered"`
Platform string `json:"platform,omitempty"`
}
PushTokenStatus is the body of GET /v1/push/token — the LOCAL registration state (does a persisted token exist on this device, and for which platform). No push-node round trip.
type QueryBodyParams ¶
type QueryBodyParams struct {
// Filter is a mongo-style condition over record fields; omitted or
// empty matches every record. Operator grammar: docs/09-query.md
// (a bad operator answers 400 filter.unknown_operator listing the
// full set).
Filter map[string]any `json:"filter,omitempty"`
// Sort lists field paths, "-" prefix for descending (e.g.
// "-createdAt"). Required when limit > 0 on subscribe, so the
// window is well-defined.
Sort []string `json:"sort,omitempty"`
// Limit bounds the window; 0 or absent = unbounded.
Limit int `json:"limit,omitempty"`
// Offset skips past the first N matches of the sorted result.
Offset int `json:"offset,omitempty"`
// IncludeTotal populates `total` (every match, regardless of
// limit/offset) + `hasNext` in the snapshot reply.
IncludeTotal bool `json:"includeTotal,omitempty"`
// MailboxCapacity (subscribe only) sizes the event mailbox before
// the stream closes with reason "overflow". Default 256, min 16.
MailboxCapacity int `json:"mailboxCapacity,omitempty"`
// DriftBudgetPercent (subscribe only) bounds window drift before
// the stream closes with reason "drifted". Default 30.
DriftBudgetPercent int `json:"driftBudgetPercent,omitempty"`
// Projection shapes the records that come back, mongo-style: a flat
// object of dotted field paths to 1 (include) or -1 (exclude).
// `{"any":1,"nav":1}` is include mode — nothing but those subtrees;
// `{"_ver":-1}` is exclude mode — every user field but that one.
// Omitted, records ship their full form. Three rules worth knowing:
// `id` always rides along and cannot be excluded, `_ver` is narrowed
// to the projection automatically (never name a `_ver` path), and
// `_addSeq`/`_applySeq` drop unless named. Full grammar and the
// divergences from mongo: docs/09-query.md § Projection.
Projection map[string]int `json:"projection,omitempty"`
}
QueryBodyParams is the shared windowed query/subscribe vocabulary — the exact top-level field set every query surface accepts beyond its own addressing extras (objectId / dataset). It is AUTHORITATIVE, not doc-only: the server derives its strict unknown-field rejection from these json tags (jsonFieldNames in internal/server), so a field absent here is a field the server 400s. Keep it in lockstep with applyQueryParams.
type QueryResponse ¶
type QueryResponse struct {
Records []json.RawMessage `json:"records"`
Total *int `json:"total,omitempty"`
HasNext *bool `json:"hasNext,omitempty"`
}
QueryResponse is the body of POST /v1/spaces/:spaceId/query and POST /v1/spaces/:spaceId/objects/query — both use Query.Snapshot under the hood. Each record is a *anyenc.Value rendered as JSON via FastJson(arena).MarshalTo. Carried as RawMessage so the outer envelope is not double-encoded.
Total is the unbounded filter-matching count (independent of limit/offset), populated only when the request body sets includeTotal=true. Pointer so the field is omitted when the caller didn't ask (`null` would be misleading; absent is unambiguous), and an explicit zero still survives the round trip.
HasNext reports whether more filter-matching records exist past this page (offset+len(records) < total). The SDK derives it from the same count, so it is meaningful only when includeTotal=true — gated on the same flag and omitted otherwise (when unknown the SDK forces it false, which would falsely read as "no more pages").
type QuerySubscribeEvent ¶
type QuerySubscribeEvent struct {
VersionId string `json:"versionId"`
Added []QuerySubscribeRecord `json:"added,omitempty"`
Updated []QuerySubscribeRecord `json:"updated,omitempty"`
Removed []RemovedRecord `json:"removed,omitempty"`
}
QuerySubscribeEvent is one batch of windowed transitions delivered in an `event: changes` SSE frame. It groups every record-level change observed during one CRDT apply:
- Added — records that entered the visible window.
- Updated — records already in the window whose state changed.
- Removed — records that left the visible window, each tagged with a Reason. Branch on reason=="deleted" to drop the object for good (it's tombstoned); "filtered-out" and "displaced" mean the record left your result set but still exists, so a fresh Snapshot would return it.
VersionId is the per-change DAG order of the underlying CRDT apply. Useful for fence-and-replay semantics ("I've processed up to X — discard ≤ X"). VersionIds are locally-scoped (each peer assigns its own); don't compare across peers.
Total is intentionally absent — the windowed engine does not maintain a live counter. Callers who need a refreshed count call Snapshot again.
type QuerySubscribeRecord ¶
type QuerySubscribeRecord struct {
Id string `json:"id"`
Doc json.RawMessage `json:"doc"`
Ops []SubscribeEventOp `json:"ops,omitempty"`
}
QuerySubscribeRecord is one record's worth of state inside a QuerySubscribeEvent's Added / Updated slices. Doc is the full post-apply JSON value (safe to retain past the event). Ops carries the per-field $set / $unset ops from the triggering change — same shape as SubscribeEventOp on the raw stream, so callers can apply atomic updates against a local mirror without re-materialising the whole record.
Under a request `projection`, both halves are shaped and Ops can come back EMPTY — every op of the triggering change fell outside the projection, so nothing the caller holds changed. Treat an empty Ops as "no visible change", never as "re-materialise from Doc": Doc is authoritative either way.
type QuerySubscribeSnapshot ¶
type QuerySubscribeSnapshot struct {
Records []json.RawMessage `json:"records"`
Total *int `json:"total,omitempty"`
HasNext *bool `json:"hasNext,omitempty"`
}
QuerySubscribeSnapshot is the data payload of the `event: snapshot` frame on a query/subscribe stream. It mirrors QueryResponse — the same point-in-time materialised window the bare Snapshot endpoint returns. Carried as its own type so future extensions (e.g. cursor) can land here without entangling Snapshot's HTTP shape.
type RecordModify ¶
type RecordModify struct {
Id string `json:"id,omitempty"`
Upsert bool `json:"upsert,omitempty"`
Ops []Op `json:"ops"`
}
RecordModify documents one record in a modify batch.
type RemovedRecord ¶
RemovedRecord is one id that left the visible window, tagged with the cause. Reason is one of:
- "deleted" — the record was tombstoned; it no longer exists. Drop it from local state for good.
- "filtered-out" — an update changed a field so the query's filter no longer matches. The record still exists.
- "displaced" — a higher-priority arrival (or the record's own sort-key change) pushed it past the Limit boundary. Still matches the filter; just outside the window.
Only "deleted" means the object is gone; for the other two a fresh Snapshot would still return it.
type SearchHit ¶
type SearchHit struct {
Scope string `json:"scope"`
ObjectId string `json:"objectId"`
Dataset string `json:"dataset"`
RecordId string `json:"recordId"`
// Chunk is the 0-based chunk of the record this hit shows: long
// records are indexed as several docs, and the hit is the record's
// best-ranked one. One hit per record — no client-side dedupe.
Chunk int `json:"chunk,omitempty"`
// Data is the hit's indexed text, windowed to MaxData runes around
// the first matching term. DataOffset is the window's rune offset
// into the chunk's full indexed text and DataTotal that text's rune
// length — Data is the whole text iff DataOffset == 0 and
// len([]rune(Data)) == DataTotal.
Data string `json:"data"`
DataOffset int `json:"dataOffset,omitempty"`
DataTotal int `json:"dataTotal"`
Score float64 `json:"score"`
// Passages are the record's next best matching chunks. Absent when
// the request did not ask (SearchRequest.Passages) and when the
// record has no other matching chunk in the search window.
Passages []SearchPassage `json:"passages,omitempty"`
}
SearchHit is one ranked result — the indexed record's identity plus its indexed text. Score semantics depend on the effective mode: BM25 for fts, cosine similarity for vector, RRF for hybrid; within one response higher is always better.
type SearchPassage ¶
type SearchPassage struct {
Chunk int `json:"chunk,omitempty"`
Data string `json:"data"`
DataOffset int `json:"dataOffset,omitempty"`
DataTotal int `json:"dataTotal"`
Score float64 `json:"score"`
}
SearchPassage is one further matching chunk of a hit's record, with the same Data window fields as the hit.
type SearchRequest ¶
type SearchRequest struct {
// Query is the search text. Required.
Query string `json:"query"`
// Scopes restricts results to the given index scopes (basic, chat,
// props, …). Empty = all scopes.
Scopes []string `json:"scopes,omitempty"`
// Limit caps returned records — every hit is a distinct
// (objectId, dataset, recordId). Default 10, max 100.
Limit int `json:"limit,omitempty"`
// Mode is hybrid (default), fts, or vector. Vector requires an
// embedder configured on the server.
Mode string `json:"mode,omitempty"`
// Require / Exclude are extra must / must-not terms ($require /
// $exclude) — a hit must contain every Require term and no Exclude
// term, in every mode: the FTS leg matches on them, and vector hits
// are post-filtered against the FTS index before fusion. Each term
// may be a "phrase" or prefix*.
Require []string `json:"require,omitempty"`
Exclude []string `json:"exclude,omitempty"`
// MaxData bounds each hit's Data to a window of at most this many
// runes around the first query/require term match (the head when
// nothing matches). 0 = DefaultSearchMaxData; -1 = the whole indexed
// chunk text. DataOffset / DataTotal on the hit locate the window.
MaxData int `json:"maxData,omitempty"`
// Passages asks for up to this many further matching chunks per
// record, best first, on hit.passages (0 = none, max 10). They are
// the record's other chunks that ranked within the search window,
// not every chunk of the record.
Passages int `json:"passages,omitempty"`
// Filter keeps only hits whose host object matches this condition,
// in the /objects/query filter grammar verbatim (any.type,
// any.collections, <ownerId>.<propId>, modifiedAt, …), in every mode — like Require /
// Exclude. The object's live row is checked, so a property write is
// honored at once. Limit still counts matching records. An object
// with no row never matches.
Filter json.RawMessage `json:"filter,omitempty"`
}
SearchRequest is the body of POST /v1/spaces/:spaceId/search. The search runs over the server's local index (see docs/13-index.md).
type SearchResponse ¶
type SearchResponse struct {
Hits []SearchHit `json:"hits"`
Mode string `json:"mode"`
// VectorStatus: used | unavailable | disabled | skipped — whether
// semantic recall participated in this response and, if not, why.
VectorStatus string `json:"vectorStatus"`
// Truncated is set when a leg's read budget under Filter ended and
// the page holds fewer than Limit records: the index may hold
// matches the reply cannot show. Absent without a filter. A Filter
// no object satisfies answers empty without running a leg
// (VectorStatus then reads skipped, or disabled without an embedder).
Truncated bool `json:"truncated,omitempty"`
}
SearchResponse is the reply. Mode reports the mode that actually ran: a hybrid request degrades to "fts" when no embedder is configured or the query embedding failed — VectorStatus says which of those it was.
type SearchText ¶
type SearchText []string
SearchText is the search `text` mapping's wire form: a bare field key or a non-empty array of field keys (the indexer joins the mapped values into one body). A single key marshals as the bare string, so single-field declarations and discovery output keep the canonical scalar shape. An empty string unmarshals to nil ("no text mapping"); an empty array stays a non-nil empty slice so declaration validation can reject it explicitly.
func (SearchText) MarshalJSON ¶
func (t SearchText) MarshalJSON() ([]byte, error)
func (*SearchText) UnmarshalJSON ¶
func (t *SearchText) UnmarshalJSON(data []byte) error
type SpaceAggregateObjectsRequest ¶
type SpaceAggregateObjectsRequest struct {
Pipeline []map[string]any `json:"pipeline"`
GroupLimit *int `json:"groupLimit,omitempty"`
AccumArrayLimit *int `json:"accumArrayLimit,omitempty"`
MemoryLimitBytes *int `json:"memoryLimitBytes,omitempty"`
Explain bool `json:"explain,omitempty"`
}
SpaceAggregateObjectsRequest documents the body of POST /v1/spaces/:spaceId/objects/aggregate.
type SpaceAggregateRequest ¶
type SpaceAggregateRequest struct {
ObjectId string `json:"objectId"`
Dataset string `json:"dataset"`
Pipeline []map[string]any `json:"pipeline"`
GroupLimit *int `json:"groupLimit,omitempty"`
AccumArrayLimit *int `json:"accumArrayLimit,omitempty"`
MemoryLimitBytes *int `json:"memoryLimitBytes,omitempty"`
Explain bool `json:"explain,omitempty"`
}
SpaceAggregateRequest documents the body of POST /v1/spaces/:spaceId/aggregate.
type SpaceBacklinks ¶
type SpaceBacklinks struct {
SpaceId string `json:"spaceId"`
Object []Link `json:"object"`
Parts []Link `json:"parts"`
Truncated bool `json:"truncated,omitempty"`
}
SpaceBacklinks is one space's share of an account-wide read.
type SpaceCreateRequest ¶
type SpaceCreateRequest struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
SpaceType string `json:"spaceType,omitempty"`
}
SpaceCreateRequest is the body of POST /v1/spaces. Mirrors space.CreateRequest.
type SpaceDebugResponse ¶
type SpaceDebugResponse struct {
SpaceId string `json:"spaceId"`
Peers []PeerSyncStats `json:"peers"`
}
SpaceDebugResponse is the wire shape of Space.Debug().Space(). In-memory only — peers reset on server restart, so Peers is empty until at least one diff round has completed against a responsible peer.
type SpaceInfo ¶
type SpaceInfo struct {
Id string `json:"id"`
Type string `json:"type,omitempty"`
SpaceType string `json:"spaceType,omitempty"`
Author string `json:"author,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
Status string `json:"status"`
OwnRole string `json:"ownRole" enums:"owner,admin,writer,reader,guest,none"`
CreatedAt time.Time `json:"createdAt"`
Settings map[string]any `json:"settings,omitempty"`
SpaceIndexObjectId string `json:"spaceIndexObjectId,omitempty"`
Push *SpacePushKeys `json:"push,omitempty"`
// Derived marks a space created by the account's own derivation
// (POST /v1/spaces/derived/:name or another consumer of the SDK's
// Derive). Derived spaces are permanent — DELETE refuses them with
// 409 space.derived_undeletable. Absent on created / joined / 1-1
// spaces.
Derived bool `json:"derived,omitempty"`
}
SpaceInfo is the wire shape for space.SpaceInfo. Status and OwnRole are rendered as strings rather than the SDK's uint8 enums; see SpaceStatus / SpacePermission for the mapping.
OwnRole is the caller's own role in the space, mirrored from ACL state by the SDK (one pass at space load + one per applied ACL record, so permission changes land as row updates). Present on list rows and single-space responses alike. "none" doubles as "not mirrored yet" — treat it as unknown/no-access, with GET …/members/me as the authoritative per-space read. On a 1-1 space participants report "writer", never "owner" (the ACL owner is a synthetic shared key).
SpaceIndexObjectId is the deterministic id of the in-space `spaceIndex` derived object — stable across peers, useful for clients that want to attach a subscribe stream for live metadata updates. Omitted when the server can't resolve a Space handle for this row (e.g. tombstoned entries in `GET /v1/spaces`).
SpaceType is the app-level classification tag (read from the in-space spaceIndex), distinct from the on-wire header Type: 1-1 spaces carry "any.onetoone", created spaces "any.space". Use it to filter direct chats vs regular spaces client-side. Author is the space owner's account identity, resolved best-effort from the ACL (empty when the ACL isn't loadable). Settings is the account-private, client-owned per-space settings object (free-form keys, scalar values — numbers surface as JSON numbers/float64). Written per key via PATCH /v1/spaces/:spaceId/settings; synced across the account's own devices through the tech space, never visible to other members. Omitted when never written.
Push is the space's push-notification key material (see docs/20-push.md § Receiver-side keys), mirrored from ACL state so a mobile client can cache it and decrypt push payloads while `any` is not running. Populated on list rows AND single-space responses (it's a plain row field — no space load needed); omitted until the SDK's per-space mirror has run, e.g. on a joiner whose access is still pending. Rotation (encKey/encKeyId change) is observed live on the `POST /v1/spaces/query/subscribe` stream.
type SpaceJoinRequest ¶
type SpaceJoinRequest struct {
InviteToken string `json:"inviteToken"`
Metadata AccountMetadata `json:"metadata,omitempty"`
}
SpaceJoinRequest is the body of POST /v1/spaces/join. Mirrors space.JoinRequest.
type SpaceListQueryRequest ¶
type SpaceListQueryRequest struct {
// Dataset defaults to "spaces"; "profile" is the only other
// reachable value (closed allowlist — identities is deliberately
// excluded, read it via GET /v1/identities).
Dataset string `json:"dataset,omitempty" enums:"spaces,profile"`
QueryBodyParams
}
SpaceListQueryRequest documents the body of POST /v1/spaces/query[/subscribe] — the account's tech-space rows. Unlike SpaceQueryRequest there is NO objectId: the target object is fixed server-side to the tech-space index.
type SpaceListResponse ¶
type SpaceListResponse struct {
Spaces []SpaceInfo `json:"spaces"`
}
SpaceListResponse is the body of GET /v1/spaces.
type SpaceModifyRequest ¶
type SpaceModifyRequest struct {
ObjectId string `json:"objectId"`
Dataset string `json:"dataset"`
Records []RecordModify `json:"records"`
TraceIds []string `json:"traceIds,omitempty"`
// Scope selects the write route: "synced" (default — the object's
// own DAG change) or "local" (device-only materialization for
// fields the dataset schema declares local-scope; explicit record
// ids, no upsert, no traceIds). See docs/03-api.md § Modify records.
Scope string `json:"scope,omitempty" enums:"synced,local"`
}
SpaceModifyRequest documents the body of POST /v1/spaces/:spaceId/modify.
type SpaceOneToOneRequest ¶
type SpaceOneToOneRequest struct {
OtherIdentity string `json:"otherIdentity"`
}
SpaceOneToOneRequest is the body of POST /v1/spaces/one-to-one. The single field mirrors the arg of Service.OneToOne — the other party's account identity (the `id` from their GET /v1/account), exchanged out-of-band. Derivation is symmetric: both peers calling with each other's identity land on the same spaceId.
type SpacePushKeys ¶
type SpacePushKeys struct {
SpaceKey string `json:"spaceKey"`
EncKey string `json:"encKey"`
EncKeyId string `json:"encKeyId"`
}
SpacePushKeys is the per-space key material a push RECEIVER caches — the wire twin of the SDK's space.PushKeys, byte-compatible with anytype-heart's spacePushNotificationKey / spacePushNotificationEncryptionKey space-view details.
SpaceKey is base64(std) of the protobuf-marshalled ed25519 private key identifying the space on the push server. EncKey is base64(std) of the raw AES payload key derived from the CURRENT ACL read key; EncKeyId is hex(sha256(raw EncKey bytes)) — the value an incoming push carries as its KeyId. Clients keep an append-only per-space {encKeyId → encKey} cache: EncKey rotates with the ACL read key, and payloads encrypted before a rotation still arrive under the old id. Holding EncKey decrypts push payloads only (one-way derivation from the read key), never space data.
type SpaceQueryObjectsRequest ¶
type SpaceQueryObjectsRequest struct {
QueryBodyParams
}
SpaceQueryObjectsRequest documents the body of POST /v1/spaces/:spaceId/objects/query[/subscribe] and the per-object files query — surfaces addressed entirely by the path.
type SpaceQueryRequest ¶
type SpaceQueryRequest struct {
// ObjectId names the object whose dataset is queried. Required.
ObjectId string `json:"objectId"`
// Dataset names the per-object dataset (chat_messages,
// editor_blocks, …). Required.
Dataset string `json:"dataset"`
// IncludeDeleted (snapshot only) returns the dataset's record-level
// tombstones next to the live rows: `{id, _deletedAt, _ver, …}`
// with the content wiped. Lets a writer of an `id: user` dataset
// find the highest id ever used — a deleted id is burned, so the
// live maximum is not the next free one. Refused on `/subscribe`
// (400 request.invalid_field); the other query surfaces reject it
// as an unknown field (a deleted OBJECT is purged, not tombstoned).
IncludeDeleted bool `json:"includeDeleted,omitempty"`
QueryBodyParams
}
SpaceQueryRequest documents the body of POST /v1/spaces/:spaceId/query[/subscribe] — one object's dataset, addressed in the body.
type SpaceRegisterIncomingRequest ¶
type SpaceRegisterIncomingRequest struct {
PeerIdentity string `json:"peerIdentity"`
DisplayHint AccountMetadata `json:"displayHint,omitempty"`
}
SpaceRegisterIncomingRequest is the body of POST /v1/spaces/one-to-one/register-incoming. Mirrors Service.RegisterIncoming: drop an out-of-band incoming 1-1 request (the app learned of the peer's intent through its own channel) into a device-local `one_to_one_pending` row for the user to approve, without materializing storage. DisplayHint is an optional name/icon snapshot for the UI. No-op if a row for the derived space already exists.
type SpaceSettingsPatchRequest ¶
type SpaceSettingsPatchRequest struct {
Set map[string]any `json:"set,omitempty"`
Unset []string `json:"unset,omitempty"`
}
SpaceSettingsPatchRequest is the body of PATCH /v1/spaces/:spaceId/settings — a per-key patch of the account-private `settings` object on the space's tech-space row (deliberately separate from PATCH /v1/spaces/:spaceId, which writes the member-replicated name/description/icon). Keys are the caller's vocabulary: non-empty, dot-free (single level under `settings`). Values are scalars — string, number, or bool. At least one set or unset entry is required; a key may not appear in both. Works on any row the account knows, deleted/tombstoned included.
type SpaceSyncStatusResponse ¶
type SpaceSyncStatusResponse struct {
SpaceId string `json:"spaceId"`
State string `json:"state"`
Synced int `json:"synced"`
Total int `json:"total"`
NetworkPeers int `json:"networkPeers"`
LocalPeers int `json:"localPeers"`
GlobalPeers int `json:"globalPeers"`
P2P string `json:"p2p"`
LastSyncedAt time.Time `json:"lastSyncedAt"`
}
SpaceSyncStatusResponse is the wire shape of Space.SyncStatus().Space() — the rolled-up sync state for one space. Cheap to read; safe to poll on a render tick.
State is one of: unknown, offline, syncing, synced, error. Synced / Total count regular objects (excluding ACL / settings / spaceIndex / members system trees). The three peer counts are the paths this space is syncing over right now: NetworkPeers the responsible sync nodes, LocalPeers the LAN peers, GlobalPeers the internet-wide direct peers (relayed or hole-punched), each with a live connection. P2P summarizes the two direct counts as one of: unknown, notpossible, notconnected, connected, restricted.
type SpaceUpdateRequest ¶
type SpaceUpdateRequest struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
IconCID *string `json:"iconCid,omitempty"`
}
SpaceUpdateRequest is the body of PATCH /v1/spaces/:spaceId. Pointer semantics mirror space.SetMetadataRequest: a nil field is leave-unchanged; a non-nil pointer to an empty string sets the field to empty. spaceType is intentionally not patchable — it's pinned by the initial Create. At least one of Name, Description, or IconCID must be present; an all-empty body returns 400 request.missing_field.
type SubscribeClosed ¶
type SubscribeClosed struct {
Reason string `json:"reason"`
}
SubscribeClosed is the data payload of the terminal `event: closed` frame. Reason is one of the SubscribeClosed* constants.
type SubscribeEventOp ¶
type SubscribeEventOp struct {
Type string `json:"type"`
Path []string `json:"path"`
Payload json.RawMessage `json:"payload,omitempty"`
}
SubscribeEventOp is one $set or $unset op the SDK emits to subscribers (windowed Query.Subscribe or — historically — the raw apply stream). $inc / $addToSet / $pull / $incGated are projected to the post-apply value as $set / $unset before delivery, so a thin client without a CRDT engine can apply Ops naively.
Path is the dotted-segment field path, always a JSON array on the wire (never `null` — an empty array `[]` means the record root). On $set, an empty Path activates the multi-field form: Payload is an object whose top-level keys are themselves dot-separated paths to assign at. Payload is the JSON-shaped post-apply value for $set, omitted for $unset.
type SubscribeReady ¶
type SubscribeReady struct{}
SubscribeReady is the data payload of the initial `event: ready` SSE frame on every subscribe-shaped endpoint (query/subscribe, members/subscribe, sync-status/subscribe). Empty in v1; reserved so the wire shape doesn't change when we add fields.
type SyncStatusLagged ¶
type SyncStatusLagged struct {
Total uint64 `json:"total"`
}
SyncStatusLagged is the data payload of an `event: lagged` frame on a sync-status subscribe stream. Emitted when the server's per-subscriber forwarder dropped a state event because the consumer fell behind. State-flip events are sparse, so this should be rare; when it happens the client should re-GET the current status to resync.
type SyncStatusReady ¶
type SyncStatusReady struct{}
SyncStatusReady is the data payload of the initial `event: ready` frame on /sync-status subscribe streams. Empty in v1; reserved so future additive fields don't break the wire shape.
type TypeDatasetsListResponse ¶
type TypeDatasetsListResponse struct {
Datasets []DatasetDefResponse `json:"datasets"`
}
TypeDatasetsListResponse is the body of GET /v1/spaces/:spaceId/types/:typeId/datasets — every dataset of every part, flat.
type TypeInfo ¶
type TypeInfo struct {
Id string `json:"id"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
// XKey is the stable, caller-side programmatic key. For builtin/registered
// types it equals Id (a clean literal like "chat"); for user types it's
// the value set at create (or derived from Name by the client). Clients use
// it as the stable type handle in dotted property paths.
XKey string `json:"xKey,omitempty"`
BuiltIn bool `json:"builtIn,omitempty"`
// Layout — see TypesCreateRequest. Absent on built-ins.
Layout json.RawMessage `json:"layout,omitempty"`
// Hidden / Meta — see TypesCreateRequest. GET …/types omits hidden
// types unless includeHidden=true.
Hidden bool `json:"hidden,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
TypeInfo mirrors space.TypeInfo on the wire.
type TypePartsListResponse ¶
type TypePartsListResponse struct {
Parts []PartDefResponse `json:"parts"`
}
TypePartsListResponse is the body of GET /v1/spaces/:spaceId/types/:typeId/parts.
type TypePatchRequest ¶
type TypePatchRequest struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
IconCID *string `json:"iconCid,omitempty"`
Layout json.RawMessage `json:"layout,omitempty"`
Hidden *bool `json:"hidden,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
TypePatchRequest is the body of PATCH /v1/spaces/:spaceId/types/:typeId — a user type's display and rendering metadata. Absent fields keep their value; an empty string clears a text field; `"layout": null` clears the layout (the generated schema shows the object form only — swag cannot express a nullable object). `meta` patches the flag bag per key: a scalar sets the key, `null` unsets it, keys not named are untouched. At least one field is required.
type TypesCreateRequest ¶
type TypesCreateRequest struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
IconCID string `json:"iconCid,omitempty"`
// XKey is the stable, caller-side programmatic key for the type
// (e.g. "agent_memory"). REQUIRED on create and unique per space: the
// server rejects an empty xKey (type.xkey_required) and one that
// collides with an existing type's xKey or id (type.xkey_conflict).
// Clients derive it as a slug of Name. It's the only human handle a
// type resolves by — the display Name is not a resolution key.
XKey string `json:"xKey,omitempty"`
// Layout is how the type's header and parts compose — {type,
// config} in the xFormat shape (v1 slugs: page, tabs, chat, profile;
// open set, unknown renders as page). Mutable via PATCH
// …/types/:typeId.
Layout json.RawMessage `json:"layout,omitempty"`
// Hidden keeps the type out of GET …/types by default (pass
// includeHidden=true to list it) and out of a client's pickers;
// GET …/types/:typeId always resolves it. Meta is the open bag of
// consumer flags — one string, bool or number per single-level key
// (no '.', no '$', ≤64 bytes), written per key so concurrent
// writers merge; opaque to the server. Both mutable via PATCH.
Hidden bool `json:"hidden,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
TypesCreateRequest is the body of POST /v1/spaces/:spaceId/types. Mirrors space.TypeCreateParams.
type TypesCreateResponse ¶
type TypesCreateResponse struct {
TypeId string `json:"typeId"`
}
TypesCreateResponse is the body returned by POST /v1/spaces/:spaceId/types.
type TypesListResponse ¶
type TypesListResponse struct {
Types []TypeInfo `json:"types"`
}
TypesListResponse is the body of GET /v1/spaces/:spaceId/types.
type UpsertRecord ¶
UpsertRecord is one row: the caller-supplied record id plus the desired field values (top-level field → value).
type UpsertRejection ¶
type UpsertRejection struct {
Index int `json:"index"`
Id string `json:"id,omitempty"`
Code string `json:"code"`
Reason string `json:"reason"`
}
UpsertRejection reports one rejected record. Code is a stable machine code: upsert.immutable_field, upsert.not_author, upsert.record_deleted, or upsert.rejected (creation screening — missing required field, id pattern/length violation, undeclared field, stamped-field write — with the specific cause in reason).
type UpsertRequest ¶
type UpsertRequest struct {
ObjectId string `json:"objectId"`
Dataset string `json:"dataset"`
Records []UpsertRecord `json:"records"`
// PageSize caps records per emitted change. 0 = 500.
PageSize int `json:"pageSize,omitempty"`
TraceIds []string `json:"traceIds,omitempty"`
}
UpsertRequest is the body of POST /v1/spaces/:spaceId/upsert — schema-driven batch ingest into an id:user dataset (space.UpsertBatch). Per record: absent id ⇒ created; present ⇒ only declared-mutable fields are diffed, changed ones written per-path, identical records skipped; a differing write-once field ⇒ whole-record rejection. The record id is the idempotency key — re-running an identical batch is a no-op. Not transactional against concurrent writers: intended deployment is a single ingest writer per dataset.
type UpsertResult ¶
type UpsertResult struct {
Pages []ModifyResult `json:"pages"`
Created int `json:"created"`
Updated int `json:"updated"`
Skipped int `json:"skipped"`
Rejections []UpsertRejection `json:"rejections,omitempty"`
}
UpsertResult mirrors space.UpsertResult. Pages holds one ModifyResult per emitted change, in page order (pages with nothing to write are absent). Rejections is the partial-success list — the call still returns 200; counters cover the records that landed.
Source Files
¶
- account.go
- aggregate.go
- auth.go
- backlinks.go
- blocks.go
- bundle.go
- catalog.go
- chat.go
- datasets.go
- debug.go
- device.go
- doc_models.go
- errors.go
- event.go
- files.go
- history.go
- identity.go
- local.go
- markdown.go
- members.go
- meta.go
- meta_entry.go
- modify.go
- objects.go
- process.go
- properties.go
- push.go
- query.go
- search.go
- spaces.go
- subscribe.go
- sync_status.go
- typedatasets.go
- types.go
- upsert.go