Skip to content
Hoody.com

The Notes service stores files and avatar images attached to notebooks. This page covers the file management endpoints: uploading and downloading avatars, listing and downloading notebook files, and the TUS 1.0.0 protocol for resumable file uploads.

Avatars are user profile images. Upload a raw image (JPEG, PNG, or WebP, up to 10 MB) as the request body. The server resizes the image to fit within 500x500 pixels and stores it as JPEG. Use the returned id to read the avatar back.

Uploads one raw image (JPEG, PNG, or WebP, at most 10 MB) as the request body, not multipart. Set Content-Type to the image type. The image is resized to fit 500x500 and stored as JPEG; the returned id is what the avatar download reads.

This endpoint takes no parameters.

The body is the raw image bytes. Set Content-Type to one of:

  • image/jpeg
  • image/png
  • image/webp

The body must be a decodable image no larger than 10 MB, and the decoded image must have no more than 50 million pixels.

The avatar was stored and is ready to read.

{
"success": true,
"id": "67e89abc123def456789abcf"
}
Terminal window
curl -X POST "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/avatars" \
-H "Content-Type: image/jpeg" \
--data-binary @avatar.jpg

Returns the avatar image as JPEG binary data.

NameInTypeRequiredDescription
avatarIdpathstringYesThe id returned when the avatar was uploaded

The body is the avatar image in JPEG format (binary bytes). Save the response to a file or feed it to an image decoder.

Terminal window
curl "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/avatars/{avatarId}" -o avatar.jpg

Files are attached to notebooks as file nodes. The list endpoint enumerates every file in a notebook; the download endpoint returns a file’s raw bytes. Bytes are uploaded through the TUS resumable protocol covered in the next section.

GET /api/v1/notes/notebooks/{notebookId}/files

Section titled “GET /api/v1/notes/notebooks/{notebookId}/files”

Returns a paginated list of files uploaded to a notebook. Supports limit/offset pagination.

NameInTypeRequiredDescription
notebookIdpathstringYesThe id of the notebook
limitqueryintegerNoMaximum number of files to return. Default: 50
offsetqueryintegerNoNumber of files to skip. Default: 0
{
"files": [
{
"id": "67e89abc123def456789ab01",
"name": "q1-report.pdf",
"mimeType": "application/pdf",
"size": 1048576,
"createdAt": "2024-01-15T10:30:00.000Z",
"createdBy": "alice",
"documentId": "67e89abc123def456789ab02",
"documentName": "Q1 Report"
},
{
"id": "67e89abc123def456789ab03",
"name": "chart.png",
"mimeType": "image/png",
"size": 524288,
"createdAt": "2024-01-16T14:22:00.000Z",
"createdBy": "bob",
"documentId": "67e89abc123def456789ab04",
"documentName": null
}
],
"total": 2
}
Terminal window
curl "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/notebooks/{notebookId}/files?limit=50&offset=0"

GET /api/v1/notes/notebooks/{notebookId}/files/{fileId}

Section titled “GET /api/v1/notes/notebooks/{notebookId}/files/{fileId}”

Downloads the content of an uploaded file byte for byte. The response content type is the uploaded one for images, audio, video, PDF, and plain text (sent inline). Every other type, including HTML, SVG, and XML, is sent as application/octet-stream with Content-Disposition: attachment. Every response carries X-Content-Type-Options: nosniff and a sandboxing Content-Security-Policy header.

NameInTypeRequiredDescription
notebookIdpathstringYesThe id of the notebook
fileIdpathstringYesThe id of the file

The body is the file’s raw bytes. The response content type is the uploaded one for images, audio, video, PDF, and plain text; every other type is returned as application/octet-stream with Content-Disposition: attachment. Every response carries X-Content-Type-Options: nosniff and a sandboxing Content-Security-Policy header.

Terminal window
curl "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/notebooks/{notebookId}/files/{fileId}" -o file.dat

Notebook file bytes are uploaded with the TUS 1.0.0 resumable upload protocol. The flow has three steps:

  1. Create a file node in the notebook (type file, status pending) through the node creation endpoint. The file node’s size is fixed at this point and is the size the upload must deliver.
  2. POST to the upload URL to create the upload, declaring the total size in Upload-Length.
  3. PATCH chunks in order, starting at Upload-Offset: 0 and increasing the offset after each chunk. When Upload-Offset reaches Upload-Length, the file is ready.

After an interruption, HEAD the upload URL to read the current Upload-Offset and resume from there. To abandon an in-flight upload, DELETE the upload URL. Only the user who created the file node may upload to it.

Every TUS request must include the Tus-Resumable: 1.0.0 header. Anything else returns 412.

POST /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus

Section titled “POST /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus”

Creates a TUS 1.0.0 resumable upload for a file node. Send no body. A create that already holds every byte (Upload-Length: 0, or a creation-with-upload body that carried every byte) finishes the upload at once with 200.

NameInTypeRequiredDescription
notebookIdpathstringYesThe id of the notebook
fileIdpathstringYesThe id of the file node
Tus-ResumableheaderstringYesTUS protocol version. Must be 1.0.0; anything else returns 412
Upload-LengthheaderintegerYesTotal size of the file in bytes. Must equal the file node’s size (set when the node was created), which must not exceed the notebook’s maximum file size. Upload-Defer-Length is not supported
Upload-MetadataheaderstringNoOptional TUS metadata: comma-separated key base64(value) pairs

The upload was created and is already complete (for example, Upload-Length: 0). The file is ready; a HEAD to the URL in the Location header reports it complete.

{
"uploadId": "67e89abc123def456789abf0"
}
HeaderDescription
LocationURL of the upload: this path, with the caller’s username and role query parameters when it sent them
Tus-ResumableTUS protocol version (1.0.0)
Terminal window
curl -X POST "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus" \
-H "Tus-Resumable: 1.0.0" \
-H "Upload-Length: 1048576"

PATCH /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus

Section titled “PATCH /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus”

Appends one chunk of bytes to the upload at Upload-Offset. Content-Type must be application/offset+octet-stream. Chunks for one upload are taken one at a time; a chunk sent while another is being written returns 409 once that one moves the offset.

NameInTypeRequiredDescription
notebookIdpathstringYesThe id of the notebook
fileIdpathstringYesThe id of the file node
Tus-ResumableheaderstringYesTUS protocol version. Must be 1.0.0; anything else returns 412
Upload-OffsetheaderintegerYesOffset this chunk starts at, the value the HEAD check (or the previous chunk) returned

The chunk bytes with Content-Type: application/offset+octet-stream.

The final chunk was received; the file is ready.

{
"uploadId": "67e89abc123def456789abf0"
}
Terminal window
curl -X PATCH "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus" \
-H "Tus-Resumable: 1.0.0" \
-H "Upload-Offset: 0" \
-H "Content-Type: application/offset+octet-stream" \
--data-binary @chunk-0.bin

HEAD /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus

Section titled “HEAD /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus”

Reports how many bytes the server holds. A finished upload keeps answering, with Upload-Offset equal to Upload-Length. Use this after an interruption to resume from the correct offset.

NameInTypeRequiredDescription
notebookIdpathstringYesThe id of the notebook
fileIdpathstringYesThe id of the file node
Tus-ResumableheaderstringYesTUS protocol version. Must be 1.0.0; anything else returns 412

Upload found. The Upload-Offset header reports the bytes the server holds; an offset equal to Upload-Length means the upload is complete.

HeaderDescription
Upload-OffsetBytes received so far; send the next chunk from here
Upload-LengthTotal size declared at creation
Tus-ResumableTUS protocol version (1.0.0)
Cache-ControlAlways no-store
Terminal window
curl -I "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus" \
-H "Tus-Resumable: 1.0.0"

DELETE /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus

Section titled “DELETE /api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus”

Abandons an unfinished upload and deletes the bytes received so far.

NameInTypeRequiredDescription
notebookIdpathstringYesThe id of the notebook
fileIdpathstringYesThe id of the file node
Tus-ResumableheaderstringYesTUS protocol version. Must be 1.0.0; anything else returns 412

The response has no body. The upload was aborted.

HeaderDescription
Tus-ResumableTUS protocol version (1.0.0)
Terminal window
curl -X DELETE "https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com/api/v1/notes/notebooks/{notebookId}/files/{fileId}/tus" \
-H "Tus-Resumable: 1.0.0"