Skip to main content

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:
  1. Reads the file content
  2. Builds a multipart/related request
  3. Uses the uploadType=multipart endpoint
  4. 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.