HTTP API 參考
語言與錯誤碼
英文是預設語言。API、Web 控制台和通知渲染共用
internal/i18n/locales/ 下的內嵌文案,internal/i18n/languages.json
定義語言程式碼和本機名稱。
| 程式碼 | 語言 |
|---|---|
en |
English |
zh-CN |
简体中文 |
zh-Hant |
繁體中文 |
ja |
日本語 |
ko |
한국어 |
de |
Deutsch |
fr |
Français |
es |
Español |
pt-BR |
Português (Brasil) |
-
首次存取按瀏覽器的
Accept-Language選擇語言,切換後在本機儲存規範程式碼。控制台語言與已儲存的通知語言獨立。 -
API(包括 App 管理介面)按
Accept-Language權重協商,返回Content-Language和Vary: Accept-Language。跳過不支援的偏好;預設、非法或全部不支援時回退en,權重 0 的語言不參與協商。 -
地區別名對映到對應語言:
fr-CA→fr,es-MX→es,pt/pt-PT→pt-BR。中文區分字形:zh-Hans/zh-CN/zh-SG→zh-CN;zh-Hant/zh-TW/zh-HK/zh-MO→zh-Hant。顯式字形優先於地區,單獨zh使用簡體。 -
GET /locales/default.json返回協商後的文案;GET /locales/{规范代码}.json返回指定文案;未知文案路徑返回locale_not_supported。 -
通道設定
language獨立控制哨站生成的通知,支援上述規範程式碼及地區別名,儲存時歸一化;省略或空值使用en,顯式不支援的值返回 400config_language_invalid。請求語言不會覆蓋該設定。 - Native 測試文案由推播中繼服務根據配對裝置語言生成,哨站通知語言不會覆蓋它。推播中繼服務和 App 各自支援相應的語言。
-
控制台本機化標準資料夾角色及常見名稱。API 保留原始 IMAP
路徑、自定義名稱和
folder_roles,App 使用自己的文案翻譯角色。通知標題繼續使用原始資料夾末級名稱;使用者輸入、郵件主旨、內文和驗證碼保持原值。 -
日誌和 CLI 使用英文。業務錯誤保持穩定的英文
snake_case錯誤碼與命名引數;儲存保留程式碼和引數,展示層負責翻譯。API 時間和數字保持原有機器可讀格式,控制台按所選語言格式化時間。
{
"error": {
"code": "unauthorized",
"message": "请使用有效会话或 API Token 登录。"
}
}
投遞記錄的 last_error 與資料夾狀態的
notice 使用相同的
{code, message, params?} 結構,例如
bark_http_error 搭配
{"status":"503"}。按
code 判斷分支,message 用於展示。
每個信箱的獨立連線預算內預留 1
個名額給資料夾發現與連線測試。監聽需求按“實時 Folder 數 +(存在定時
Folder 時的 1 個)”計算,最多使用
connection_limit - 1 個名額(預設 9
個);該信箱所有操作的總連線數保持在
connection_limit(2–100)以內。已儲存上限為 1 的設定按
configuration_invalid 降級啟動,允許透過該信箱的 PUT
介面修正。
HTTP API
GET /、靜態資源和
/healthz 公開存取。首次設定完成前,其他管理介面統一返回
403 setup_required;POST /api/v1/setup
只能成功一次。設定後公開登入介面
POST /api/v1/session,其餘介面使用會話 Cookie 或
Authorization: Bearer mwk_…。
Cookie 屬性為 HttpOnly、SameSite=Strict、Path=/,TLS 連線或 HTTPS
Origin 加 Secure;空閒 7 天或絕對 30 天過期。Cookie 修改請求同時要求
X-CSRF-Token 和使用 HTTP 或 HTTPS、主機與埠和請求 Host
完全一致的 Origin。Bearer 請求免於 CSRF;顯式提交錯誤的
Authorization 時,即使 Cookie 有效也拒絕請求。
登入和設定碼失敗按連線來源地址共享限額:15 分鐘內 10
次失敗,後續請求返回 429 too_many_attempts,Retry-After
為秒數。密碼修改也使用該限額,來源由 Gin ClientIP
按上述可信代理網段解析。登入和設定請求中的跨站 Origin
會被拒絕。由於所有內網對端都被視為可信代理,區域網內的客戶端可以偽造
X-Forwarded-For,把失敗嘗試分散到多個來源地址。不要把哨站監聽埠暴露在不可信的區域網中,只透過反向代理對外提供存取。
JSON 請求體上限 64 KiB,未知欄位或多餘 JSON 返回 400。密碼至少 12 個字元、最多 1024 個 UTF-8 位元組;使用者名稱及 Token 名稱為 1–128 位元組。管理 API 的時間戳統一為 UTC RFC 3339 字串,包括投遞 created_at/accepted_at、Token created_at/last_used_at、資料夾檢查時間、日誌時間和診斷生成時間;小數秒保留儲存精度。未使用 Token 的 last_used_at 為 null,尚未接受的投遞省略 accepted_at。計數、時長和 revision 保持數字。
401 表示會話或 API Token 鑑權失敗,或
POST /api/v1/session 登入憑據錯誤。設定碼錯誤返回 400
setup_code_invalid,嚮導回到設定碼步驟並保留使用者名稱。PUT /api/v1/admin/password
的當前密碼錯誤返回 400
current_password_invalid,仍計入失敗限速,當前會話保持有效。登入失敗與當前密碼錯誤在原表單內提示並保留輸入。
| 方法 | 路徑 | 請求與回應 |
|---|---|---|
| POST | /api/v1/setup |
{"code":"XXXX-XXXX-XXXX","username":"admin","password":"…"};201,Cookie 與 csrf_token;重複設定返回 409
|
| POST | /api/v1/session |
{"username":"admin","password":"…"};200,Cookie 與 csrf_token
|
| GET | /api/v1/session |
返回
authenticated:true、csrf_token;Bearer 返回
method:"token"
|
| DELETE | /api/v1/session |
204,登出當前 Cookie 會話;需要會話鑑權 |
| PUT | /api/v1/admin/password |
{"current_password":"…","password":"…"};204,登出其他會話;Bearer 修改會登出全部會話
|
| POST | /api/v1/tokens |
{"name":"automation"};201,返回
id、name、created_at、last_used_at
和僅顯示一次的 token
|
| GET | /api/v1/tokens |
{"tokens":[…]},僅後設資料 |
| DELETE | /api/v1/tokens/:id |
204,撤銷 Token;重複撤銷仍返回 204 |
| GET | /api/v1/mailboxes |
{"mailboxes":[…]},信箱脫敏檢視列表
|
| POST | /api/v1/mailboxes |
使用下方信箱表單建立;201,返回生成的 ID、revision 1 和脫敏檢視 |
| GET / PUT / DELETE | /api/v1/mailboxes/:id |
讀取 / 攜帶當前 revision 更新 / 刪除(204);不存在返回 404
mailbox_not_found
|
| POST | /api/v1/mailboxes/test |
測試未儲存的信箱表單,返回
{"folders":[…]},保持設定原值
|
| POST | /api/v1/mailboxes/:id/test |
合併該信箱已儲存的憑據後測試,連線目標相同時省略密碼保留原值 |
| GET | /api/v1/mailboxes/:id/folders |
使用該信箱預算發現可選資料夾 |
| GET / PUT | /api/v1/mailboxes/:id/subscriptions |
讀取 / 按獨立 revision 儲存訂閱;成功返回 202 |
| GET / PUT | /api/v1/settings/delivery |
讀取 / 攜帶獨立 revision 儲存全域性通道設定 |
| DELETE | /api/v1/settings/delivery |
攜帶
{revision} 清除通道與憑據;204,版本衝突409
|
| POST | /api/v1/settings/delivery/test |
合併已儲存憑據並測試通道表單;204,保持設定原值 |
| GET | /api/v1/status |
資料夾狀態、通道、投遞計數及按作用域組織的 notices |
| GET | /api/v1/diagnostics |
下載脫敏 JSON 診斷報告,省略執行日誌 |
| GET | /api/v1/logs |
鑑權後查詢執行日誌,支援 after、level、mailbox_id、limit(見下文) |
| GET | /api/v1/deliveries |
最近 50 條請求記錄,包含標題和信箱 / 資料夾摘要 |
| POST | /api/v1/test-push |
使用已儲存設定傳送測試,接受後返回 204,保持設定原值 |
| POST | /api/v1/deliveries/:id/retry |
重新處理 dead 任務,返回 202 |
投遞記錄的可選 message 物件包含
mailbox_id、mailbox_label、folder、subject(字串或
null)和
test(布林值)。名稱按入隊時儲存,信箱改名或刪除後保持歷史來源。subject
為 null 表示標題未保留,空字串表示郵件無主旨。測試通知的
test=true,來源為空。摘要介面省略寄件者和內文。
建立信箱示例:
{
"label": "工作邮箱",
"host": "imap.example.org",
"port": 993,
"username": "user@example.org",
"password": "…",
"connection_limit": 10
}
最多儲存 20 個信箱,包含待修正的無效設定;繼續建立返回 400
mailbox_limit_exceeded。ID 為
mbx_ 加隨機串,建立後保持穩定。label
預設取 username(信箱地址),最長 64 個 Unicode
字元,禁止換行。使用者名稱超過 64
字元時需顯式填寫較短名稱。更新時省略名稱保留原值,空名稱使用本次提交的
username。
信箱 PUT 使用相同表單並攜帶 GET 讀到的 revision,例如
"revision":1,必須填寫
host、port、username。host、port、username 保持原值時,省略 password
保留原密碼,顯式空密碼會被拒絕。省略
connection_limit 保留當前值;新信箱預設 10,範圍
2–100。建立 POST 省略 revision 或傳 0。測試介面接受相同欄位,無須
revision,保持設定原值;未儲存信箱的測試需要憑據,帶 ID
的測試只合並該信箱的已有憑據。
信箱 GET 返回
id、label、revision、host、port、username、connection_limit、connections_in_use
與
"password":{"configured":true}。降級的無效信箱返回 configured:false,保留 ID 和
revision 供修正。讀取回應中的密碼物件屬於展示檢視,不能作為寫入值。
每個信箱的連線預算獨立。實時 Folder 各佔一條連線,全部定時 Folder
合計佔一條,需求最多為
connection_limit - 1,預留一條供管理。PUT
訂閱及修改連線上限共用此公式,容量不足返回
connection_budget_exceeded。未儲存信箱的測試使用臨時預算。未儲存信箱測試、已儲存信箱測試和資料夾發現三個入口還共用全域性併發上限
2,超出立即返回 429
discovery_busy,結束或取消時釋放名額。
首次儲存通道示例:
{
"revision": 0,
"channel": "bark",
"preview": "off",
"retry_count": 0,
"language": "zh-CN",
"bark": { "endpoint": "https://api.day.app", "key": "…" }
}
每次更新前讀取 /settings/delivery 並提交其
revision,首次儲存從 0 增加到 1。Pushover 使用
pushover.token、pushover.user;Webhook
使用
webhook.url、webhook.secret。channel、preview、revision
必填;省略 language、retry_count 使用預設值。省略憑據(含 Webhook
URL)保留已儲存值,顯式空的當前通道憑據會被拒絕;GET 將憑據替換為
{"configured":true|false}。獨立測試介面無須
revision。
信箱建立和連線設定修改在儲存前測試連線及登入。host、port、username、connection_limit
與現值相同且省略 password 時,PUT 只改 label:仍校驗 revision
並儲存,保持連線與進度,已入隊通知保留原名稱,之後入隊使用新名稱。建立或修改後的身分若與其他信箱相同,返回
409 mailbox_duplicate;host 與 username
忽略大小寫、port 精確匹配,同身分併發建立只成功一個。通道 PUT
對所有通道統一校驗欄位、地址、所選配對狀態與
revision,直接儲存,儲存過程不傳送測試或聯絡通道服務。顯式通道測試保持設定原值,失敗後仍可儲存合法設定。信箱網路測試在設定鎖外執行,現有監聽保持執行,信箱測試失敗保留原設定。設定
revision 過期返回 409
settings_conflict;信箱測試期間訂閱變化同樣使快照失效,需重新讀取後提交。各信箱、全域性通道分別維護
revision,修改不同信箱、同時修改信箱和通道互不衝突。
PUT 成功返回脫敏檢視並立即生效。信箱連線設定更新先停止自身監聽,再儲存並按需清理進度;儲存失敗恢復原監聽,其他信箱繼續執行。通道變更時,進行中的請求沿用原快照,後續嘗試使用新快照;尚未設定通道時佇列保持待處理。
GET /api/v1/mailboxes/:id/subscriptions 返回
{"revision":1,"folders":[{"name":"INBOX","check":"realtime"},{"name":"Clients","check":"5m"}]}。PUT 提交讀取到的 revision 與完整 folders
陣列,空陣列取消該信箱的全部訂閱。名稱在信箱內唯一,INBOX
大小寫統一,每項最多 4096 個 UTF-8 位元組;每項 name、check
必填,check 為 realtime、5m 或 15m;缺失、非法 check
或舊字串陣列返回 400。連線需求使用上文公式。只改 check
保留進度和事件
ID,銜接新郵件補查;取消後重新訂閱繼續重建基線。儲存成功返回 202
和下一個版本,舊版本返回 409
subscriptions_conflict。資料夾存在性由監聽確認,信箱離線時仍可取消訂閱。儲存失敗返回
503,當前訂閱保持不變。
/status.folders[] 每項包含
mailbox_id、mailbox_label 與
check。mode 為 idle、poll 或 scheduled;定時 Folder
另有 RFC 3339 時間 next_check(失敗時為下次重試時間),實時 Folder
省略該欄位。已儲存設定的 JSON
或模型校驗失敗時,對應項降級為未設定,在
/status.notices 的 mailbox:<id> 或
delivery 下報告
configuration_invalid,可透過該項 PUT
修正。訂閱超預算時僅暫停該信箱,在
subscriptions:<id> 下報告
connection_budget_exceeded;減少訂閱或提高預算後恢復。解密失敗仍拒絕啟動。
診斷白名單包含生成時間、構建/Go/平臺資訊、佇列計數以及匿名信箱和監聽狀態(含
check 與 mode)。mailboxes[].index 與
watches[].mailbox_index 對應本次報告的“信箱 1、信箱
2……”;信箱內監聽有獨立的 index。信箱條目包含設定及訂閱
notice 的錯誤碼。僅 imap_folder_rejected 可匯出
watches[].response_code。報告省略信箱
ID、顯示名稱、地址、主機、資料夾名、郵件內容、任務
ID、憑據及其他錯誤引數。
任務狀態:pending 等待請求,accepted
通道接受請求,dead 本輪請求結束且記錄失敗。
執行日誌
透過 docker compose logs -f core(或
docker logs <容器名>)檢視 JSON stderr
日誌。管理客戶端可使用會話 Cookie 或 API Token
查詢同一組執行事件:GET
/api/v1/logs?after=0&level=info&mailbox_id=mbx_example&limit=200。
記憶體環形緩衝保留最近 2000 條 Info/Warn/Error
日誌,重啟清空。after 是排除本身的非負序號;level 為
info/warn/error,包含指定級別及以上,預設 info;省略 mailbox_id
時包含全部信箱和全域性操作。limit 預設 200,範圍 1–500。引數非法返回
400 logs_request_invalid。
{
"entries": [
{
"seq": 42,
"time": "2026-09-29T00:00:00Z",
"level": "info",
"message": "Folder connection established",
"attrs": {
"mailbox_id": "mbx_example",
"folder": "INBOX",
"mode": "idle",
"check": "realtime"
}
}
],
"next": 42,
"cleared_through": 0
}
下一次請求把 next 作為 after。達到頁大小時 next 為最後返回序號;遍歷完快照時為快照最大序號,過濾結果為空也推進。淘汰的日誌從當前保留記錄繼續;重啟導致 next 小於 after 時,將遊標重置為 0。條目按序號升序返回。
日誌包含信箱/Folder 生命週期、基線與入隊數量、投遞嘗試、設定變更和管理員操作,全域性事件的 mailbox_id 為空。attrs 僅輸出這些標量欄位:mailbox_id、folder、mode、check、code、event_id、channel、attempt、duration_ms、http_status、next_attempt、backoff_seconds、count、revision、token_id、version、listen。http_status=0 表示未收到 HTTP 回應;token_id 為公開記錄 ID,區別於 Token 完整值。密碼、Token/會話值、設定碼、寄件者、主旨、內文和憑據 URL 均省略;設定碼那一行只輸出到控制台。日誌包含 Folder 名稱,匿名診斷匯出繼續省略日誌和名稱。
資料夾掃描與管理員信箱測試返回原始路徑陣列
folders,並可附帶 folder_roles:路徑到
inbox、drafts、sent、trash、junk、archive、all
或 flagged 的對映。用途來自 IMAP SPECIAL-USE
屬性,INBOX 按協議名稱識別。Web
介面在缺少用途時,按常見英文資料夾名稱進行忽略大小寫的完整匹配;譯名後用括號保留原始路徑,其餘名稱保持原樣。介面翻譯不改變訂閱路徑。
通知標題僅顯示斜槓分隔路徑的末級名稱;結構化 folder
欄位保留完整路徑。App 信箱測試繼續僅返回連線狀態。
GET /api/v1/session 在 Cookie 會話回應中返回
username,Token 鑑權回應保持原有結構。
App 接收裝置
通知設定增加 native_pairing_id。native
管道必須從
/api/v1/native/devices
選擇一個有效配對;測試通知和新事件只投遞給該裝置。更新時省略此欄位保留原選擇;空選擇返回
native_target_required,失效目標返回
native_target_unavailable。當前 native
目標撤銷後,通道與 native_pairing_id 同時清空,revision
增加一次;其他目標和通道保留。已開始的投遞保留原目標及撤銷結果。狀態同步、併發與重啟規則見配對撤銷同步。
App 授權頁分別管理管理權限和推播權限,兩者獨立撤銷。
Native 測試通知
哨站使用簽章 POST /v1/pairing-tests,內文
{pairing_id,test_id};每次顯式測試生成新的 UUID
test_id。推播中繼服務生成固定內容並同步提交 APNs,無須 Native Push
權益。表單測試、App 已儲存設定測試和
/api/v1/test-push 共用此呼叫鏈。測試獨立於郵件
Outbox,不自動重試。
僅推播中繼服務返回 accepted 對應哨站 HTTP 204。APNs
拒絕、結果未知、sending
均返回本機化錯誤;推播中繼服務限頻對映為哨站 HTTP 429 並保留
Retry-After。安全日誌記錄推播中繼服務 HTTP
狀態與穩定錯誤碼,省去回應內文、Token 和通知內容。哨站與 App
共享推播中繼服務現有每裝置每分鐘、每主體每日額度及
(device_id,test_id)
冪等。使用者再次點選測試會建立新的測試 ID。
正式郵件仍使用 /v1/push 並校驗權益,事件 ID
或客戶端測試標誌均保持此規則。先部署支援配對測試介面的推播中繼服務,再部署此版本哨站;哨站不回退到正式郵件介面。
清除投遞記錄與執行日誌
-
DELETE /api/v1/deliveries返回200 {"deleted":N},永久清除全部歷史中已結束的accepted/dead記錄及關聯 Native 記錄。待投遞/重試、Native 的 pending/queued/sending 狀態、待執行的狀態檢查和活動更新會保留。清除失敗記錄後,其手動重試入口一併消失。信箱檢查點與設定保持原樣。 -
DELETE /api/v1/logs返回200 {"cleared_through":N},清除所有級別、所有信箱共享的記憶體日誌。序號繼續遞增,標準錯誤/容器日誌和匯出檔案保留。GET /api/v1/logs同時返回cleared_through;客戶端先移除快取中seq <= cleared_through的條目,再追加回應中的日誌。 - 兩個介面均要求管理員會話及 Origin/CSRF,或管理員 API Token。App 裝置憑證無法執行這些操作。重複清除安全;操作完成後仍可產生新任務與新日誌。
App 郵件正文
POST /api/v1/app/content
使用裝置綁定的控制憑證與站主授予的 content 權限。請求為
{ "reference": <message_ref> },回應包含 text、truncated、可選的清理後
html 和 has_remote_images。正文閱讀免費。
正文可讀後,使用相同憑證、權限和引用呼叫
POST /api/v1/app/content/read,將信箱中的郵件標記為已讀。成功回傳 204 No Content 與
Cache-Control: no-store。僅取得正文會保留信箱原有的已讀狀態。兩個操作均驗證目前授權、訂閱資料夾、信箱身分和郵件引用。
憑據與連線目標
測試或儲存信箱時,修改 host、port 或
username 須重新輸入已儲存的信箱密碼,否則返回 400
mailbox_password_required_for_change。修改已儲存的 Bark
位址須重新輸入裝置 Key,即使目前選中其他通道亦適用;否則返回 400
bark_key_required_for_change。位址包含連接埠、路徑和末尾斜線。拒絕時不建立連線、不傳送通知,設定與
revision 保持原值。
App 請求診斷
診斷匯出使用 schema_version: 2,新增
app_requests:從共用的 2000 筆記憶體日誌擷取最近最多
300 筆已完成的 App 請求。每筆包含時間、伺服器產生的
request_id(同時透過
X-Request-ID 回傳)、路由範本、方法、HTTP
狀態、耗時、階段、結果與安全錯誤碼。匯出排除資源
ID、查詢參數、憑證、簽章參照、內文與完整執行日誌。重新啟動哨站或清除日誌會移除記錄,其他日誌也可能擠出較舊請求。下載前會更新報告。未到達哨站的請求仍需
App 診斷。
對於 POST /api/v1/app/content/read,哨站查詢 UID 和
flags:已讀直接成功,未讀則標記後再次確認。STORE OK
本身無法證明郵件存在。UID 不存在、UIDVALIDITY
改變或資料夾明確不存在回傳 404;服務商或權限失敗回傳 503,逾時回傳
504。遠端參照失效時,本機快取內文仍可閱讀。
Markdown · AGPL-3.0-only · Mailwake 貢獻者