GetSafeDocs API & MCP Server Documentation
Welcome to the GetSafeDocs REST API and Model Context Protocol (MCP) Server! This documentation covers API key authentication, stateless file uploads, secure document sharing, tracking, document requests, mailing lists, malware scan reports, enterprise management, and connecting AI assistants via /mcp.
Base URL
- API Base URL:
https://getsafedocs.cloud.run - MCP Server URL:
https://getsafedocs.cloud.run/mcp(alias:https://getsafedocs.cloud.run/api/mcp)
Authentication
1. API Key Authentication (Recommended)
You can authenticate any API request using a personal API Key without needing a password, browser cookies, or interactive MFA prompts. Works with all account types (including Google Sign-In, Passkey, and MFA-protected accounts).
How to Get Your API Key
- Sign in to GetSafeDocs and go to your Profile.
- Under Security Settings → Developer API Keys, enter a key name (e.g.,
CLI ScriptorCI/CD Pipeline), choose an optional expiration (Never expires,30 days,90 days,1 year), and click Generate API Key. - Copy your
gsd_...key immediately (for security, only the SHA-256 hash is stored and the full key is shown only once).
Passing Your API Key in Requests
Include your API key in the X-API-Key header or the Authorization: Bearer header:
# Option A: X-API-Key header
curl -H "X-API-Key: gsd_your_api_key_here" \
https://getsafedocs.cloud.run/api/whoami
# Option B: Authorization Bearer header
curl -H "Authorization: Bearer gsd_your_api_key_here" \
https://getsafedocs.cloud.run/api/whoami
2. Verify Authentication (/api/whoami)
- Endpoint:
GET https://getsafedocs.cloud.run/api/whoami(alias:GET /api/me) - Authentication: Required (API Key or Session)
- Response:
{
"success": true,
"auth_method": "api_key",
"api_key_id": 4,
"account": {
"id": 123,
"email": "user@example.com",
"access_level": "premium",
"is_company_admin": false,
"company_id": null,
"mfa_enabled": true
},
"limits": {
"messages_per_month": 300,
"max_attachment_size_mb": 128,
"max_attachments": 20,
"max_recipients": 30,
"max_received_size_mb": 3000
},
"usage": {
"message_count": 12,
"sent_kb": 15420,
"received_kb": 4100
}
}
3. Managing API Keys via API
List Active API Keys
- Endpoint:
GET https://getsafedocs.cloud.run/api/api_keys - Authentication: Required
- Response:
{
"success": true,
"count": 1,
"api_keys": [
{
"id": 4,
"name": "CI/CD Pipeline",
"key_prefix": "gsd_8f9a1b2c...4e5f",
"scopes": "full",
"last_used_at": "2026-11-09 17:15:00",
"last_used_ip": "203.0.113.10",
"expires_at": null,
"is_active": 1,
"is_expired": 0,
"created_at": "2026-11-09 16:00:00"
}
]
}
Create a New API Key
- Endpoint:
POST https://getsafedocs.cloud.run/api/api_keys(alias:POST /api/create_api_key) - Authentication: Required
- Body (JSON):
{
"name": "Production Server",
"expires_days": 90
}
- Response:
{
"success": true,
"api_key": "gsd_8f9a1b2c3d4e5f60718293a4b5c6d7e8f9a0b1c2d3e4f5a6",
"key": {
"id": 5,
"name": "Production Server",
"key_prefix": "gsd_8f9a1b2c...f5a6",
"scopes": "full",
"expires_at": "2027-02-07 17:20:00",
"created_at": "2026-11-09 17:20:00"
},
"message": "API key generated. Copy this key now — for security, the full key will not be shown again."
}
Revoke an API Key
- Endpoint:
DELETE https://getsafedocs.cloud.run/api/api_keysorPOST https://getsafedocs.cloud.run/api/revoke_api_key - Authentication: Required
- Body (JSON):
{ "key_id": 5 } - Response:
{ "success": true, "message": "API key revoked", "key_id": 5 }
4. Legacy Session Authentication (Optional)
If you are building a session-based client instead of using API keys, session endpoints remain supported:
- Register:
POST https://getsafedocs.cloud.run/api/register({ "email": "...", "password": "..." }) - Login:
POST https://getsafedocs.cloud.run/api/login({ "email": "...", "password": "..." }) - Logout:
POST https://getsafedocs.cloud.run/api/logout - Refresh Session:
POST https://getsafedocs.cloud.run/api/refresh_token
File Uploads & Stateless Message Sending
All file uploads use a 3-step direct-to-GCS signed URL workflow with automatic MIME inspection and QuickSand malware analysis. When using an API key, uploaded files are tracked statelessly by their uuid so no cookies or sessions are needed.
Step 1: Request a Signed Upload URL
- Endpoint:
POST https://getsafedocs.cloud.run/api/get_signed_url(also available at/get_signed_url) - Authentication: Required (
X-API-KeyorAuthorization: Bearer) - Body (JSON):
{
"filename": "contract.pdf",
"contentType": "application/pdf",
"fileSize": 1024000
}
- Response:
{
"success": true,
"signedUrl": "https://storage.googleapis.com/bucket/uploads/...",
"tempObject": "uploads/12345678-1234-1234-1234-123456789012_contract.pdf",
"tempBucketPath": "uploads/12345678-1234-1234-1234-123456789012_contract.pdf",
"uuid": "12345678-1234-1234-1234-123456789012",
"kmsKeyName": "projects/.../cryptoKeys/..."
}
Step 2: Upload Raw File Bytes to GCS
- Method:
PUTto thesignedUrlreturned in Step 1 - Headers:
Content-Type: Match thecontentTypefrom Step 1 (Note: CMEK encryption key is already embedded as a signed query parameter onsignedUrl; do not pass an extrax-goog-encryption-kms-key-nameheader)- Body: Raw binary file content
Step 3: Process & Scan the Uploaded File
- Endpoint:
POST https://getsafedocs.cloud.run/api/upload_file(alias:POST /api/process_cloud_upload) - Authentication: Required (
X-API-KeyorAuthorization: Bearer) - Body (JSON):
{
"tempObject": "uploads/12345678-1234-1234-1234-123456789012_contract.pdf",
"filename": "contract.pdf",
"contentType": "application/pdf",
"uuid": "12345678-1234-1234-1234-123456789012"
}
- Response:
{
"success": true,
"file_id": "12345678-1234-1234-1234-123456789012",
"uuid": "12345678-1234-1234-1234-123456789012",
"file": {
"uuid": "12345678-1234-1234-1234-123456789012",
"access_uuid": "9f8e7d6c5b4a...",
"scan_id": 42,
"name": "contract.pdf",
"size": 1024000,
"type": "application/pdf",
"scan_rating": 0,
"scan_risk": "Clean"
},
"scan_result": {
"rating": 0,
"risk": "Clean",
"uuid": "12345678-1234-1234-1234-123456789012",
"access_uuid": "9f8e7d6c5b4a...",
"scan_id": 42
}
}
Delete a Temporary Uploaded File (Before Sending)
- Endpoint:
POST https://getsafedocs.cloud.run/api/delete_file - Authentication: Required
- Body (JSON):
{ "uuid": "12345678-1234-1234-1234-123456789012" }
Messages & Document Sharing
Send a Secure Message
- Endpoint:
POST https://getsafedocs.cloud.run/api/send_message - Authentication: Required
- Content-Type:
application/jsonorapplication/x-www-form-urlencoded - Fields:
recipients(array of strings or comma-separated string) — Recipient email addresses. Omit and pass"generate_token_only": trueto generate a manual share token without emailing.mailing_list_id(integer, optional) — Send to all recipients in a saved external mailing list.team_ids(array of integers, optional) — Expand internal Enterprise Teams into recipients (Enterprise tier).subject(string, optional, default"Document Delivery") — Message subject.bodyormessage(string, optional if files are attached) — Message text.file_uuidsoruploaded_file_ids(array of UUID strings or comma-separated string, optional) — File UUIDs from/api/upload_file.repo_file_ids(array of integers, optional) — Attach existing Enterprise Document Repository files (repo_file_id) directly without re-uploading (one-click resend).save_to_repository(boolean, optional, defaultfalse) — Archive newly uploaded attachments into the Enterprise Document Repository upon sending.classification(string, optional, default"None") — Enterprise classification marking (None,Confidential,NTK,Restricted, or custom company markings).expiry_days(integer, optional, default30, max365) — Days until the message expires.notify_on_activity(boolean, optional, defaulttrue) — Email sender when recipients view/download files.preview_only(boolean, optional, defaultfalse) — Restrict recipients to safe sandbox viewing only (disable raw downloads).send_email(boolean, optional, defaulttrue) — Automatically email share links to recipients.generate_token_only(boolean, optional, defaultfalse) — Generate a shareableaccess_tokenandaccess_urlwithout specifying recipient emails.- Example Request (JSON):
{
"recipients": ["client@example.com", "legal@example.com"],
"subject": "Signed Q4 Agreement",
"body": "Please find the signed agreement attached.",
"file_uuids": ["12345678-1234-1234-1234-123456789012"],
"expiry_days": 30,
"notify_on_activity": true,
"preview_only": false
}
- Response:
{
"success": true,
"message_id": 123,
"subject": "Signed Q4 Agreement",
"created_at": "2026-11-09 17:30:00",
"expiry_date": "2026-12-09 17:30:00",
"preview_only": false,
"recipients": [
{
"recipient_id": 456,
"email": "client@example.com",
"access_token": "k9m2p4x7",
"access_url": "https://getsafedocs.cloud.run/access_document?token=k9m2p4x7",
"email_sent": true
}
],
"files": [
{
"file_id": 789,
"file_name": "contract.pdf",
"mime_type": "application/pdf",
"uuid": "12345678-1234-1234-1234-123456789012",
"access_uuid": "9f8e7d6c5b4a...",
"scan_rating": 0,
"scan_risk": "Clean",
"preview_only": false
}
]
}
List Sent Messages (Outbox)
- Endpoint:
GET https://getsafedocs.cloud.run/api/list_messages?limit=20&offset=0&search= - Authentication: Required
- Response: Returns
messages(each includingrecipients,files,file_count,unread_replies_count) andpagination.
List Received Messages (Inbox)
- Endpoint:
GET https://getsafedocs.cloud.run/api/list_received_messages?limit=20&offset=0&archived=0&unread_only=0&search= - Authentication: Required
- Query Parameters:
archived:0(active inbox, default),1(archived), orallunread_only:1ortrueto filter unread messagessearch: Filter by subject, body, or sender email
View Message Details
- Endpoint:
GET https://getsafedocs.cloud.run/api/message_details?message_id=123 - Authentication: Required (sender or recipient)
- Response: Returns
message,files,recipients(withaccess_tokenandaccess_urlwhen requested by sender), andreplies.
Message Activity & Tracking
- Endpoint:
GET https://getsafedocs.cloud.run/api/message_tracking?message_id=123 - Authentication: Required (sender only)
- Response: Returns
activities/tracking(views, downloads, timestamps, IPs, user agents) andnotifications.
Resend Recipient Notification Emails
- Endpoint:
POST https://getsafedocs.cloud.run/api/resend_notification - Authentication: Required (sender only)
- Body (JSON):
{
"message_id": 123,
"emails": ["client@example.com"]
}
Archive / Unarchive Message
- Endpoint:
POST https://getsafedocs.cloud.run/api/archive_message(orPOST /api/unarchive_message) - Authentication: Required
- Body (JSON):
{ "message_id": 123, "archive": true }(set"archive": falseto unarchive)
Delete Sent Message
- Endpoint:
POST https://getsafedocs.cloud.run/api/delete_message - Authentication: Required (sender only)
- Body (JSON):
{ "message_id": 123 } - Note: If the sender is under a Visible Legal Hold, deletion returns HTTP
403. If under a Silent (Stealth) Legal Hold, the message is hidden from the sender's Outbox (sender_deleted = 1) while preserved in the Enterprise eDiscovery Vault.
Promote Attachment to Enterprise Repository
- Endpoint:
POST https://getsafedocs.cloud.run/api/save_file_to_repo - Authentication: Required (Enterprise sender or Company Admin)
- Body (JSON):
{ "file_id": 789, "message_id": 123, "folder_name": "Contracts", "visibility": "private" }
Toggle Message Legal Hold
- Endpoint:
POST https://getsafedocs.cloud.run/api/toggle_message_legal_hold - Authentication: Required (Enterprise Company Admin or System Admin)
- Body (JSON):
{ "message_id": 123, "legal_hold": true }
Access Shared Message via Recipient Token (No Account Required)
- Endpoint:
GET https://getsafedocs.cloud.run/api/access_document?token=k9m2p4x7 - Authentication: Token-based (
tokenquery parameter) - Response: Returns
message,files, andreplies.
Files, Downloads, ZIP Archives & Scan Reports
Get File Metadata & Access Statistics
- Endpoint:
GET https://getsafedocs.cloud.run/api/get_file_metadata?file_id=789(or?uuid=...) - Authentication: Required
Download Single Attachment (Signed URL)
- Endpoint:
GET https://getsafedocs.cloud.run/api/download_attachment?file_id=789(or?uuid=...&token=...) - Authentication: API Key, Session, or Recipient
token - Response:
{
"success": true,
"signed_url": "https://storage.googleapis.com/...",
"signedUrl": "https://storage.googleapis.com/...",
"filename": "contract.pdf",
"expires_in": 900
}
Download All Message Files as ZIP (Signed URL)
- Endpoint:
GET https://getsafedocs.cloud.run/api/download_zip?message_id=123(or?token=k9m2p4x7) - Authentication: API Key, Session, or Recipient
token - Response:
{
"success": true,
"signed_url": "https://storage.googleapis.com/...",
"signedUrl": "https://storage.googleapis.com/...",
"file_count": 3
}
Get Malware Scan Report
- Endpoint:
GET https://getsafedocs.cloud.run/api/scan_report?uuid=12345678-...(or?file_id=789or?scan_id=42) - Response: Returns cryptographic hashes (
md5,sha1,sha256),risk_score,risk_rating, and detailed QuickSand static analysis results.
Replies
Add Reply
- Endpoint:
POST https://getsafedocs.cloud.run/api/add_reply - Authentication: API Key, Session, or Recipient
token - Body (JSON):
{ "message_id": 123, "reply_text": "Thank you, received!", "token": "optional_recipient_token" }
List Replies
- Endpoint:
GET https://getsafedocs.cloud.run/api/list_replies?message_id=123 - Authentication: API Key, Session, or
?token=recipient_token
Mark Reply as Read
- Endpoint:
POST https://getsafedocs.cloud.run/api/mark_reply_read - Authentication: Required
- Body (JSON):
{ "reply_id": 42 }
Document Requests
Document requests allow external users to upload files to you using a secure access_token without needing a GetSafeDocs account.
Create Document Request
- Endpoint:
POST https://getsafedocs.cloud.run/api/create_document_request - Authentication: Required
- Body (JSON):
{
"request_name": "Tax Documents 2026",
"description": "Please upload your signed tax forms and receipts",
"allow_multiple_submissions": true,
"max_file_size_mb": 50,
"max_files_per_submission": 10,
"allowed_file_types": "pdf,doc,docx,xlsx",
"require_email": true,
"require_subject": false,
"require_message": true,
"expiry_days": 30,
"notify_emails": ["client@example.com"]
}
List Document Requests
- Endpoint:
GET https://getsafedocs.cloud.run/api/list_document_requests?status=all&limit=50&offset=0 - Authentication: Required
- Query Parameters:
status(active,closed,expired,all),limit,offset
Get Document Request & Submissions
- Endpoint:
GET https://getsafedocs.cloud.run/api/get_document_request?request_id=123(or?request_token=abc123def456) - Authentication: Required
- Response: Returns the
requestobject and allsubmissionswith their attachedfiles.
Update Document Request
- Endpoint:
POST https://getsafedocs.cloud.run/api/update_document_request - Authentication: Required
- Body (JSON):
{
"request_id": 123,
"request_name": "Updated Tax Documents",
"description": "Updated instructions",
"is_active": true,
"max_file_size_mb": 100,
"expiry_days": 60
}
Delete Document Request
- Endpoint:
POST https://getsafedocs.cloud.run/api/delete_document_request - Authentication: Required
- Body (JSON):
{ "request_id": 123 }
Get Single Submission Details
- Endpoint:
GET https://getsafedocs.cloud.run/api/get_submission_details?submission_id=45 - Authentication: Required
Public Upload to a Document Request (Token-Based)
- Get Signed Upload URL:
POST https://getsafedocs.cloud.run/api/get_document_request_signed_url - Body:
{ "filename": "form.pdf", "contentType": "application/pdf", "fileSize": 512000, "access_token": "abc123def456" } - PUT File to GCS:
PUTraw bytes tosignedUrl - Complete Submission:
POST https://getsafedocs.cloud.run/api/upload_document_request_file - Body:
{ "tempObject": "...", "uuid": "...", "filename": "form.pdf", "contentType": "application/pdf", "access_token": "abc123def456", "submitter_email": "client@example.com", "submitter_name": "Jane Doe", "notes": "Attached!" }
Mailing Lists
List Mailing Lists
- Endpoint:
GET https://getsafedocs.cloud.run/api/mailing_lists - Authentication: Required
- Response: Returns all mailing lists owned by the account, including
recipientsandrecipient_count.
Create Mailing List
- Endpoint:
POST https://getsafedocs.cloud.run/api/mailing_lists - Authentication: Required
- Body (JSON):
{
"name": "Board of Directors",
"description": "Monthly board packet distribution list",
"emails": ["director1@example.com", "director2@example.com"]
}
Update Mailing List
- Endpoint:
POST https://getsafedocs.cloud.run/api/mailing_lists/update - Authentication: Required
- Body (JSON):
{
"list_id": 10,
"name": "Board of Directors",
"add_emails": ["newdirector@example.com"],
"remove_emails": ["olddirector@example.com"]
}
(You can also pass "emails": [...] to replace the entire recipient list.)
Delete Mailing List
- Endpoint:
POST https://getsafedocs.cloud.run/api/mailing_lists/delete(orDELETE /api/mailing_lists) - Authentication: Required
- Body (JSON):
{ "list_id": 10 }
Get Mailing List Recipients
- Endpoint:
GET https://getsafedocs.cloud.run/api/mailing_lists/recipients?list_id=10 - Authentication: Required
User Profile, Usage & File Types
- Get Profile:
GET https://getsafedocs.cloud.run/api/get_profile - Update Profile:
POST https://getsafedocs.cloud.run/api/update_profile({ "email_marketing_opt_in": false }) - Get Usage Statistics:
GET https://getsafedocs.cloud.run/api/get_usage_stats - Get Allowed File Types & Tier Limits:
GET https://getsafedocs.cloud.run/api/file_types - System Status:
GET https://getsafedocs.cloud.run/api/get_system_status
Bulk Operations
- Endpoint:
POST https://getsafedocs.cloud.run/api/bulk_operations - Authentication: Required
- Body (JSON):
{
"operation": "archive_messages",
"targets": [123, 456, 789]
}
- Supported Operations:
archive_messages,unarchive_messages,mark_messages_read,delete_messages,delete_document_requests
Enterprise Repository, Teams, Legal Hold & Admin Endpoints
Enterprise Document Repository (/api/repository/*)
- List & Search Repository Files:
GET https://getsafedocs.cloud.run/api/repository/files?folder=&classification=&scope=all&q= - Upload or Promote Files to Repository:
POST https://getsafedocs.cloud.run/api/repository/upload - Body:
{ "file_uuids": ["..."], "folder_name": "Contracts", "classification": "Confidential", "visibility": "shared", "share_team_ids": [1], "can_view": true, "can_download": true, "can_resend": true, "can_delete": false }(or pass"file_id": 789to promote an existing message attachment) - Update Repository File Metadata:
POST https://getsafedocs.cloud.run/api/repository/update - Body:
{ "repo_file_id": 12, "folder_name": "Legal", "description": "Master MSA", "visibility": "company", "classification": "Confidential" } - Grant Granular Share (Team or User):
POST https://getsafedocs.cloud.run/api/repository/share - Body:
{ "repo_file_id": 12, "target_type": "team", "target_team_id": 1, "can_view": true, "can_download": true, "can_resend": true, "can_delete": false } - Revoke Share:
POST https://getsafedocs.cloud.run/api/repository/unshare({ "share_id": 5 }) - Toggle Repository File Legal Hold:
POST https://getsafedocs.cloud.run/api/repository/legal_hold({ "repo_file_id": 12, "legal_hold": true }) - Download Repository File (Signed URL):
GET https://getsafedocs.cloud.run/api/repository/download?repo_file_id=12 - Delete Repository File:
POST https://getsafedocs.cloud.run/api/repository/delete({ "repo_file_id": 12, "purge_reason": "Superseded" })
Enterprise Company Admin (/api/enterprise/*)
- Overview (Members, Seats, Teams, Held Messages / eDiscovery Vault, Invites, Settings):
GET https://getsafedocs.cloud.run/api/enterprise/overview - Create / Rename Company:
POST /api/enterprise/create_company/POST /api/enterprise/rename_company({ "company_name": "Acme Corp" }) - Update Security & Repository Governance Settings:
POST https://getsafedocs.cloud.run/api/enterprise/update_settings - Body:
{ "classification_options": ["None", "Confidential", "NTK", "Restricted"], "disable_remote_preview": true, "auto_archive_to_repo": true, "repo_retention_days": 365 } - Invite Member:
POST https://getsafedocs.cloud.run/api/enterprise/invite({ "email": "teammate@company.com" }) - Resend / Cancel Invite:
POST /api/enterprise/resend_invite/POST /api/enterprise/cancel_invite({ "invite_id": 10 }) - Accept / Decline Invite (Invited User):
POST https://getsafedocs.cloud.run/api/enterprise/accept_invite({ "invite_token": "...", "decision": "accept" }) - Set Member Role / Tier:
POST https://getsafedocs.cloud.run/api/enterprise/set_member_role({ "account_id": 456, "is_company_admin": true }) - Remove Member:
POST https://getsafedocs.cloud.run/api/enterprise/remove_member({ "account_id": 456 }) - Set User Legal Hold (Visible, Silent/Stealth, or Off):
POST https://getsafedocs.cloud.run/api/enterprise/set_legal_hold - Body:
{ "account_id": 456, "legal_hold_mode": "silent", "legal_hold_reason": "Case #2026-09" } - Manage Internal Enterprise Teams:
GET / POST https://getsafedocs.cloud.run/api/enterprise/teams - Actions (
action):create_team,delete_team,add_team_member,remove_team_member
System Admin (/api/admin/*)
- List Users:
GET https://getsafedocs.cloud.run/api/admin/list_users?limit=50&offset=0 - Update User:
POST https://getsafedocs.cloud.run/api/admin/update_user - Security Logs:
GET https://getsafedocs.cloud.run/api/admin/get_security_logs - Malware Detections:
GET https://getsafedocs.cloud.run/api/admin/get_malware_detections - Rescan File:
POST https://getsafedocs.cloud.run/api/rescan_file({ "uuid": "..." })
Code Examples
Complete Python Example (Upload & Send with API Key)
import os
import requests
API_BASE = "https://getsafedocs.cloud.run"
API_KEY = os.environ["GETSAFEDOCS_API_KEY"] # e.g. "gsd_..."
HEADERS = {"X-API-Key": API_KEY}
file_path = "contract.pdf"
file_size = os.path.getsize(file_path)
# 1. Get signed upload URL
sign_resp = requests.post(
f"{API_BASE}/api/get_signed_url",
headers=HEADERS,
json={
"filename": "contract.pdf",
"contentType": "application/pdf",
"fileSize": file_size,
},
).json()
# 2. Upload file bytes to GCS (KMS key is pre-signed in the URL query string)
put_headers = {"Content-Type": "application/pdf"}
with open(file_path, "rb") as f:
requests.put(sign_resp["signedUrl"], data=f, headers=put_headers).raise_for_status()
# 3. Process & malware-scan the uploaded file
upload_resp = requests.post(
f"{API_BASE}/api/upload_file",
headers=HEADERS,
json={
"tempObject": sign_resp["tempObject"],
"uuid": sign_resp["uuid"],
"filename": "contract.pdf",
"contentType": "application/pdf",
},
).json()
# 4. Send the secure message
send_resp = requests.post(
f"{API_BASE}/api/send_message",
headers=HEADERS,
json={
"recipients": ["recipient@example.com"],
"subject": "Quarterly Contract",
"body": "Please review the attached contract.",
"file_uuids": [upload_resp["uuid"]],
"expiry_days": 30,
},
).json()
print("Sent message ID:", send_resp["message_id"])
print("Recipient access link:", send_resp["recipients"][0]["access_url"])
Complete JavaScript / Node.js Example (with API Key)
const API_BASE = 'https://getsafedocs.cloud.run';
const API_KEY = process.env.GETSAFEDOCS_API_KEY; // "gsd_..."
const authHeaders = {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
};
// Step 1: Get signed URL
const signRes = await fetch(`${API_BASE}/api/get_signed_url`, {
method: 'POST',
headers: authHeaders,
body: JSON.stringify({
filename: file.name,
contentType: file.type || 'application/pdf',
fileSize: file.size
})
});
const { signedUrl, tempObject, uuid } = await signRes.json();
// Step 2: Upload file directly to GCS
const putHeaders = { 'Content-Type': file.type || 'application/pdf' };
await fetch(signedUrl, { method: 'PUT', headers: putHeaders, body: file });
// Step 3: Process & scan upload
const procRes = await fetch(`${API_BASE}/api/upload_file`, {
method: 'POST',
headers: authHeaders,
body: JSON.stringify({
tempObject,
uuid,
filename: file.name,
contentType: file.type || 'application/pdf'
})
});
const { file_id } = await procRes.json();
// Step 4: Send message with attached file UUID
const sendRes = await fetch(`${API_BASE}/api/send_message`, {
method: 'POST',
headers: authHeaders,
body: JSON.stringify({
recipients: ['user@example.com'],
subject: 'Secure Document Delivery',
body: 'Here is the requested document.',
file_uuids: [file_id]
})
});
const result = await sendRes.json();
console.log('Message sent:', result);
Model Context Protocol (MCP) Server (/mcp)
GetSafeDocs provides a built-in Model Context Protocol (MCP) Server at https://getsafedocs.cloud.run/mcp (and /api/mcp) implementing JSON-RPC 2.0 over Streamable HTTP (2025-03-26 & 2024-11-05). You can connect AI assistants (Claude Desktop, Cursor, Antigravity, Windsurf, or custom MCP agents) directly using your personal gsd_... API Key.
1. Connecting via Remote Streamable HTTP (Recommended — Zero Install)
Add the following to your AI client's MCP configuration file (e.g., mcp_config.json or .cursor/mcp.json):
{
"mcpServers": {
"getsafedocs": {
"url": "https://getsafedocs.cloud.run/mcp",
"headers": {
"X-API-Key": "gsd_your_api_key_here"
}
}
}
}
2. Connecting via Local STDIO Bridge (For Local Disk File Uploads)
If you want your desktop AI assistant to upload files directly from local disk paths (e.g., "Send ~/Documents/contract.pdf to alice@example.com"), download the zero-dependency Python STDIO script (curl -sSL https://getsafedocs.cloud.run/mcp/getsafedocs_mcp.py -o ~/getsafedocs_mcp.py):
{
"mcpServers": {
"getsafedocs": {
"command": "python3",
"args": ["/path/to/mcp/getsafedocs_mcp.py"],
"env": {
"GETSAFEDOCS_API_KEY": "gsd_your_api_key_here"
}
}
}
}
3. Available MCP Tools (tools/list & tools/call)
| Tool Name | Description |
|---|---|
whoami |
Get authenticated account profile, tier (free, premium, enterprise), quota limits, and monthly usage. |
get_supported_file_types |
List allowed and forbidden file extensions and max file size limits per tier. |
upload_inline_file |
Upload a file from content_text or content_base64 to Toronto staging (northamerica-northeast2) and run QuickSand malware analysis. |
get_upload_signed_url |
Generate a GCS V4 Signed PUT URL (signedUrl, tempObject, uuid) for uploading large binary files. |
process_and_scan_upload |
Verify a file uploaded via get_upload_signed_url and run QuickSand malware analysis. |
send_secure_message |
Send a secure message with file_uuids, repo_file_ids (one-click resend from Enterprise Repository), or inline_files (uploads, scans, and sends in one call), recipients, mailing_list_id, team_ids (internal Enterprise Teams), save_to_repository, classification, expiry_days, preview_only, and send_emails. |
list_messages |
List messages in outbox (sent) or inbox (received) with pagination. |
get_message_details |
Get message details, attached files, malware scan ratings, recipient delivery/read status, activity audit logs, and replies. |
reply_to_message |
Send a reply to a message thread using message_id or token. |
manage_message |
Perform message & recipient lifecycle actions: extend_expiry, toggle_notify, set_classification, resend_notification, add_recipients (supports team_ids & mailing_list_id), remove_recipient, add_files (supports repo_file_ids & save_to_repository), remove_file, save_file_to_repo, toggle_legal_hold, toggle_preview_only, mark_read, mark_reply_read, archive, unarchive, or delete. |
download_attachment |
Generate a short-lived GCS V4 signed download URL for a file (file_id or uuid) or a ZIP of all message files (as_zip: true), or save directly to local disk (save_to_path in STDIO bridge). |
get_scan_report |
Inspect QuickSand malware analysis findings and cryptographic hashes (MD5, SHA-1, SHA-256, SHA-512) for a file uuid. |
access_shared_document |
Access a shared document package using a token or message_id. |
list_document_requests |
List all Document Request intake portals created by the user (optional status filter). |
get_document_request |
Get details and client file submissions for a specific Document Request (request_id or request_token). |
submit_to_document_request |
Upload and submit files (inline_files or local_file_paths in STDIO bridge) to a Document Request portal using its request_token. |
create_document_request |
Create a token-protected Document Request intake portal (request_name, expiry_days, max_file_size_mb, allowed_extensions, notify_emails). |
update_document_request |
Update, activate, deactivate, email (notify_emails), or delete a Document Request portal. |
manage_mailing_lists |
List, inspect (get), create, update, or delete external recipient Mailing Lists. |
enterprise_admin |
Enterprise Company Admins: overview (seat usage, members, internal teams, held_messages eDiscovery vault, invites, settings), create_company, rename_company, update_settings (classification_options, disable_remote_preview, auto_archive_to_repo, repo_retention_days), invite, resend_invite, cancel_invite, accept_invite, set_member_role, remove_member, set_user_legal_hold (visible, silent, off), toggle_message_legal_hold, list_teams, create_team, delete_team, add_team_member, and remove_team_member. |
enterprise_repository |
Enterprise Document Repository: list (filter by folder, classification, scope, search), upload (via file_uuids, inline_files, local_file_paths, or promote file_id), update, share (grant can_view, can_download, can_resend, can_delete to a team or user), unshare, toggle_legal_hold, download (supports save_to_path in STDIO bridge), and delete. |
4. Available MCP Resources (resources/list & resources/read)
getsafedocs://guide/quickstart— Complete MCP & API integration guide and workflow referencegetsafedocs://account/profile— Current account profile, tier limits, and monthly quota usagegetsafedocs://config/file-types— Supported & forbidden file extensions per tiergetsafedocs://messages/outbox— Recent Outbox (sent) messagesgetsafedocs://messages/inbox— Recent Inbox (received) messagesgetsafedocs://document-requests— Active Document Request intake portalsgetsafedocs://mailing-lists— Saved recipient mailing listsgetsafedocs://repository— Enterprise Document Repository files, folders, classifications, and permissions- Resource Templates (
resources/templates/list): getsafedocs://messages/{message_id}getsafedocs://scan-report/{uuid}getsafedocs://document-requests/{request_id}
5. Example MCP JSON-RPC Call (tools/call)
curl -X POST https://getsafedocs.cloud.run/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: gsd_your_api_key_here" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "send_secure_message",
"arguments": {
"subject": "Security Audit Summary",
"body": "Attached is the Q4 security summary.",
"recipients": ["client@example.com"],
"preview_only": true,
"inline_files": [
{
"filename": "q4_summary.md",
"content_text": "# Q4 Security Summary\n\nAll systems passed 99/100 OWASP assessment."
}
]
}
}
}'
Related Documentation
- Quick Start Guide: View Quick Start Guide
- Complete User Guide: View User Guide
- Enterprise Admin Guide: View Enterprise Admin Guide
- Supported File Types (Web / JSON / Markdown): https://getsafedocs.cloud.run/file_types | https://getsafedocs.cloud.run/file_types?format=json
- Security Documentation: View Security Documentation
- Contact Support: https://getsafedocs.cloud.run/contact