Documentation Index
Fetch the complete documentation index at: https://mintlify.com/googleworkspace/cli/llms.txt
Use this file to discover all available pages before exploring further.
The CLI supports multipart uploads for APIs that accept file content, such as Drive, Gmail, and Apps Script.
Basic Upload Syntax
Use the --upload flag to specify a local file to upload:
gws drive files create --json '{"name": "report.pdf"}' --upload ./report.pdf
The CLI automatically:
- Reads the file content
- Builds a
multipart/related request
- Uses the
uploadType=multipart endpoint
- Includes both metadata (JSON) and file content
How It Works
The multipart upload implementation (in src/executor.rs:621-659) creates a multipart/related body:
--boundary_12345
Content-Type: application/json; charset=UTF-8
{"name": "report.pdf", "mimeType": "application/pdf"}
--boundary_12345
Content-Type: application/pdf
<binary file content>
--boundary_12345--
Supported Services
Upload support varies by API. Common use cases:
Drive Files
Create a new file:
gws drive files create --json '{"name": "budget.xlsx", "mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}' \
--upload ./budget.xlsx
Update existing file content:
gws drive files update --params '{"fileId": "1A2B3C"}' \
--json '{"mimeType": "application/pdf"}' \
--upload ./updated-report.pdf
Gmail Messages
Send a message with an attachment:
gws gmail users messages send --params '{"userId": "me"}' \
--json '{"raw": "...base64-encoded-email..."}' \
--upload ./message.eml
For Gmail, you typically construct the full MIME message locally and upload it. The CLI helper gws gmail +send provides a simpler interface for attachments.
Apps Script Projects
Deploy a script project:
gws script projects create --json '{"title": "My Script"}' --upload ./script.json
MIME Type Detection
The CLI extracts the MIME type from the mimeType field in your JSON metadata:
gws drive files create --json '{"name": "image.png", "mimeType": "image/png"}' --upload ./photo.png
If no mimeType is provided, it defaults to application/octet-stream.
Upload Endpoint Selection
The CLI reads the Discovery Document’s mediaUpload section to determine the upload endpoint:
"mediaUpload": {
"protocols": {
"simple": {
"path": "/upload/drive/v3/files"
}
}
}
The upload path is automatically substituted at runtime (see src/executor.rs:516-533).
Examples
Upload a CSV file to Drive
gws drive files create \
--json '{"name": "data.csv", "parents": ["1XYZ"], "mimeType": "text/csv"}' \
--upload ./data.csv
Upload and convert to Google Sheets
gws drive files create \
--json '{"name": "Q1 Sales", "mimeType": "application/vnd.google-apps.spreadsheet"}' \
--upload ./sales.xlsx
Replace file content
# Get the file ID first
FILE_ID=$(gws drive files list --params '{"q": "name='report.pdf'"}' | jq -r '.files[0].id')
# Update the content
gws drive files update --params '{"fileId": "'$FILE_ID'"}' --upload ./report-v2.pdf
Error Handling
If the file cannot be read:
{
"error": "Failed to read upload file './missing.pdf': No such file or directory (os error 2)"
}
If the API doesn’t support uploads for the method:
{
"error": "Method supports media upload but no upload path found in Discovery Document"
}
Dry Run
Preview the upload request structure without sending it:
gws drive files create --json '{"name": "test.pdf"}' --upload ./test.pdf --dry-run
{
"dry_run": true,
"url": "https://www.googleapis.com/upload/drive/v3/files",
"method": "POST",
"query_params": {
"uploadType": "multipart"
},
"body": {
"name": "test.pdf"
},
"is_multipart_upload": true
}
Best Practices
Always specify the correct mimeType in your JSON metadata to ensure the file is uploaded with the right content type.
Large file uploads (>5 MB) may fail with multipart mode. Use resumable uploads for files larger than 5 MB (currently not supported; use the Drive API directly for resumable uploads).
The --upload flag is only valid for methods that declare supportsMediaUpload: true in the Discovery Document.