Documentation

Cloud Storage API Reference

Google Drive integration for importing and exporting files

Cloud Provider Integration

Connect cloud storage providers (Google Drive) to import and export files. Uses OAuth 2.0 for secure access. Large operations run as background jobs.

OAuth Authentication

POST/api/v2/cloud-storage/auth/{provider}

Initiate OAuth flow for cloud storage connection. Returns an authorization URL to redirect the user to.

Request

json
{
"provider": "google_drive"
}

Response

json
{
"authorization_url": "https://accounts.google.com/o/oauth2/auth?...",
"state": "csrf_state_token_abc123",
"provider": "google_drive"
}
GET/api/v2/cloud-storage/auth/{provider}/callback

OAuth callback redirect handler. Google redirects here after user authorization. Returns HTML that posts a message to the popup opener window via postMessage.

Request

json
// Query parameters (set by Google redirect):
?code=authorization_code_from_google
&state=csrf_state_token_abc123
&error=access_denied // optional, present on failure
&error_description=User+denied // optional

Response

json
// Returns HTML (not JSON). On success, posts to opener:
{
"type": "oauth-complete",
"success": true,
"connection": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "google_drive",
"provider_email": "user@gmail.com",
"display_name": "John Doe",
"is_token_expired": false
}
}
// On failure, posts to opener:
{
"type": "oauth-complete",
"success": false,
"error": "User denied access"
}
POST/api/v2/cloud-storage/auth/{provider}/callback

Complete OAuth flow and create connection. Called programmatically after user authorizes the application.

Request

json
{
"code": "authorization_code_from_google",
"state": "csrf_state_token_abc123"
}

Response

json
{
"connection": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "google_drive",
"provider_email": "user@gmail.com",
"provider_display_name": "John Doe",
"is_active": true,
"connected_at": "2025-01-15T10:30:00Z",
"last_used_at": null
},
"is_new": true
}

Connection Management

GET/api/v2/cloud-storage/connections

List cloud storage connections for the authenticated user

Request

json
// Query parameters:
?provider=google_drive // optional, filter by provider
&active_only=true // optional, defaults to true
&limit=20 // optional, 1-100, default 20
&offset=0 // optional, default 0

Response

json
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "google_drive",
"provider_email": "user@gmail.com",
"provider_display_name": "John Doe",
"is_active": true,
"connected_at": "2025-01-15T10:30:00Z",
"last_used_at": "2025-01-15T11:00:00Z"
}
],
"total_count": 1,
"limit": 20,
"offset": 0,
"has_more": false
}
GET/api/v2/cloud-storage/connections/{connection_id}/browse

Browse files and folders in a cloud storage connection. Supports hierarchical navigation for providers like Procore (Company > Project > Tool) and Autodesk ACC (Hub > Project > Folder).

Request

json
// Query parameters:
?folder_id=gdrive_folder_id // optional, folder/container ID (None browses the root)
&page_token=abc123 // optional, pagination token from prior response
&page_size=50 // optional, 1-200, default 50

Response

json
{
"files": [
{
"id": "gdrive_file_id_1",
"name": "photo.jpg",
"mime_type": "image/jpeg",
"size_bytes": 2048576,
"modified_at": "2025-01-15T10:30:00Z",
"is_folder": false,
"web_view_link": "https://drive.google.com/file/d/...",
"thumbnail_url": "https://...",
"is_importable": true
}
],
"next_page_token": null,
"current_folder_id": null,
"breadcrumbs": [],
"provider": "google_drive"
}
DELETE/api/v2/cloud-storage/connections/{connection_id}

Disconnect a cloud storage account. Revokes OAuth tokens and removes the connection.

Response

json
{
"success": true,
"message": "Connection disconnected successfully"
}

File Picker

Server-Side Token Security

The picker token endpoint returns a session ID along with credentials for the Google Picker UI. The picker proxy endpoint lets you make Google Drive API calls server-side using the session ID, keeping access tokens secure and not directly exposed to frontend JavaScript.

GET/api/v2/cloud-storage/connections/{connection_id}/picker-token

Get a picker session for the Google Picker file selection UI. Returns credentials needed to initialize the picker component.

Response

json
{
"session": {
"session_id": "picker_sess_abc123",
"access_token": "ya29...",
"app_id": "1234567890",
"developer_key": "AIza...",
"expires_at": "2025-01-15T11:30:00Z"
}
}
POST/api/v2/cloud-storage/picker-proxy

Proxy Google Drive API calls server-side. Uses the session from picker-token to make authenticated requests without exposing tokens to the frontend.

Request

json
{
"session_id": "picker_sess_abc123",
"endpoint": "files/abc123",
"params": { // optional
"fields": "id,name,mimeType,size"
}
}
// Allowed endpoint patterns:
// files - List files
// files/{id} - Get file by ID
// files/{id}/export - Export file
// about - Account/quota info

Response

json
{
"data": {
"id": "abc123",
"name": "photo.jpg",
"mimeType": "image/jpeg",
"size": "2048576"
}
}

Import & Export

POST/api/v2/cloud-storage/import

Import files from cloud storage. All imports are processed asynchronously via a background job. Placeholder image records are created immediately.

Request

json
{
"connection_id": "550e8400-e29b-41d4-a716-446655440000",
"files": [
{
"id": "gdrive_file_id_1",
"name": "photo1.jpg",
"mime_type": "image/jpeg", // optional
"size_bytes": 2048576 // optional
}
],
"auto_describe": true, // deprecated - always generated. Accepted for compatibility.
"tags": ["imported", "drive"], // optional, defaults to []
"folder_id": "550e8400-e29b-41d4-a716-446655440000", // optional, destination folder
"provider_metadata": { // optional, provider-specific context
"procore_project_id": "12345",
"procore_tool": "documents"
}
}

Response

json
{
"image_ids": ["img_001", "img_002"],
"job_id": "job_550e8400",
"status": "pending",
"total_files": 2,
"is_async": true,
"message": "Importing 2 files"
}
// All imports are asynchronous. image_ids are placeholder records
// created immediately. Use job_id to poll progress via
// GET /cloud-storage/jobs/{job_id}.
POST/api/v2/cloud-storage/export

Export files to cloud storage. Uploads images to the user's connected cloud storage account.

Request

json
{
"connection_id": "550e8400-e29b-41d4-a716-446655440000",
"image_ids": ["img_001", "img_002"],
"folder_id": "gdrive_folder_id", // optional, existing folder in cloud
"folder_name": "Scopix Export" // optional, create new folder
}

Response

json
{
"cloud_file_ids": null,
"job_id": "job_660f9500",
"job_status": "pending",
"is_async": true,
"message": "Export job created"
}

Job Status

GET/api/v2/cloud-storage/jobs/{job_id}

Get status of an import or export job. Use this to track progress of async operations.

Response

json
{
"job": {
"job_id": "job_550e8400",
"type": "import",
"status": "in_progress",
"connection_id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "google_drive",
"total_files": 50,
"completed_files": 30,
"failed_files": 2,
"error": null,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:35:00Z",
"completed_at": null
}
}
// Status values: pending | in_progress | completed | partial | failed | cancelled
// Job type values: import | export