Library
Brand files.
Privacy and analytics
We use necessary technical cookies and, only with your consent, analytics and marketing pixels to improve the website and measure campaigns.
Brand files.
Searches brand files by name, category or type. Agents and external clients only see files approved for agent use; people see what their role allows.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.search |
| MCP tool | library_search |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Nödo, Voice, MCP, API, Chat, Screens, Apps |
| Status | Available |
| Widget | carousel |
Input
{
query?: string // ≤ 200
category?: string // ≤ 60
type?: "image" | "video" | "audio" | "document" | "logo" | "font"
cursor?: string // ≤ 512 · Opaque cursor from a previous `nextCursor`.
limit?: integer // 1–50 · default 20
}Output
{
items: Array<{
id: string // uuid
name: string
category: string | null
mimeType: string
status: "proposed" | "approved" | "archived"
createdAt: string
}>
nextCursor: string | null
}Details of one file plus a signed download URL valid for one hour. The URL is signed from the stored record, never from a caller-supplied path.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.asset.get |
| MCP tool | library_asset_get |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Nödo, Voice, MCP, API, Chat, Screens, Apps |
| Status | Available |
| Widget | record |
Input
{
assetId: string // uuid
}Output
{
id: string // uuid
name: string
category: string | null
mimeType: string
status: "proposed" | "approved" | "archived"
createdAt: string
description: string | null
sizeBytes: integer // -9007199254740991–9007199254740991
url: string // uri
urlExpiresAt: string
}Approves or archives a proposed file, for example an image Nödo generated. Only approved files can be used by agents or published.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.asset.review |
| MCP tool | library_asset_review |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | Yes |
| Doors | Nödo, MCP, API, Chat, Screens, Apps |
| Status | Available |
| Widget | confirm |
Input
{
assetId: string // uuid
decision: "approve" | "archive"
note?: string // ≤ 500
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Returns a signed upload URL for one file within the plan storage quota; call again with complete: true and the upload id to register it.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.upload.create |
| MCP tool | library_upload_create |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, Nödo, Chat, Screens, Apps |
| Status | Planned |
Input
{
step: "start"
fileName: string // ≤ 200
mimeType: string // ≤ 120
sizeBytes: integer // –9007199254740991
category?: string // ≤ 60
}
| {
step: "complete"
uploadId: string
name?: string // ≤ 200
}Output
{
uploadId: string
uploadUrl?: string // uri
assetId?: string // uuid
}Moves up to 100 Library files to the trash, where they can be restored during the recovery window. Files on hold (a publication in progress, a legal hold) are refused.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.trash |
| MCP tool | library_files_trash |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | Yes |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetIds: string[] // ≤ 100 items
}Output
{
ids: string[]
blocked: integer // -9007199254740991–9007199254740991
}Brings up to 100 files back from the trash with the status they had (restoring never approves). Fails once the recovery window is over.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.restore |
| MCP tool | library_files_restore |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetIds: string[] // ≤ 100 items
}Output
{
ids: string[]
blocked: integer // -9007199254740991–9007199254740991
}Deletes for good files that are already in the trash, all or nothing. Owner and admin of the brand only; there is no undo.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.purge |
| MCP tool | library_files_purge |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | Yes |
| Doors | API, Screens, Apps |
| Status | Available |
Input
{
assetIds: string[] // ≤ 100 items
}Output
{
ids: string[]
blocked: integer // -9007199254740991–9007199254740991
}Deletes for good everything in the brand trash; files on hold stay and are counted in blocked. There is no undo.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.trash.empty |
| MCP tool | library_trash_empty |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | Yes |
| Doors | API, Screens, Apps |
| Status | Available |
Input
{}Output
{
ids: string[]
blocked: integer // -9007199254740991–9007199254740991
}Before uploading one file to the Library: checks the category and the plan storage, reserves the bytes and returns a single-use signed upload URL (2 h) for a path the server chooses. Upload the bytes to uploadUrl (HTTP PUT), then call library.files.register with storagePath. Refusals: invalid_input (category), conflict with detail QUOTA_EXCEEDED (plan storage or file size).
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.prepare_upload |
| MCP tool | library_files_prepare_upload |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | Screens, Apps, API |
| Status | Available |
Input
{
fileName: string // ≤ 255
fileSize: integer // –9007199254740991
mimeType: string // ≤ 255
category: string // ≤ 64
}Output
{
storagePath: string
uploadUrl: string // uri
token: string
}Registers in the Library a file already uploaded with its signed URL: checks the stored object matches, counts it against the plan storage, then processes and indexes it. Brand uploads are approved; staff uploads wait for review. Registering the same object twice returns the same file.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.register |
| MCP tool | library_files_register |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | Screens, Apps, API |
| Status | Available |
Input
{
storagePath: string // ≤ 1024
fileName: string // ≤ 255
fileSize: integer // –9007199254740991
mimeType: string // ≤ 255
name: string // ≤ 160
category: string // ≤ 64
description?: string // ≤ 1000
type?: string // ≤ 64
posterPending?: boolean
}Output
{
asset: {
id: string // uuid
}
}Records in the brand Library a copy of a file that lives elsewhere (another Library, a mail, a picture on screen) whose bytes are already stored at its Library path, checked against the stored object. Processed, indexed and counted like an upload, with where it came from in its metadata. Brand imports are approved; staff imports wait for review. The same bytes under the same name return the same file.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.import |
| MCP tool | library_files_import |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | Screens, Apps, API |
| Status | Available |
Input
{
storagePath: string // ≤ 1024
fileName: string // ≤ 180
fileSize: integer // –9007199254740991
mimeType: string // ≤ 255
sha256: string
source: {
kind: string
}
}Output
{
id: string // uuid
name: string
}Changes the name, description, alt text or category of one Library file. altText describes an image for screen readers and publications; an empty string or null clears it. A category and a type that disagree are rejected.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.update |
| MCP tool | library_files_update |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetId: string // uuid
name?: string // ≤ 160
description?: string // ≤ 1000
altText?: string | null
type?: string // ≤ 64
categoryId?: string | null
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Registers as the thumbnail of a Library video the WebP frame the browser already uploaded to the poster path of its current version.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.poster |
| MCP tool | library_files_poster |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | Screens, Apps |
| Status | Available |
Input
{
assetId: string // uuid
width: integer // –10000
height: integer // –10000
fileSize: integer // –1048576
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Moves a Library file to another section by changing its role within its own format (an image can become a logo or a product photo, never a font). Returns the new type.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.files.set_section |
| MCP tool | library_files_set_section |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetId: string // uuid
group: "logos" | "fonts" | "images" | "icons" | "products" | "videos" | "audio" | "documents"
}Output
{
type: string
}Makes an object already uploaded for the file the current version. The file keeps its id; renditions are rebuilt. Fails on another format or over the plan storage.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.versions.commit |
| MCP tool | library_versions_commit |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetId: string // uuid
storagePath: string // ≤ 1024
fileName: string // ≤ 255
}Output
{
version: integer // -9007199254740991–9007199254740991
}Makes an earlier version current again, as a new version on top. Restoring the current version changes nothing.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.versions.restore |
| MCP tool | library_versions_restore |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetId: string // uuid
versionNumber: integer // 1–9007199254740991
}Output
{
version: integer // -9007199254740991–9007199254740991
}Creates one Library collection at the end of the list. Names are unique per brand (conflict otherwise).
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.create |
| MCP tool | library_collections_create |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
name: string // ≤ 80
}Output
{
id: string // uuid
name: string
}Renames one Library collection. Names are unique per brand (conflict otherwise).
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.rename |
| MCP tool | library_collections_rename |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
collectionId: string // uuid
name: string // ≤ 80
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Removes one collection; its files stay in the Library. Returns what was deleted so library.collections.restore can put it back.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.delete |
| MCP tool | library_collections_delete |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | Yes |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
collectionId: string // uuid
}Output
{
collection: {
id: string // uuid
brandId: string // uuid
name: string // ≤ 80
position: integer // -9007199254740991–9007199254740991
items: Array<{
assetId: string // uuid
position: integer // -9007199254740991–9007199254740991
}> // ≤ 2000 items
}
}Undo of library.collections.delete: the same collection comes back with its id, place and files; files removed for good meanwhile are skipped.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.restore |
| MCP tool | library_collections_restore |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
collection: {
id: string // uuid
brandId: string // uuid
name: string // ≤ 80
position: integer // -9007199254740991–9007199254740991
items: Array<{
assetId: string // uuid
position: integer // -9007199254740991–9007199254740991
}> // ≤ 2000 items
}
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Appends up to 100 Library files to a collection; files already in it are skipped. Returns how many were added.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.add_files |
| MCP tool | library_collections_add_files |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
collectionId: string // uuid
assetIds: string[] // ≤ 100 items
}Output
{
added: integer // -9007199254740991–9007199254740991
}Takes one file out of a collection; the file stays in the Library.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.remove_file |
| MCP tool | library_collections_remove_file |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
collectionId: string // uuid
assetId: string // uuid
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Saves the order of the files of one collection in a single write, first to last.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.collections.reorder |
| MCP tool | library_collections_reorder |
| Scope | library.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
collectionId: string // uuid
assetIds: string[] // ≤ 500 items
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Converts or packs brand Library files with a recipe. Light work comes back finished (queued: false, with its signed link); video, audio and large batches are queued (queued: true). Converting needs the plan's library export; at most five exports in flight per person.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.exports.create |
| MCP tool | library_exports_create |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens |
| Status | Available |
Input
{
sources: Array<{
kind: "brand_file"
id: string // uuid
}> // ≤ 50 items
recipe: {
preset: string // ≤ 80
} // An export recipe of the dialog (`lib/file-export/catalog`): a preset and the settings per kind of file.
returnTo?: string | null
}Output
{
ok: true
queued: boolean
job: Record<string, unknown>
}
| {
ok: false
reason: string // ≤ 60
job?: Record<string, unknown>
denial?: Record<string, unknown>
}The real size of one picture after a recipe, without storing anything (and, for a cover crop, where the subject was found); for a font, its variable axes and outline flavour.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.exports.estimate |
| MCP tool | library_exports_estimate |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens |
| Status | Available |
Input
{
source: {
kind: "brand_file"
id: string // uuid
}
recipe: {
preset: string // ≤ 80
} // An export recipe of the dialog (`lib/file-export/catalog`): a preset and the settings per kind of file.
}Output
{
ok: true
}
| {
ok: false
reason: string // ≤ 60
job?: Record<string, unknown>
denial?: Record<string, unknown>
}Cancels one of the person's own exports while it is queued or running; a finished file is left as it is. Returns the job as it stands.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/library.exports.cancel |
| MCP tool | library_exports_cancel |
| Scope | library.write |
| Minimum role | self |
| Human confirmation | No |
| Doors | Screens |
| Status | Available |
Input
{
id: string // uuid
}Output
{
job: Record<string, unknown>
}How many of the brand Library's files sit in the trash (whole files, not their parts).
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.trash.count |
| MCP tool | library_trash_count |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{}Output
{
count: integer // 0–9007199254740991
}One page of the brand Library for one section (all, a file group, collection:<id>, favorites, mine = files the caller uploaded, or trash), ordered as asked; each file says whether it is the caller's (mine). With includeCounts also the rail counts and whether the caller may manage files. The same read the file pickers use.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.files.page |
| MCP tool | library_files_page |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
view: string // ≤ 80
query?: string // ≤ 120
sort?: string // ≤ 20
offset?: integer // 0–5000
includeCounts?: boolean
}Output
{
files: Array<{
id: string
brand_id: string
name: string | null // The file name when the row has no display name of its own.
description: string | null
type: string // The stored role: logo, icon, image, typography, document, video, audio…
status: string // proposed, approved or archived.
file_url: string
thumbnail_url?: string | null
preview_url?: string | null
file_name: string | null
file_size: integer | null
mime_type: string | null
category_id: string | null
created_at: string
show_in_brand_kit?: boolean | null
uploader_name?: string | null
metadata?: Record<string, unknown> | null // Public metadata only (`projectAssetMetadata`): technical, logoVariant, altText…
storage_path?: string | null
storage_bucket?: string | null
group: string // The Library section: logos, fonts, images, icons, products, videos, audio or documents.
agentVisible: boolean
favorite: boolean // The reader's own favourite.
mine: boolean // Uploaded (or saved here) by the reader.
isPrimaryLogo: boolean
audience: string
version: integer // -9007199254740991–9007199254740991
versionsCount: integer // -9007199254740991–9007199254740991
collectionIds: string[]
trashedAt?: string | null
}>
total: integer // -9007199254740991–9007199254740991
nextOffset: integer | null // The `offset` of the next page; null on the last one.
counts: Record<string, integer> | null
collections: Array<{
id: string
name: string
count: integer // -9007199254740991–9007199254740991
coverUrl: string | null
}>
| null
brandName: string
canManage: boolean
isStaff: boolean
primaryLogoAssetId: string | null
trashCount: integer | null
error: "not_allowed" | "read_failed" | null // A page that could not be read answers empty with its reason.
}The file behind a shared ?asset= link, as the preview draws it (trashed files too); file is null when it does not exist or is not the caller's to see.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.files.preview |
| MCP tool | library_files_preview |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetId: string // uuid
}Output
{
file: {
id: string
brand_id: string
name: string | null // The file name when the row has no display name of its own.
description: string | null
type: string // The stored role: logo, icon, image, typography, document, video, audio…
status: string // proposed, approved or archived.
file_url: string
thumbnail_url?: string | null
preview_url?: string | null
file_name: string | null
file_size: integer | null
mime_type: string | null
category_id: string | null
created_at: string
show_in_brand_kit?: boolean | null
uploader_name?: string | null
metadata?: Record<string, unknown> | null // Public metadata only (`projectAssetMetadata`): technical, logoVariant, altText…
storage_path?: string | null
storage_bucket?: string | null
group: string // The Library section: logos, fonts, images, icons, products, videos, audio or documents.
agentVisible: boolean
favorite: boolean // The reader's own favourite.
mine: boolean // Uploaded (or saved here) by the reader.
isPrimaryLogo: boolean
audience: string
version: integer // -9007199254740991–9007199254740991
versionsCount: integer // -9007199254740991–9007199254740991
collectionIds: string[]
trashedAt?: string | null
}
| null
}One-hour signed URLs to view or download Library files: each storagePath must be the original or a variant of a live file of this brand that its members see (brand or public audience); anything else is refused. Up to 100 at once; urls maps asset id to URL.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.files.sign |
| MCP tool | library_files_sign |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assets: Array<{
assetId: string // uuid
storagePath: string // ≤ 1024
}> // ≤ 100 items
}Output
{
urls: Record<string, string>
}The detail page of a Library file with the category catalogue and whether the caller may manage it. A file in the trash answers asset: null and deleted (name, when, who) so its deleted state can be shown instead of a 404.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/library.files.detail |
| MCP tool | library_files_detail |
| Scope | library.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
assetId: string // uuid
}Output
Record<string, unknown>Updated on January 1, 1970