Przio · Assets API ← Assets Manager guide

Assets Manager — API reference

REST endpoints for folders, files, content blocks, and data-table definitions under /api/projects/<projectId>/assets. Multipart uploads use /assets/upload. Row ingest and reads use /api/projects/<projectId>/data/… (see Data rows section).

Base URL

Replace PROJECT_ID with your MongoDB project id (same as in the app URL). Examples use https://app.przio.com; use your self-hosted origin if applicable.

  • /api/projects/PROJECT_ID/assets
  • /api/projects/PROJECT_ID/assets/upload
  • /api/projects/PROJECT_ID/data/session (and other /data/… routes)

Authentication

Method Auth
GET /assets User JWT (Bearer or session cookie as in the app) or X-API-Key: … / Authorization: Bearer <api_key> scoped to the same project. API key access is read-only for this route.
POST /assets/upload User JWT only (member of the project). API keys are not accepted for multipart upload.
POST /assets User JWT only.
PUT /assets User JWT only.
DELETE /assets User JWT only.

Create API keys under project settings. Treat keys like secrets; for browser-side read of folder JSON, use X-API-Key on GET /assets and restrict exposure if possible.

Endpoints by folder type

Each folder has folderType assets, content, or data. The same /assets resource handles all three; the server validates the folder type for each operation.

folderType What it stores Primary operations
assets Binary files (image, video, PDF) and optional image entries by URL. POST /assets/upload, POST /assets (imageUrl), PUT /assets (file metadata), DELETE /assets (file or folder), GET /assets (list or single folder).
content Named contentBlocks with columns and typed fields. POST /assets (contentBlock), PUT /assets (blockId), DELETE /assets (contentBlockId), GET /assets (folder or blockId / blockName).
data dataTables definitions (keys, hashes for write/read/share). Row data lives in ProjectDataRow, not inside the folder document. POST /assets (dataTable — returns write key once), PUT /assets (table metadata, rotate keys), DELETE /assets (table or rows), GET /assets (folder metadata). Row CRUD: /data/session, /data/rows, etc.

GET /api/projects/PROJECT_ID/assets

JSON response always includes projectId. Responses include CORS headers suitable for browser fetch from allowed origins.

Query Response
(none) { "folders": [...], "projectId" } — all folders; file URLs and blocks included; data tables show writeKeyConfigured, readKeyConfigured, shareLinkConfigured (never the raw keys).
folderId { "folder": {...}, "projectId" } — one folder.
folderId + blockId or blockName { "block": {...}, "folderId": "…", "projectId": "…" } — single content block.
blockId or blockName (no folderId) Searches all folders for the block.
curl -s -H "X-API-Key: YOUR_KEY" \
  "https://app.przio.com/api/projects/PROJECT_ID/assets?folderId=FOLDER_ID"

POST /api/projects/PROJECT_ID/assets/upload

multipart/form-data with folderId (required) and one or more files as files or a single file. Only folderType === "assets" folders accept uploads. Max 25 MB per file. Allowed: images, videos, PDFs (same as UI).

Response 201: { folders: [...] } (updated project folders array).

POST /api/projects/PROJECT_ID/assets

Content-Type: application/json. Exactly one of the following bodies applies per request.

Create folder

{ "folderName": "Marketing media", "folderType": "assets" }

folderType: assets | content | data (default assets). Returns 201 with folders.

Add image by URL (assets folder)

{ "folderId": "fld-...", "imageUrl": "https://cdn.example.com/hero.jpg", "fileName": "optional-display-name" }

Add content block (content folder)

Requires at least one of fields or columns (see app normalization). Block name must be unique per folder (case-insensitive).

{ "folderId": "fld-...", "contentBlock": {
  "name": "homepage-hero",
  "description": "optional",
  "fields": [...],
  "columns": [...]
} }

Create data table (data folder)

Returns dataTableWriteKey once in the response; store it securely.

{ "folderId": "fld-...", "dataTable": {
  "name": "leads",
  "description": "optional",
  "keys": [
    { "name": "email", "type": "string", "unique": true, "required": true },
    { "name": "meta", "type": "json", "maxLength": 10000 }
  ]
} }

Key type: string | number | boolean | json. Optional: unique, required, appendArray, maxLength.

PUT /api/projects/PROJECT_ID/assets

Always include folderId. Branch determined by additional fields:

  • Image metadatafileId + optional title, description, altTag (images only).
  • Content blockblockId + blockName + fields / columns (non-empty).
  • Data tabledataTableId + optional dataTableName, dataTableDescription, dataTableKeys (replaces keys when sent).
  • Rotate write keydataTableId + rotateDataTableWriteKey: true → response includes new dataTableWriteKey once.
  • Rotate read keyrotateDataTableReadKey: truedataTableReadKey once.
  • Rotate share link tokenrotateDataTableShareLinkToken: truedataTableShareLinkToken once (for ?share= URLs).

DELETE /api/projects/PROJECT_ID/assets

JSON body; folderId required.

Body shape Effect
folderId only Deletes the entire folder. For data folders, deletes all rows for that folder. Removes asset files from disk when paths are stored.
folderId + fileId Removes one file from an assets folder (and deletes stored binary when applicable).
folderId + contentBlockId Removes one content block.
folderId + dataTableId Deletes the table definition and all its rows.
folderId + dataTableIds (array) Bulk table delete + rows for each id.
folderId + dataTableId + emptyRowsOnly: true Deletes all rows in that table; keeps the table schema.

Public file URLs

Uploaded binaries are referenced with a url and relativePath such as /project-assets/PROJECT_ID/FOLDER_ID/<filename>. The app serves these under its public /project-assets/… route; use the absolute url returned in GET responses in production.

Data rows APIs

After a data table exists, row operations use separate endpoints under /api/projects/PROJECT_ID/data/…:

  • POST /data/session — exchange writeKey for a short-lived JWT.
  • POST / PUT / PATCH / DELETE /data/rows — mutate rows (auth: session JWT, user JWT, or body includes folderId + tableId as documented).
  • GET /data/rows — list rows with readKey, share / shareToken, or JWT.
  • POST /data/rows/bulk, POST /data/rows/clear, POST /data/rows/query, etc.

Full parameter tables, match filters, and SDK notes live in the product repo file documentation/retrieve-data-api.md.

CORS

GET /assets (and OPTIONS) include Access-Control-Allow-Origin (reflected origin or *) so browser apps on other domains can read folder JSON with an API key. If a reverse proxy answers OPTIONS without forwarding to Next.js, or duplicates CORS headers, browsers may block requests — see frontend/docs/ASSETS_API_CORS.md.