Qside files API

Docs

Upload private files to Qside, organize them into folders, and attach them to profiles or spaces.

API keys

Endpoint

POST /api/qside/files

Send multipart form data. Files are private by default and stored in R2 under the qside-user-storage prefix. Free accounts can store up to 3 GB of files. Upload targets such as spaceSlug may be sent as form fields or query parameters.

Authentication

Create an API key from /api-keys. Pass it with either header:

Authorization: Bearer qside_your_api_key
x-qside-api-key: qside_your_api_key

Payload

filerequiredOne or more repeated multipart file fields.
pathoptionalPer-file folder path plus filename, e.g. research/notes.md. Repeat to match multiple files by order.
folderPathoptionalGlobal folder path only, e.g. research. Applies to every file when keeping uploaded filenames.
nameoptionalPer-file display filename. Repeat to match multiple files by order.
profileUsername / profileIdoptionalAttach file to a profile owned by the API key account.
spaceSlug / spaceIdoptionalAttach file to a space owned by the API key account.

Use either a profile field or a space field, not both. Omit both for general files. Global optional fields may be sent as query parameters when you want a reusable target-specific endpoint.

Examples

General file

curl -X POST https://qside.io/api/qside/files \
  -H "Authorization: Bearer $QSIDE_API_KEY" \
  -F "file=@./notes.md" \
  -F "path=research/notes.md"

Attach to a profile

curl -X POST https://qside.io/api/qside/files \
  -H "Authorization: Bearer $QSIDE_API_KEY" \
  -F "file=@./avatar-notes.txt" \
  -F "profileUsername=complexia"

Attach to a space

curl -X POST "https://qside.io/api/qside/files?spaceSlug=my-space" \
  -H "Authorization: Bearer $QSIDE_API_KEY" \
  -F "file=@./brief.pdf" \
  -F "folderPath=briefs"

Bulk upload to a space

curl -X POST "https://qside.io/api/qside/files?spaceSlug=my-space" \
  -H "Authorization: Bearer $QSIDE_API_KEY" \
  -F "file=@./brief.pdf" \
  -F "file=@./photo.jpg" \
  -F "file=@./notes.md" \
  -F "folderPath=briefs"

Bulk upload with per-file paths

curl -X POST https://qside.io/api/qside/files \
  -H "Authorization: Bearer $QSIDE_API_KEY" \
  -F "file=@./brief.pdf" \
  -F "path=client/brief.pdf" \
  -F "file=@./photo.jpg" \
  -F "path=client/images/photo.jpg"

Response

{
  "file": {
    "_id": "...",
    "name": "notes.md",
    "contentType": "text/markdown",
    "size": 1234,
    "viewToken": "...",
    "visibility": "private"
  },
  "link": "https://qside.io/files/...",
  "url": "https://qside.io/files/...",
  "viewUrl": "https://qside.io/api/qside/files/...?disposition=inline",
  "downloadUrl": "https://qside.io/api/qside/files/...?disposition=download"
}

Bulk uploads return files as an array of the same per-file objects:

{
  "uploadedCount": 2,
  "files": [
    {
      "file": { "_id": "...", "name": "brief.pdf", "visibility": "private" },
      "link": "https://qside.io/files/...",
      "url": "https://qside.io/files/...",
      "viewUrl": "https://qside.io/api/qside/files/...?disposition=inline",
      "downloadUrl": "https://qside.io/api/qside/files/...?disposition=download"
    }
  ]
}

The qside link can be shared, but private visibility means it only opens for the authenticated owner. Sharing and public visibility can be added later without changing the upload contract.

If an upload would exceed the 3 GB free storage cap, the API returns 413 with usage fields including usedBytes, limitBytes, and remainingBytes.