[{"data":1,"prerenderedAt":1229},["ShallowReactive",2],{"navigation_docs":3,"-configuration":32,"-configuration-surround":1226},[4,8,12,16,20,24,28],{"title":5,"path":6,"stem":7},"Set up your server","\u002Fsetup","1.setup",{"title":9,"path":10,"stem":11},"Addresses and domains","\u002Faddresses","2.addresses",{"title":13,"path":14,"stem":15},"Sign-in and discovery","\u002Fsign-in","3.sign-in",{"title":17,"path":18,"stem":19},"Mail apps","\u002Fproxy","4.proxy",{"title":21,"path":22,"stem":23},"Spam","\u002Fspam","5.spam",{"title":25,"path":26,"stem":27},"Configuration","\u002Fconfiguration","6.configuration",{"title":29,"path":30,"stem":31},"Troubleshooting","\u002Ftroubleshooting","7.troubleshooting",{"id":33,"title":25,"body":34,"description":230,"extension":1219,"links":1220,"meta":1221,"navigation":1222,"path":26,"seo":1223,"stem":27,"__hash__":1225},"docs\u002F6.configuration.md",{"type":35,"value":36,"toc":1194},"minimark",[37,46,56,61,71,180,190,195,218,224,240,243,247,257,326,332,631,641,645,652,695,698,701,704,707,715,719,728,745,748,755,758,764,767,782,785,789,792,806,810,813,821,824,828,835,844,847,851,860,867,871,880,933,939,946,950,953,967,970,973,976,985,994,997,1006,1009,1015,1024,1030,1034,1037,1105,1147,1150,1153,1184,1190],[38,39,40,41,45],"p",{},"Everything your server reads comes from ",[42,43,44],"code",{},"wrangler.jsonc",", from Worker secrets, or from rows in D1. This page lists all of it, then covers the optional features: notifications, Swiftly signatures, Gmail import, backups and the JMAP endpoint for other clients.",[38,47,48,49,51,52,55],{},"After editing ",[42,50,44],{},", deploy again with ",[42,53,54],{},"pnpm run deploy",". Secrets take effect without a deploy.",[57,58,60],"h2",{"id":59},"variables","Variables",[38,62,63,64,67,68,70],{},"Set these under ",[42,65,66],{},"vars"," in ",[42,69,44],{},".",[72,73,74,90],"table",{},[75,76,77],"thead",{},[78,79,80,84,87],"tr",{},[81,82,83],"th",{},"Variable",[81,85,86],{},"Default",[81,88,89],{},"What it does",[91,92,93,109,129,145,160],"tbody",{},[78,94,95,101,106],{},[96,97,98],"td",{},[42,99,100],{},"APP_ORIGIN",[96,102,103],{},[42,104,105],{},"https:\u002F\u002Fapp.mailopus.net",[96,107,108],{},"Where the UI runs. Passkey sign-ins must come from this origin, writes and WebSockets from any other origin are refused, and CORS answers only this origin.",[78,110,111,116,121],{},[96,112,113],{},[42,114,115],{},"RP_ID",[96,117,118],{},[42,119,120],{},"mailopus.net",[96,122,123,124,126,127,70],{},"The passkey domain. It must be ",[42,125,100],{},"'s host or a parent of it. Change it only together with ",[42,128,100],{},[78,130,131,136,139],{},[96,132,133],{},[42,134,135],{},"IMAP_HOST",[96,137,138],{},"unset",[96,140,141,142,70],{},"The IMAP proxy's hostname, shown in Settings next to app passwords. Unset means Settings says there's no proxy. See ",[143,144,17],"a",{"href":18},[78,146,147,152,154],{},[96,148,149],{},[42,150,151],{},"SMTP_HOST",[96,153,138],{},[96,155,156,157,159],{},"The SMTP hostname, shown with ",[42,158,135],{},". Ignored without it.",[78,161,162,167,169],{},[96,163,164],{},[42,165,166],{},"VAPID_PUBLIC_KEY",[96,168,138],{},[96,170,171,172,175,176,70],{},"Web Push public key. Set it only together with the ",[42,173,174],{},"VAPID_PRIVATE_KEY"," secret. See ",[143,177,179],{"href":178},"#notifications","Notifications",[38,181,182,185,186,189],{},[42,183,184],{},"DEV_ORIGIN"," and ",[42,187,188],{},"SWIFTLY_BASE"," also exist, for local development against a dev server or a local Swiftly. Leave them unset in production.",[191,192,194],"h3",{"id":193},"serving-the-ui-yourself","Serving the UI yourself",[38,196,197,198,200,201,203,204,206,207,210,211,214,215,70],{},"Your Worker serves the full UI too, not only the API. If you set ",[42,199,100],{}," to your Worker's own origin and ",[42,202,115],{}," to its host or parent domain, you can use Mailopus at your Worker's URL with no mailopus.net involved. On workers.dev, ",[42,205,115],{}," has to be the full host, ",[42,208,209],{},"mailopus.\u003Cyour subdomain>.workers.dev",", because workers.dev is a public suffix. A custom domain such as ",[42,212,213],{},"mail.example.com"," can use ",[42,216,217],{},"example.com",[38,219,220,221,223],{},"Passkeys made for ",[42,222,120],{}," don't work at the new origin. Make a new one with an invite link whose base URL is the new origin:",[225,226,231],"pre",{"className":227,"code":228,"language":229,"meta":230,"style":230},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","MAILOPUS_DB=mailopus node scripts\u002Finvite.mjs sam@example.com https:\u002F\u002Fmail.example.com\n","sh","",[42,232,233],{"__ignoreMap":230},[234,235,238],"span",{"class":236,"line":237},"line",1,[234,239,228],{},[38,241,242],{},"This setup works in the code, but the supported and tested path is app.mailopus.net.",[57,244,246],{"id":245},"secrets","Secrets",[38,248,249,250,253,254,70],{},"Set each with ",[42,251,252],{},"npx wrangler secret put \u003CNAME>"," from your clone. Wrangler asks for the value, so it stays out of your shell history. Remove one with ",[42,255,256],{},"npx wrangler secret delete \u003CNAME>",[72,258,259,268],{},[75,260,261],{},[78,262,263,266],{},[81,264,265],{},"Secret",[81,267,89],{},[91,269,270,282,293,312],{},[78,271,272,277],{},[96,273,274],{},[42,275,276],{},"SPAM_CLASSIFIERS",[96,278,279,280,70],{},"JSON list of remote spam classifiers. See ",[143,281,21],{"href":22},[78,283,284,288],{},[96,285,286],{},[42,287,174],{},[96,289,290,291,70],{},"Web Push private key as a JWK string, paired with ",[42,292,166],{},[78,294,295,300],{},[96,296,297],{},[42,298,299],{},"INGEST_SECRET",[96,301,302,303,307,308,311],{},"Shared with the relay Worker for domains in another Cloudflare account. See ",[143,304,306],{"href":305},"\u002Faddresses#domains-in-another-cloudflare-account","Addresses",". Without it, ",[42,309,310],{},"\u002Fapi\u002Fingest"," refuses everything.",[78,313,314,319],{},[96,315,316],{},[42,317,318],{},"GOOGLE_SA_\u003CNAME>",[96,320,321,322,70],{},"A Google service account key, as JSON, for Gmail import. See ",[143,323,325],{"href":324},"#gmail-import","Gmail import",[57,327,329,330],{"id":328},"bindings-and-the-rest-of-wranglerjsonc","Bindings and the rest of ",[42,331,44],{},[72,333,334,347],{},[75,335,336],{},[78,337,338,341,344],{},[81,339,340],{},"Key",[81,342,343],{},"Value",[81,345,346],{},"What it's for",[91,348,349,364,383,405,420,437,459,484,501,518,537,555,570,588,606],{},[78,350,351,356,361],{},[96,352,353],{},[42,354,355],{},"name",[96,357,358],{},[42,359,360],{},"mailopus",[96,362,363],{},"The Worker's name, and part of its workers.dev URL",[78,365,366,371,376],{},[96,367,368],{},[42,369,370],{},"main",[96,372,373],{},[42,374,375],{},".\u002F.output\u002Fserver\u002Findex.mjs",[96,377,378,379,382],{},"The built Worker. ",[42,380,381],{},"nuxt build"," makes it.",[78,384,385,390,395],{},[96,386,387],{},[42,388,389],{},"workers_dev",[96,391,392],{},[42,393,394],{},"true",[96,396,397,398,400,401,404],{},"Serves the Worker at ",[42,399,209],{},". Your ",[42,402,403],{},"_mailopus"," TXT record can name that URL.",[78,406,407,412,417],{},[96,408,409],{},[42,410,411],{},"preview_urls",[96,413,414],{},[42,415,416],{},"false",[96,418,419],{},"No per-version preview URLs",[78,421,422,431,434],{},[96,423,424,427,428],{},[42,425,426],{},"ratelimits"," ",[42,429,430],{},"AUTH_LIMIT",[96,432,433],{},"20 a minute",[96,435,436],{},"Caps sign-in, invite and claim calls per IP, and failed app-password sign-ins per username",[78,438,439,448,456],{},[96,440,441,444,445],{},[42,442,443],{},"compatibility_date",", ",[42,446,447],{},"compatibility_flags",[96,449,450,444,453],{},[42,451,452],{},"2026-11-01",[42,454,455],{},"nodejs_compat",[96,457,458],{},"Workers runtime version and Node.js APIs",[78,460,461,469,477],{},[96,462,463,427,466],{},[42,464,465],{},"assets",[42,467,468],{},"ASSETS",[96,470,471,444,474],{},[42,472,473],{},".\u002F.output\u002Fpublic",[42,475,476],{},"run_worker_first: true",[96,478,479,480,483],{},"The UI's static files. ",[42,481,482],{},"run_worker_first"," sends every request, static files included, through the auth gate first.",[78,485,486,491,494],{},[96,487,488],{},[42,489,490],{},"observability",[96,492,493],{},"on",[96,495,496,497,500],{},"Logs in the dashboard. ",[42,498,499],{},"npx wrangler tail"," streams them.",[78,502,503,511,515],{},[96,504,505,427,508],{},[42,506,507],{},"d1_databases",[42,509,510],{},"DB",[96,512,513],{},[42,514,360],{},[96,516,517],{},"Accounts, addresses, message index, sessions, passkeys, settings",[78,519,520,528,534],{},[96,521,522,427,525],{},[42,523,524],{},"durable_objects",[42,526,527],{},"ACCOUNT",[96,529,530,531],{},"class ",[42,532,533],{},"Account",[96,535,536],{},"One per account. Runs every write to that account in order, holds the live WebSockets and sends scheduled mail.",[78,538,539,544,552],{},[96,540,541],{},[42,542,543],{},"migrations",[96,545,546,549,550],{},[42,547,548],{},"v1",", SQLite class ",[42,551,533],{},[96,553,554],{},"The Durable Object class's own migration, separate from D1's",[78,556,557,565,567],{},[96,558,559,427,562],{},[42,560,561],{},"send_email",[42,563,564],{},"EMAIL",[96,566],{},[96,568,569],{},"Outbound mail through Email Sending",[78,571,572,580,585],{},[96,573,574,427,577],{},[42,575,576],{},"queues",[42,578,579],{},"IMPORT_QUEUE",[96,581,582],{},[42,583,584],{},"mailopus-import",[96,586,587],{},"Gmail import, one page per message, up to 4 at once, 10 retries",[78,589,590,598,603],{},[96,591,592,427,595],{},[42,593,594],{},"triggers",[42,596,597],{},"crons",[96,599,600],{},[42,601,602],{},"*\u002F5 * * * *",[96,604,605],{},"Every 5 minutes: start and restart import jobs, sync Swiftly signatures, backfill old rows",[78,607,608,616,621],{},[96,609,610,427,613],{},[42,611,612],{},"r2_buckets",[42,614,615],{},"MAIL",[96,617,618],{},[42,619,620],{},"mailopus-mail",[96,622,623,624,627,628],{},"Each message's raw ",[42,625,626],{},".eml",", under ",[42,629,630],{},"raw\u002F\u003Caccount id>\u002F",[38,632,633,634,637,638,70],{},"The template has no ",[42,635,636],{},"services"," entry. app.mailopus.net binds its private spam Worker there. See ",[143,639,21],{"href":640},"\u002Fspam#a-spam-worker-on-the-spam-binding",[57,642,644],{"id":643},"settings-in-d1","Settings in D1",[38,646,647,648,651],{},"Some state lives in the ",[42,649,650],{},"instance_settings"," table:",[72,653,654,663],{},[75,655,656],{},[78,657,658,660],{},[81,659,340],{},[81,661,662],{},"What it is",[91,664,665,675,685],{},[78,666,667,672],{},[96,668,669],{},[42,670,671],{},"claimed",[96,673,674],{},"When the server was claimed. Its presence keeps the claim page closed.",[78,676,677,682],{},[96,678,679],{},[42,680,681],{},"vapid",[96,683,684],{},"The Web Push key pair the server made for itself",[78,686,687,692],{},[96,688,689],{},[42,690,691],{},"swiftly-connect:\u003Cstate>",[96,693,694],{},"A Swiftly connection in progress, deleted after 10 minutes",[38,696,697],{},"Per-account settings, such as blocked senders, address groups and highlight exclusions, live in their own tables and are edited in Settings.",[57,699,179],{"id":700},"notifications",[38,702,703],{},"Settings > This device > Notifications turns on a push notification for each new Inbox message, per browser. On iPhone and iPad, add Mailopus to the home screen first. Safari only allows notifications there.",[38,705,706],{},"Mail filed in Junk, mail you sent yourself, and imported mail never notify. The message is encrypted for your browser, so Apple's and Google's push services carry it without being able to read it.",[38,708,709,710,185,712,714],{},"Push needs no setup. On first use the server makes a VAPID key pair and keeps it in D1. Set ",[42,711,166],{},[42,713,174],{}," only to bring an existing key pair, for example when moving to a new server with existing subscriptions. Changing the keys breaks every existing subscription, so each browser has to turn notifications off and on again.",[57,716,718],{"id":717},"swiftly-signatures","Swiftly signatures",[38,720,721,727],{},[143,722,726],{"href":723,"rel":724},"https:\u002F\u002Fswiftly.biz",[725],"nofollow","Swiftly"," keeps email signatures up to date across a team. Mailopus can let Swiftly manage an address's signature.",[729,730,731,739,742],"ol",{},[732,733,734,735],"li",{},"Settings > Addresses, then an address's menu > ",[736,737,738],"strong",{},"Signature…",[732,740,741],{},"Pick Swiftly and connect. Your browser goes to swiftly.biz to approve, then comes back.",[732,743,744],{},"Choose whether Swiftly manages this address only or all your addresses.",[38,746,747],{},"The connection uses an authorization code with PKCE. The Swiftly token stays on your Worker and never reaches the browser. The 5-minute cron syncs each managed address at most every 30 minutes.",[38,749,750,751,754],{},"While Swiftly manages a signature, the dialog shows it read-only. Swiftly refuses to sync over an edit made somewhere else. Turning Swiftly on keeps what you wrote, and Swiftly adds its own part. ",[736,752,753],{},"Disconnect"," stops the updates and leaves the signatures as they are.",[57,756,325],{"id":757},"gmail-import",[38,759,760,761,70],{},"Mailopus can copy a Google Workspace mailbox into an account. It's built for Workspace, not personal Gmail. It reads mail through a Google service account with domain-wide delegation, which only a Workspace admin can grant. There's no UI. You drive it with ",[42,762,763],{},"scripts\u002Fimport.mjs",[38,765,766],{},"What comes over:",[768,769,770,773,776,779],"ul",{},[732,771,772],{},"Every message, as its original raw file",[732,774,775],{},"Read and starred state, and drafts",[732,777,778],{},"Inbox, Sent, Drafts, Spam and Trash into the matching mailboxes",[732,780,781],{},"Your Gmail labels as labels",[38,783,784],{},"It's safe to run again. Each message is stored once per account, so a rerun skips what's already there.",[191,786,788],{"id":787},"_1-make-a-service-account","1. Make a service account",[38,790,791],{},"In Google Cloud:",[729,793,794,797,800,803],{},[732,795,796],{},"Create a project, or use one you have.",[732,798,799],{},"Enable the Gmail API.",[732,801,802],{},"Create a service account with no roles. Create a JSON key for it and download it.",[732,804,805],{},"Note the service account's numeric client ID.",[191,807,809],{"id":808},"_2-grant-domain-wide-delegation","2. Grant domain-wide delegation",[38,811,812],{},"As the Workspace's admin, open admin.google.com > Security > Access and data control > API controls > Manage domain-wide delegation. Add the client ID with exactly one scope:",[225,814,819],{"className":815,"code":817,"language":818},[816],"language-text","https:\u002F\u002Fwww.googleapis.com\u002Fauth\u002Fgmail.readonly\n","text",[42,820,817],{"__ignoreMap":230},[38,822,823],{},"This lets the key read every mailbox in the Workspace. Treat the key file like a password, and delete it after the next step.",[191,825,827],{"id":826},"_3-store-the-key-as-a-secret","3. Store the key as a secret",[38,829,830,831,834],{},"Pick a short name for the Workspace, such as ",[42,832,833],{},"work",". From your clone:",[225,836,838],{"className":227,"code":837,"language":229,"meta":230,"style":230},"npx wrangler secret put GOOGLE_SA_WORK \u003C path\u002Fto\u002Fkey.json\n",[42,839,840],{"__ignoreMap":230},[234,841,842],{"class":236,"line":237},[234,843,837],{},[38,845,846],{},"Then delete the downloaded key file.",[191,848,850],{"id":849},"_4-start-an-import","4. Start an import",[225,852,854],{"className":227,"code":853,"language":229,"meta":230,"style":230},"MAILOPUS_DB=mailopus node scripts\u002Fimport.mjs start work sam@company.example sam@example.com\n",[42,855,856],{"__ignoreMap":230},[234,857,858],{"class":236,"line":237},[234,859,853],{},[38,861,862,863,866],{},"The arguments are the secret's name without ",[42,864,865],{},"GOOGLE_SA_",", the Gmail address to read, and any address the target Mailopus account sends as. The 5-minute cron picks up the job, and the queue fetches 100 messages per page.",[191,868,870],{"id":869},"watch-and-control-it","Watch and control it",[225,872,874],{"className":227,"code":873,"language":229,"meta":230,"style":230},"MAILOPUS_DB=mailopus node scripts\u002Fimport.mjs status\n",[42,875,876],{"__ignoreMap":230},[234,877,878],{"class":236,"line":237},[234,879,873],{},[72,881,882,891],{},[75,883,884],{},[78,885,886,889],{},[81,887,888],{},"Command",[81,890,89],{},[91,892,893,903,913,923],{},[78,894,895,900],{},[96,896,897],{},[42,898,899],{},"status",[96,901,902],{},"Lists jobs with progress, counts and the last error",[78,904,905,910],{},[96,906,907],{},[42,908,909],{},"pause \u003Cjob id>",[96,911,912],{},"Stops after the current page",[78,914,915,920],{},[96,916,917],{},[42,918,919],{},"resume \u003Cjob id>",[96,921,922],{},"Continues where it stopped",[78,924,925,930],{},[96,926,927],{},[42,928,929],{},"rescan \u003Cjob id>",[96,931,932],{},"Walks the mailbox again from the start. Stored mail is skipped, so only missing messages are fetched.",[38,934,935,936,70],{},"A job id prefix is enough. Every command needs ",[42,937,938],{},"MAILOPUS_DB=mailopus",[38,940,941,942,945],{},"When you're done, delete the secret with ",[42,943,944],{},"npx wrangler secret delete GOOGLE_SA_WORK"," and remove the delegation in the admin console.",[57,947,949],{"id":948},"backups","Backups",[38,951,952],{},"Mailopus has no backup feature of its own. Your data is in two places, and both need covering:",[768,954,955,961],{},[732,956,957,960],{},[736,958,959],{},"D1"," holds accounts, addresses, the message index, flags, mailboxes, sessions and passkeys.",[732,962,963,966],{},[736,964,965],{},"R2"," holds each message's raw file.",[38,968,969],{},"The Account Durable Objects hold only scheduling state, nothing you'd need to restore.",[191,971,959],{"id":972},"d1",[38,974,975],{},"D1 Time Travel keeps a restore point for every minute of the last 30 days on Workers Paid. To undo a mistake:",[225,977,979],{"className":227,"code":978,"language":229,"meta":230,"style":230},"npx wrangler d1 time-travel info mailopus\n",[42,980,981],{"__ignoreMap":230},[234,982,983],{"class":236,"line":237},[234,984,978],{},[225,986,988],{"className":227,"code":987,"language":229,"meta":230,"style":230},"npx wrangler d1 time-travel restore mailopus --timestamp=\u003Cunix time or RFC 3339>\n",[42,989,990],{"__ignoreMap":230},[234,991,992],{"class":236,"line":237},[234,993,987],{},[38,995,996],{},"A restore replaces the whole database. For a copy outside Cloudflare, export it to a file on a schedule:",[225,998,1000],{"className":227,"code":999,"language":229,"meta":230,"style":230},"npx wrangler d1 export mailopus --remote --output=mailopus-$(date +%F).sql\n",[42,1001,1002],{"__ignoreMap":230},[234,1003,1004],{"class":236,"line":237},[234,1005,999],{},[191,1007,965],{"id":1008},"r2",[38,1010,1011,1012,1014],{},"R2 keeps no versions of its own. To copy the bucket somewhere else, make an R2 API token with read access in the dashboard under R2 > Manage API tokens, then use any S3 tool. With rclone set up for R2 as a remote called ",[42,1013,1008],{},":",[225,1016,1018],{"className":227,"code":1017,"language":229,"meta":230,"style":230},"rclone sync r2:mailopus-mail \u002Fpath\u002Fto\u002Fbackup\u002Fmailopus-mail\n",[42,1019,1020],{"__ignoreMap":230},[234,1021,1022],{"class":236,"line":237},[234,1023,1017],{},[38,1025,1026,1027,1029],{},"Each file is a standard ",[42,1028,626],{}," that any mail program opens. Together with a D1 export, that's a full copy of your mail.",[57,1031,1033],{"id":1032},"jmap-for-other-clients","JMAP for other clients",[38,1035,1036],{},"Mailopus speaks JMAP, RFC 8620 and RFC 8621, so a JMAP client can use it directly with no proxy.",[72,1038,1039,1047],{},[75,1040,1041],{},[78,1042,1043,1045],{},[81,1044],{},[81,1046],{},[91,1048,1049,1063,1073,1083,1093],{},[78,1050,1051,1054],{},[96,1052,1053],{},"Session",[96,1055,1056,1059,1060],{},[42,1057,1058],{},"https:\u002F\u002F\u003Cyour worker>\u002F.well-known\u002Fjmap",", also at ",[42,1061,1062],{},"\u002Fjmap\u002Fsession",[78,1064,1065,1068],{},[96,1066,1067],{},"API",[96,1069,1070],{},[42,1071,1072],{},"\u002Fjmap\u002Fapi",[78,1074,1075,1078],{},[96,1076,1077],{},"Upload",[96,1079,1080],{},[42,1081,1082],{},"\u002Fjmap\u002Fupload\u002F{accountId}\u002F",[78,1084,1085,1088],{},[96,1086,1087],{},"Download",[96,1089,1090],{},[42,1091,1092],{},"\u002Fjmap\u002Fdownload\u002F{accountId}\u002F{blobId}\u002F{name}",[78,1094,1095,1098],{},[96,1096,1097],{},"Auth",[96,1099,1100,1101],{},"HTTP Basic with your email address and an ",[143,1102,1104],{"href":1103},"\u002Fproxy#app-passwords","app password",[38,1106,1107,1108,444,1111,444,1114,444,1117,444,1120,444,1123,444,1126,444,1129,444,1132,444,1135,444,1138,444,1141,185,1144,70],{},"Methods: ",[42,1109,1110],{},"Mailbox\u002Fget",[42,1112,1113],{},"Mailbox\u002Fchanges",[42,1115,1116],{},"Mailbox\u002Fset",[42,1118,1119],{},"Thread\u002Fget",[42,1121,1122],{},"Email\u002Fget",[42,1124,1125],{},"Email\u002Fquery",[42,1127,1128],{},"Email\u002Fchanges",[42,1130,1131],{},"Email\u002Fset",[42,1133,1134],{},"Email\u002Fimport",[42,1136,1137],{},"Identity\u002Fget",[42,1139,1140],{},"Identity\u002Fset",[42,1142,1143],{},"EmailSubmission\u002Fget",[42,1145,1146],{},"EmailSubmission\u002Fset",[38,1148,1149],{},"Limits: 25 MB per upload, 10 MB per request, 32 calls per request, 500 objects per get or set, 4 concurrent requests.",[38,1151,1152],{},"What's missing or partial:",[768,1154,1155,1158,1169,1176,1181],{},[732,1156,1157],{},"The session gives its URLs as paths, not full URLs. Clients that expect absolute URLs may fail.",[732,1159,1160,1161,1164,1165,1168],{},"It lists an ",[42,1162,1163],{},"eventSourceUrl",", but ",[42,1166,1167],{},"\u002Fjmap\u002Feventsource"," isn't served yet, so push over EventSource doesn't work.",[732,1170,1171,1172,1175],{},"The web UI gets live updates over a WebSocket at ",[42,1173,1174],{},"\u002Fjmap\u002Fws",". The session doesn't announce the JMAP WebSocket capability, so other clients won't find it.",[732,1177,1178,1180],{},[42,1179,1116],{}," renames and destroys labels. It can't create one, and the standard mailboxes can't be renamed or destroyed. Labels appear when mail is filed into them.",[732,1182,1183],{},"Calendars and contacts aren't there.",[38,1185,1186,1187,1189],{},"Browsers can't call the API from another site. CORS answers only ",[42,1188,100],{},". Native and server-side clients aren't affected.",[1191,1192,1193],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":230,"searchDepth":1195,"depth":1195,"links":1196},2,[1197,1201,1202,1204,1205,1206,1207,1214,1218],{"id":59,"depth":1195,"text":60,"children":1198},[1199],{"id":193,"depth":1200,"text":194},3,{"id":245,"depth":1195,"text":246},{"id":328,"depth":1195,"text":1203},"Bindings and the rest of wrangler.jsonc",{"id":643,"depth":1195,"text":644},{"id":700,"depth":1195,"text":179},{"id":717,"depth":1195,"text":718},{"id":757,"depth":1195,"text":325,"children":1208},[1209,1210,1211,1212,1213],{"id":787,"depth":1200,"text":788},{"id":808,"depth":1200,"text":809},{"id":826,"depth":1200,"text":827},{"id":849,"depth":1200,"text":850},{"id":869,"depth":1200,"text":870},{"id":948,"depth":1195,"text":949,"children":1215},[1216,1217],{"id":972,"depth":1200,"text":959},{"id":1008,"depth":1200,"text":965},{"id":1032,"depth":1195,"text":1033},"md",null,{},{"title":25},{"description":1224,"title":25},"Everything your server reads comes from wrangler.jsonc, from Worker secrets, or from rows in D1. This page lists all of it, then covers the optional features: notifications, Swiftly signatures, Gmail import, backups and the JMAP endpoint for other clients.","m9-4_ytDSPuQc-SqV3rkkJ-_U2O4pX9UqA9hzV2T-dA",[1227,1228],{"title":21,"path":22,"stem":23,"description":230,"children":-1},{"title":29,"path":30,"stem":31,"description":230,"children":-1},1794228095132]