Workspace
Files, folders, shares and mounted drives.
Files, folders, shares and mounted drives.
Files, folders, versions, shares and changes: the same store the /workspace UI shows, as an HTTP interface.
Everything is a node. A folder is a node with children, a file is a node with content. The id is the contract: it survives renames and moves. Build automation on ids, not on paths.
Every file carries a revision that increases by one on each write. Writing calls take the revision you last saw; if it no longer matches, the server answers 409 REVISION_CONFLICT instead of overwriting someone else's work. Re-read, re-apply your change, send again.
| Parameter | Type | Description |
|---|---|---|
id | uuid | Stable identifier of a node. Never changes, not on rename and not on move. |
type | "folder" | "file" | Folder or file. Decides which fields are set: childCount only on folders, sizeBytes and revision only on files. |
kind | "document" | "presentation" | "deck" | "sheet" | "sketch" | "text" | "markdown" | "code" | "pdf" | "image" | null | The file kind, derived from the MIME type by the server. Do not rebuild it yourself or you maintain the same mapping twice. |
revision | integer | Counter of the file content. Increases by one on every write and is the basis of every conflict check. |
role | "owner" | "editor" | "commenter" | "viewer" | Your role on this node, inherited along the folder chain. owner may do everything, editor may write, commenter may comment, viewer may read. |
projectId | uuid | null | Set when the node lives in a project space instead of the personal one. Moving between the two is not possible. |
mountId | uuid | null | Set when the node comes from a mounted drive. Such nodes belong to the source system: moving in or out is blocked. |
1curl "https://app.anymize.ai/api/v1/workspace/usage" \2 -H "Authorization: Bearer YOUR_API_KEY" Create, read, change and trash folders and files. This is the core of the API; everything else hangs off a node id.
Children of a folder, or the root when no parent is given. Folders carry childCount for the fill level, files the state of their preview.
/api/v1/workspace/nodesQuery
| Parameter | Type | Description |
|---|---|---|
parentId | uuid | Parent folder. Omit for the root. |
projectId | uuid | Project storage instead of personal storage. |
{
"nodes": [
{
"id": "1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63",
"type": "folder",
"name": "Angebote",
"kind": null,
"color": "teal",
"icon": "chart",
"childCount": 14,
"thumbnailState": "unsupported",
"updatedAt": "2026-08-11T09: 12: 00.000Z"
},
{
"id": "7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05",
"type": "file",
"name": "Q3.xlsx",
"kind": "sheet",
"sizeBytes": 48213,
"revision": 3,
"thumbnailState": "ready",
"updatedAt": "2026-08-11T09: 20: 00.000Z"
}
],
"breadcrumbs": [],
"role": "owner"
}| 404 | NOT_FOUND | The node does not exist, or you may not see it. Both answer alike: an API that tells the two apart reveals the existence of other people's files. |
1curl "https://app.anymize.ai/api/v1/workspace/nodes?parentId=1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63" \2 -H "Authorization: Bearer YOUR_API_KEY" Metadata of a node. Breadcrumbs and content come only with content=1.
/api/v1/workspace/nodes/:idQuery
| Parameter | Type | Description |
|---|---|---|
content | "1" | With 1, Word files additionally return the editor content as JSON, including paragraph styles, headers and footers and comments. |
{
"node": {
"id": "6f1c2b7e-9a44-4f0d-8f2b-1e7d3c5a9b10",
"parentId": null,
"projectId": null,
"type": "file",
"name": "Angebot Q3.docx",
"mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"sizeBytes": 48213,
"revision": 3,
"starred": false,
"color": null,
"icon": null,
"description": null,
"trashedAt": null,
"role": "owner",
"updatedAt": "2026-08-24T09: 20: 00.000Z"
}
}| 404 | NOT_FOUND | The node does not exist, or you may not see it. Both answer alike: an API that tells the two apart reveals the existence of other people's files. |
| 415 | NOT_READABLE | This file cannot be read as editor content. Download it instead. |
| 422 | IMPORT_FAILED | The document could not be translated into the editor form. Downloading and opening it in Word still works. |
| 502 | BLOB_UNAVAILABLE | The row is alive, the stored object is not. Not a fault of your call; report the file if this happens repeatedly. |
Creates a folder, or an empty Word, Excel or PowerPoint file from the matching template.
/api/v1/workspace/nodesBody
| Parameter | Type | Description |
|---|---|---|
kindrequired | "folder" | "doc" | "sheet" | "slides" | "sketch" | Kind of the new node. |
namerequired | string (1-255) | Name, up to 255 characters. |
parentId | uuid | null | Parent folder. Omit for the root. |
projectId | uuid | null | Project storage instead of personal storage. |
sheetName | string (1-31) | Name of the first worksheet in a new workbook. Defaults to Tabelle1. |
{
"node": {
"id": "6f1c2b7e-9a44-4f0d-8f2b-1e7d3c5a9b10",
"parentId": null,
"projectId": null,
"type": "file",
"name": "Angebot Q3.docx",
"mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"kind": "document",
"sizeBytes": 48213,
"revision": 3,
"starred": false,
"isAnonymized": false,
"anonymizationStatus": "none",
"anonymizationStale": false,
"color": null,
"icon": null,
"childCount": null,
"thumbnailState": "ready",
"updatedAt": "2026-08-24T09: 20: 00.000Z",
"createdAt": "2026-08-11T09: 12: 00.000Z"
}
}| 400 | INVALID_BODY | The body does not match the expected schema. |
| 403 | FORBIDDEN | You may not write in the target folder. |
| 413 | QUOTA_EXCEEDED | The account storage is full, or the file would blow it. Trash and kept versions count towards it. |
1curl -X POST "https://app.anymize.ai/api/v1/workspace/nodes" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json" \4 -d '{"kind":"sheet","name":"Umsatz Q3","parentId":null}' Rename, star, set the folder appearance, or save editor content. Exactly one of these shapes per call.
/api/v1/workspace/nodes/:idBody
| Parameter | Type | Description |
|---|---|---|
name | string (1-255) | New name. |
parentId | uuid | null | Move. null means the root of the personal space. |
description | string (0-2000) | null | Free-text description, at most 2000 characters. null removes it. |
starred | boolean | Set or clear the personal star. |
color | string | null | Folder colour key (amber, tuareg, teal, green, red, purple, pink, slate). null resets it. |
icon | string | null | Folder icon key (star, team, project, document, image, chart, money, lock, code, cloud, flag, heart). null removes the icon. |
agentRead | boolean | null | Folder lock: may agents read here? null means the setting is inherited from above. |
agentWrite | boolean | null | Folder lock: may agents write here? null means the setting is inherited from above. |
doc | object | Editor content; also requires revision. |
revision | integer | The revision your change is based on. Required for every content write. |
| 400 | INVALID_BODY | The body carries none or more than one of the allowed shapes. |
| 403 | FORBIDDEN | You lack the permission for this change. Moving and the agent lock are reserved for the owner. |
| 409 | REVISION_CONFLICT | Someone changed the file in the meantime. Re-read, apply your change to the new state and send again. |
| 400 | NOT_A_FOLDER | Colour and icon exist on folders only. The server rejects them on a file instead of silently swallowing them. |
| 422 | SCOPE_CHANGE | Source and target lie in different scopes. Moving between personal and project space is not provided for. |
| 422 | MOUNT_TARGET | Source or target belongs to a mounted drive. The next sync would take the move apart. |
1curl -X PATCH "https://app.anymize.ai/api/v1/workspace/nodes/1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json" \4 -d '{"color":"teal","icon":"chart"}' Moves the node to the trash. For a folder the whole subtree goes with it.
/api/v1/workspace/nodes/:id| 404 | NOT_FOUND | The node does not exist, or you may not see it. Both answer alike: an API that tells the two apart reveals the existence of other people's files. |
Puts the node back where it was. If the parent folder is gone it lands in the root.
/api/v1/workspace/nodes/:id/restore| 404 | NOT_FOUND | The node does not exist, or you may not see it. Both answer alike: an API that tells the two apart reveals the existence of other people's files. |
Irreversibly removes a node that is already in the trash, together with all kept versions.
/api/v1/workspace/nodes/:id/permanent| 404 | NOT_FOUND | The node does not exist, or you may not see it. Both answer alike: an API that tells the two apart reveals the existence of other people's files. |
| 409 | NOT_IN_TRASH | The node is not in the trash. |
| 409 | PURGE_CONFLICT | The node is being changed right now. Try again shortly. |
Personal star. Read access is enough: whoever may see a node may star it for themselves. Idempotent.
/api/v1/workspace/nodes/:id/star{
"starred": true
}Removes the personal star. Idempotent.
/api/v1/workspace/nodes/:id/star{
"starred": false
}The id is the contract, the path is the convenience. When you only know a file by its name, resolve it to an id once and work with that afterwards.
Takes a path such as /Vertraege/Miete.docx and returns the node together with breadcrumbs. Meant as an entry point: afterwards you work with the returned id.
/api/v1/workspace/nodes/by-pathQuery
| Parameter | Type | Description |
|---|---|---|
pathrequired | string | Absolute path starting with /. Segments are matched against child names, case-insensitively. A lone / means the root. |
children | "1" | With 1, a folder additionally returns its direct children, saving the second call. |
{
"node": {
"id": "7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05",
"type": "file",
"name": "Miete.docx",
"kind": "document",
"revision": 4
},
"path": "/Vertraege/Miete.docx",
"breadcrumbs": [
{
"id": "1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63",
"name": "Vertraege"
}
],
"role": "owner"
}| 400 | INVALID_PATH | The path is empty, goes deeper than 32 levels, contains a segment made only of dots, or a forbidden character. A missing leading slash, by contrast, is allowed. |
| 404 | NOT_FOUND | A segment of the path does not exist, or you may not see it. Both answer alike so the route does not reveal other people's folder names. |
1curl -G "https://app.anymize.ai/api/v1/workspace/nodes/by-path" \2 --data-urlencode "path=/Vertraege/Miete.docx" \3 -H "Authorization: Bearer YOUR_API_KEY" One endpoint for reading, writing, replacing, creating, moving and deleting via paths: the same route the agent tools take. Handy for text files and workbooks when you do not want to manage ids.
/api/v1/workspace/fsBody
| Parameter | Type | Description |
|---|---|---|
aktionrequired | "read" | "write" | "edit" | "manage" | "create_xlsx" | "update_xlsx" | Which operation. read reads a text file, write creates or replaces it, edit swaps a passage, manage creates folders, moves and deletes, create_xlsx and update_xlsx write workbooks. |
path | string | Absolute path inside the personal space. |
content | string | The complete new content for aktion=write. |
alt / neu | string | For aktion=edit: alt is the passage to replace, neu the replacement. If alt occurs more than once you need alle_vorkommen. |
unteraktion | "mkdir" | "move" | "delete" | For aktion=manage: mkdir creates a folder, move moves to to, delete puts it in the trash. |
name | string (1-200) | Only with aktion=create_xlsx: name of the new workbook, at most 200 characters. |
folder_id | uuid | null | Only with aktion=create_xlsx: target folder. Without it, the root. |
workbook | object | The workbook tree: sheets with rows and cells. Required for create_xlsx and update_xlsx. |
node_id | uuid | Only with aktion=update_xlsx: which workbook is changed. |
revision | integer | Only with aktion=update_xlsx: the revision your change is based on. |
| 403 | FORBIDDEN | The path points outside the personal space, or a folder lock blocks the folder. |
| 409 | REVISION_CONFLICT | Someone changed the file in the meantime. Re-read, apply your change to the new state and send again. |
| 409 | WOULD_DESTROY_CONTENT | Only with aktion=update_xlsx. Full replacement is blocked because the workbook was not created by anymize, or it carries content we cannot rebuild without loss (charts, merged cells). The hint names the reason. For targeted cell changes use PATCH /nodes/:id/sheet. |
| 415 | NOT_A_XLSX | The file is not an Excel workbook. |
Getting content in and out again. Small files in one call, large ones in chunks, plus export to nine formats.
Creates a new file and generates its thumbnail in the same step. The server checks that the content matches the extension and rejects zip packages with a suspicious compression ratio.
/api/v1/workspace/uploadRequest: multipart/form-data
Body
| Parameter | Type | Description |
|---|---|---|
filerequired | File | The file content as the form field file. |
parentId | uuid | Parent folder. Omit for the root. |
projectId | uuid | Project storage instead of personal storage. |
withAnonymization | "true" | "1" | Asks for the document to be anonymized on upload. |
| 400 | FILE_MISSING | The form has no file field, or it does not contain a file. |
| 413 | FILE_TOO_LARGE | The file exceeds 50 MiB. |
| 415 | CONTENT_MISMATCH | The content does not match the file extension. A PDF named .docx is rejected so the editor does not choke on it later. |
| 415 | ZIP_RATIO_SUSPICIOUS | The Office package expands suspiciously far, holds too many entries or is too large when unpacked. |
1curl -X POST "https://app.anymize.ai/api/v1/workspace/upload" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -F "file=@Angebot.docx" \4 -F "parentId=1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63" Rewrites the raw bytes of an existing file without creating a second node. The previous state moves into the versions and the revision goes up by one.
/api/v1/workspace/nodes/:id/contentRequest: application/octet-stream
Query
| Parameter | Type | Description |
|---|---|---|
revision | integer | The revision you last saw. If it differs the server answers 409 instead of overwriting. Leave it out and you overwrite blindly. |
{
"node": {
"id": "7f2a…",
"revision": 5,
"sizeBytes": 51200
}
}| 403 | FORBIDDEN | You have no write permission on this node. |
| 409 | REVISION_CONFLICT | Someone changed the file in the meantime. Re-read, apply your change to the new state and send again. |
| 413 | FILE_TOO_LARGE | The file exceeds 50 MiB. |
| 415 | CONTENT_MISMATCH | The content does not match the file extension. A PDF named .docx is rejected so the editor does not choke on it later. |
1curl -X PUT "https://app.anymize.ai/api/v1/workspace/nodes/7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05/content?revision=4 " \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/octet-stream" \4 --data-binary @Angebot.docxCreates an upload session. You get back an address to send the file to in ranges; if the connection drops you continue at the same offset instead of starting over.
/api/v1/workspace/uploadsBody
| Parameter | Type | Description |
|---|---|---|
namerequired | string (1-255) | Name, up to 255 characters. |
sizeBytesrequired | integer | The total size of the file in bytes. The server checks it upfront against the file limit and the quota instead of rejecting you after the last chunk. |
parentId | uuid | null | Parent folder. Omit for the root. |
projectId | uuid | null | Project storage instead of personal storage. |
nodeId | uuid | Instead of creating a new file, replace the content of this existing node. |
revision | integer | The revision you last saw. If it differs the server answers 409 instead of overwriting. Leave it out and you overwrite blindly. |
{
"uploadUrl": "https://app.anymize.ai/api/v1/workspace/uploads/8f4c1a02-77d3-4b6e-9c31-5ad0e2f81b64",
"sessionId": "8f4c1a02-77d3-4b6e-9c31-5ad0e2f81b64",
"expiresAt": "2026-08-24T11: 20: 00.000Z",
"chunkSizeBytes": 8388608,
"nextExpectedRanges": [
"0-"
]
}| 413 | FILE_TOO_LARGE | The file exceeds 50 MiB. |
| 413 | QUOTA_EXCEEDED | The account storage is full, or the file would blow it. Trash and kept versions count towards it. |
| 415 | BLOCKED_TYPE | Files of this type are blocked in the workspace: executable, macro-enabled or scriptable. |
| 415 | UNSUPPORTED_TYPE | The extension is not on the allowlist, or the name has none at all. |
Sends one range of the file. The Content-Range header says which one. While something is still missing the server answers 202 and names where to continue in nextExpectedRanges; with the last range it answers 201 and returns the finished node.
/api/v1/workspace/uploads/:sessionIdRequest: application/octet-stream
{
"sessionId": "8f4c1a02…",
"nextExpectedRanges": [
"8388608-"
],
"expiresAt": "2026-08-24T11: 20: 00.000Z"
}{
"node": {
"id": "7f2a…",
"name": "Praesentation.pptx",
"revision": 1,
"sizeBytes": 41943040
}
}| 400 | INVALID_RANGE | The Content-Range header is missing or unreadable. |
| 404 | SESSION_NOT_FOUND | This session does not exist, or it belongs to another account. |
| 409 | RANGE_MISMATCH | The range sent does not start where the last one ended. The response names the right offset in nextExpectedRanges. |
| 409 | REVISION_CONFLICT | Someone changed the file in the meantime. Re-read, apply your change to the new state and send again. |
| 410 | SESSION_EXPIRED | The session has expired. Start a new one; the chunks already sent are discarded. |
| 413 | QUOTA_EXCEEDED | The account storage is full, or the file would blow it. Trash and kept versions count towards it. |
| 415 | CONTENT_MISMATCH | The content does not match the file extension. A PDF named .docx is rejected so the editor does not choke on it later. |
1curl -X PUT "https://app.anymize.ai/api/v1/workspace/uploads/8f4c1a02-77d3-4b6e-9c31-5ad0e2f81b64" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Range: bytes 0 -8388607 /41943040 " \4 -H "Content-Type: application/octet-stream" \5 --data-binary @teil-1 .binSays how many bytes arrived gapless and where to continue. After a client crash this is the only question that matters: without it, starting blindly from zero is all that is left.
/api/v1/workspace/uploads/:sessionId{
"sessionId": "8f4c1a02-77d3-4b6e-9c31-5ad0e2f81b64",
"name": "Praesentation.pptx",
"sizeBytes": 41943040,
"receivedBytes": 16777216,
"nextExpectedRanges": [
"16777216-"
],
"chunkSizeBytes": 8388608,
"expiresAt": "2026-08-24T11: 20: 00.000Z"
}| 404 | SESSION_NOT_FOUND | This session does not exist, or it belongs to another account. |
| 410 | SESSION_EXPIRED | The session has expired. Start a new one; the chunks already sent are discarded. |
Aborts the session and clears the chunks already sent. Without this call the one-hour expiry does it by itself.
/api/v1/workspace/uploads/:sessionIdWithout format the file comes exactly as stored. With format it is converted.
/api/v1/workspace/nodes/:id/downloadResponse: application/octet-stream
Query
| Parameter | Type | Description |
|---|---|---|
format | "docx" | "pdf" | "odt" | "rtf" | "epub" | "md" | "txt" | "html" | "csv" | Target format of the conversion. Without it the original file comes back. |
sheet | string | integer | Only with format=csv: which worksheet, by name or by zero-based index. Without it the first visible one. |
| 400 | INVALID_FORMAT | The server does not know the requested format, or format was given more than once. |
| 400 | INVALID_QUERY | A query parameter is missing, given twice or unreadable. |
| 415 | NOT_EXPORTABLE | The requested format does not exist for this file type. |
| 502 | CONVERSION_FAILED | The converter could not process the file. Retrying rarely helps; download the original instead. |
| 503 | CONVERTER_UNAVAILABLE | The conversion service is not answering right now. This is temporary: try again later. |
1curl "https://app.anymize.ai/api/v1/workspace/nodes/7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05/download?format=pdf" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -o Angebot.pdfCreates a copy of a file. The copy starts at revision 1 and carries neither the versions nor the comments of the original.
/api/v1/workspace/nodes/:id/copyBody
| Parameter | Type | Description |
|---|---|---|
namerequired | string (1-255) | Name of the copy. The original extension is kept. |
| 400 | NOT_A_FILE | The node is a folder; this endpoint only works on files. |
| 409 | NAME_TAKEN | That name already exists in the target folder. |
Serves the finished preview image. It is generated on upload, not on request - that is why it appears instantly.
/api/v1/workspace/nodes/:id/thumbnailResponse: image/webp
| 404 | NO_THUMBNAIL | There is no thumbnail. The state field of the response says why: unsupported for formats without one, failed after a failure. |
Renders a PowerPoint file as PDF so you can display it without downloading. The result is cached per node and revision.
/api/v1/workspace/nodes/:id/previewResponse: application/pdf
| 404 | UNSUPPORTED_TYPE | Only presentations have such a preview. |
| 503 | PREVIEW_UNAVAILABLE | The conversion failed. Temporary; you can still download the original. |
Private view of a DOCX, XLSX or PPTX file. Requires CoWork access and permission to read the file. The source and revision stay unchanged; responses are not cached.
/api/v1/workspace/nodes/:id/office-viewResponse: application/pdf | Office MIME | application/json
Query
| Parameter | Type | Description |
|---|---|---|
view | "clear" | "anonymized" | clear resolves your available mappings; missing values stay as placeholders. anonymized uses the text service to anonymize text. Images and embedded content stay unchanged. |
format | "pdf" | "native" | "metadata" | pdf returns the styled preview; native returns the original Office format in the selected view. metadata returns revision, hasPlaceholders and canEdit as JSON. |
{
"revision": 7,
"hasPlaceholders": true,
"canEdit": false
}| 400 | INVALID_VIEW | A query parameter is missing, given twice or unreadable. |
| 404 | NOT_FOUND | The node does not exist, or you may not see it. Both answer alike: an API that tells the two apart reveals the existence of other people's files. |
| 415 | OFFICE_VIEW_UNSUPPORTED | DOCX, XLSX and PPTX are supported. |
| 503 | DOCUMENT_ANONYMIZATION_FAILED | Text anonymization failed. No unanonymized fallback file is returned. |
1curl "https://app.anymize.ai/api/v1/workspace/nodes/6f1c2b7e-9a44-4f0d-8f2b-1e7d3c5a9b10/office-view?view=anonymized&format=native" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -o Angebot.docxOnly after an explicit user action and with write permission: resolve all text placeholders and save a new revision. The previous version is retained. People with file access can see the original values. Missing mappings or a changed revision prevent the write.
/api/v1/workspace/nodes/:id/office-viewRequest: application/json
Body
| Parameter | Type | Description |
|---|---|---|
baseRevisionrequired | integer >= 0 | The revision your change is based on. Required for every content write. |
{
"revision": 8,
"hasPlaceholders": false
}| 403 | FORBIDDEN | This request is not yours, or your role does not allow overriding. |
| 409 | REVISION_CONFLICT | Someone changed the file in the meantime. Re-read, apply your change to the new state and send again. |
| 415 | OFFICE_VIEW_UNSUPPORTED | DOCX, XLSX and PPTX are supported. |
| 422 | OFFICE_MAPPINGS_UNAVAILABLE | At least one of your mappings is missing or expired. The source file stays unchanged. |
Stores an image meant to sit inside a document and returns its address. PNG, JPEG, GIF and WebP are allowed; the check reads the first bytes, not the name.
/api/v1/workspace/imagesRequest: multipart/form-data
Body
| Parameter | Type | Description |
|---|---|---|
filerequired | File (png, jpeg, gif, webp) | The image as the form field file. |
{
"url": "/api/v1/workspace/images/9f3c…webp"
}| 415 | UNSUPPORTED_TYPE | The content is not a PNG, JPEG, GIF or WebP. |
Fetches an image from an https address and stores it exactly like an uploaded one.
/api/v1/workspace/images/from-urlBody
| Parameter | Type | Description |
|---|---|---|
urlrequired | string (https) | The source address. https only. |
| 400 | INVALID_URL | The address is unusable or not https. |
| 502 | FETCH_FAILED | The source did not answer, or answered with an error. |
Serves a stored image. Its address comes from the response of the store call.
/api/v1/workspace/images/:nameResponse: image/*
Every write keeps the previous state. You can list, compare and roll back.
The kept versions of a file, newest first. Anyone who may see the file may read them.
/api/v1/workspace/versionsQuery
| Parameter | Type | Description |
|---|---|---|
node_idrequired | uuid | The file in question. |
{
"node_id": "7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05",
"current_revision": 5,
"max_versionen": 10,
"versions": [
{
"id": "b41f…",
"revision": 4,
"size_bytes": 51200,
"actor": "user",
"agent_id": null,
"author": {
"id": "9b2e…",
"name": "Nora Berg"
},
"agent": null,
"author_source": "direct",
"pinned": false,
"label": null,
"created_at": "2026-08-24T09: 20: 00.000Z"
}
]
}| 400 | NOT_A_FILE | The node is a folder; this endpoint only works on files. |
Makes an older version the current state again, or first asks the person whose work would drop out of it.
/api/v1/workspace/versionsBody
| Parameter | Type | Description |
|---|---|---|
node_idrequired | uuid | The file in question. |
revisionrequired | integer | The version that should apply again. |
{
"art": "wiederhergestellt",
"revision": 5
}{
"art": "angefragt",
"requestId": "5b1e…"
}| 409 | ALREADY_PENDING | A consent request is already running for this file. |
| 409 | STALE | Someone was faster: the state changed since you listed it. |
approve agrees, reject declines, override goes ahead anyway. The three end in different states and read differently in an audit report: an override never looks like an approval. Whether you may override is decided by the server from your team role, not by the call.
/api/v1/workspace/restore-requests/:idBody
| Parameter | Type | Description |
|---|---|---|
actionrequired | "approve" | "reject" | "override" | What you decide. |
| 403 | FORBIDDEN | This request is not yours, or your role does not allow overriding. |
| 409 | NOT_PENDING | The request has already been answered. |
Shows line by line what changed between a version and the current state.
/api/v1/workspace/nodes/:id/diffQuery
| Parameter | Type | Description |
|---|---|---|
revisionrequired | integer | The version to compare against. |
| 409 | NO_BASELINE | There is no kept version for this revision. |
| 410 | BLOB_UNAVAILABLE | The row is alive, the stored object is not. Not a fault of your call; report the file if this happens repeatedly. |
| 413 | TOO_LARGE | The file is too large for a comparison. |
| 415 | UNSUPPORTED_FORMAT | There is no comparison for this format. |
Who may see and change what. Shares go to people and to team groups.
All shares on this node, plus the groups you could still grant to.
/api/v1/workspace/nodes/:id/shares{
"shares": [
{
"id": "3a7f0c15-8b62-4d09-91ae-6c0f2d84b731",
"kind": "user",
"email": "kollege@firma.de",
"role": "editor",
"source": "manual",
"syncedAt": null
}
],
"pendingShares": [],
"availableGroups": [
{
"id": "b2c9…",
"name": "Vertrieb"
}
],
"isTeamMember": true,
"canManage": true,
"canManageGroups": true,
"role": "owner"
}Grants access to a person or a team group. With kind=user pass email, with kind=group pass groupId.
/api/v1/workspace/nodes/:id/sharesBody
| Parameter | Type | Description |
|---|---|---|
kindrequired | "user" | "group" | Person or team group. |
email | string | The person's address. Only with kind=user. |
groupId | uuid | Id of the team group. Only with kind=group. |
rolerequired | "viewer" | "editor" | viewer may read, editor may change. |
| 400 | INVALID_ROLE | role must be viewer or editor. |
| 400 | INVALID_KIND | kind must be user or group, and the matching field must be set. |
| 403 | FORBIDDEN | You may not manage shares on this node. Groups may additionally only be granted by the owner. |
| 404 | USER_NOT_FOUND | There is no account for that address. Invite the person first. |
| 409 | MANAGED_BY_SYNC | This share belongs to the source system and cannot be changed here. |
Takes back a single share.
/api/v1/workspace/nodes/:id/sharesQuery
| Parameter | Type | Description |
|---|---|---|
shareIdrequired | uuid | The id from the share list. |
| 409 | MANAGED_BY_SYNC | This share belongs to the source system and cannot be changed here. |
Comments on the document, the change history, your own inbox and the agent lock.
All comment threads on a file, each with its messages and its anchor in the text.
/api/v1/workspace/nodes/:id/comments{
"comments": [
{
"id": "c41f8e07-3b52-4a90-9d16-2c8e5b7a0f43",
"nodeId": "7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05",
"status": "open",
"version": 1,
"anchor": {
"revision": 4,
"from": 120,
"to": 168,
"exactQuote": "Umsatz im dritten Quartal",
"prefix": "",
"suffix": ""
},
"author": {
"id": "9b2e…",
"displayName": "Nora Berg"
},
"resolvedBy": null,
"resolvedAt": null,
"createdAt": "2026-08-24T09: 22: 00.000Z",
"updatedAt": "2026-08-24T09: 22: 00.000Z",
"messages": [
{
"id": "m_1",
"body": "Zahl bitte pruefen.",
"isRoot": true,
"author": {
"id": "9b2e…",
"displayName": "Nora Berg"
},
"createdAt": "2026-08-24T09: 22: 00.000Z",
"updatedAt": "2026-08-24T09: 22: 00.000Z"
}
],
"messagesTruncated": false
}
],
"commentsTruncated": false,
"documentRevision": 4,
"portability": "workspace_only"
}Starts a new thread, optionally anchored to a passage.
/api/v1/workspace/nodes/:id/commentsBody
| Parameter | Type | Description |
|---|---|---|
bodyrequired | string (1-…) | The comment text. |
anchorrequired | object | Where in the document the comment hangs. The server checks that the anchor fits the file. |
anchor.revisionrequired | integer | The document revision the passage refers to. |
anchor.from / torequired | integer | Start and end of the passage. to must be greater than from. |
anchor.exactQuoterequired | string | The quoted text itself, not empty. It is what finds the spot again when the document shifts. |
anchor.prefix / suffix | string | Text before and after. Helps find the spot again when the quote occurs more than once. |
| 400 | INVALID_BODY | anchor is missing or incomplete. A comment without a passage is not provided for in the workspace; the schema also accepts no unknown field. |
| 403 | FORBIDDEN | You have no write permission on this node. |
Changes the text, anchor or state of a thread, for instance to mark it resolved.
/api/v1/workspace/nodes/:id/comments/:threadIdBody
| Parameter | Type | Description |
|---|---|---|
versionrequired | integer | The thread state you saw. Protects against deleting a reply that arrived in between. |
status | "open" | "resolved" | open or resolved. This is how you tick off a thread. |
anchor | object | Where in the document the comment hangs. The server checks that the anchor fits the file. |
body | string | The comment text. |
| 400 | INVALID_BODY | The body changes nothing. Give at least one of status, anchor or body. |
| 404 | COMMENT_NOT_FOUND | That thread does not exist on this file. |
| 409 | COMMENT_VERSION_CONFLICT | Someone changed the thread in the meantime. Re-read it and send the new version along. |
Removes a thread with its messages. Answers 204 with no body.
/api/v1/workspace/nodes/:id/comments/:threadIdQuery
| Parameter | Type | Description |
|---|---|---|
versionrequired | integer | The thread state you saw. Protects against deleting a reply that arrived in between. |
| 400 | INVALID_VERSION | version is missing from the query or is not a positive number. |
| 409 | COMMENT_VERSION_CONFLICT | Someone changed the thread in the meantime. Re-read it and send the new version along. |
Appends a message to an existing thread.
/api/v1/workspace/nodes/:id/comments/:threadId/messagesBody
| Parameter | Type | Description |
|---|---|---|
versionrequired | integer | The thread state you saw. Protects against deleting a reply that arrived in between. |
bodyrequired | string | The comment text. |
| 409 | COMMENT_VERSION_CONFLICT | Someone changed the thread in the meantime. Re-read it and send the new version along. |
For a file its own history, for a folder the history of its content.
/api/v1/workspace/nodes/:id/activityQuery
| Parameter | Type | Description |
|---|---|---|
limit | integer | How many entries at most. The server caps it on top. |
What concerns you: new shares, comments addressed to you, consent requests. Always your own inbox: the user id comes from the authentication, never from the call.
/api/v1/workspace/inboxQuery
| Parameter | Type | Description |
|---|---|---|
limit | integer | How many entries at most. |
unread | "1" | With 1, only the unread ones. |
Either a list of ids or everything at once. One of the two must be set.
/api/v1/workspace/inboxBody
| Parameter | Type | Description |
|---|---|---|
ids | uuid[] (max 200) | The entries to mark. At most 200. |
all | boolean | Mark everything. |
Says whether agents may read and write this node. The lock is set via PATCH on the node, and only by the owner.
/api/v1/workspace/nodes/:id/agent-lock{
"read": true,
"write": false,
"readGeerbt": true,
"writeGeerbt": false
}Finding files and fetching the home views.
Searches case-insensitively in the name of every node you may see. All parameters are optional and can be combined.
/api/v1/workspace/searchQuery
| Parameter | Type | Description |
|---|---|---|
q | string (max 255) | The search term. Without it you get every visible node, filtered by the remaining parameters. |
kind | "all" | "folder" | "file" | Folders only, files only, or both. |
owner | "alle" | "ich" | "andere" | ich limits to your own nodes, andere to those shared with you. |
locationId | uuid | Folder to search in. |
modifiedFrom | ISO-8601 | Only nodes changed since this point in time. |
modifiedTo | ISO-8601 | Only nodes changed up to this point in time. |
| 400 | INVALID_QUERY | A query parameter is missing, given twice or unreadable. |
The home views: recently used, shared with you, starred, trash and the activity stream. home additionally returns the folders.
/api/v1/workspace/overviewQuery
| Parameter | Type | Description |
|---|---|---|
view | "home" | "activity" | "recent" | "shared" | "starred" | "trash" | Which view. |
| 400 | INVALID_VIEW | That view does not exist. |
What changed since the last call? This keeps a copy up to date without walking the whole tree.
The loop is always the same: first call without cursor, then with the last one received. The response ALWAYS carries a new cursor, even when nothing came. How it is built is none of your business: pass it back unchanged.
One page of the change stream together with the cursor for the next call.
/api/v1/workspace/deltaQuery
| Parameter | Type | Description |
|---|---|---|
cursor | string | The cursor from the last response. Omit it on the first call. |
limit | integer | How many changes per page at most. The server caps it on top. |
{
"changes": [
{
"id": "3f8a1c47-2e5b-4d90-8a16-7c0e9b4d2f31",
"action": "updated",
"at": "2026-08-24T09: 20: 00.000Z",
"node": {
"id": "7f2a5e91-0c6d-4b83-8e14-9d3f7a2c6b05",
"name": "Q3.xlsx",
"type": "file",
"parent_id": "1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63",
"revision": 4,
"trashed_at": null
},
"actor": {
"user_id": "9b2e…",
"agent_id": null
}
},
{
"id": "5d0c7b22-9a13-4e68-b7f4-3e1a8c0d5629",
"action": "trashed",
"at": "2026-08-24T09: 24: 00.000Z",
"node": {
"id": "1c9f6d2a-3b48-4c11-9a7e-2f5b8d0c4e63",
"name": "Angebote",
"type": "folder",
"parent_id": null,
"revision": null,
"trashed_at": "2026-08-24T09: 24: 00.000Z"
},
"actor": {
"user_id": "9b2e…",
"agent_id": null
}
}
],
"cursor": "eyJ0IjoiMjAyNi0wOC0yNFQwOToyNDowMFoiLCJpIjoiMWM5Zi4uLiJ9",
"has_more": false
}1let cursor = null 2for (;;) {3 const url = new URL("https://app.anymize.ai/api/v1/workspace/delta" )4 if (cursor) url.searchParams.set("cursor" , cursor)5 const page = await fetch(url, {6 headers: { Authorization: `Bearer ${process.env.ANYMIZE_API_KEY}` },7 }).then((r) => r.json())89 // change.action + change.node.* - siehe die Antwortform oben. 10 for (const change of page.changes) apply(change.action, change.node)11 cursor = page.cursor1213 // has_more heisst: sofort weiterfragen. Erst bei false warten. 14 if (!page.has_more) break15}Read, search, analyse and change Excel workbooks sheet by sheet.
Returns a window of one worksheet. Formulas are evaluated locally when possible; when not, the last stored value comes back.
/api/v1/workspace/nodes/:id/sheetQuery
| Parameter | Type | Description |
|---|---|---|
sheet | string | integer | Which sheet, by name or zero-based index. Without it the first visible one. |
fromRow | integer | First row of the window, counted from 1. |
toRow | integer | Last row of the window. The server caps the window size. |
view | "externalData" | With externalData the directory of external references comes back instead of the sheet projection. |
| 400 | XLSX_INVALID_ADDRESS | A cell or range address is unreadable. |
| 404 | XLSX_SHEET_NOT_FOUND | That sheet does not exist in the workbook. |
| 415 | NOT_A_XLSX | The file is not an Excel workbook. |
Takes a list of operations: write cells, insert or delete rows and columns, sort and import, create or rename sheets, set rules, cut external data. Exactly one of the six lists per call, otherwise 400 INVALID_BODY.
/api/v1/workspace/nodes/:id/sheetBody
| Parameter | Type | Description |
|---|---|---|
revisionrequired | integer | The revision your change is based on. Required for every content write. |
operations | object[] | Cell operations: values, formulas, formats. |
structureOperations | object[] | Insert, delete, hide or resize rows and columns. |
dataOperations | object[] | Sort, remove duplicates, import text, split text into columns. |
sheetOperations | object[] | Create, rename, move or delete sheets. |
ruleOperations | object[] | Create, change or remove conditional formatting and pivot rules. |
externalDataOperations | object[] | Maintain the workbook's external references. The same directory that GET with view=externalData reads. |
| 400 | INVALID_BODY | The body does not match the schema, or it does not set exactly one of the six operation lists. Two lists at once is the same error as none. |
| 400 | FORMULA_TRANSLATION_FAILED | The formula could not be parsed. The hint names sheet, cell and position. Almost always a localized notation is behind it: semicolon instead of comma between arguments, or a function name in a national language. |
| 409 | REVISION_CONFLICT | Someone changed the file in the meantime. Re-read, apply your change to the new state and send again. |
| 409 | DATA_VALIDATION_CONFIRMATION_REQUIRED | The change violates a validation rule of the workbook. The response lists the violations; repeat the call with the supplied confirmation if you want it anyway. |
| 413 | BODY_TOO_LARGE | The body exceeds 8 MiB. Split the import into several calls. |
| 422 | WOULD_OVERWRITE_CELLS | The operation would have overwritten occupied cells. State explicitly that you want that, or choose another range. |
Searches across all sheets and replaces on request. Replacing needs write permission and the current revision.
/api/v1/workspace/nodes/:id/sheet/searchReturns figures about a range without changing the workbook.
/api/v1/workspace/nodes/:id/sheet/analysisPage setup, headers and footers, and the two writing aids.
Format, orientation and margins of the document.
/api/v1/workspace/nodes/:id/docx/page-setupBody
| Parameter | Type | Description |
|---|---|---|
revisionrequired | integer | The revision your change is based on. Required for every content write. |
format | "A4" | "Letter" | Page format. |
orientation | "portrait" | "landscape" | Portrait or landscape. |
margins | { top, right, bottom, left } | Margins in twips, settable individually. A twip is one twentieth of a point. |
| 400 | INVALID_BODY | The body contains no change. Give at least one of format, orientation or margins. |
| 400 | INVALID_PAGE_SETUP | The values do not form a valid page setup, for instance because the margins are wider than the page. |
| 415 | NOT_EDITABLE | This route only edits .docx files, and this file is not one. Not to be confused with 422 UNSUPPORTED_FEATURE: that is a .docx whose formatting we cannot write back without loss. |
| 422 | UNSUPPORTED_FEATURE | The document contains formatting we cannot write back without loss. The response names it in features. |
Sets the document's headers and footers, optionally separately for the first page and for even and odd pages.
/api/v1/workspace/nodes/:id/docx/header-footerBody
| Parameter | Type | Description |
|---|---|---|
revisionrequired | integer | The revision your change is based on. Required for every content write. |
header / footer | object | The new content. Leaving it out keeps that line unchanged. |
| 422 | UNSUPPORTED_FEATURE | The document contains formatting we cannot write back without loss. The response names it in features. |
Suggests the next three or four words. When nothing obvious fits, completion: null comes back.
/api/v1/workspace/nodes/:id/completeBody
| Parameter | Type | Description |
|---|---|---|
prefixrequired | string | The text immediately before the caret. |
language | "de" | "en" | "fr" | "da" | "es" | "no" | Which language to answer in. |
{
"completion": " im dritten Quartal"
}Reports spelling and grammar spots with suggestions. Names, product names, addresses and numbers are left alone.
/api/v1/workspace/nodes/:id/proofreadBody
| Parameter | Type | Description |
|---|---|---|
textrequired | string | The text to check. |
language | "de" | "en" | "fr" | "da" | "es" | "no" | Which language to answer in. |
{
"spelling": [
{
"word": "Angbot",
"suggestion": "Angebot"
}
],
"grammar": []
}Mount a drive from another storage system and sync it. Supported providers are google, microsoft, nextcloud and webdav.
All mounted drives of the account with their sync state.
/api/v1/workspace/mountsMounts a folder of a connected provider as a drive. The provider must be connected as a connector beforehand.
/api/v1/workspace/mountsBody
| Parameter | Type | Description |
|---|---|---|
providerrequired | "google" | "microsoft" | "nextcloud" | "webdav" | The drive's provider. |
labelrequired | string | Display name of the drive in the workspace. |
remoteToken | string | Folder reference from the provider's file picker. Without it, the root. |
remoteName | string | Name of the folder at the provider, for display only. |
syncMode | "manual" | "auto" | manual syncs on request, auto by itself. |
| 400 | NOT_A_FOLDER | The reference points at a file, not at a folder. |
| 409 | CONNECTOR_MISSING | No account is connected for this provider, or the access has expired. Connect it in the settings first. |
Changes the display name, sync mode, state or permission takeover.
/api/v1/workspace/mounts/:idBody
| Parameter | Type | Description |
|---|---|---|
label | string | Display name of the drive in the workspace. |
syncMode | "manual" | "auto" | manual syncs on request, auto by itself. |
status | "idle" | "paused" | paused halts the sync, idle resumes it. |
syncPermissions | boolean | Take over permissions as well. Switching it off removes the shares already taken over from this drive. |
Removes the mount. Nothing is deleted at the provider itself.
/api/v1/workspace/mounts/:idSyncs the drive now and reports what came out of it.
/api/v1/workspace/mounts/:id/sync{
"success": true,
"imported": 42,
"skipped": 3,
"folders": 7,
"permissions": {
"granted": 12,
"unchanged": 30,
"revoked": 1,
"pending": 2,
"skipped": 4
},
"permissionsTruncated": false,
"filesTruncated": false
}| 409 | BUSY | A sync is already running for this drive. |
| 409 | CONNECTOR_MISSING | No account is connected for this provider, or the access has expired. Connect it in the settings first. |
The same API and the same documentation, for assistants instead of your code. An MCP-capable client (Claude, Cursor, your own agent) gets tools here for the documentation, for your files and for your workflows.
Thirteen tools in three groups. docs_list, docs_search and docs_get look things up in this documentation. workspace_list, workspace_resolve_path, workspace_search, workspace_read_file, workspace_write_file, workspace_manage and workspace_changes work on your files. workflows_list, workflows_get and workflows_run drive your workflows.
1{2 "mcpServers" : {3 "anymize" : {4 "type" : "http" ,5 "url" : "https://app.anymize.ai/api/mcp/anymize" ,6 "headers" : {7 "Authorization" : "Bearer YOUR_API_KEY" 8 }9 }10 }11}The same API and the same documentation, for assistants instead of your code. An MCP-capable client (Claude, Cursor, your own agent) gets tools here for the documentation, for your files and for your workflows.
/api/mcp/anymizeRequest: application/json·Response: application/json
What an account may hold, how fast you may ask, and what errors look like.
| Parameter | Type | Description |
|---|---|---|
maxBytesPerUser | 2 GiB | Storage per account. Trash and kept versions count towards it. |
maxFiles | 5000 | Number of files per account. |
maxFileSizeBytes | 50 MiB | Size of a single file. |
How much space the account takes and how many files it holds.
/api/v1/workspace/usage{
"bytesUsed": 184320119,
"maxBytes": 2147483648,
"fileCount": 312,
"maxFiles": 5000
}