/api/qmail/net/messages/send

GET POST

Send an email through the QMail network. The handler accepts query parameters or form-encoded bodies; this page includes a one-click GET test link for the standard Client1 to Client2 developer setup.

Description

The /api/qmail/net/messages/send endpoint sends an email message through the QMail network. Parameters are read with resolve_wallet_path(), so omitting both wallet and wallet_path means the send is paid from the Default wallet.

Recipient Format

Use repeated to= and cc= parameters for multiple recipients. Example: ?to=Mohsin.Mehraj%40FullStack%23FVH.giga&to=Sean.Worthington%40Founder%23FUV.giga. The API still accepts one legacy comma/semicolon-separated string for backward compatibility.

Recipient Limits

The send flow accepts up to 50 recipients per field. If the request exceeds the HTTP parameter limit because of too many repeated values, the server now returns HTTP 413 Payload Too Large with { "error": true, "message": "Too many request parameters", "code": 413 } instead of truncating the tail of the list.

Standard Test Setup

For local docs testing, use Client1 on port 8081 to send to Client2 at Mohsin.Mehraj@FullStack#FVH.giga. If you do not specify a wallet, the API uses the Default wallet.

Parameters

Send parameters as form data or query string values:

Parameter Type Required Description
to string Yes Repeat this parameter for each recipient. Each value can be a QMail address or a raw serial number.
body string Yes The email message body content.
cc string No Optional repeated CC parameter. Legacy comma/semicolon-separated strings still work.
subject string No Email subject line.
storage_weeks integer No Number of weeks to store the message on the network. Default: 4.
wallet or wallet_path string No Optional wallet selector. If omitted, resolve_wallet_path() uses the Default wallet automatically.

Response

Returns a JSON object indicating the result of the send operation.

Success Response Properties

success boolean
Always true on success.
message string
Human-readable status message (e.g., "Email sent successfully").
file_guid string
A 32-character hexadecimal identifier for the sent message.
upload_successes integer
Number of RAIDA servers that successfully received the message.
upload_failures integer
Number of RAIDA servers that failed to receive the message.
tell_success boolean
Whether the recipient was successfully notified of the new message.
used_sync_fallback boolean
Whether the handler had to fall back to the synchronous send path.
low_balance_warning boolean
Whether the sender wallet is approaching a low balance condition for QMail operations.

Example Success Response

{
  "success": true,
  "message": "Email sent successfully",
  "file_guid": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "upload_successes": 25,
  "upload_failures": 0,
  "tell_success": true,
  "used_sync_fallback": false,
  "low_balance_warning": false
}

Error Response Properties

error boolean
Always true on error.
message string
Human-readable error description.
code integer
HTTP status code repeated in the JSON body, usually 400 for validation failures or 500 for send failures.
detail string
Optional internal result string returned on some server-side send failures.

Example Error Responses

{
  "error": true,
  "message": "Missing required parameters: to, body",
  "code": 400
}

{
  "error": true,
  "message": "Send failed",
  "code": 500,
  "detail": "network_error"
}

{
  "error": true,
  "message": "Too many request parameters",
  "code": 413
}

Try It Out

Enter one recipient per line. The tester sends them as repeated to= parameters.

Examples

cURL

curl "http://localhost:8081/api/qmail/net/messages/send?to=Mohsin.Mehraj%40FullStack%23FVH.giga&body=QMail%20doc%20test%20from%20Client1%20using%20the%20Default%20wallet.&subject=QMail%20Doc%20Test&storage_weeks=4"

curl -X POST "http://localhost:8081/api/qmail/net/messages/send" \
  -d "to=Mohsin.Mehraj%40FullStack%23FVH.giga" \
  -d "to=Sean.Worthington%40Founder%23FUV.giga" \
  -d "body=QMail doc test from Client1 using the Default wallet." \
  -d "subject=QMail Doc Test" \
  -d "storage_weeks=4"

JavaScript (fetch)

const API_BASE = 'http://localhost:8081/api';

async function sendEmail() {
    const params = new URLSearchParams();
    [
        'Mohsin.Mehraj@FullStack#FVH.giga',
        'Sean.Worthington@Founder#FUV.giga'
    ].forEach(value => params.append('to', value));
    params.append('body', 'QMail doc test from Client1 using the Default wallet.');
    params.append('subject', 'QMail Doc Test');
    params.append('storage_weeks', '4');

    try {
        const response = await fetch(`${API_BASE}/qmail/net/messages/send`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: params.toString()
        });

        const result = await response.json();

        if (response.ok && result.success) {
            console.log('Email sent successfully!');
            console.log('File GUID:', result.file_guid);
            console.log('Upload successes:', result.upload_successes);
            console.log('Upload failures:', result.upload_failures);
            console.log('Tell success:', result.tell_success);
        } else {
            console.error('Failed to send email:', result.message);
            console.error('HTTP code:', result.code ?? response.status);
            if (result.detail) {
                console.error('Detail:', result.detail);
            }
        }
    } catch (error) {
        console.error('Error sending email:', error);
    }
}

sendEmail();

Python

import requests

API_BASE = 'http://localhost:8081/api'

def send_email():
    params = [
        ('to', 'Mohsin.Mehraj@FullStack#FVH.giga'),
        ('to', 'Sean.Worthington@Founder#FUV.giga'),
        ('body', 'QMail doc test from Client1 using the Default wallet.'),
        ('subject', 'QMail Doc Test'),
        ('storage_weeks', 4)
    ]

    try:
        response = requests.post(f'{API_BASE}/qmail/net/messages/send', data=params)
        result = response.json()

        if response.ok and result.get('success'):
            print('Email sent successfully!')
            print(f'File GUID: {result["file_guid"]}')
            print(f'Upload successes: {result["upload_successes"]}')
            print(f'Upload failures: {result["upload_failures"]}')
            print(f'Tell success: {result["tell_success"]}')
        else:
            print(f'Failed to send email: {result["message"]}')
            print(f'HTTP code: {result.get("code", response.status_code)}')
            if result.get('detail'):
                print(f'Detail: {result["detail"]}')

    except Exception as e:
        print(f'Error sending email: {str(e)}')

send_email()