curl --request POST \
--url https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "<string>",
"subject": "<string>",
"body": "<string>",
"cc": "<string>",
"bcc": "<string>",
"threadId": "<string>",
"attachments": [
"<string>"
]
}
'import requests
url = "https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts"
payload = {
"to": "<string>",
"subject": "<string>",
"body": "<string>",
"cc": "<string>",
"bcc": "<string>",
"threadId": "<string>",
"attachments": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '<string>',
subject: '<string>',
body: JSON.stringify('<string>'),
cc: '<string>',
bcc: '<string>',
threadId: '<string>',
attachments: ['<string>']
})
};
fetch('https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'to' => '<string>',
'subject' => '<string>',
'body' => '<string>',
'cc' => '<string>',
'bcc' => '<string>',
'threadId' => '<string>',
'attachments' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts"
payload := strings.NewReader("{\n \"to\": \"<string>\",\n \"subject\": \"<string>\",\n \"body\": \"<string>\",\n \"cc\": \"<string>\",\n \"bcc\": \"<string>\",\n \"threadId\": \"<string>\",\n \"attachments\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"to\": \"<string>\",\n \"subject\": \"<string>\",\n \"body\": \"<string>\",\n \"cc\": \"<string>\",\n \"bcc\": \"<string>\",\n \"threadId\": \"<string>\",\n \"attachments\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"to\": \"<string>\",\n \"subject\": \"<string>\",\n \"body\": \"<string>\",\n \"cc\": \"<string>\",\n \"bcc\": \"<string>\",\n \"threadId\": \"<string>\",\n \"attachments\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"ok": true,
"draftId": "<string>",
"messageId": "<string>",
"draftUrl": "<string>",
"threadUrl": "<string>",
"to": "<string>",
"subject": "<string>",
"threadId": "<string>",
"quotedHistoryIncluded": true,
"attachments": [
{
"filename": "<string>",
"mimeType": "<string>",
"size": 4503599627370495
}
]
}{
"error": "invalid_request",
"details": [
{
"message": "<string>",
"path": [
"<string>"
]
}
],
"capability": "<string>"
}{
"error": "unauthorized"
}{
"error": "needs_connection",
"message": "<string>"
}{
"ok": false,
"error": "file_input_requires_host",
"created": false,
"message": "Workspace attachments require a supporting OpenWork host. No draft was created. Do not retry without attachments."
}{
"error": "google_api_error",
"message": "<string>"
}Create a Gmail draft or threaded reply with optional workspace attachments
Creates a plain-text Gmail draft in the calling member own mailbox. Optional attachments are workspace paths, up to 10 files totaling at most 4 MiB, fulfilled outside model context by a supporting OpenWork host on direct execute_capability calls. Code Mode and other MCP hosts cannot fulfill attachments and create no draft. Set threadId for replies and forwards. Always share the returned draftUrl.
curl --request POST \
--url https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "<string>",
"subject": "<string>",
"body": "<string>",
"cc": "<string>",
"bcc": "<string>",
"threadId": "<string>",
"attachments": [
"<string>"
]
}
'import requests
url = "https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts"
payload = {
"to": "<string>",
"subject": "<string>",
"body": "<string>",
"cc": "<string>",
"bcc": "<string>",
"threadId": "<string>",
"attachments": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '<string>',
subject: '<string>',
body: JSON.stringify('<string>'),
cc: '<string>',
bcc: '<string>',
threadId: '<string>',
attachments: ['<string>']
})
};
fetch('https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'to' => '<string>',
'subject' => '<string>',
'body' => '<string>',
'cc' => '<string>',
'bcc' => '<string>',
'threadId' => '<string>',
'attachments' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts"
payload := strings.NewReader("{\n \"to\": \"<string>\",\n \"subject\": \"<string>\",\n \"body\": \"<string>\",\n \"cc\": \"<string>\",\n \"bcc\": \"<string>\",\n \"threadId\": \"<string>\",\n \"attachments\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"to\": \"<string>\",\n \"subject\": \"<string>\",\n \"body\": \"<string>\",\n \"cc\": \"<string>\",\n \"bcc\": \"<string>\",\n \"threadId\": \"<string>\",\n \"attachments\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.openworklabs.com/v1/capabilities/google-workspace/gmail-drafts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"to\": \"<string>\",\n \"subject\": \"<string>\",\n \"body\": \"<string>\",\n \"cc\": \"<string>\",\n \"bcc\": \"<string>\",\n \"threadId\": \"<string>\",\n \"attachments\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"ok": true,
"draftId": "<string>",
"messageId": "<string>",
"draftUrl": "<string>",
"threadUrl": "<string>",
"to": "<string>",
"subject": "<string>",
"threadId": "<string>",
"quotedHistoryIncluded": true,
"attachments": [
{
"filename": "<string>",
"mimeType": "<string>",
"size": 4503599627370495
}
]
}{
"error": "invalid_request",
"details": [
{
"message": "<string>",
"path": [
"<string>"
]
}
],
"capability": "<string>"
}{
"error": "unauthorized"
}{
"error": "needs_connection",
"message": "<string>"
}{
"ok": false,
"error": "file_input_requires_host",
"created": false,
"message": "Workspace attachments require a supporting OpenWork host. No draft was created. Do not retry without attachments."
}{
"error": "google_api_error",
"message": "<string>"
}Authorizations
Session token passed as Authorization: Bearer <session-token> for user-authenticated Den routes.
Body
Recipient email address.
3 - 320Draft subject line. For replies or forwards, include threadId; subjects starting with Re: or Fwd: are rejected without threadId so the draft stays on the existing conversation.
1 - 500Plain-text draft body. Write plain prose with no markdown syntax, separate paragraphs with blank lines, and do not hard-wrap prose. For threaded drafts, the server appends the quoted conversation automatically; do not include quoted history.
1 - 50000Optional comma-separated Cc email addresses.
3 - 1000Optional comma-separated Bcc email addresses.
3 - 1000Gmail thread id to reply on. Required for replies and forwards; get it from the gmail-messages capability. When set, the draft is attached to that thread as a reply — keep the thread's subject (e.g. 'Re: …').
1 - 512Optional workspace file paths, 1 to 10 files totaling at most 4 MiB. File bytes stay outside model context. Requires a direct execute_capability call from a supporting OpenWork host; Code Mode and other MCP hosts are unsupported and create no draft. Do not retry without attachments.
1 - 10 elements1Response
Draft created.
Gmail URL for the ready-to-send draft. Always share draftUrl with the user so they can open the draft in Gmail for review and send.
Gmail URL for the conversation thread returned by Gmail for this draft.
True when quoted conversation history was included by the server or already present in the request body.
Show child attributes
Show child attributes
Was this page helpful?