[{"data":1,"prerenderedAt":2701},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fguides\u002Femail-testing-api\u002F":109,"\u002Fdocs\u002Fguides\u002Femail-testing-api\u002F-surround":2696},[4,8,22,26,43,92],{"title":5,"path":6,"stem":7},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started",{"title":9,"path":10,"stem":11,"children":12,"page":21},"Setup","\u002Fdocs\u002Fsetup","1.docs\u002F2.setup",[13,17],{"title":14,"path":15,"stem":16},"Domain","\u002Fdocs\u002Fsetup\u002Fdomain","1.docs\u002F2.setup\u002F2.domain",{"title":18,"path":19,"stem":20},"Email","\u002Fdocs\u002Fsetup\u002Faccount","1.docs\u002F2.setup\u002F3.account",false,{"title":23,"path":24,"stem":25},"Email Testing API","\u002Fdocs\u002Fapi","1.docs\u002F3.api",{"title":27,"path":28,"stem":29,"children":30,"page":21},"Features","\u002Fdocs\u002Ffeatures","1.docs\u002F4.features",[31,35,39],{"title":32,"path":33,"stem":34},"Account","\u002Fdocs\u002Ffeatures\u002Faccount","1.docs\u002F4.features\u002F1.account",{"title":36,"path":37,"stem":38},"Mailbox","\u002Fdocs\u002Ffeatures\u002Fmailbox","1.docs\u002F4.features\u002F2.mailbox",{"title":40,"path":41,"stem":42},"Messages","\u002Fdocs\u002Ffeatures\u002Fmessage","1.docs\u002F4.features\u002F3.message",{"title":44,"path":45,"stem":46,"children":47,"page":21},"Guides","\u002Fdocs\u002Fguides","1.docs\u002F5.guides",[48,52,56,60,64,68,72,76,80,84,88],{"title":49,"path":50,"stem":51},"SMTP Test","\u002Fdocs\u002Fguides\u002Fsend-test-email","1.docs\u002F5.guides\u002F01.send-test-email",{"title":53,"path":54,"stem":55},"API Quickstart","\u002Fdocs\u002Fguides\u002Femail-testing-api","1.docs\u002F5.guides\u002F02.email-testing-api",{"title":57,"path":58,"stem":59},"CI","\u002Fdocs\u002Fguides\u002Fci","1.docs\u002F5.guides\u002F03.ci",{"title":61,"path":62,"stem":63},"Catch-All","\u002Fdocs\u002Fguides\u002Fcatch-all","1.docs\u002F5.guides\u002F04.catch-all",{"title":65,"path":66,"stem":67},"SPF, DKIM, DMARC","\u002Fdocs\u002Fguides\u002Fspf-dkim-dmarc","1.docs\u002F5.guides\u002F05.spf-dkim-dmarc",{"title":69,"path":70,"stem":71},"Playwright","\u002Fdocs\u002Fguides\u002Fe2e","1.docs\u002F5.guides\u002F06.e2e",{"title":73,"path":74,"stem":75},"Cypress","\u002Fdocs\u002Fguides\u002Fcypress","1.docs\u002F5.guides\u002F07.cypress",{"title":77,"path":78,"stem":79},"Email Clients","\u002Fdocs\u002Fguides\u002Femail-clients","1.docs\u002F5.guides\u002F08.email-clients",{"title":81,"path":82,"stem":83},"AI Agents","\u002Fdocs\u002Fguides\u002Fagents","1.docs\u002F5.guides\u002F09.agents",{"title":85,"path":86,"stem":87},"Local Development","\u002Fdocs\u002Fguides\u002Flocal-development","1.docs\u002F5.guides\u002F10.local-development",{"title":89,"path":90,"stem":91},"Size Limits","\u002Fdocs\u002Fguides\u002Femail-size-limits","1.docs\u002F5.guides\u002F11.email-size-limits",{"title":93,"path":94,"stem":95,"children":96,"page":21},"Alternatives","\u002Fdocs\u002Falternatives","1.docs\u002F6.alternatives",[97,101,105],{"title":98,"path":99,"stem":100},"Mailtrap","\u002Fdocs\u002Falternatives\u002Fmailtrap","1.docs\u002F6.alternatives\u002F1.mailtrap",{"title":102,"path":103,"stem":104},"Mailosaur","\u002Fdocs\u002Falternatives\u002Fmailosaur","1.docs\u002F6.alternatives\u002F2.mailosaur",{"title":106,"path":107,"stem":108},"Mailinator","\u002Fdocs\u002Falternatives\u002Fmailinator","1.docs\u002F6.alternatives\u002F3.mailinator",{"id":110,"title":111,"body":112,"description":2690,"extension":2691,"meta":2692,"navigation":2693,"path":54,"seo":2694,"stem":55,"__hash__":2695},"docs\u002F1.docs\u002F5.guides\u002F02.email-testing-api.md","Email Testing API Quickstart",{"type":113,"value":114,"toc":2681},"minimark",[115,125,130,153,168,172,180,266,287,291,294,324,327,416,423,427,442,473,484,514,612,635,639,642,1656,1659,2543,2563,2567,2620,2633,2637,2677],[116,117,118,119,124],"p",{},"Create an account, send it a message, read the message back as JSON. No SDK. The ",[120,121,123],"a",{"href":122},"\u002Fdocs\u002Fapi\u002F","API reference"," lists every endpoint and field.",[126,127,129],"h2",{"id":128},"before-you-start","Before You Start",[116,131,132,133,137,138,142,143,148,149,152],{},"You need a domain with its MX record pointing at ",[134,135,136],"code",{},"mx.smtp.dev"," (",[120,139,141],{"href":140},"\u002Fdocs\u002Fsetup\u002Fdomain\u002F","how",") and a key from the ",[120,144,147],{"href":145,"target":146},"\u002Ftokens\u002F","_blank","API Keys"," page. The examples read the key from ",[134,150,151],{},"SMTP_DEV_API_KEY",".",[116,154,155,156,159,160,164,165,152],{},"Every request sends the key in an ",[134,157,158],{},"X-API-KEY"," header. The limit is ",[120,161,163],{"href":162},"\u002Fdocs\u002Fapi\u002F#rate-limiting","4096 requests per minute",", and every response carries ",[134,166,167],{},"RateLimit-Remaining",[126,169,171],{"id":170},"create-an-inbox","Create an Inbox",[116,173,174,175,179],{},"An inbox is an ",[120,176,178],{"href":177},"\u002Fdocs\u002Fapi\u002F#create-an-account","account",". Create one on your domain:",[181,182,187],"pre",{"className":183,"code":184,"language":185,"meta":186,"style":186},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -X POST \"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\" \\\n  -H \"X-API-KEY: $SMTP_DEV_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"address\": \"qa@test.example.com\", \"password\": \"use-a-secret\"}'\n","bash","",[134,188,189,219,237,251],{"__ignoreMap":186},[190,191,194,198,202,205,209,212,215],"span",{"class":192,"line":193},"line",1,[190,195,197],{"class":196},"sBMFI","curl",[190,199,201],{"class":200},"sfazB"," -X",[190,203,204],{"class":200}," POST",[190,206,208],{"class":207},"sMK4o"," \"",[190,210,211],{"class":200},"https:\u002F\u002Fapi.smtp.dev\u002Faccounts",[190,213,214],{"class":207},"\"",[190,216,218],{"class":217},"sTEyZ"," \\\n",[190,220,222,225,227,230,233,235],{"class":192,"line":221},2,[190,223,224],{"class":200},"  -H",[190,226,208],{"class":207},[190,228,229],{"class":200},"X-API-KEY: ",[190,231,232],{"class":217},"$SMTP_DEV_API_KEY",[190,234,214],{"class":207},[190,236,218],{"class":217},[190,238,240,242,244,247,249],{"class":192,"line":239},3,[190,241,224],{"class":200},[190,243,208],{"class":207},[190,245,246],{"class":200},"Content-Type: application\u002Fjson",[190,248,214],{"class":207},[190,250,218],{"class":217},[190,252,254,257,260,263],{"class":192,"line":253},4,[190,255,256],{"class":200},"  -d",[190,258,259],{"class":207}," '",[190,261,262],{"class":200},"{\"address\": \"qa@test.example.com\", \"password\": \"use-a-secret\"}",[190,264,265],{"class":207},"'\n",[116,267,268,269,272,273,276,277,279,280,283,284,152],{},"The response holds the account ",[134,270,271],{},"id"," and its ",[134,274,275],{},"mailboxes",". Keep the ",[134,278,271],{}," of the mailbox whose ",[134,281,282],{},"path"," is ",[134,285,286],{},"INBOX",[126,288,290],{"id":289},"send-a-message","Send a Message",[116,292,293],{},"Your app gets mail into the sandbox one of two ways:",[295,296,297,318],"ul",{},[298,299,300,304,305,308,309,313,314,317],"li",{},[301,302,303],"strong",{},"SMTP."," Point its mailer at ",[134,306,307],{},"send.smtp.dev"," and log in as a sandbox account (",[120,310,312],{"href":311},"\u002Fdocs\u002Fguides\u002Fsend-test-email\u002F#settings","settings","). It delivers only to accounts in your sandbox, so a wrong ",[134,315,316],{},"to"," can't email a customer.",[298,319,320,323],{},[301,321,322],{},"MX."," Keep the app on its usual provider and send to an address on your domain. The provider delivers it like any other email, which also tests its SPF and DKIM.",[116,325,326],{},"To put a message in the inbox without the app, send it from a second account over the API:",[181,328,330],{"className":183,"code":329,"language":185,"meta":186,"style":186},"curl -X POST \"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\u002F{senderAccountId}\u002Fmessages\u002Fsend\" \\\n  -H \"X-API-KEY: $SMTP_DEV_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"from\": { \"address\": \"sender@test.example.com\" },\n    \"to\": [{ \"address\": \"qa@test.example.com\" }],\n    \"subject\": \"Confirm your address\",\n    \"text\": \"https:\u002F\u002Fexample.com\u002Fconfirm\u002Fabc123\"\n  }'\n",[134,331,332,349,363,375,384,390,396,402,408],{"__ignoreMap":186},[190,333,334,336,338,340,342,345,347],{"class":192,"line":193},[190,335,197],{"class":196},[190,337,201],{"class":200},[190,339,204],{"class":200},[190,341,208],{"class":207},[190,343,344],{"class":200},"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\u002F{senderAccountId}\u002Fmessages\u002Fsend",[190,346,214],{"class":207},[190,348,218],{"class":217},[190,350,351,353,355,357,359,361],{"class":192,"line":221},[190,352,224],{"class":200},[190,354,208],{"class":207},[190,356,229],{"class":200},[190,358,232],{"class":217},[190,360,214],{"class":207},[190,362,218],{"class":217},[190,364,365,367,369,371,373],{"class":192,"line":239},[190,366,224],{"class":200},[190,368,208],{"class":207},[190,370,246],{"class":200},[190,372,214],{"class":207},[190,374,218],{"class":217},[190,376,377,379,381],{"class":192,"line":253},[190,378,256],{"class":200},[190,380,259],{"class":207},[190,382,383],{"class":200},"{\n",[190,385,387],{"class":192,"line":386},5,[190,388,389],{"class":200},"    \"from\": { \"address\": \"sender@test.example.com\" },\n",[190,391,393],{"class":192,"line":392},6,[190,394,395],{"class":200},"    \"to\": [{ \"address\": \"qa@test.example.com\" }],\n",[190,397,399],{"class":192,"line":398},7,[190,400,401],{"class":200},"    \"subject\": \"Confirm your address\",\n",[190,403,405],{"class":192,"line":404},8,[190,406,407],{"class":200},"    \"text\": \"https:\u002F\u002Fexample.com\u002Fconfirm\u002Fabc123\"\n",[190,409,411,414],{"class":192,"line":410},9,[190,412,413],{"class":200},"  }",[190,415,265],{"class":207},[116,417,418,419,422],{},"The API sets ",[134,420,421],{},"from"," to the sending account's address. Use it for fixtures. The app's own mail should take the path it takes in production.",[126,424,426],{"id":425},"read-the-message","Read the Message",[116,428,429,433,434,437,438,441],{},[120,430,432],{"href":431},"\u002Fdocs\u002Fapi\u002F#list-messages","List messages",", newest first, 30 to a page. The messages are in ",[134,435,436],{},"member",", and ",[134,439,440],{},"view.next"," links the next page:",[181,443,445],{"className":183,"code":444,"language":185,"meta":186,"style":186},"curl \"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\u002F{accountId}\u002Fmailboxes\u002F{mailboxId}\u002Fmessages\" \\\n  -H \"X-API-KEY: $SMTP_DEV_API_KEY\"\n",[134,446,447,460],{"__ignoreMap":186},[190,448,449,451,453,456,458],{"class":192,"line":193},[190,450,197],{"class":196},[190,452,208],{"class":207},[190,454,455],{"class":200},"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\u002F{accountId}\u002Fmailboxes\u002F{mailboxId}\u002Fmessages",[190,457,214],{"class":207},[190,459,218],{"class":217},[190,461,462,464,466,468,470],{"class":192,"line":221},[190,463,224],{"class":200},[190,465,208],{"class":207},[190,467,229],{"class":200},[190,469,232],{"class":217},[190,471,472],{"class":207},"\"\n",[116,474,475,476,480,481,483],{},"Then ",[120,477,479],{"href":478},"\u002Fdocs\u002Fapi\u002F#get-a-message","get the message"," by ",[134,482,271],{},":",[181,485,487],{"className":183,"code":486,"language":185,"meta":186,"style":186},"curl \"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\u002F{accountId}\u002Fmailboxes\u002F{mailboxId}\u002Fmessages\u002F{id}\" \\\n  -H \"X-API-KEY: $SMTP_DEV_API_KEY\"\n",[134,488,489,502],{"__ignoreMap":186},[190,490,491,493,495,498,500],{"class":192,"line":193},[190,492,197],{"class":196},[190,494,208],{"class":207},[190,496,497],{"class":200},"https:\u002F\u002Fapi.smtp.dev\u002Faccounts\u002F{accountId}\u002Fmailboxes\u002F{mailboxId}\u002Fmessages\u002F{id}",[190,499,214],{"class":207},[190,501,218],{"class":217},[190,503,504,506,508,510,512],{"class":192,"line":221},[190,505,224],{"class":200},[190,507,208],{"class":207},[190,509,229],{"class":200},[190,511,232],{"class":217},[190,513,472],{"class":207},[515,516,517,530],"table",{},[518,519,520],"thead",{},[521,522,523,527],"tr",{},[524,525,526],"th",{},"Field",[524,528,529],{},"Holds",[531,532,533,549,565,575,589,602],"tbody",{},[521,534,535,546],{},[536,537,538,541,542,541,544],"td",{},[134,539,540],{},"subject",", ",[134,543,421],{},[134,545,316],{},[536,547,548],{},"What the recipient sees",[521,550,551,559],{},[536,552,553,541,556],{},[134,554,555],{},"text",[134,557,558],{},"html",[536,560,561,562,564],{},"The body. ",[134,563,558],{}," is an array of HTML parts",[521,566,567,572],{},[536,568,569],{},[134,570,571],{},"headers",[536,573,574],{},"Every header, as received",[521,576,577,582],{},[536,578,579],{},[134,580,581],{},"verifications",[536,583,584,588],{},[120,585,587],{"href":586},"\u002Fdocs\u002Fguides\u002Fspf-dkim-dmarc\u002F","SPF, DKIM, and DMARC"," results",[521,590,591,596],{},[536,592,593],{},[134,594,595],{},"attachments",[536,597,598,599],{},"Each file, with a ",[134,600,601],{},"downloadUrl",[521,603,604,609],{},[536,605,606],{},[134,607,608],{},"sourceUrl",[536,610,611],{},"Where to fetch the raw source",[116,613,614,618,619,622,623,626,627,630,631,634],{},[120,615,617],{"href":616},"\u002Fdocs\u002Fapi\u002F#get-a-message-source","The raw message",", headers and MIME parts included, comes back from ",[134,620,621],{},"...\u002Fmessages\u002F{id}\u002Fsource"," as ",[134,624,625],{},"raw",". ",[134,628,629],{},"...\u002Fmessages\u002F{id}\u002Fdownload"," returns it as an ",[134,632,633],{},".eml"," file.",[126,636,638],{"id":637},"in-a-test","In a Test",[116,640,641],{},"Give each run its own address, wait for the message, assert on it, then delete the account:",[181,643,647],{"className":644,"code":645,"language":646,"meta":186,"style":186},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import assert from 'node:assert'\nimport { test } from 'node:test'\n\nconst API = 'https:\u002F\u002Fapi.smtp.dev'\nconst headers = {\n  'X-API-KEY': process.env.SMTP_DEV_API_KEY,\n  'Content-Type': 'application\u002Fjson',\n}\n\nasync function api(path, options) {\n  const res = await fetch(API + path, { headers, ...options })\n  assert.ok(res.ok, `${path} returned ${res.status}`)\n  return res.status === 204\n    ? null\n    : res.json()\n}\n\nasync function waitForMessage(accountId, mailboxId, timeout = 30_000) {\n  const messages = `\u002Faccounts\u002F${accountId}\u002Fmailboxes\u002F${mailboxId}\u002Fmessages`\n  const deadline = Date.now() + timeout\n  while (Date.now() \u003C deadline) {\n    const { member } = await api(messages)\n    if (member[0])\n      return api(`${messages}\u002F${member[0].id}`)\n    await new Promise(resolve => setTimeout(resolve, 2000))\n  }\n  throw new Error(`no message after ${timeout}ms`)\n}\n\ntest('signup sends a confirmation link', async () => {\n  const address = `qa-${crypto.randomUUID()}@test.example.com`\n  const account = await api('\u002Faccounts', {\n    method: 'POST',\n    body: JSON.stringify({\n      address,\n      password: crypto.randomUUID(),\n    }),\n  })\n  const inbox = account.mailboxes.find(m => m.path === 'INBOX')\n\n  await signUp(address) \u002F\u002F your app sends the email\n\n  const message = await waitForMessage(account.id, inbox.id)\n  assert.match(message.subject, \u002Fconfirm\u002Fi)\n  assert.match(message.text, \u002F\\\u002Fconfirm\\\u002F\u002F)\n\n  await api(`\u002Faccounts\u002F${account.id}`, { method: 'DELETE' })\n})\n","js",[134,648,649,667,690,696,715,727,755,775,780,784,814,863,911,930,939,955,960,965,999,1037,1064,1091,1117,1136,1174,1209,1215,1248,1253,1258,1285,1320,1347,1364,1384,1392,1411,1421,1428,1473,1478,1498,1503,1535,1569,1601,1606,1649],{"__ignoreMap":186},[190,650,651,655,658,660,662,665],{"class":192,"line":193},[190,652,654],{"class":653},"s7zQu","import",[190,656,657],{"class":217}," assert ",[190,659,421],{"class":653},[190,661,259],{"class":207},[190,663,664],{"class":200},"node:assert",[190,666,265],{"class":207},[190,668,669,671,674,677,680,683,685,688],{"class":192,"line":221},[190,670,654],{"class":653},[190,672,673],{"class":207}," {",[190,675,676],{"class":217}," test",[190,678,679],{"class":207}," }",[190,681,682],{"class":653}," from",[190,684,259],{"class":207},[190,686,687],{"class":200},"node:test",[190,689,265],{"class":207},[190,691,692],{"class":192,"line":239},[190,693,695],{"emptyLinePlaceholder":694},true,"\n",[190,697,698,702,705,708,710,713],{"class":192,"line":253},[190,699,701],{"class":700},"spNyl","const",[190,703,704],{"class":217}," API ",[190,706,707],{"class":207},"=",[190,709,259],{"class":207},[190,711,712],{"class":200},"https:\u002F\u002Fapi.smtp.dev",[190,714,265],{"class":207},[190,716,717,719,722,724],{"class":192,"line":386},[190,718,701],{"class":700},[190,720,721],{"class":217}," headers ",[190,723,707],{"class":207},[190,725,726],{"class":207}," {\n",[190,728,729,732,735,738,740,743,745,748,750,752],{"class":192,"line":392},[190,730,731],{"class":207},"  '",[190,733,158],{"class":734},"swJcz",[190,736,737],{"class":207},"'",[190,739,483],{"class":207},[190,741,742],{"class":217}," process",[190,744,152],{"class":207},[190,746,747],{"class":217},"env",[190,749,152],{"class":207},[190,751,151],{"class":217},[190,753,754],{"class":207},",\n",[190,756,757,759,762,764,766,768,771,773],{"class":192,"line":398},[190,758,731],{"class":207},[190,760,761],{"class":734},"Content-Type",[190,763,737],{"class":207},[190,765,483],{"class":207},[190,767,259],{"class":207},[190,769,770],{"class":200},"application\u002Fjson",[190,772,737],{"class":207},[190,774,754],{"class":207},[190,776,777],{"class":192,"line":404},[190,778,779],{"class":207},"}\n",[190,781,782],{"class":192,"line":410},[190,783,695],{"emptyLinePlaceholder":694},[190,785,787,790,793,797,800,803,806,809,812],{"class":192,"line":786},10,[190,788,789],{"class":700},"async",[190,791,792],{"class":700}," function",[190,794,796],{"class":795},"s2Zo4"," api",[190,798,799],{"class":207},"(",[190,801,282],{"class":802},"sHdIc",[190,804,805],{"class":207},",",[190,807,808],{"class":802}," options",[190,810,811],{"class":207},")",[190,813,726],{"class":207},[190,815,817,820,823,826,829,832,834,837,840,843,845,847,850,852,855,858,860],{"class":192,"line":816},11,[190,818,819],{"class":700},"  const",[190,821,822],{"class":217}," res",[190,824,825],{"class":207}," =",[190,827,828],{"class":653}," await",[190,830,831],{"class":795}," fetch",[190,833,799],{"class":734},[190,835,836],{"class":217},"API",[190,838,839],{"class":207}," +",[190,841,842],{"class":217}," path",[190,844,805],{"class":207},[190,846,673],{"class":207},[190,848,849],{"class":217}," headers",[190,851,805],{"class":207},[190,853,854],{"class":207}," ...",[190,856,857],{"class":217},"options",[190,859,679],{"class":207},[190,861,862],{"class":734},")\n",[190,864,866,869,871,874,876,879,881,883,885,888,890,893,896,899,901,903,906,909],{"class":192,"line":865},12,[190,867,868],{"class":217},"  assert",[190,870,152],{"class":207},[190,872,873],{"class":795},"ok",[190,875,799],{"class":734},[190,877,878],{"class":217},"res",[190,880,152],{"class":207},[190,882,873],{"class":217},[190,884,805],{"class":207},[190,886,887],{"class":207}," `${",[190,889,282],{"class":217},[190,891,892],{"class":207},"}",[190,894,895],{"class":200}," returned ",[190,897,898],{"class":207},"${",[190,900,878],{"class":217},[190,902,152],{"class":207},[190,904,905],{"class":217},"status",[190,907,908],{"class":207},"}`",[190,910,862],{"class":734},[190,912,914,917,919,921,923,926],{"class":192,"line":913},13,[190,915,916],{"class":653},"  return",[190,918,822],{"class":217},[190,920,152],{"class":207},[190,922,905],{"class":217},[190,924,925],{"class":207}," ===",[190,927,929],{"class":928},"sbssI"," 204\n",[190,931,933,936],{"class":192,"line":932},14,[190,934,935],{"class":207},"    ?",[190,937,938],{"class":207}," null\n",[190,940,942,945,947,949,952],{"class":192,"line":941},15,[190,943,944],{"class":207},"    :",[190,946,822],{"class":217},[190,948,152],{"class":207},[190,950,951],{"class":795},"json",[190,953,954],{"class":734},"()\n",[190,956,958],{"class":192,"line":957},16,[190,959,779],{"class":207},[190,961,963],{"class":192,"line":962},17,[190,964,695],{"emptyLinePlaceholder":694},[190,966,968,970,972,975,977,980,982,985,987,990,992,995,997],{"class":192,"line":967},18,[190,969,789],{"class":700},[190,971,792],{"class":700},[190,973,974],{"class":795}," waitForMessage",[190,976,799],{"class":207},[190,978,979],{"class":802},"accountId",[190,981,805],{"class":207},[190,983,984],{"class":802}," mailboxId",[190,986,805],{"class":207},[190,988,989],{"class":802}," timeout",[190,991,825],{"class":207},[190,993,994],{"class":928}," 30_000",[190,996,811],{"class":207},[190,998,726],{"class":207},[190,1000,1002,1004,1007,1009,1012,1015,1017,1019,1021,1024,1026,1029,1031,1034],{"class":192,"line":1001},19,[190,1003,819],{"class":700},[190,1005,1006],{"class":217}," messages",[190,1008,825],{"class":207},[190,1010,1011],{"class":207}," `",[190,1013,1014],{"class":200},"\u002Faccounts\u002F",[190,1016,898],{"class":207},[190,1018,979],{"class":217},[190,1020,892],{"class":207},[190,1022,1023],{"class":200},"\u002Fmailboxes\u002F",[190,1025,898],{"class":207},[190,1027,1028],{"class":217},"mailboxId",[190,1030,892],{"class":207},[190,1032,1033],{"class":200},"\u002Fmessages",[190,1035,1036],{"class":207},"`\n",[190,1038,1040,1042,1045,1047,1050,1052,1055,1058,1061],{"class":192,"line":1039},20,[190,1041,819],{"class":700},[190,1043,1044],{"class":217}," deadline",[190,1046,825],{"class":207},[190,1048,1049],{"class":217}," Date",[190,1051,152],{"class":207},[190,1053,1054],{"class":795},"now",[190,1056,1057],{"class":734},"() ",[190,1059,1060],{"class":207},"+",[190,1062,1063],{"class":217}," timeout\n",[190,1065,1067,1070,1072,1075,1077,1079,1081,1084,1086,1089],{"class":192,"line":1066},21,[190,1068,1069],{"class":653},"  while",[190,1071,137],{"class":734},[190,1073,1074],{"class":217},"Date",[190,1076,152],{"class":207},[190,1078,1054],{"class":795},[190,1080,1057],{"class":734},[190,1082,1083],{"class":207},"\u003C",[190,1085,1044],{"class":217},[190,1087,1088],{"class":734},") ",[190,1090,383],{"class":207},[190,1092,1094,1097,1099,1102,1104,1106,1108,1110,1112,1115],{"class":192,"line":1093},22,[190,1095,1096],{"class":700},"    const",[190,1098,673],{"class":207},[190,1100,1101],{"class":217}," member",[190,1103,679],{"class":207},[190,1105,825],{"class":207},[190,1107,828],{"class":653},[190,1109,796],{"class":795},[190,1111,799],{"class":734},[190,1113,1114],{"class":217},"messages",[190,1116,862],{"class":734},[190,1118,1120,1123,1125,1127,1130,1133],{"class":192,"line":1119},23,[190,1121,1122],{"class":653},"    if",[190,1124,137],{"class":734},[190,1126,436],{"class":217},[190,1128,1129],{"class":734},"[",[190,1131,1132],{"class":928},"0",[190,1134,1135],{"class":734},"])\n",[190,1137,1139,1142,1144,1146,1149,1151,1153,1156,1158,1161,1163,1166,1168,1170,1172],{"class":192,"line":1138},24,[190,1140,1141],{"class":653},"      return",[190,1143,796],{"class":795},[190,1145,799],{"class":734},[190,1147,1148],{"class":207},"`${",[190,1150,1114],{"class":217},[190,1152,892],{"class":207},[190,1154,1155],{"class":200},"\u002F",[190,1157,898],{"class":207},[190,1159,1160],{"class":217},"member[",[190,1162,1132],{"class":928},[190,1164,1165],{"class":217},"]",[190,1167,152],{"class":207},[190,1169,271],{"class":217},[190,1171,908],{"class":207},[190,1173,862],{"class":734},[190,1175,1177,1180,1183,1186,1188,1191,1194,1197,1199,1201,1203,1206],{"class":192,"line":1176},25,[190,1178,1179],{"class":653},"    await",[190,1181,1182],{"class":207}," new",[190,1184,1185],{"class":196}," Promise",[190,1187,799],{"class":734},[190,1189,1190],{"class":802},"resolve",[190,1192,1193],{"class":700}," =>",[190,1195,1196],{"class":795}," setTimeout",[190,1198,799],{"class":734},[190,1200,1190],{"class":217},[190,1202,805],{"class":207},[190,1204,1205],{"class":928}," 2000",[190,1207,1208],{"class":734},"))\n",[190,1210,1212],{"class":192,"line":1211},26,[190,1213,1214],{"class":207},"  }\n",[190,1216,1218,1221,1223,1226,1228,1231,1234,1236,1239,1241,1244,1246],{"class":192,"line":1217},27,[190,1219,1220],{"class":653},"  throw",[190,1222,1182],{"class":207},[190,1224,1225],{"class":795}," Error",[190,1227,799],{"class":734},[190,1229,1230],{"class":207},"`",[190,1232,1233],{"class":200},"no message after ",[190,1235,898],{"class":207},[190,1237,1238],{"class":217},"timeout",[190,1240,892],{"class":207},[190,1242,1243],{"class":200},"ms",[190,1245,1230],{"class":207},[190,1247,862],{"class":734},[190,1249,1251],{"class":192,"line":1250},28,[190,1252,779],{"class":207},[190,1254,1256],{"class":192,"line":1255},29,[190,1257,695],{"emptyLinePlaceholder":694},[190,1259,1261,1264,1266,1268,1271,1273,1275,1278,1281,1283],{"class":192,"line":1260},30,[190,1262,1263],{"class":795},"test",[190,1265,799],{"class":217},[190,1267,737],{"class":207},[190,1269,1270],{"class":200},"signup sends a confirmation link",[190,1272,737],{"class":207},[190,1274,805],{"class":207},[190,1276,1277],{"class":700}," async",[190,1279,1280],{"class":207}," ()",[190,1282,1193],{"class":700},[190,1284,726],{"class":207},[190,1286,1288,1290,1293,1295,1297,1300,1302,1305,1307,1310,1313,1315,1318],{"class":192,"line":1287},31,[190,1289,819],{"class":700},[190,1291,1292],{"class":217}," address",[190,1294,825],{"class":207},[190,1296,1011],{"class":207},[190,1298,1299],{"class":200},"qa-",[190,1301,898],{"class":207},[190,1303,1304],{"class":217},"crypto",[190,1306,152],{"class":207},[190,1308,1309],{"class":795},"randomUUID",[190,1311,1312],{"class":217},"()",[190,1314,892],{"class":207},[190,1316,1317],{"class":200},"@test.example.com",[190,1319,1036],{"class":207},[190,1321,1323,1325,1328,1330,1332,1334,1336,1338,1341,1343,1345],{"class":192,"line":1322},32,[190,1324,819],{"class":700},[190,1326,1327],{"class":217}," account",[190,1329,825],{"class":207},[190,1331,828],{"class":653},[190,1333,796],{"class":795},[190,1335,799],{"class":734},[190,1337,737],{"class":207},[190,1339,1340],{"class":200},"\u002Faccounts",[190,1342,737],{"class":207},[190,1344,805],{"class":207},[190,1346,726],{"class":207},[190,1348,1350,1353,1355,1357,1360,1362],{"class":192,"line":1349},33,[190,1351,1352],{"class":734},"    method",[190,1354,483],{"class":207},[190,1356,259],{"class":207},[190,1358,1359],{"class":200},"POST",[190,1361,737],{"class":207},[190,1363,754],{"class":207},[190,1365,1367,1370,1372,1375,1377,1380,1382],{"class":192,"line":1366},34,[190,1368,1369],{"class":734},"    body",[190,1371,483],{"class":207},[190,1373,1374],{"class":217}," JSON",[190,1376,152],{"class":207},[190,1378,1379],{"class":795},"stringify",[190,1381,799],{"class":734},[190,1383,383],{"class":207},[190,1385,1387,1390],{"class":192,"line":1386},35,[190,1388,1389],{"class":217},"      address",[190,1391,754],{"class":207},[190,1393,1395,1398,1400,1403,1405,1407,1409],{"class":192,"line":1394},36,[190,1396,1397],{"class":734},"      password",[190,1399,483],{"class":207},[190,1401,1402],{"class":217}," crypto",[190,1404,152],{"class":207},[190,1406,1309],{"class":795},[190,1408,1312],{"class":734},[190,1410,754],{"class":207},[190,1412,1414,1417,1419],{"class":192,"line":1413},37,[190,1415,1416],{"class":207},"    }",[190,1418,811],{"class":734},[190,1420,754],{"class":207},[190,1422,1424,1426],{"class":192,"line":1423},38,[190,1425,413],{"class":207},[190,1427,862],{"class":734},[190,1429,1431,1433,1436,1438,1440,1442,1444,1446,1449,1451,1454,1456,1459,1461,1463,1465,1467,1469,1471],{"class":192,"line":1430},39,[190,1432,819],{"class":700},[190,1434,1435],{"class":217}," inbox",[190,1437,825],{"class":207},[190,1439,1327],{"class":217},[190,1441,152],{"class":207},[190,1443,275],{"class":217},[190,1445,152],{"class":207},[190,1447,1448],{"class":795},"find",[190,1450,799],{"class":734},[190,1452,1453],{"class":802},"m",[190,1455,1193],{"class":700},[190,1457,1458],{"class":217}," m",[190,1460,152],{"class":207},[190,1462,282],{"class":217},[190,1464,925],{"class":207},[190,1466,259],{"class":207},[190,1468,286],{"class":200},[190,1470,737],{"class":207},[190,1472,862],{"class":734},[190,1474,1476],{"class":192,"line":1475},40,[190,1477,695],{"emptyLinePlaceholder":694},[190,1479,1481,1484,1487,1489,1492,1494],{"class":192,"line":1480},41,[190,1482,1483],{"class":653},"  await",[190,1485,1486],{"class":795}," signUp",[190,1488,799],{"class":734},[190,1490,1491],{"class":217},"address",[190,1493,1088],{"class":734},[190,1495,1497],{"class":1496},"sHwdD","\u002F\u002F your app sends the email\n",[190,1499,1501],{"class":192,"line":1500},42,[190,1502,695],{"emptyLinePlaceholder":694},[190,1504,1506,1508,1511,1513,1515,1517,1519,1521,1523,1525,1527,1529,1531,1533],{"class":192,"line":1505},43,[190,1507,819],{"class":700},[190,1509,1510],{"class":217}," message",[190,1512,825],{"class":207},[190,1514,828],{"class":653},[190,1516,974],{"class":795},[190,1518,799],{"class":734},[190,1520,178],{"class":217},[190,1522,152],{"class":207},[190,1524,271],{"class":217},[190,1526,805],{"class":207},[190,1528,1435],{"class":217},[190,1530,152],{"class":207},[190,1532,271],{"class":217},[190,1534,862],{"class":734},[190,1536,1538,1540,1542,1545,1547,1550,1552,1554,1556,1559,1562,1564,1567],{"class":192,"line":1537},44,[190,1539,868],{"class":217},[190,1541,152],{"class":207},[190,1543,1544],{"class":795},"match",[190,1546,799],{"class":734},[190,1548,1549],{"class":217},"message",[190,1551,152],{"class":207},[190,1553,540],{"class":217},[190,1555,805],{"class":207},[190,1557,1558],{"class":207}," \u002F",[190,1560,1561],{"class":200},"confirm",[190,1563,1155],{"class":207},[190,1565,1566],{"class":928},"i",[190,1568,862],{"class":734},[190,1570,1572,1574,1576,1578,1580,1582,1584,1586,1588,1590,1593,1595,1597,1599],{"class":192,"line":1571},45,[190,1573,868],{"class":217},[190,1575,152],{"class":207},[190,1577,1544],{"class":795},[190,1579,799],{"class":734},[190,1581,1549],{"class":217},[190,1583,152],{"class":207},[190,1585,555],{"class":217},[190,1587,805],{"class":207},[190,1589,1558],{"class":207},[190,1591,1592],{"class":217},"\\\u002F",[190,1594,1561],{"class":200},[190,1596,1592],{"class":217},[190,1598,1155],{"class":207},[190,1600,862],{"class":734},[190,1602,1604],{"class":192,"line":1603},46,[190,1605,695],{"emptyLinePlaceholder":694},[190,1607,1609,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1636,1638,1640,1643,1645,1647],{"class":192,"line":1608},47,[190,1610,1483],{"class":653},[190,1612,796],{"class":795},[190,1614,799],{"class":734},[190,1616,1230],{"class":207},[190,1618,1014],{"class":200},[190,1620,898],{"class":207},[190,1622,178],{"class":217},[190,1624,152],{"class":207},[190,1626,271],{"class":217},[190,1628,908],{"class":207},[190,1630,805],{"class":207},[190,1632,673],{"class":207},[190,1634,1635],{"class":734}," method",[190,1637,483],{"class":207},[190,1639,259],{"class":207},[190,1641,1642],{"class":200},"DELETE",[190,1644,737],{"class":207},[190,1646,679],{"class":207},[190,1648,862],{"class":734},[190,1650,1652,1654],{"class":192,"line":1651},48,[190,1653,892],{"class":207},[190,1655,862],{"class":217},[116,1657,1658],{},"The same test with pytest. The fixture deletes the account even when the test fails:",[181,1660,1664],{"className":1661,"code":1662,"language":1663,"meta":186,"style":186},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import os\nimport time\nimport uuid\n\nimport pytest\nimport requests\n\nAPI = \"https:\u002F\u002Fapi.smtp.dev\"\nsession = requests.Session()\nsession.headers[\"X-API-KEY\"] = os.environ[\"SMTP_DEV_API_KEY\"]\n\n\ndef api(method, path, **kwargs):\n    res = session.request(method, API + path, **kwargs)\n    res.raise_for_status()\n    return None if res.status_code == 204 else res.json()\n\n\ndef wait_for_message(account_id, mailbox_id, timeout=30):\n    messages = f\"\u002Faccounts\u002F{account_id}\u002Fmailboxes\u002F{mailbox_id}\u002Fmessages\"\n    deadline = time.monotonic() + timeout\n    while time.monotonic() \u003C deadline:\n        member = api(\"GET\", messages)[\"member\"]\n        if member:\n            return api(\"GET\", f\"{messages}\u002F{member[0]['id']}\")\n        time.sleep(2)\n    raise TimeoutError(f\"no message after {timeout}s\")\n\n\n@pytest.fixture\ndef inbox():\n    address = f\"qa-{uuid.uuid4()}@test.example.com\"\n    account = api(\"POST\", \"\u002Faccounts\", json={\"address\": address, \"password\": str(uuid.uuid4())})\n    mailbox = next(m for m in account[\"mailboxes\"] if m[\"path\"] == \"INBOX\")\n    yield address, account[\"id\"], mailbox[\"id\"]\n    api(\"DELETE\", f\"\u002Faccounts\u002F{account['id']}\")\n\n\ndef test_signup_sends_a_confirmation_link(inbox):\n    address, account_id, mailbox_id = inbox\n    sign_up(address)  # your app sends the email\n\n    message = wait_for_message(account_id, mailbox_id)\n    assert \"confirm\" in message[\"subject\"].lower()\n    assert \"\u002Fconfirm\u002F\" in message[\"text\"]\n","python",[134,1665,1666,1673,1680,1687,1691,1698,1705,1709,1722,1739,1779,1783,1787,1814,1849,1861,1896,1900,1904,1932,1964,1985,2006,2039,2048,2102,2119,2146,2150,2154,2167,2176,2205,2273,2333,2368,2407,2411,2415,2429,2449,2463,2467,2486,2518],{"__ignoreMap":186},[190,1667,1668,1670],{"class":192,"line":193},[190,1669,654],{"class":653},[190,1671,1672],{"class":217}," os\n",[190,1674,1675,1677],{"class":192,"line":221},[190,1676,654],{"class":653},[190,1678,1679],{"class":217}," time\n",[190,1681,1682,1684],{"class":192,"line":239},[190,1683,654],{"class":653},[190,1685,1686],{"class":217}," uuid\n",[190,1688,1689],{"class":192,"line":253},[190,1690,695],{"emptyLinePlaceholder":694},[190,1692,1693,1695],{"class":192,"line":386},[190,1694,654],{"class":653},[190,1696,1697],{"class":217}," pytest\n",[190,1699,1700,1702],{"class":192,"line":392},[190,1701,654],{"class":653},[190,1703,1704],{"class":217}," requests\n",[190,1706,1707],{"class":192,"line":398},[190,1708,695],{"emptyLinePlaceholder":694},[190,1710,1711,1714,1716,1718,1720],{"class":192,"line":404},[190,1712,1713],{"class":217},"API ",[190,1715,707],{"class":207},[190,1717,208],{"class":207},[190,1719,712],{"class":200},[190,1721,472],{"class":207},[190,1723,1724,1727,1729,1732,1734,1737],{"class":192,"line":410},[190,1725,1726],{"class":217},"session ",[190,1728,707],{"class":207},[190,1730,1731],{"class":217}," requests",[190,1733,152],{"class":207},[190,1735,1736],{"class":795},"Session",[190,1738,954],{"class":207},[190,1740,1741,1744,1746,1748,1750,1752,1754,1756,1758,1760,1763,1765,1768,1770,1772,1774,1776],{"class":192,"line":786},[190,1742,1743],{"class":217},"session",[190,1745,152],{"class":207},[190,1747,571],{"class":734},[190,1749,1129],{"class":207},[190,1751,214],{"class":207},[190,1753,158],{"class":200},[190,1755,214],{"class":207},[190,1757,1165],{"class":207},[190,1759,825],{"class":207},[190,1761,1762],{"class":217}," os",[190,1764,152],{"class":207},[190,1766,1767],{"class":734},"environ",[190,1769,1129],{"class":207},[190,1771,214],{"class":207},[190,1773,151],{"class":200},[190,1775,214],{"class":207},[190,1777,1778],{"class":207},"]\n",[190,1780,1781],{"class":192,"line":816},[190,1782,695],{"emptyLinePlaceholder":694},[190,1784,1785],{"class":192,"line":865},[190,1786,695],{"emptyLinePlaceholder":694},[190,1788,1789,1792,1794,1796,1799,1801,1803,1805,1808,1811],{"class":192,"line":913},[190,1790,1791],{"class":700},"def",[190,1793,796],{"class":795},[190,1795,799],{"class":207},[190,1797,1798],{"class":802},"method",[190,1800,805],{"class":207},[190,1802,842],{"class":802},[190,1804,805],{"class":207},[190,1806,1807],{"class":207}," **",[190,1809,1810],{"class":802},"kwargs",[190,1812,1813],{"class":207},"):\n",[190,1815,1816,1819,1821,1824,1826,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847],{"class":192,"line":932},[190,1817,1818],{"class":217},"    res ",[190,1820,707],{"class":207},[190,1822,1823],{"class":217}," session",[190,1825,152],{"class":207},[190,1827,1828],{"class":795},"request",[190,1830,799],{"class":207},[190,1832,1798],{"class":795},[190,1834,805],{"class":207},[190,1836,704],{"class":795},[190,1838,1060],{"class":207},[190,1840,842],{"class":795},[190,1842,805],{"class":207},[190,1844,1807],{"class":207},[190,1846,1810],{"class":795},[190,1848,862],{"class":207},[190,1850,1851,1854,1856,1859],{"class":192,"line":941},[190,1852,1853],{"class":217},"    res",[190,1855,152],{"class":207},[190,1857,1858],{"class":795},"raise_for_status",[190,1860,954],{"class":207},[190,1862,1863,1866,1869,1872,1874,1876,1879,1882,1885,1888,1890,1892,1894],{"class":192,"line":957},[190,1864,1865],{"class":653},"    return",[190,1867,1868],{"class":207}," None",[190,1870,1871],{"class":653}," if",[190,1873,822],{"class":217},[190,1875,152],{"class":207},[190,1877,1878],{"class":734},"status_code",[190,1880,1881],{"class":207}," ==",[190,1883,1884],{"class":928}," 204",[190,1886,1887],{"class":653}," else",[190,1889,822],{"class":217},[190,1891,152],{"class":207},[190,1893,951],{"class":795},[190,1895,954],{"class":207},[190,1897,1898],{"class":192,"line":962},[190,1899,695],{"emptyLinePlaceholder":694},[190,1901,1902],{"class":192,"line":967},[190,1903,695],{"emptyLinePlaceholder":694},[190,1905,1906,1908,1911,1913,1916,1918,1921,1923,1925,1927,1930],{"class":192,"line":1001},[190,1907,1791],{"class":700},[190,1909,1910],{"class":795}," wait_for_message",[190,1912,799],{"class":207},[190,1914,1915],{"class":802},"account_id",[190,1917,805],{"class":207},[190,1919,1920],{"class":802}," mailbox_id",[190,1922,805],{"class":207},[190,1924,989],{"class":802},[190,1926,707],{"class":207},[190,1928,1929],{"class":928},"30",[190,1931,1813],{"class":207},[190,1933,1934,1937,1939,1942,1945,1948,1950,1952,1954,1956,1959,1961],{"class":192,"line":1039},[190,1935,1936],{"class":217},"    messages ",[190,1938,707],{"class":207},[190,1940,1941],{"class":700}," f",[190,1943,1944],{"class":200},"\"\u002Faccounts\u002F",[190,1946,1947],{"class":928},"{",[190,1949,1915],{"class":217},[190,1951,892],{"class":928},[190,1953,1023],{"class":200},[190,1955,1947],{"class":928},[190,1957,1958],{"class":217},"mailbox_id",[190,1960,892],{"class":928},[190,1962,1963],{"class":200},"\u002Fmessages\"\n",[190,1965,1966,1969,1971,1974,1976,1979,1981,1983],{"class":192,"line":1066},[190,1967,1968],{"class":217},"    deadline ",[190,1970,707],{"class":207},[190,1972,1973],{"class":217}," time",[190,1975,152],{"class":207},[190,1977,1978],{"class":795},"monotonic",[190,1980,1312],{"class":207},[190,1982,839],{"class":207},[190,1984,1063],{"class":217},[190,1986,1987,1990,1992,1994,1996,1998,2001,2003],{"class":192,"line":1093},[190,1988,1989],{"class":653},"    while",[190,1991,1973],{"class":217},[190,1993,152],{"class":207},[190,1995,1978],{"class":795},[190,1997,1312],{"class":207},[190,1999,2000],{"class":207}," \u003C",[190,2002,1044],{"class":217},[190,2004,2005],{"class":207},":\n",[190,2007,2008,2011,2013,2015,2017,2019,2022,2024,2026,2028,2031,2033,2035,2037],{"class":192,"line":1119},[190,2009,2010],{"class":217},"        member ",[190,2012,707],{"class":207},[190,2014,796],{"class":795},[190,2016,799],{"class":207},[190,2018,214],{"class":207},[190,2020,2021],{"class":200},"GET",[190,2023,214],{"class":207},[190,2025,805],{"class":207},[190,2027,1006],{"class":795},[190,2029,2030],{"class":207},")[",[190,2032,214],{"class":207},[190,2034,436],{"class":200},[190,2036,214],{"class":207},[190,2038,1778],{"class":207},[190,2040,2041,2044,2046],{"class":192,"line":1138},[190,2042,2043],{"class":653},"        if",[190,2045,1101],{"class":217},[190,2047,2005],{"class":207},[190,2049,2050,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077,2079,2081,2083,2085,2088,2090,2092,2094,2096,2098,2100],{"class":192,"line":1176},[190,2051,2052],{"class":653},"            return",[190,2054,796],{"class":795},[190,2056,799],{"class":207},[190,2058,214],{"class":207},[190,2060,2021],{"class":200},[190,2062,214],{"class":207},[190,2064,805],{"class":207},[190,2066,1941],{"class":700},[190,2068,214],{"class":200},[190,2070,1947],{"class":928},[190,2072,1114],{"class":795},[190,2074,892],{"class":928},[190,2076,1155],{"class":200},[190,2078,1947],{"class":928},[190,2080,436],{"class":795},[190,2082,1129],{"class":207},[190,2084,1132],{"class":928},[190,2086,2087],{"class":207},"][",[190,2089,737],{"class":207},[190,2091,271],{"class":200},[190,2093,737],{"class":207},[190,2095,1165],{"class":207},[190,2097,892],{"class":928},[190,2099,214],{"class":200},[190,2101,862],{"class":207},[190,2103,2104,2107,2109,2112,2114,2117],{"class":192,"line":1211},[190,2105,2106],{"class":217},"        time",[190,2108,152],{"class":207},[190,2110,2111],{"class":795},"sleep",[190,2113,799],{"class":207},[190,2115,2116],{"class":928},"2",[190,2118,862],{"class":207},[190,2120,2121,2124,2127,2129,2132,2135,2137,2139,2141,2144],{"class":192,"line":1217},[190,2122,2123],{"class":653},"    raise",[190,2125,2126],{"class":196}," TimeoutError",[190,2128,799],{"class":207},[190,2130,2131],{"class":700},"f",[190,2133,2134],{"class":200},"\"no message after ",[190,2136,1947],{"class":928},[190,2138,1238],{"class":795},[190,2140,892],{"class":928},[190,2142,2143],{"class":200},"s\"",[190,2145,862],{"class":207},[190,2147,2148],{"class":192,"line":1250},[190,2149,695],{"emptyLinePlaceholder":694},[190,2151,2152],{"class":192,"line":1255},[190,2153,695],{"emptyLinePlaceholder":694},[190,2155,2156,2159,2162,2164],{"class":192,"line":1260},[190,2157,2158],{"class":207},"@",[190,2160,2161],{"class":795},"pytest",[190,2163,152],{"class":207},[190,2165,2166],{"class":795},"fixture\n",[190,2168,2169,2171,2173],{"class":192,"line":1287},[190,2170,1791],{"class":700},[190,2172,1435],{"class":795},[190,2174,2175],{"class":207},"():\n",[190,2177,2178,2181,2183,2185,2188,2190,2193,2195,2198,2200,2202],{"class":192,"line":1322},[190,2179,2180],{"class":217},"    address ",[190,2182,707],{"class":207},[190,2184,1941],{"class":700},[190,2186,2187],{"class":200},"\"qa-",[190,2189,1947],{"class":928},[190,2191,2192],{"class":217},"uuid",[190,2194,152],{"class":207},[190,2196,2197],{"class":795},"uuid4",[190,2199,1312],{"class":207},[190,2201,892],{"class":928},[190,2203,2204],{"class":200},"@test.example.com\"\n",[190,2206,2207,2210,2212,2214,2216,2218,2220,2222,2224,2226,2228,2230,2232,2235,2238,2240,2242,2244,2246,2248,2250,2252,2255,2257,2259,2262,2264,2266,2268,2270],{"class":192,"line":1349},[190,2208,2209],{"class":217},"    account ",[190,2211,707],{"class":207},[190,2213,796],{"class":795},[190,2215,799],{"class":207},[190,2217,214],{"class":207},[190,2219,1359],{"class":200},[190,2221,214],{"class":207},[190,2223,805],{"class":207},[190,2225,208],{"class":207},[190,2227,1340],{"class":200},[190,2229,214],{"class":207},[190,2231,805],{"class":207},[190,2233,2234],{"class":802}," json",[190,2236,2237],{"class":207},"={",[190,2239,214],{"class":207},[190,2241,1491],{"class":200},[190,2243,214],{"class":207},[190,2245,483],{"class":207},[190,2247,1292],{"class":795},[190,2249,805],{"class":207},[190,2251,208],{"class":207},[190,2253,2254],{"class":200},"password",[190,2256,214],{"class":207},[190,2258,483],{"class":207},[190,2260,2261],{"class":196}," str",[190,2263,799],{"class":207},[190,2265,2192],{"class":795},[190,2267,152],{"class":207},[190,2269,2197],{"class":795},[190,2271,2272],{"class":207},"())})\n",[190,2274,2275,2278,2280,2283,2285,2288,2291,2294,2297,2299,2301,2303,2305,2307,2309,2311,2313,2315,2317,2319,2321,2323,2325,2327,2329,2331],{"class":192,"line":1366},[190,2276,2277],{"class":217},"    mailbox ",[190,2279,707],{"class":207},[190,2281,2282],{"class":795}," next",[190,2284,799],{"class":207},[190,2286,2287],{"class":795},"m ",[190,2289,2290],{"class":653},"for",[190,2292,2293],{"class":795}," m ",[190,2295,2296],{"class":653},"in",[190,2298,1327],{"class":795},[190,2300,1129],{"class":207},[190,2302,214],{"class":207},[190,2304,275],{"class":200},[190,2306,214],{"class":207},[190,2308,1165],{"class":207},[190,2310,1871],{"class":653},[190,2312,1458],{"class":795},[190,2314,1129],{"class":207},[190,2316,214],{"class":207},[190,2318,282],{"class":200},[190,2320,214],{"class":207},[190,2322,1165],{"class":207},[190,2324,1881],{"class":207},[190,2326,208],{"class":207},[190,2328,286],{"class":200},[190,2330,214],{"class":207},[190,2332,862],{"class":207},[190,2334,2335,2338,2340,2342,2344,2346,2348,2350,2352,2355,2358,2360,2362,2364,2366],{"class":192,"line":1386},[190,2336,2337],{"class":653},"    yield",[190,2339,1292],{"class":217},[190,2341,805],{"class":207},[190,2343,1327],{"class":217},[190,2345,1129],{"class":207},[190,2347,214],{"class":207},[190,2349,271],{"class":200},[190,2351,214],{"class":207},[190,2353,2354],{"class":207},"],",[190,2356,2357],{"class":217}," mailbox",[190,2359,1129],{"class":207},[190,2361,214],{"class":207},[190,2363,271],{"class":200},[190,2365,214],{"class":207},[190,2367,1778],{"class":207},[190,2369,2370,2373,2375,2377,2379,2381,2383,2385,2387,2389,2391,2393,2395,2397,2399,2401,2403,2405],{"class":192,"line":1394},[190,2371,2372],{"class":795},"    api",[190,2374,799],{"class":207},[190,2376,214],{"class":207},[190,2378,1642],{"class":200},[190,2380,214],{"class":207},[190,2382,805],{"class":207},[190,2384,1941],{"class":700},[190,2386,1944],{"class":200},[190,2388,1947],{"class":928},[190,2390,178],{"class":795},[190,2392,1129],{"class":207},[190,2394,737],{"class":207},[190,2396,271],{"class":200},[190,2398,737],{"class":207},[190,2400,1165],{"class":207},[190,2402,892],{"class":928},[190,2404,214],{"class":200},[190,2406,862],{"class":207},[190,2408,2409],{"class":192,"line":1413},[190,2410,695],{"emptyLinePlaceholder":694},[190,2412,2413],{"class":192,"line":1423},[190,2414,695],{"emptyLinePlaceholder":694},[190,2416,2417,2419,2422,2424,2427],{"class":192,"line":1430},[190,2418,1791],{"class":700},[190,2420,2421],{"class":795}," test_signup_sends_a_confirmation_link",[190,2423,799],{"class":207},[190,2425,2426],{"class":802},"inbox",[190,2428,1813],{"class":207},[190,2430,2431,2434,2436,2439,2441,2444,2446],{"class":192,"line":1475},[190,2432,2433],{"class":217},"    address",[190,2435,805],{"class":207},[190,2437,2438],{"class":217}," account_id",[190,2440,805],{"class":207},[190,2442,2443],{"class":217}," mailbox_id ",[190,2445,707],{"class":207},[190,2447,2448],{"class":217}," inbox\n",[190,2450,2451,2454,2456,2458,2460],{"class":192,"line":1480},[190,2452,2453],{"class":795},"    sign_up",[190,2455,799],{"class":207},[190,2457,1491],{"class":795},[190,2459,811],{"class":207},[190,2461,2462],{"class":1496},"  # your app sends the email\n",[190,2464,2465],{"class":192,"line":1500},[190,2466,695],{"emptyLinePlaceholder":694},[190,2468,2469,2472,2474,2476,2478,2480,2482,2484],{"class":192,"line":1505},[190,2470,2471],{"class":217},"    message ",[190,2473,707],{"class":207},[190,2475,1910],{"class":795},[190,2477,799],{"class":207},[190,2479,1915],{"class":795},[190,2481,805],{"class":207},[190,2483,1920],{"class":795},[190,2485,862],{"class":207},[190,2487,2488,2491,2493,2495,2497,2500,2502,2504,2506,2508,2510,2513,2516],{"class":192,"line":1537},[190,2489,2490],{"class":653},"    assert",[190,2492,208],{"class":207},[190,2494,1561],{"class":200},[190,2496,214],{"class":207},[190,2498,2499],{"class":207}," in",[190,2501,1510],{"class":217},[190,2503,1129],{"class":207},[190,2505,214],{"class":207},[190,2507,540],{"class":200},[190,2509,214],{"class":207},[190,2511,2512],{"class":207},"].",[190,2514,2515],{"class":795},"lower",[190,2517,954],{"class":207},[190,2519,2520,2522,2524,2527,2529,2531,2533,2535,2537,2539,2541],{"class":192,"line":1571},[190,2521,2490],{"class":653},[190,2523,208],{"class":207},[190,2525,2526],{"class":200},"\u002Fconfirm\u002F",[190,2528,214],{"class":207},[190,2530,2499],{"class":207},[190,2532,1510],{"class":217},[190,2534,1129],{"class":207},[190,2536,214],{"class":207},[190,2538,555],{"class":200},[190,2540,214],{"class":207},[190,2542,1778],{"class":207},[116,2544,2545,2546,2550,2551,2554,2555,2557,2558,2562],{},"Delete the account when the test ends. Accounts count against the plan limit. To create none, send each run to a ",[120,2547,2549],{"href":2548},"\u002Fdocs\u002Ffeatures\u002Faccount\u002F#plus-sign-aliasing","plus alias"," of one account, like ",[134,2552,2553],{},"qa+\u003Cuuid>@test.example.com",", and match messages on ",[134,2556,316],{},". That works on every plan. On Pro and Max, a ",[120,2559,2561],{"href":2560},"\u002Fdocs\u002Fguides\u002Fcatch-all\u002F","catch-all"," also receives every address on the domain.",[126,2564,2566],{"id":2565},"when-a-request-fails","When a Request Fails",[515,2568,2569,2579],{},[518,2570,2571],{},[521,2572,2573,2576],{},[524,2574,2575],{},"Status",[524,2577,2578],{},"Usually means",[531,2580,2581,2592,2600,2608],{},[521,2582,2583,2586],{},[536,2584,2585],{},"401",[536,2587,2588,2589,2591],{},"The ",[134,2590,158],{}," header is missing, or the key is invalid",[521,2593,2594,2597],{},[536,2595,2596],{},"404",[536,2598,2599],{},"A wrong id. Message paths take the account id and the INBOX mailbox id, not the address",[521,2601,2602,2605],{},[536,2603,2604],{},"422",[536,2606,2607],{},"The body didn't validate, for example an address on a domain that isn't yours",[521,2609,2610,2613],{},[536,2611,2612],{},"429",[536,2614,2615,2616,2619],{},"More than 4096 requests in a minute. ",[134,2617,2618],{},"RateLimit-Reset"," says when to retry",[116,2621,2622,2623,2626,2627,2630,2631,152],{},"Updates (",[134,2624,2625],{},"PATCH",") take ",[134,2628,2629],{},"Content-Type: application\u002Fmerge-patch+json",", not ",[134,2632,770],{},[126,2634,2636],{"id":2635},"next","Next",[295,2638,2639,2646,2653,2663,2669],{},[298,2640,2641,2645],{},[120,2642,2644],{"href":2643},"\u002Fdocs\u002Fapi\u002F#real-time-updates","SSE"," pushes the message instead of polling.",[298,2647,2588,2648,2652],{},[120,2649,2651],{"href":2650},"\u002Fdocs\u002Fguides\u002Fci\u002F","CI guide"," runs the same loop on every push.",[298,2654,2655,2658,2659,2662],{},[120,2656,69],{"href":2657},"\u002Fdocs\u002Fguides\u002Fe2e\u002F"," and ",[120,2660,73],{"href":2661},"\u002Fdocs\u002Fguides\u002Fcypress\u002F"," wait for the email inside a browser test and follow its link.",[298,2664,2665,2668],{},[120,2666,49],{"href":2667},"\u002Fdocs\u002Fguides\u002Fsend-test-email\u002F"," sends from the command line or your app's mailer instead of the API.",[298,2670,2671,2672,2676],{},"To see the message rendered, open the account in a ",[120,2673,2675],{"href":2674},"\u002Fdocs\u002Fguides\u002Femail-clients\u002F","mail client"," over IMAP.",[2678,2679,2680],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":186,"searchDepth":221,"depth":221,"links":2682},[2683,2684,2685,2686,2687,2688,2689],{"id":128,"depth":221,"text":129},{"id":170,"depth":221,"text":171},{"id":289,"depth":221,"text":290},{"id":425,"depth":221,"text":426},{"id":637,"depth":221,"text":638},{"id":2565,"depth":221,"text":2566},{"id":2635,"depth":221,"text":2636},"Create a test inbox over REST, send it a message, and read the subject, body, and SPF, DKIM, and DMARC results as JSON. No SDK.","md",{},{"title":53},{"title":111,"description":2690},"w0iZ-zGjMv4BqUGFVYGXBNBW7fJzJzc7CxfcgC3f8ow",[2697,2699],{"title":49,"path":50,"stem":51,"description":2698,"children":-1},"Send a test email through send.smtp.dev with swaks, curl, openssl, or your app's mailer, then read it back over IMAP, POP3, or the REST API.",{"title":57,"path":58,"stem":59,"description":2700,"children":-1},"Send from your test suite through send.smtp.dev, poll the REST API for the message, and assert on subject and body. Works on any CI.",1794185300843]