API files
This page is for the person who connects a program to the API.
Files, their immutable revisions, and the atomic changesets that accept them.
openSyncNotices
GET /api/sync/notices
Open the WebSocket stream of sync notices.
Upgrades the connection to the WebSocket stream that tells a signed in device when the feed of a subscribed workspace changes. The stream carries notices only. Saves, receipts, feed pages and snapshots stay on the HTTP operations, and a device that cannot open the stream reads the feed on its own schedule. asyncapi.yaml states every message of the stream.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
sec-websocket-protocol
{
"name": "sec-websocket-protocol",
"in": "header",
"required": true,
"style": "simple",
"explode": false,
"description": "The subprotocol that the browser asks for when it opens the notice stream. The server opens the stream only for the one subprotocol that this contract names.",
"schema": {
"$ref": "#/components/schemas/SyncNoticeProtocol"
}
}
Schemas: SyncNoticeProtocol.
Responses
101
The server switched the connection to the notice stream. The messages of the stream are in asyncapi.yaml.
{
"description": "The server switched the connection to the notice stream. The messages of the stream are in `asyncapi.yaml`."
}
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
This deployment does not open the notice stream now. The code is notices_unavailable. The client keeps its work, reads the feed on its own schedule, and tries the stream again later.
{
"description": "This deployment does not open the notice stream now. The code is notices_unavailable. The client keeps its work, reads the feed on its own schedule, and tries the stream again later.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
uploadAttachment
POST /api/workspaces/{workspaceId}/attachments
Upload a temporary attachment image file.
Uploads an image as multipart/form-data. The server stores the bytes in a temporary object, validates format, dimensions, and pixel count in an isolated worker, and computes the SHA-256 digest.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "Multipart form upload that contains the binary attachment file.",
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/UploadAttachmentInput"
}
}
}
}
Schemas: UploadAttachmentInput.
Responses
201
The uploaded temporary attachment object and its verified digest.
{
"description": "The uploaded temporary attachment object and its verified digest.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AttachmentUploadResult"
}
}
}
}
Schemas: AttachmentUploadResult.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
408
The request body stopped arriving before the operation could read all of it, so the operation did nothing.
{
"description": "The request body stopped arriving before the operation could read all of it, so the operation did nothing.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.
{
"description": "The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
finalizeAttachment
POST /api/workspaces/{workspaceId}/attachments/{objectId}/finalize
Finalize an attachment object and create an immutable revision.
Finalizes an uploaded temporary attachment object and commits an attachment revision to the workspace file tree in one transaction. An existing file requires an If-Match header naming the accepted head.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
objectId
{
"name": "objectId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the attachment object that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
if-match
{
"name": "if-match",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "The strong entity tag of the accepted head that the client saw, for example \"3f1c2b7a-0e5d-4c1b-9a7e-2b6d4f8c1a03\". A list of tags is accepted and the request proceeds when any of them names the current head. The operation needs a tag: a request without one answers 428, and a head that has moved answers 412. The parameter is declared optional so that the missing case reaches the documented 428 answer instead of a schema error. The value * is refused with 428 as well: it would permit a write against a state the client never read, which is the lost update that this precondition exists to prevent.",
"schema": {
"$ref": "#/components/schemas/EntityTagCondition"
}
}
Schemas: EntityTagCondition.
Request body
{
"description": "Payload to finalize an attachment and create an immutable revision.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FinalizeAttachmentInput"
}
}
}
}
Schemas: FinalizeAttachmentInput.
Responses
200
The accepted revision and the outcome of its changeset.
{
"description": "The accepted revision and the outcome of its changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileChange"
}
}
}
}
Schemas: FileChange.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
428
The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.
{
"description": "The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
getAttachmentRevision
GET /api/workspaces/{workspaceId}/attachments/{revisionId}
Read the binary image of an accepted attachment revision.
Streams the immutable binary bytes of an accepted attachment revision with its declared media type.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
revisionId
{
"name": "revisionId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the revision that the operation reads.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
Binary bytes of the immutable attachment.
{
"description": "Binary bytes of the immutable attachment.",
"headers": {
"content-disposition": {
"description": "Names the file and states what the client does with the bytes. An image of an accepted type is shown, and every other type is saved.",
"schema": {
"type": "string",
"maxLength": 1024
}
}
},
"content": {
"image/png": {
"schema": {
"type": "string",
"format": "binary"
}
},
"image/jpeg": {
"schema": {
"type": "string",
"format": "binary"
}
},
"image/gif": {
"schema": {
"type": "string",
"format": "binary"
}
},
"image/webp": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
commitChangeset
POST /api/workspaces/{workspaceId}/changesets
Accept one atomic change of one or more files.
Accepts a complete changeset: every revision commits or none does. The request states an expected head for each file it changes, and null for a file that must not exist yet. It is the operation that the sync engine uses, and it also performs a folder change of up to 1000 files. A retry with the same mutation identity and the same body returns the first outcome; the same identity with a different body is refused.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "One atomic change of one or more files.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChangesetInput"
}
}
}
}
Schemas: ChangesetInput.
Responses
200
The outcome of one accepted changeset.
{
"description": "The outcome of one accepted changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AcceptedChangeset"
}
}
}
}
Schemas: AcceptedChangeset.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.
{
"description": "This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.",
"headers": {
"Retry-After": {
"description": "Seconds to wait before the caller asks again.",
"required": false,
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
exportWorkspace
GET /api/workspaces/{workspaceId}/export
Download every live note and image as a zip archive.
Answers a zip archive that holds every live note of the workspace as a Markdown file at its stored path, plus every live image at its stored path. A deleted file is not in the archive. Nothing in the archive needs this application to be read again, so it is also the cheapest disaster recovery. The server plans the archive from the live heads before its first byte, so the answer states its exact length and streams at once. A workspace of more files or bytes than one zip archive holds without ZIP64 answers 422 with the code export_too_large. One import or export of an account runs at once (429 archive_job_running) and a few of the installation (503 archive_jobs_busy, with Retry-After). A request that states Sec-Fetch-Site cross-site is refused, so a page of another site cannot start an export of the account. A browser reads this address itself to save a large archive to its disk, so it holds no required query or header parameter (record 0178). Every archive that this operation answers is an archive that importWorkspace takes.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
A zip archive of every live note and its attachments.
{
"description": "A zip archive of every live note and its attachments.",
"headers": {
"content-disposition": {
"description": "Names the download and asks the client to save it rather than to show it.",
"schema": {
"type": "string",
"maxLength": 1024
}
}
},
"content": {
"application/zip": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.
{
"description": "The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
inspectWorkspaceExport
HEAD /api/workspaces/{workspaceId}/export
Check that the workspace can be exported now.
Plans the archive of exportWorkspace and answers its headers with no body: the exact length and the download name. It runs no export job, so it costs one read of the live heads. A client checks it before it hands the address of exportWorkspace to the browser, so a workspace that one archive cannot hold, a missing workspace and a missing session reach the person as a sentence (record 0178). A HEAD answer has no body, so the status names the cause.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
The workspace can be exported now. The answer states the exact length of its archive and its download name, and carries no body.
{
"description": "The workspace can be exported now. The answer states the exact length of its archive and its download name, and carries no body.",
"headers": {
"content-length": {
"description": "The exact length of the archive in bytes.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"content-disposition": {
"description": "The download name of the archive.",
"schema": {
"type": "string",
"maxLength": 1024
}
}
}
}
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
listFiles
GET /api/workspaces/{workspaceId}/files
List the live files of a workspace.
Lists the accepted files of the workspace in the requested order, paged with a keyset cursor. updated is the newest accepted change first and is the default; path is the order of the folder tree. A deleted file is not listed, because it holds no place in the file tree; its history stays readable through its revisions. The answer carries metadata only, so a file tree can be drawn without downloading any note.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
cursor
{
"name": "cursor",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Position to continue a file listing from. Use the nextCursor value of the previous page, together with the same sort. The first page names no cursor.",
"schema": {
"$ref": "#/components/schemas/FilePageToken"
}
}
Schemas: FilePageToken.
limit
{
"name": "limit",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Largest number of entries in one page. The server uses 100 when the parameter is absent and never returns more than 500.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 500
}
}
sort
{
"name": "sort",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Order of the listing. `updated` puts the newest accepted change first and is the default. `path` orders by the stored path, which is the order of the folder tree.",
"schema": {
"$ref": "#/components/schemas/FileSortOrder"
}
}
Schemas: FileSortOrder.
Responses
200
One page of the live files of a workspace.
{
"description": "One page of the live files of a workspace.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WorkspaceFileList"
}
}
}
}
Schemas: WorkspaceFileList.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
createFile
POST /api/workspaces/{workspaceId}/files
Create a file with its first revision.
Creates a file that does not exist yet, together with the first revision of its content. The client assigns the file, revision, and mutation identifiers, so a retry that lost its answer repeats the same operation instead of creating a second file. The answer carries a strong entity tag that names the accepted revision.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "The identifiers, the path, and the first content of a new file.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateFileInput"
}
}
}
}
Schemas: CreateFileInput.
Responses
201
The accepted revision and the outcome of its changeset.
{
"description": "The accepted revision and the outcome of its changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileChange"
}
}
}
}
Schemas: FileChange.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
getFile
GET /api/workspaces/{workspaceId}/files/{fileId}
Read a file and the content of its accepted head.
Reports the metadata of one live file and the Markdown of its accepted head revision, and the document of the note unless the caller asks for the text alone. The answer carries a strong entity tag that names that revision, so a later conditional read answers 304 and a later conditional write answers 412 when the head has moved. If-None-Match with that tag, or with *, answers 304. A deleted file answers 404; its revisions stay readable.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
content
{
"name": "content",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "The parts of the head that the answer carries. `text` answers the Markdown and a null document. `full` also answers the document of the note, and it is the value when the parameter is absent, so a caller that names none reads what it read before.",
"schema": {
"$ref": "#/components/schemas/FileReadContent"
}
}
Schemas: FileReadContent.
if-none-match
{
"name": "if-none-match",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Entity tag that the client already holds, or a list of them. The answer is 304 with no body when one of them names the current head. The value * means any representation, so it answers 304 for a file that exists.",
"schema": {
"$ref": "#/components/schemas/EntityTagCondition"
}
}
Schemas: EntityTagCondition.
Responses
200
One live file and the content of its accepted head.
{
"description": "One live file and the content of its accepted head.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WorkspaceFile"
}
}
}
}
Schemas: WorkspaceFile.
304
The entity tag in the request names the current head, so the answer carries no body.
{
"description": "The entity tag in the request names the current head, so the answer carries no body."
}
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
updateFile
PUT /api/workspaces/{workspaceId}/files/{fileId}
Replace the content or the path of a file.
Writes one revision of an existing file. The request must carry the entity tag of the head that the client saw in If-Match; a request without it, and a request that carries *, both answer 428, and a head that has moved answers 412. The request states the new text, the new path, or both; a member that is absent keeps the value of the expected head. The answer carries the accepted revision without its text.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
if-match
{
"name": "if-match",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "The strong entity tag of the accepted head that the client saw, for example \"3f1c2b7a-0e5d-4c1b-9a7e-2b6d4f8c1a03\". A list of tags is accepted and the request proceeds when any of them names the current head. The operation needs a tag: a request without one answers 428, and a head that has moved answers 412. The parameter is declared optional so that the missing case reaches the documented 428 answer instead of a schema error. The value * is refused with 428 as well: it would permit a write against a state the client never read, which is the lost update that this precondition exists to prevent.",
"schema": {
"$ref": "#/components/schemas/EntityTagCondition"
}
}
Schemas: EntityTagCondition.
Request body
{
"description": "The identifiers and the new content or path of a file.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateFileInput"
}
}
}
}
Schemas: UpdateFileInput.
Responses
200
The accepted revision and the outcome of its changeset.
{
"description": "The accepted revision and the outcome of its changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileChange"
}
}
}
}
Schemas: FileChange.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
428
The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.
{
"description": "The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
deleteFile
DELETE /api/workspaces/{workspaceId}/files/{fileId}
Delete a file by writing a tombstone revision.
Deletes one file. The deletion is a revision, so the history of the file stays complete and a later restore is possible. The tombstone carries no note text, and a submitted tombstone that carries Markdown is refused with 422, so a deletion can never add content. Deleting removes the file from search, so a workspace at its storage limit can still be tidied. The request must carry the entity tag of the head that the client saw.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
if-match
{
"name": "if-match",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "The strong entity tag of the accepted head that the client saw, for example \"3f1c2b7a-0e5d-4c1b-9a7e-2b6d4f8c1a03\". A list of tags is accepted and the request proceeds when any of them names the current head. The operation needs a tag: a request without one answers 428, and a head that has moved answers 412. The parameter is declared optional so that the missing case reaches the documented 428 answer instead of a schema error. The value * is refused with 428 as well: it would permit a write against a state the client never read, which is the lost update that this precondition exists to prevent.",
"schema": {
"$ref": "#/components/schemas/EntityTagCondition"
}
}
Schemas: EntityTagCondition.
Request body
{
"description": "The identifiers of the tombstone revision.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeleteFileInput"
}
}
}
}
Schemas: DeleteFileInput.
Responses
200
The accepted revision and the outcome of its changeset.
{
"description": "The accepted revision and the outcome of its changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileChange"
}
}
}
}
Schemas: FileChange.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
428
The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.
{
"description": "The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
listBacklinks
GET /api/workspaces/{workspaceId}/files/{fileId}/backlinks
List notes that link to one live file.
Reads the accepted path-based link index. Each result names the live note and revision that contains at least one link to this file.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
Live notes that link to one file path.
{
"description": "Live notes that link to one file path.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BacklinkList"
}
}
}
}
Schemas: BacklinkList.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
exportNote
GET /api/workspaces/{workspaceId}/files/{fileId}/export
Download one note as a Markdown file.
Returns the accepted head of one note as Markdown, with a content disposition that names the file. A deleted note answers 404, because it holds no place in the file tree any more.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
The accepted head of one note as a Markdown file.
{
"description": "The accepted head of one note as a Markdown file.",
"headers": {
"content-disposition": {
"description": "Names the download and asks the client to save it rather than to show it.",
"schema": {
"type": "string",
"maxLength": 1024
}
}
},
"content": {
"text/markdown": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
listHistory
GET /api/workspaces/{workspaceId}/files/{fileId}/history
Read the revision history of a file.
Lists the immutable revisions of one file in reverse chronological order. The result supports cursor pagination. Each item reports byte size, author identity, checkpoint status, and restored-from references.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
cursor
{
"name": "cursor",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Position to continue a listing from. Use the nextCursor value of the previous page. The first page names no cursor.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
limit
{
"name": "limit",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Largest number of history items to return. Defaults to 50.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
}
Responses
200
One page of file history revisions.
{
"description": "One page of file history revisions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HistoryPage"
}
}
}
}
Schemas: HistoryPage.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
restoreRevision
POST /api/workspaces/{workspaceId}/files/{fileId}/restore
Restore a file to a historic revision.
Appends a child revision to the current accepted head referencing the historic target revision in restoredFrom, reusing existing content bytes without rewriting history.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "Revision restore payload.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RestoreRevisionInput"
}
}
}
}
Schemas: RestoreRevisionInput.
Responses
200
The outcome of one accepted changeset.
{
"description": "The outcome of one accepted changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AcceptedChangeset"
}
}
}
}
Schemas: AcceptedChangeset.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
startWorkspaceImport
POST /api/workspaces/{workspaceId}/imports
Start the upload of a portable workspace zip archive in parts.
An import sends its archive in parts, because a proxy in front of the server refuses a large request body (record 0192). This operation starts the upload and answers its identifier and the size of each part. The client then sends every part with sendWorkspaceImportPart and ends with completeWorkspaceImport. The stated size is checked against the bound of one archive, up to 4 GiB without ZIP64, so a zip file that is too large is refused before a part is sent. An account has one open import: a start removes every earlier import of the account that is still open. When the server keeps the parts on its own disk, a size that its free space cannot hold answers 507 storage_full. Any server instance of the installation takes the next request of the upload. An upload that nobody completes is removed after one day.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "The size of the zip archive that the import sends in parts.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StartWorkspaceImportInput"
}
}
}
}
Schemas: StartWorkspaceImportInput.
Responses
201
The import upload and the size of each of its parts.
{
"description": "The import upload and the size of each of its parts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WorkspaceImportStarted"
}
}
}
}
Schemas: WorkspaceImportStarted.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.
{
"description": "The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
507
The storage of the server has no room for this request body now.
{
"description": "The storage of the server has no room for this request body now.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
abortWorkspaceImport
DELETE /api/workspaces/{workspaceId}/imports/{importId}
Remove an import upload and every part that it holds.
Removes one import that startWorkspaceImport started, with its parts and with the archive of a completion that a refusal stopped (record 0192). A client calls it when a part or the completion fails, so the parts do not hold the storage of the server for a day. An import that is not there, or that another account started, answers removed as well, so a second call changes nothing.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
importId
{
"name": "importId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the import upload that startWorkspaceImport answered.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
The named record no longer exists.
{
"description": "The named record no longer exists.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Removed"
}
}
}
}
Schemas: Removed.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
completeWorkspaceImport
POST /api/workspaces/{workspaceId}/imports/{importId}/complete
Complete an import and read its zip archive into the workspace.
Joins the parts of an import into one archive and imports it (record 0192). Parts that do not make one archive answer archive_invalid. The import reads Markdown files and image files at their archive paths. An image outside the attachments folder moves into it, and a wiki link whose target is in the archive becomes a standard link (record 0172). The settings of a tool and every other kind of file are left out, and the answer counts them. Every imported path must be free in the workspace. The operation takes every archive that exportWorkspace answers: up to 65534 files and 4 GiB without ZIP64. A refused archive answers archive_invalid, archive_too_many_files or archive_too_large. Record 0170 bounds the work: one import or export of an account runs at once (429 archive_job_running) and a few of the installation (503 archive_jobs_busy, with Retry-After), and an archive that the storage cannot hold answers 507 storage_full. After such a refusal the parts stay, so the client completes the import again later. Every file is checked before the first commit, so only a failure of the service stops an import after it (503 import_incomplete, which states how many files came in). The upload is removed when the import ends.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
importId
{
"name": "importId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the import upload that startWorkspaceImport answered.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
Counts of the files read from one portable archive.
{
"description": "Counts of the files read from one portable archive.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ImportWorkspaceResult"
}
}
}
}
Schemas: ImportWorkspaceResult.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.
{
"description": "The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
507
The storage of the server has no room for this request body now.
{
"description": "The storage of the server has no room for this request body now.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
sendWorkspaceImportPart
PUT /api/workspaces/{workspaceId}/imports/{importId}/parts/{partNumber}
Send one part of a workspace zip archive.
Stores one part of an import that startWorkspaceImport started (record 0192). The body is the bytes of the part, and it states its length. Every part but the last holds exactly the part size that the start answered, and no part holds more. A part sent again replaces the earlier one. The gap between two chunks of the body is bounded, so a sender that stops in the middle is answered and the part is not stored. An import that does not exist, or that another account started, answers not_found. When the server keeps the parts on its own disk, a part that its free space cannot hold answers 507 storage_full before a byte of it is read.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
importId
{
"name": "importId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the import upload that startWorkspaceImport answered.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
partNumber
{
"name": "partNumber",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "The place of the part in the archive, from 1. The server takes as many parts as one archive of the largest size needs, and refuses a higher number.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 10000
}
}
Request body
{
"description": "The bytes of one part of a zip archive, with their stated length.",
"required": true,
"content": {
"application/octet-stream": {
"schema": {
"$ref": "#/components/schemas/WorkspaceImportPart"
}
}
}
}
Schemas: WorkspaceImportPart.
Responses
200
The part that the server stored.
{
"description": "The part that the server stored.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WorkspaceImportPartReceived"
}
}
}
}
Schemas: WorkspaceImportPartReceived.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
408
The request body stopped arriving before the operation could read all of it, so the operation did nothing.
{
"description": "The request body stopped arriving before the operation could read all of it, so the operation did nothing.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.
{
"description": "The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
507
The storage of the server has no room for this request body now.
{
"description": "The storage of the server has no room for this request body now.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
getMutationReceipt
GET /api/workspaces/{workspaceId}/mutations/{mutationId}
Read what the workspace knows about one mutation identity.
States whether this workspace accepted the request that carries the mutation identity and the request digest. A device reads it after a lost answer, before it transforms work that may already have committed. The answer repeats the stored outcome and never the text of a note, so an actor that may write and not read learns nothing. A digest that names another request answers other_request.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
mutationId
{
"name": "mutationId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "The stable identity that the device gave one mutation.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
digest
{
"name": "digest",
"in": "query",
"required": true,
"style": "form",
"explode": true,
"description": "The digest of the exact request that the device froze on its first send. It decides whether the stored receipt belongs to this request.",
"schema": {
"$ref": "#/components/schemas/ContentDigest"
}
}
Schemas: ContentDigest.
Responses
200
What the workspace knows about one mutation identity.
{
"description": "What the workspace knows about one mutation identity.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MutationReceipt"
}
}
}
}
Schemas: MutationReceipt.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
purgeFiles
POST /api/workspaces/{workspaceId}/purge
Permanently delete files and write purge markers.
Permanently purges files and revisions, writes purge markers, and reclaims storage. Subsequent writes to purged file identifiers answer 410 Gone. Restricted to the workspace owner.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "File purge payload.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PurgeFilesInput"
}
}
}
}
Schemas: PurgeFilesInput.
Responses
200
Outcome of executed permanent file purge.
{
"description": "Outcome of executed permanent file purge.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PurgedFiles"
}
}
}
}
Schemas: PurgedFiles.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
previewPurge
POST /api/workspaces/{workspaceId}/purge/preview
Preview permanent deletion of files.
Reports affected revisions, reclaimable bytes, and blocking references such as attachments referenced by external revisions. Restricted to workspace owners.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "Purge preview payload.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PreviewPurgeInput"
}
}
}
}
Schemas: PreviewPurgeInput.
Responses
200
Preview of permanent file purge.
{
"description": "Preview of permanent file purge.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PurgePreview"
}
}
}
}
Schemas: PurgePreview.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
getRevision
GET /api/workspaces/{workspaceId}/revisions/{revisionId}
Read one immutable revision.
Reports one accepted revision of the workspace with its parents, its path at that time, and its content. A Markdown revision carries its text. An attachment revision carries the identity of its immutable object; its bytes are transferred through the attachment operations.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
revisionId
{
"name": "revisionId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the revision that the operation reads.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Responses
200
One immutable revision of a workspace.
{
"description": "One immutable revision of a workspace.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileRevision"
}
}
}
}
Schemas: FileRevision.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
searchFiles
GET /api/workspaces/{workspaceId}/search
Search accepted live notes in a workspace.
Searches the accepted names of notes and the text that a reader of each note sees, with no Markdown mark and no link address. One text configuration serves every language: it is the PostgreSQL simple configuration with the unaccent filter, so it has no stemming and no stop words, and a letter with an accent matches the same letter without one. A word of the query of three characters or more matches as a prefix, and a shorter word matches only itself. Deleted files and historic revisions are excluded.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
query
{
"name": "query",
"in": "query",
"required": true,
"style": "form",
"explode": true,
"description": "Words to find in accepted note names and in the text that a reader of a note sees.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
limit
{
"name": "limit",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Largest number of search results to return.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
}
Responses
200
Accepted live notes that match the search query.
{
"description": "Accepted live notes that match the search query.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchResults"
}
}
}
}
Schemas: SearchResults.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
getChanges
GET /api/workspaces/{workspaceId}/sync/changes
Read ordered incremental changes after a cursor.
Reads the commit ordered change records after a cursor the client already applied, oldest first. Every relevant write allocates its cursor under the workspace lock, so the stream cannot skip a file transaction that commits late. A page never splits a commit, so the next cursor never passes a record of it. Change records are kept for 90 days; an older cursor answers 410 with the code snapshot_required, while saved revision identifiers stay valid beyond that window.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
cursor
{
"name": "cursor",
"in": "query",
"required": true,
"style": "form",
"explode": true,
"description": "Commit ordered cursor the client already applied. The answer carries the records after this position, oldest first. A cursor that predates the retained 90 day window needs a fresh snapshot instead.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 32,
"pattern": "^[0-9]+$"
}
}
limit
{
"name": "limit",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Largest number of change records in one answer. The server uses 100 when the parameter is absent and accepts at most 500. A page ends only at the end of a commit, so the server stops before a commit that does not fit. When the first commit is larger than the limit, the answer holds that one whole commit.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 500
}
}
Responses
200
Ordered incremental changes after a cursor.
{
"description": "Ordered incremental changes after a cursor.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SyncChanges"
}
}
}
}
Schemas: SyncChanges.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The snapshot expired, is unknown, was invalidated by a purge, or the sync cursor predates the retained 90 day window. The code is snapshot_required. The client starts a fresh snapshot and keeps its local work.
{
"description": "The snapshot expired, is unknown, was invalidated by a purge, or the sync cursor predates the retained 90 day window. The code is snapshot_required. The client starts a fresh snapshot and keeps its local work.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.
{
"description": "This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.",
"headers": {
"Retry-After": {
"description": "Seconds to wait before the caller asks again.",
"required": false,
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
startSnapshot
POST /api/workspaces/{workspaceId}/sync/snapshots
Capture a consistent download snapshot of a workspace.
Captures the accepted file metadata and the workspace high-water cursor in one repeatable-read transaction and materializes bounded metadata pages for 15 minutes. Each item names an immutable revision identifier; content transfer reuses the revision read by that identifier, never a later current head. The syncVersion names the sync protocol version; only version 1 is served and any other value is rejected without changing data.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "Snapshot start payload.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StartSnapshotInput"
}
}
}
}
Schemas: StartSnapshotInput.
Responses
200
The captured snapshot and its opaque page token.
{
"description": "The captured snapshot and its opaque page token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SnapshotStarted"
}
}
}
}
Schemas: SnapshotStarted.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.
{
"description": "This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.",
"headers": {
"Retry-After": {
"description": "Seconds to wait before the caller asks again.",
"required": false,
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
getSnapshotPage
GET /api/workspaces/{workspaceId}/sync/snapshots/{token}
Read one page of a materialized snapshot.
Reads one page of the items that the snapshot captured. The page runs in its own short transaction and rechecks current access; no database transaction stays open across network pages. A missing token, an expired snapshot, and a snapshot that a purge invalidated all answer 410 with the code snapshot_required: the client starts a fresh snapshot and keeps its local work.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
token
{
"name": "token",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Opaque token of a materialized snapshot, issued by the snapshot start operation. Only its hash is stored, so the value cannot be guessed.",
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^[A-Za-z0-9_-]{43}$"
}
}
position
{
"name": "position",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Ordinal of the first snapshot item to return. Use the nextPosition value of the previous page. The first page starts at zero.",
"schema": {
"type": "integer",
"minimum": 0
}
}
limit
{
"name": "limit",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Largest number of snapshot items in one page. The server uses the page size stored with the snapshot when the parameter is absent and never returns more than 500.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 500
}
}
Responses
200
One page of the items that a snapshot captured.
{
"description": "One page of the items that a snapshot captured.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SnapshotPage"
}
}
}
}
Schemas: SnapshotPage.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The snapshot expired, is unknown, was invalidated by a purge, or the sync cursor predates the retained 90 day window. The code is snapshot_required. The client starts a fresh snapshot and keeps its local work.
{
"description": "The snapshot expired, is unknown, was invalidated by a purge, or the sync cursor predates the retained 90 day window. The code is snapshot_required. The client starts a fresh snapshot and keeps its local work.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
429
Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.
{
"description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
"headers": {
"retry-after": {
"description": "The seconds after which the caller may try again.",
"schema": {
"type": "string",
"maxLength": 16
}
},
"notesapp-limit": {
"description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
"schema": {
"$ref": "#/components/schemas/UsageLimit"
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails, UsageLimit.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
503
This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.
{
"description": "This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.",
"headers": {
"Retry-After": {
"description": "Seconds to wait before the caller asks again.",
"required": false,
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
listDeletedFiles
GET /api/workspaces/{workspaceId}/trash
List the deleted files of a workspace.
Lists the files of the workspace that a tombstone revision deleted, in the requested order and paged with a keyset cursor, exactly as the live listing is. A deleted file holds no place in the file tree, so it appears here instead. Each entry names the instant of the deletion and the tombstone that is the accepted head, which the restore operation needs. A permanently purged file is not listed, because nothing of it is left to restore.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
cursor
{
"name": "cursor",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Position to continue a file listing from. Use the nextCursor value of the previous page, together with the same sort. The first page names no cursor.",
"schema": {
"$ref": "#/components/schemas/FilePageToken"
}
}
Schemas: FilePageToken.
limit
{
"name": "limit",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Largest number of entries in one page. The server uses 100 when the parameter is absent and never returns more than 500.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 500
}
}
sort
{
"name": "sort",
"in": "query",
"required": false,
"style": "form",
"explode": true,
"description": "Order of the listing. `updated` puts the newest accepted change first and is the default. `path` orders by the stored path, which is the order of the folder tree.",
"schema": {
"$ref": "#/components/schemas/FileSortOrder"
}
}
Schemas: FileSortOrder.
Responses
200
One page of the deleted files of a workspace.
{
"description": "One page of the deleted files of a workspace.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WorkspaceDeletedFileList"
}
}
}
}
Schemas: WorkspaceDeletedFileList.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
restoreFile
POST /api/workspaces/{workspaceId}/trash/{fileId}/restore
Bring one deleted file back into the file tree.
Writes one revision on top of the tombstone that un-deletes the file with the content of its last revision before the deletion. The tombstone is the expected head, so a change that arrived after the deletion answers 412 and nothing is written. The file keeps its identifier, so every link to it and its whole history stay valid. The file goes back to the path it held before the deletion. If a live file already holds that path, the answer restores the file beside it under the name plus " (restored)" in the same folder, so a restore never overwrites live work. A file that is not deleted answers 404, and a permanently purged one answers 410.
Authentication
Use one of these options:
Parameters
x-request-id
{
"name": "x-request-id",
"in": "header",
"required": false,
"style": "simple",
"explode": false,
"description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
}
}
workspaceId
{
"name": "workspaceId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the workspace that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
fileId
{
"name": "fileId",
"in": "path",
"required": true,
"style": "simple",
"explode": false,
"description": "Identifier of the file that the operation acts on.",
"schema": {
"$ref": "#/components/schemas/Uuid"
}
}
Schemas: Uuid.
Request body
{
"description": "Deleted file restore payload.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RestoreFileInput"
}
}
}
}
Schemas: RestoreFileInput.
Responses
200
The accepted revision and the outcome of its changeset.
{
"description": "The accepted revision and the outcome of its changeset.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileChange"
}
}
}
}
Schemas: FileChange.
400
The request did not match the contract.
{
"description": "The request did not match the contract.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
401
The request carries no usable session.
{
"description": "The request carries no usable session.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
403
The actor may not perform this operation.
{
"description": "The actor may not perform this operation.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
404
The requested resource does not exist.
{
"description": "The requested resource does not exist.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
409
The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.
{
"description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
410
The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.
{
"description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
412
An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.
{
"description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
413
The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.
{
"description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
415
The request media type is not supported.
{
"description": "The request media type is not supported.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
422
The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.
{
"description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
423
The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.
{
"description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.
500
The service failed to complete the request.
{
"description": "The service failed to complete the request.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
Schemas: ProblemDetails.