Skip to main content

Drive Upload

Misskey's Drive is the file storage system. All files attached to notes must first be uploaded to your Drive. The client.drive facade exposes files, folders, and stats sub-APIs.

Uploading a file

import 'dart:io';

final bytes = await File('photo.jpg').readAsBytes();
final driveFile = await client.drive.files.create(
bytes: bytes,
filename: 'photo.jpg',
comment: 'Alt text for accessibility',
);

print(driveFile.id); // Use this ID to attach to a note
print(driveFile.url); // Public URL

Upload with folder and sensitivity

final driveFile = await client.drive.files.create(
bytes: bytes,
filename: 'nsfw.jpg',
folderId: myFolderId,
isSensitive: true,
force: true, // Upload even if a file with the same name exists
);

Upload progress

final driveFile = await client.drive.files.create(
bytes: largeBytes,
filename: 'large-video.mp4',
onSendProgress: (sent, total) {
final percent = (sent / total * 100).toStringAsFixed(1);
print('Uploading: $percent%');
},
);

Upload from URL

await client.drive.files.uploadFromUrl(
url: 'https://example.com/image.jpg',
folderId: myFolderId,
isSensitive: false,
);

This is a fire-and-forget endpoint; the file appears in Drive asynchronously.

Attaching Drive files to notes

final driveFile = await client.drive.files.create(
bytes: imageBytes,
filename: 'photo.jpg',
);

final note = await client.notes.create(
text: 'Check this out!',
fileIds: [driveFile.id],
);

Multiple files can be attached by passing multiple IDs in fileIds.

Listing files

// List files in the root folder
final files = await client.drive.files.list(limit: 20);

// List files in a specific folder
final files = await client.drive.files.list(
limit: 20,
folderId: myFolderId,
);

// Filter by MIME type
final images = await client.drive.files.list(type: 'image/*');

// Sort by size descending
final large = await client.drive.files.list(sort: '-size');

sort accepts: +createdAt, -createdAt, +name, -name, +size, -size.

Stream (all files, no folder filter)

final all = await client.drive.stream(limit: 20, type: 'video/*');

Search by name

final found = await client.drive.files.find(
name: 'photo.jpg',
folderId: myFolderId,
);

Check for duplicates

final exists = await client.drive.files.checkExistence(md5: fileMd5);

Fetching file details

// By file ID
final file = await client.drive.files.showByFileId(fileId);

// By URL
final file = await client.drive.files.showByUrl('https://example.com/file.jpg');

Updating file attributes

final updated = await client.drive.files.update(
fileId: driveFile.id,
name: 'new-name.jpg',
comment: 'Updated alt text',
isSensitive: false,
);

Move to a different folder:

await client.drive.files.update(
fileId: driveFile.id,
folderId: newFolderId,
);

Move to root:

await client.drive.files.update(
fileId: driveFile.id,
moveToRoot: true,
);

Deleting files

await client.drive.files.delete(fileId: driveFile.id);

Folder management

// List root folders
final folders = await client.drive.folders.list();

// Create a folder
final folder = await client.drive.folders.create(
name: 'Vacation Photos',
);

// Create a nested folder
final nested = await client.drive.folders.create(
name: 'Day 1',
parentId: folder.id,
);

// Rename a folder
await client.drive.folders.update(
folderId: folder.id,
name: 'Summer 2025',
);

// Move to root
await client.drive.folders.update(
folderId: folder.id,
moveToRoot: true,
);

// Delete a folder (must be empty)
await client.drive.folders.delete(folderId: folder.id);

Drive statistics

final capacity = await client.drive.stats.getCapacity();
print('Used: ${capacity.usage} bytes');
print('Capacity: ${capacity.capacity} bytes');