/api/qmail/poll
GETLong-poll beacon endpoint. Blocks until new mail arrives or the specified timeout expires, providing an efficient way to receive real-time mail notifications without constant polling.
Description
The /api/qmail/poll endpoint implements a long-poll pattern for receiving real-time mail notifications. When called, the request blocks (holds the connection open) until either new mail arrives or the specified timeout period expires. This is far more efficient than repeatedly calling the quick-check endpoint.
This endpoint is designed for:
- Real-time mail notification systems
- Efficient server-push-style updates over HTTP
- Reducing network overhead compared to frequent short polling
- Desktop and mobile clients that need instant new-mail alerts
Unlike the /api/qmail/check endpoint which returns quickly with a 10-second timeout, this endpoint blocks for up to 10 minutes (600 seconds) by default. Use /poll when you want to be notified as soon as new mail arrives, and /check for quick non-blocking lookups.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
timeout |
integer | No | Timeout in seconds for the long-poll. The request will block for at most this many seconds before returning. Default: 600. Maximum: 600 (10 minutes). |
Response
Success Response Properties
true when new mail was found.Notification Object Properties
Error / Timeout Response Properties
false when the poll timed out or encountered an error.Success Response Example (New Mail Arrived)
{
"success": true,
"new_mail_count": 3,
"total_remaining": 7,
"notifications": [
{
"file_guid": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"sender_sn": 14582,
"timestamp": 1735689800,
"tell_type": 1,
"total_file_size": 2048
},
{
"file_guid": "f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3",
"sender_sn": 28743,
"timestamp": 1735689820,
"tell_type": 1,
"total_file_size": 15360
},
{
"file_guid": "01234567890abcdef01234567890abcd",
"sender_sn": 5091,
"timestamp": 1735689845,
"tell_type": 2,
"total_file_size": 524288
}
]
}
Timeout Response Example
{
"success": false,
"message": "Poll timed out or failed",
"error": "poll_timeout"
}
Interactive API Tester
Test this Endpoint
Examples
cURL
# Long-poll with default 600-second timeout
curl "http://localhost:8080/api/qmail/poll"
# Long-poll with a custom 60-second timeout
curl "http://localhost:8080/api/qmail/poll?timeout=60"
JavaScript (fetch)
async function pollForMail(timeoutSeconds = 600) {
const url = 'http://localhost:8080/api/qmail/poll'
+ `?timeout=${timeoutSeconds}`;
// Set a client-side abort timeout slightly longer than the server timeout
const controller = new AbortController();
const clientTimeout = setTimeout(() => controller.abort(), (timeoutSeconds + 10) * 1000);
try {
const response = await fetch(url, { signal: controller.signal });
const result = await response.json();
if (result.success) {
console.log(`New mail! ${result.new_mail_count} notification(s).`);
console.log(`${result.total_remaining} more remaining in queue.`);
result.notifications.forEach(n => {
console.log(` File: ${n.file_guid}, Sender SN: ${n.sender_sn}, Size: ${n.total_file_size} bytes`);
});
} else {
console.log('Poll ended:', result.message);
}
return result;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Poll request timed out on client side.');
} else {
console.error('Poll error:', error);
}
} finally {
clearTimeout(clientTimeout);
}
}
// Continuous long-poll loop
async function startPolling() {
while (true) {
const result = await pollForMail(300);
if (result && result.success) {
// Process new mail notifications here
}
// Immediately re-poll (the server handles the wait)
}
}
pollForMail(60);
Python
import requests
def poll_for_mail(timeout_seconds=600):
"""Long-poll for new mail notifications."""
url = 'http://localhost:8080/api/qmail/poll'
params = {'timeout': timeout_seconds}
# Set a client-side timeout slightly longer than the server timeout
response = requests.get(url, params=params, timeout=timeout_seconds + 10)
result = response.json()
if result['success']:
print(f"New mail! {result['new_mail_count']} notification(s).")
print(f"{result['total_remaining']} more remaining in queue.")
for n in result['notifications']:
print(f" File: {n['file_guid']}, Sender SN: {n['sender_sn']}, Size: {n['total_file_size']} bytes")
else:
print(f"Poll ended: {result['message']}")
return result
# Continuous long-poll loop
def start_polling():
while True:
try:
result = poll_for_mail(timeout_seconds=300)
if result['success']:
# Process new mail notifications here
pass
except requests.exceptions.Timeout:
print('Poll request timed out, restarting...')
except requests.exceptions.RequestException as e:
print(f'Poll error: {e}')
poll_for_mail(timeout_seconds=60)
Important Notes
This is a long-poll endpoint. The HTTP connection remains open until new mail arrives or the timeout expires. Ensure your HTTP client is configured with an appropriate timeout that exceeds the server-side timeout parameter to avoid premature client-side disconnections.
The timeout parameter controls how long the server will wait for new mail. The default and maximum value is 600 seconds (10 minutes). If no new mail arrives within the timeout, the server responds with success: false and the message "Poll timed out or failed". Simply re-issue the request to continue waiting.
Always set your client-side HTTP timeout to be slightly longer than the server-side timeout value. For example, if you set timeout=300, configure your HTTP client to wait at least 310 seconds. This prevents the client from disconnecting before the server has a chance to respond.
For real-time notifications, implement a continuous loop: call /poll, process any results, then immediately call /poll again. The server handles the waiting, so there is no need to add a sleep delay between requests.