Use the Cloud REST API
Make your first request, choose a mailbox, and look up operation arguments.
Call POST https://cloud.fluxmail.ai/api/mail/{operation} with JSON arguments and an Authorization: Bearer header. REST and MCP use the same operations, mailbox grants, and scopes.
You need a connected mailbox and a Cloud agent key. The examples below use mail.read. Complete the quickstart if you haven't created a key yet.
Verify a read-only connection
Make your key available privately as FLUXMAIL_CLOUD_AGENT_KEY in your terminal's environment. Keep its value out of shell history, source files, and logs.
1. List your mailboxes
curl --fail-with-body https://cloud.fluxmail.ai/api/mail/list_accounts \
--header "Authorization: Bearer $FLUXMAIL_CLOUD_AGENT_KEY" \
--header 'Content-Type: application/json' \
--data '{}'The response contains only mailboxes available to the key. An example response:
{
"data": [
{
"id": "11111111-1111-4111-8111-111111111111",
"email": "you@example.com",
"provider": "gmail",
"shared": false,
"enabled": true
}
]
}2. List your 5 most recent emails
Copy the intended mailbox's id into this request, replacing MAILBOX_ID:
curl --fail-with-body https://cloud.fluxmail.ai/api/mail/list_emails \
--header "Authorization: Bearer $FLUXMAIL_CLOUD_AGENT_KEY" \
--header 'Content-Type: application/json' \
--data '{"accountId":"MAILBOX_ID","pageSize":5,"includeSnippet":false}'A successful response contains up to 5 email summaries. These two calls verify the key, its mailbox access, and the provider connection without opening message bodies or changing mail. A mailbox with fewer than 5 emails returns fewer results.
Operations and arguments
| Operation | Scope | Arguments |
|---|---|---|
list_accounts | mail.read | {} |
list_emails | mail.read | accountId, optional filters such as text, from, subject, read, after, before, and pageSize (1 to 100), pageToken |
get_email | mail.read | accountId, messageId, optional includeHeaders |
get_thread | mail.read | accountId, threadId |
list_folders, list_labels, list_send_as | mail.read | accountId |
download_attachment | mail.read | accountId, messageId, attachmentId |
get_draft | mail.drafts | accountId, draftId |
create_draft | mail.drafts | accountId, message fields |
update_draft | mail.drafts | accountId, draftId, message fields |
delete_draft | mail.drafts | accountId, draftId |
preview_send | mail.send | accountId, message fields |
send_email | mail.send, plus mail.drafts with draftId | accountId, idempotencyKey, message fields or draftId |
get_delivery_operation | mail.send | accountId, operationId |
modify_emails | mail.organize, mail.trash, or mail.delete, depending on action | accountId, messageIds, action, and folder or labels when required |
Modification actions require mail.organize for flags, labels, archive, and move; mail.trash for trash and untrash; or mail.delete for permanent deletion. Generic moves cannot target Trash or Archive or restore messages from Trash.
Use IDs returned by Cloud, and include accountId to select a mailbox. Filters for list_emails are top-level fields, not a nested query object. Dates use YYYY-MM-DD. Follow returned pagination tokens; the default page size is 25.
Message fields include to, cc, and bcc as arrays of address strings, subject, bodyText, bodyHtml, optional from, attachments, replyToMessageId, and replyAll. Attachments use filename, mimeType, and base64 content, with optional inline-image fields. A new message or draft needs at least one recipient. Replying to a message requires mail.read as well as the operation's scope so Cloud can read the original.
Modification actions are markRead, markUnread, star, unstar, archive, trash, untrash, delete, move, addLabels, and removeLabels. move requires folder; label actions require labels. Permanent deletion is unavailable for Gmail OAuth connections.
Search example
Send this body to /api/mail/list_emails with a read-scoped key:
{
"accountId": "MAILBOX_ID",
"subject": "invoice",
"after": "2026-10-01",
"pageSize": 10
}Call from Node.js
Save this helper in an .mjs file and run it with a Node.js release that includes fetch. Supply your key and the mailbox ID from list_accounts as environment variables before running it.
const token = process.env.FLUXMAIL_CLOUD_AGENT_KEY;
const accountId = process.env.FLUXMAIL_CLOUD_ACCOUNT_ID;
if (!token || !accountId) {
throw new Error('Set FLUXMAIL_CLOUD_AGENT_KEY and FLUXMAIL_CLOUD_ACCOUNT_ID.');
}
async function call(operation, args) {
const response = await fetch(
`https://cloud.fluxmail.ai/api/mail/${operation}`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(args),
}
);
const result = await response.json();
if (!response.ok) {
const code = result.error?.code ?? response.status;
const requestId = result.requestId ?? response.headers.get('x-request-id');
throw new Error(`${operation}: ${code}; request ${requestId}`);
}
return result.data;
}
await call('list_emails', { accountId, pageSize: 5, includeSnippet: false });
console.log('Fluxmail Cloud mailbox access verified.');The helper makes one request per call and leaves retries to your application. It prints neither message contents nor the key.
Send status and duplicate protection
Every send requires an idempotencyKey. See sending and retries for message examples and the steps to take after a timeout. Never retry an uncertain send with a fresh key.
Errors and retries
Failures return an error with a code and message. Keep the requestId or x-request-id response header for troubleshooting. See errors and retries for status codes and limits for quotas and attachment sizes.
Cloud uses /api/mail/{operation} paths, separate from the self-hosted package's versioned API. Agent keys cannot manage mailbox connections or create keys; use the dashboard for those actions.
Last updated