Data Access

Files & Assets

Upload, download, and manage files through the API.
Note
The SDK does not include file upload or download methods — its HTTP client only supports JSON. Use fetch directly for file transfers.

Upload a File

Send a POST request with multipart/form-data to the assets endpoint. The response returns the file IDs only.

// Upload with fetch — the SDK has no upload method
const form = new FormData();
form.append('file', fileInput.files[0]);

const uploadResponse = await fetch('https://example.monospace.io/api/blog/assets', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
  },
  body: form,
});

const { data } = await uploadResponse.json();
const fileId = data[0].id;

// Then query metadata via SDK
const fileMeta = await client.MonospaceFile.readOne({
  key: fileId,
  fields: ['id', 'fileName', 'fileSize', 'mediaType', 'title', 'description'],
});
Known Limitation
The upload response only returns file IDs. To get full metadata like fileName, fileSize, and mediaType, query the MonospaceFile collection in a separate request.
File Size Limit
Uploads are subject to a server-configured maximum file size (MONOSPACE_MAX_FILE_PAYLOAD_SIZE). Requests exceeding this limit receive 413 Payload Too Large.

Upload Multiple Files

Include multiple file fields in a single request. Each field with a filename is treated as a separate file upload.

curl -X POST https://example.monospace.io/api/blog/assets \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file1=@photo.jpg" \
  -F "file2=@document.pdf" \
  -F "file3=@report.csv"

Download a File

Retrieve a file by its ID. Common image, audio, video, and plain-text formats display in the browser; other formats download as attachments. See Content Type Handling for the allow-list.

curl https://example.monospace.io/api/blog/assets/a1b2c3d4-5678-90ab-cdef-1234567890ab \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o photo.jpg

You can include any filename after the file ID in the URL. This is useful for SEO — search engines and link previews will use the filename from the URL:

GET /api/blog/assets/a1b2c3d4-5678-90ab-cdef-1234567890ab/photo.jpg
Note
If MONOSPACE_REDIRECT_ASSET_READ is enabled and the storage connector supports presigned URLs, the server returns a 307 Temporary Redirect. Presigned URLs expire after one hour by default; configure the duration with MONOSPACE_ASSET_PRESIGNED_URL_TTL. Otherwise, the file is streamed directly.

Force a File Download

Files on the inline allow-list are served with Content-Disposition: inline. Add ?download=true to force the browser to download one as an attachment instead. Files outside the allow-list are always attachments, and ?download=true has no additional effect on them.

curl "https://example.monospace.io/api/blog/assets/a1b2c3d4-5678-90ab-cdef-1234567890ab?download=true" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o photo.jpg

Content Type Handling

Monospace preserves the stored content type for the formats listed below. Other formats use application/octet-stream and download as attachments, preventing uploaded HTML from running as a page at your asset URL.

Content typeServed asContent-Disposition
audio/*, video/*, text/plainStored typeinline, or attachment with ?download=true
image/avif, image/bmp, image/gif, image/jpeg, image/png, image/vnd.microsoft.icon, image/webp, image/x-iconStored typeinline, or attachment with ?download=true
image/svg+xmlimage/svg+xmlAlways attachment
Everything elseapplication/octet-streamAlways attachment

An SVG still renders in an <img> tag because the browser fetches it as a subresource. Navigating directly to an SVG asset URL downloads it.

Warning
You cannot configure content types outside the allow-list to display inline. TIFF, HEIC, APNG, PDF, CSV, JSON, CSS, and fonts all download as attachments.

Read File Metadata

File metadata lives in the MonospaceFile collection. System files and workspace files are read differently.

Workspace Files

Read a workspace file's metadata through the file field that references it, with include. See Associate a File with an Item.

Note
MonospaceFile is a system collection. Requests to /api/{workspace}/items/MonospaceFile return 422.

System Files

System files (org logos, workspace logos, user avatars) have a dedicated endpoint at /api/system/files. These require authentication and only expose the base metadata fields.

curl https://example.monospace.io/api/system/files/a1b2c3d4-5678-90ab-cdef-1234567890ab \
  -H "Authorization: Bearer YOUR_API_KEY"

List Files

List system files at /api/system/files:

curl "https://example.monospace.io/api/system/files?fields=id,fileName,fileSize,mediaType" \
  -H "Authorization: Bearer YOUR_API_KEY"

Delete a File

Delete a file and its metadata. Returns 204 No Content on success. This removes both the database record and the file from storage.

curl -X DELETE https://example.monospace.io/api/blog/assets/a1b2c3d4-5678-90ab-cdef-1234567890ab \
  -H "Authorization: Bearer YOUR_API_KEY"

File Metadata Fields

Workspace MonospaceFile

FieldTypeNullableDescription
iduuidNoPrimary key
fileNamestringNoOriginal file name
fileSizebigintNoSize in bytes
mediaTypestringNoMIME type (auto-detected from extension if not provided)
titlestringYesUser-editable title
descriptionstringYesUser-editable description
tagsjsonYesUser-editable tags

System MonospaceFile

FieldTypeNullableDescription
iduuidNoPrimary key
fileNamestringNoOriginal file name
fileSizebigintNoSize in bytes
mediaTypestringNoMIME type

Associate a File with an Item

Store the file's UUID in a relation field on your collection. Upload the file first, then reference its ID when creating or updating an item.

// 1. Upload with fetch
const form = new FormData();
form.append('file', fileInput.files[0]);

const uploadResponse = await fetch('https://example.monospace.io/api/blog/assets', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
  },
  body: form,
});

const { data: uploaded } = await uploadResponse.json();
const fileId = uploaded[0].id;

// 2. Create the article via SDK, connecting the file
const article = await client.Articles.createOne({
  data: {
    title: 'My Article',
    cover_image: {
      _connect: { key: { id: fileId } },
    },
  },
  fields: ['id', 'title'],
  include: {
    cover_image: { fields: ['id', 'fileName'] },
  },
});
Tip
File fields are to-one relations to the MonospaceFile collection. Use _connect to link an uploaded file — see Relational Data for all relational operations.

Endpoint Summary

OperationEndpointMethodResponse
Upload (workspace)/api/{workspace}/assetsPOST{ data: [{ id }] }
Upload (system)/api/system/assetsPOST{ data: [{ id }] }
Download/api/{workspace}/assets/{file_id}GETFile stream
Download (named)/api/{workspace}/assets/{file_id}/{file_name}GETFile stream
Delete (workspace)/api/{workspace}/assets/{file_id}DELETE204
Delete (system)/api/system/assets/{file_id}DELETE204
File metadata (system)/api/system/files/{file_id}GET{ data: {...} }
List files (system)/api/system/filesGET{ data: [...] }

See Also

MonospaceThe governed API layer for every app, person, and agent.

Copyright © 2026 Monospace Inc.