[{"data":1,"prerenderedAt":1290},["ShallowReactive",2],{"content-\u002Fguides\u002Fdownload-files-using-axiom-chrome-api":3,"content-doc-\u002Fguides\u002Fdownload-files-using-axiom-chrome-api-inline":1289},{"id":4,"title":5,"body":6,"date":1271,"description":1272,"extension":1273,"meta":1274,"navigation":108,"order":1271,"path":1285,"seo":1286,"stem":1287,"__hash__":1288},"guides\u002Fguides\u002Fdownload-files-using-axiom-chrome-api.md","Download invoices from a portal behind a login with Axiom Chrome API",{"type":7,"value":8,"toc":1262},"minimark",[9,13,18,21,62,66,68,71,229,243,247,249,252,348,352,354,357,478,482,484,487,675,686,690,692,1227,1233,1237,1239,1258],[10,11,12],"p",{},"The Chrome API is a cloud browser you drive over Chrome DevTools Protocol with Playwright or Puppeteer, so you get full control from your own code, including file downloads. This guide signs in to a portal, finds every invoice link, and saves each PDF to disk. Because the download reuses the signed-in session, it works even when the files sit behind a login.",[14,15,17],"h2",{"id":16},"before-you-begin","Before you begin",[19,20],"hr",{},[22,23,24,28,36,49,59],"ul",{},[25,26,27],"li",{},"Node.js 18 or later.",[25,29,30,31,35],{},"Playwright installed: ",[32,33,34],"code",{},"npm install playwright",".",[25,37,38,39,44,45,48],{},"An axiom.ai API key from the ",[40,41,43],"a",{"href":42},"\u002Fdocs\u002Fcode\u002Ftoken-generation","Code Dashboard",", set as the ",[32,46,47],{},"AXIOM_API_KEY"," environment variable.",[25,50,51,52,55,56,35],{},"Your portal credentials in environment variables, for example ",[32,53,54],{},"PORTAL_USER"," and ",[32,57,58],{},"PORTAL_PASS",[25,60,61],{},"The CSS selectors for the login fields and the invoice download links.",[14,63,65],{"id":64},"connect-to-the-cloud-browser","Connect to the cloud browser",[19,67],{},[10,69,70],{},"Connect over CDP to a fresh cloud browser. There's no Chromium to install locally.",[72,73,78],"pre",{"className":74,"code":75,"language":76,"meta":77,"style":77},"language-javascript shiki shiki-themes github-light-default github-dark-default","import { chromium } from 'playwright';\n\nconst browser = await chromium.connectOverCDP(\n  `wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=${process.env.AXIOM_API_KEY}`\n);\n\nconst context = browser.contexts()[0];\nconst page = context.pages()[0] ?? await context.newPage();\n","javascript","",[32,79,80,103,110,136,157,163,168,193],{"__ignoreMap":77},[81,82,85,89,93,96,100],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"sjeE4","import",[81,90,92],{"class":91},"s4rv2"," { chromium } ",[81,94,95],{"class":87},"from",[81,97,99],{"class":98},"sSVrQ"," 'playwright'",[81,101,102],{"class":91},";\n",[81,104,106],{"class":83,"line":105},2,[81,107,109],{"emptyLinePlaceholder":108},true,"\n",[81,111,113,116,120,123,126,129,133],{"class":83,"line":112},3,[81,114,115],{"class":87},"const",[81,117,119],{"class":118},"sHrmB"," browser",[81,121,122],{"class":87}," =",[81,124,125],{"class":87}," await",[81,127,128],{"class":91}," chromium.",[81,130,132],{"class":131},"sbjLL","connectOverCDP",[81,134,135],{"class":91},"(\n",[81,137,139,142,145,147,150,152,154],{"class":83,"line":138},4,[81,140,141],{"class":98},"  `wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=${",[81,143,144],{"class":91},"process",[81,146,35],{"class":98},[81,148,149],{"class":91},"env",[81,151,35],{"class":98},[81,153,47],{"class":118},[81,155,156],{"class":98},"}`\n",[81,158,160],{"class":83,"line":159},5,[81,161,162],{"class":91},");\n",[81,164,166],{"class":83,"line":165},6,[81,167,109],{"emptyLinePlaceholder":108},[81,169,171,173,176,178,181,184,187,190],{"class":83,"line":170},7,[81,172,115],{"class":87},[81,174,175],{"class":118}," context",[81,177,122],{"class":87},[81,179,180],{"class":91}," browser.",[81,182,183],{"class":131},"contexts",[81,185,186],{"class":91},"()[",[81,188,189],{"class":118},"0",[81,191,192],{"class":91},"];\n",[81,194,196,198,201,203,206,209,211,213,216,219,221,223,226],{"class":83,"line":195},8,[81,197,115],{"class":87},[81,199,200],{"class":118}," page",[81,202,122],{"class":87},[81,204,205],{"class":91}," context.",[81,207,208],{"class":131},"pages",[81,210,186],{"class":91},[81,212,189],{"class":118},[81,214,215],{"class":91},"] ",[81,217,218],{"class":87},"??",[81,220,125],{"class":87},[81,222,205],{"class":91},[81,224,225],{"class":131},"newPage",[81,227,228],{"class":91},"();\n",[230,231,232],"blockquote",{},[10,233,234,238,239,242],{},[235,236,237],"strong",{},"Note:"," Puppeteer works too: ",[32,240,241],{},"puppeteer.connect({ browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=...\" })",". This guide uses Playwright.",[14,244,246],{"id":245},"sign-in","Sign in",[19,248],{},[10,250,251],{},"Fill the login form and submit. Keep credentials in environment variables, never in the script.",[72,253,255],{"className":74,"code":254,"language":76,"meta":77,"style":77},"await page.goto('https:\u002F\u002Fportal.example.com\u002Flogin');\nawait page.fill(\"input[name='email']\", process.env.PORTAL_USER);\nawait page.fill(\"input[name='password']\", process.env.PORTAL_PASS);\nawait page.click(\"button[type='submit']\");\nawait page.waitForLoadState('networkidle');\n",[32,256,257,276,297,316,332],{"__ignoreMap":77},[81,258,259,262,265,268,271,274],{"class":83,"line":84},[81,260,261],{"class":87},"await",[81,263,264],{"class":91}," page.",[81,266,267],{"class":131},"goto",[81,269,270],{"class":91},"(",[81,272,273],{"class":98},"'https:\u002F\u002Fportal.example.com\u002Flogin'",[81,275,162],{"class":91},[81,277,278,280,282,285,287,290,293,295],{"class":83,"line":105},[81,279,261],{"class":87},[81,281,264],{"class":91},[81,283,284],{"class":131},"fill",[81,286,270],{"class":91},[81,288,289],{"class":98},"\"input[name='email']\"",[81,291,292],{"class":91},", process.env.",[81,294,54],{"class":118},[81,296,162],{"class":91},[81,298,299,301,303,305,307,310,312,314],{"class":83,"line":112},[81,300,261],{"class":87},[81,302,264],{"class":91},[81,304,284],{"class":131},[81,306,270],{"class":91},[81,308,309],{"class":98},"\"input[name='password']\"",[81,311,292],{"class":91},[81,313,58],{"class":118},[81,315,162],{"class":91},[81,317,318,320,322,325,327,330],{"class":83,"line":138},[81,319,261],{"class":87},[81,321,264],{"class":91},[81,323,324],{"class":131},"click",[81,326,270],{"class":91},[81,328,329],{"class":98},"\"button[type='submit']\"",[81,331,162],{"class":91},[81,333,334,336,338,341,343,346],{"class":83,"line":159},[81,335,261],{"class":87},[81,337,264],{"class":91},[81,339,340],{"class":131},"waitForLoadState",[81,342,270],{"class":91},[81,344,345],{"class":98},"'networkidle'",[81,347,162],{"class":91},[14,349,351],{"id":350},"collect-the-invoice-links","Collect the invoice links",[19,353],{},[10,355,356],{},"Open the invoices page and read every download link's URL. Adjust the selector to match the portal.",[72,358,360],{"className":74,"code":359,"language":76,"meta":77,"style":77},"await page.goto('https:\u002F\u002Fportal.example.com\u002Finvoices');\n\nconst links = await page.$$eval(\n  \"a[href$='.pdf']\", \u002F\u002F match the portal's invoice download links\n  (anchors) => anchors.map((a) => a.href)\n);\n\nconsole.log(`Found ${links.length} invoices`);\n",[32,361,362,377,381,399,411,444,448,452],{"__ignoreMap":77},[81,363,364,366,368,370,372,375],{"class":83,"line":84},[81,365,261],{"class":87},[81,367,264],{"class":91},[81,369,267],{"class":131},[81,371,270],{"class":91},[81,373,374],{"class":98},"'https:\u002F\u002Fportal.example.com\u002Finvoices'",[81,376,162],{"class":91},[81,378,379],{"class":83,"line":105},[81,380,109],{"emptyLinePlaceholder":108},[81,382,383,385,388,390,392,394,397],{"class":83,"line":112},[81,384,115],{"class":87},[81,386,387],{"class":118}," links",[81,389,122],{"class":87},[81,391,125],{"class":87},[81,393,264],{"class":91},[81,395,396],{"class":131},"$$eval",[81,398,135],{"class":91},[81,400,401,404,407],{"class":83,"line":138},[81,402,403],{"class":98},"  \"a[href$='.pdf']\"",[81,405,406],{"class":91},", ",[81,408,410],{"class":409},"sU953","\u002F\u002F match the portal's invoice download links\n",[81,412,413,416,420,423,426,429,432,435,437,439,441],{"class":83,"line":159},[81,414,415],{"class":91},"  (",[81,417,419],{"class":418},"sTDnQ","anchors",[81,421,422],{"class":91},") ",[81,424,425],{"class":87},"=>",[81,427,428],{"class":91}," anchors.",[81,430,431],{"class":131},"map",[81,433,434],{"class":91},"((",[81,436,40],{"class":418},[81,438,422],{"class":91},[81,440,425],{"class":87},[81,442,443],{"class":91}," a.href)\n",[81,445,446],{"class":83,"line":165},[81,447,162],{"class":91},[81,449,450],{"class":83,"line":170},[81,451,109],{"emptyLinePlaceholder":108},[81,453,454,457,460,462,465,468,470,473,476],{"class":83,"line":195},[81,455,456],{"class":91},"console.",[81,458,459],{"class":131},"log",[81,461,270],{"class":91},[81,463,464],{"class":98},"`Found ${",[81,466,467],{"class":91},"links",[81,469,35],{"class":98},[81,471,472],{"class":118},"length",[81,474,475],{"class":98},"} invoices`",[81,477,162],{"class":91},[14,479,481],{"id":480},"download-each-pdf","Download each PDF",[19,483],{},[10,485,486],{},"Fetch each file with the browser context's request client. It shares the signed-in session's cookies, so authenticated downloads work without handling any download dialog. Save the bytes to disk.",[72,488,490],{"className":74,"code":489,"language":76,"meta":77,"style":77},"import { writeFileSync, mkdirSync } from 'node:fs';\nimport { basename } from 'node:path';\n\nmkdirSync('.\u002Finvoices', { recursive: true });\n\nfor (const url of links) {\n  const response = await context.request.get(url);\n  const file = `.\u002Finvoices\u002F${basename(new URL(url).pathname)}`;\n  writeFileSync(file, await response.body());\n  console.log(`Saved ${file}`);\n}\n",[32,491,492,506,520,524,543,547,566,587,629,649,669],{"__ignoreMap":77},[81,493,494,496,499,501,504],{"class":83,"line":84},[81,495,88],{"class":87},[81,497,498],{"class":91}," { writeFileSync, mkdirSync } ",[81,500,95],{"class":87},[81,502,503],{"class":98}," 'node:fs'",[81,505,102],{"class":91},[81,507,508,510,513,515,518],{"class":83,"line":105},[81,509,88],{"class":87},[81,511,512],{"class":91}," { basename } ",[81,514,95],{"class":87},[81,516,517],{"class":98}," 'node:path'",[81,519,102],{"class":91},[81,521,522],{"class":83,"line":112},[81,523,109],{"emptyLinePlaceholder":108},[81,525,526,529,531,534,537,540],{"class":83,"line":138},[81,527,528],{"class":131},"mkdirSync",[81,530,270],{"class":91},[81,532,533],{"class":98},"'.\u002Finvoices'",[81,535,536],{"class":91},", { recursive: ",[81,538,539],{"class":118},"true",[81,541,542],{"class":91}," });\n",[81,544,545],{"class":83,"line":159},[81,546,109],{"emptyLinePlaceholder":108},[81,548,549,552,555,557,560,563],{"class":83,"line":165},[81,550,551],{"class":87},"for",[81,553,554],{"class":91}," (",[81,556,115],{"class":87},[81,558,559],{"class":118}," url",[81,561,562],{"class":87}," of",[81,564,565],{"class":91}," links) {\n",[81,567,568,571,574,576,578,581,584],{"class":83,"line":170},[81,569,570],{"class":87},"  const",[81,572,573],{"class":118}," response",[81,575,122],{"class":87},[81,577,125],{"class":87},[81,579,580],{"class":91}," context.request.",[81,582,583],{"class":131},"get",[81,585,586],{"class":91},"(url);\n",[81,588,589,591,594,596,599,602,604,607,610,612,615,618,621,624,627],{"class":83,"line":195},[81,590,570],{"class":87},[81,592,593],{"class":118}," file",[81,595,122],{"class":87},[81,597,598],{"class":98}," `.\u002Finvoices\u002F${",[81,600,601],{"class":131},"basename",[81,603,270],{"class":98},[81,605,606],{"class":87},"new",[81,608,609],{"class":131}," URL",[81,611,270],{"class":98},[81,613,614],{"class":91},"url",[81,616,617],{"class":98},").",[81,619,620],{"class":91},"pathname",[81,622,623],{"class":98},")",[81,625,626],{"class":98},"}`",[81,628,102],{"class":91},[81,630,632,635,638,640,643,646],{"class":83,"line":631},9,[81,633,634],{"class":131},"  writeFileSync",[81,636,637],{"class":91},"(file, ",[81,639,261],{"class":87},[81,641,642],{"class":91}," response.",[81,644,645],{"class":131},"body",[81,647,648],{"class":91},"());\n",[81,650,652,655,657,659,662,665,667],{"class":83,"line":651},10,[81,653,654],{"class":91},"  console.",[81,656,459],{"class":131},[81,658,270],{"class":91},[81,660,661],{"class":98},"`Saved ${",[81,663,664],{"class":91},"file",[81,666,626],{"class":98},[81,668,162],{"class":91},[81,670,672],{"class":83,"line":671},11,[81,673,674],{"class":91},"}\n",[230,676,677],{},[10,678,679,681,682,685],{},[235,680,237],{}," ",[32,683,684],{},"context.request"," reuses the browser context's cookies, so the request is authenticated exactly like the browser. This is more reliable than intercepting browser download events over a remote connection.",[14,687,689],{"id":688},"full-script","Full script",[19,691],{},[72,693,695],{"className":74,"code":694,"language":76,"meta":77,"style":77},"import { chromium } from 'playwright';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { basename } from 'node:path';\n\nasync function run() {\n  const browser = await chromium.connectOverCDP(\n    `wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=${process.env.AXIOM_API_KEY}`\n  );\n\n  try {\n    const context = browser.contexts()[0];\n    const page = context.pages()[0] ?? await context.newPage();\n\n    \u002F\u002F Sign in\n    await page.goto('https:\u002F\u002Fportal.example.com\u002Flogin');\n    await page.fill(\"input[name='email']\", process.env.PORTAL_USER);\n    await page.fill(\"input[name='password']\", process.env.PORTAL_PASS);\n    await page.click(\"button[type='submit']\");\n    await page.waitForLoadState('networkidle');\n\n    \u002F\u002F Collect invoice links\n    await page.goto('https:\u002F\u002Fportal.example.com\u002Finvoices');\n    const links = await page.$$eval(\"a[href$='.pdf']\", (anchors) =>\n      anchors.map((a) => a.href)\n    );\n    console.log(`Found ${links.length} invoices`);\n\n    \u002F\u002F Download each PDF using the signed-in session\n    mkdirSync('.\u002Finvoices', { recursive: true });\n    for (const url of links) {\n      const response = await context.request.get(url);\n      const file = `.\u002Finvoices\u002F${basename(new URL(url).pathname)}`;\n      writeFileSync(file, await response.body());\n      console.log(`Saved ${file}`);\n    }\n  } finally {\n    await browser.close();\n  }\n}\n\nrun();\n",[32,696,697,709,721,733,737,751,767,784,789,793,801,820,849,854,860,876,895,914,929,944,949,955,970,1000,1018,1024,1046,1051,1057,1073,1089,1107,1140,1156,1174,1180,1191,1203,1209,1214,1219],{"__ignoreMap":77},[81,698,699,701,703,705,707],{"class":83,"line":84},[81,700,88],{"class":87},[81,702,92],{"class":91},[81,704,95],{"class":87},[81,706,99],{"class":98},[81,708,102],{"class":91},[81,710,711,713,715,717,719],{"class":83,"line":105},[81,712,88],{"class":87},[81,714,498],{"class":91},[81,716,95],{"class":87},[81,718,503],{"class":98},[81,720,102],{"class":91},[81,722,723,725,727,729,731],{"class":83,"line":112},[81,724,88],{"class":87},[81,726,512],{"class":91},[81,728,95],{"class":87},[81,730,517],{"class":98},[81,732,102],{"class":91},[81,734,735],{"class":83,"line":138},[81,736,109],{"emptyLinePlaceholder":108},[81,738,739,742,745,748],{"class":83,"line":159},[81,740,741],{"class":87},"async",[81,743,744],{"class":87}," function",[81,746,747],{"class":131}," run",[81,749,750],{"class":91},"() {\n",[81,752,753,755,757,759,761,763,765],{"class":83,"line":165},[81,754,570],{"class":87},[81,756,119],{"class":118},[81,758,122],{"class":87},[81,760,125],{"class":87},[81,762,128],{"class":91},[81,764,132],{"class":131},[81,766,135],{"class":91},[81,768,769,772,774,776,778,780,782],{"class":83,"line":170},[81,770,771],{"class":98},"    `wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=${",[81,773,144],{"class":91},[81,775,35],{"class":98},[81,777,149],{"class":91},[81,779,35],{"class":98},[81,781,47],{"class":118},[81,783,156],{"class":98},[81,785,786],{"class":83,"line":195},[81,787,788],{"class":91},"  );\n",[81,790,791],{"class":83,"line":631},[81,792,109],{"emptyLinePlaceholder":108},[81,794,795,798],{"class":83,"line":651},[81,796,797],{"class":87},"  try",[81,799,800],{"class":91}," {\n",[81,802,803,806,808,810,812,814,816,818],{"class":83,"line":671},[81,804,805],{"class":87},"    const",[81,807,175],{"class":118},[81,809,122],{"class":87},[81,811,180],{"class":91},[81,813,183],{"class":131},[81,815,186],{"class":91},[81,817,189],{"class":118},[81,819,192],{"class":91},[81,821,823,825,827,829,831,833,835,837,839,841,843,845,847],{"class":83,"line":822},12,[81,824,805],{"class":87},[81,826,200],{"class":118},[81,828,122],{"class":87},[81,830,205],{"class":91},[81,832,208],{"class":131},[81,834,186],{"class":91},[81,836,189],{"class":118},[81,838,215],{"class":91},[81,840,218],{"class":87},[81,842,125],{"class":87},[81,844,205],{"class":91},[81,846,225],{"class":131},[81,848,228],{"class":91},[81,850,852],{"class":83,"line":851},13,[81,853,109],{"emptyLinePlaceholder":108},[81,855,857],{"class":83,"line":856},14,[81,858,859],{"class":409},"    \u002F\u002F Sign in\n",[81,861,863,866,868,870,872,874],{"class":83,"line":862},15,[81,864,865],{"class":87},"    await",[81,867,264],{"class":91},[81,869,267],{"class":131},[81,871,270],{"class":91},[81,873,273],{"class":98},[81,875,162],{"class":91},[81,877,879,881,883,885,887,889,891,893],{"class":83,"line":878},16,[81,880,865],{"class":87},[81,882,264],{"class":91},[81,884,284],{"class":131},[81,886,270],{"class":91},[81,888,289],{"class":98},[81,890,292],{"class":91},[81,892,54],{"class":118},[81,894,162],{"class":91},[81,896,898,900,902,904,906,908,910,912],{"class":83,"line":897},17,[81,899,865],{"class":87},[81,901,264],{"class":91},[81,903,284],{"class":131},[81,905,270],{"class":91},[81,907,309],{"class":98},[81,909,292],{"class":91},[81,911,58],{"class":118},[81,913,162],{"class":91},[81,915,917,919,921,923,925,927],{"class":83,"line":916},18,[81,918,865],{"class":87},[81,920,264],{"class":91},[81,922,324],{"class":131},[81,924,270],{"class":91},[81,926,329],{"class":98},[81,928,162],{"class":91},[81,930,932,934,936,938,940,942],{"class":83,"line":931},19,[81,933,865],{"class":87},[81,935,264],{"class":91},[81,937,340],{"class":131},[81,939,270],{"class":91},[81,941,345],{"class":98},[81,943,162],{"class":91},[81,945,947],{"class":83,"line":946},20,[81,948,109],{"emptyLinePlaceholder":108},[81,950,952],{"class":83,"line":951},21,[81,953,954],{"class":409},"    \u002F\u002F Collect invoice links\n",[81,956,958,960,962,964,966,968],{"class":83,"line":957},22,[81,959,865],{"class":87},[81,961,264],{"class":91},[81,963,267],{"class":131},[81,965,270],{"class":91},[81,967,374],{"class":98},[81,969,162],{"class":91},[81,971,973,975,977,979,981,983,985,987,990,993,995,997],{"class":83,"line":972},23,[81,974,805],{"class":87},[81,976,387],{"class":118},[81,978,122],{"class":87},[81,980,125],{"class":87},[81,982,264],{"class":91},[81,984,396],{"class":131},[81,986,270],{"class":91},[81,988,989],{"class":98},"\"a[href$='.pdf']\"",[81,991,992],{"class":91},", (",[81,994,419],{"class":418},[81,996,422],{"class":91},[81,998,999],{"class":87},"=>\n",[81,1001,1003,1006,1008,1010,1012,1014,1016],{"class":83,"line":1002},24,[81,1004,1005],{"class":91},"      anchors.",[81,1007,431],{"class":131},[81,1009,434],{"class":91},[81,1011,40],{"class":418},[81,1013,422],{"class":91},[81,1015,425],{"class":87},[81,1017,443],{"class":91},[81,1019,1021],{"class":83,"line":1020},25,[81,1022,1023],{"class":91},"    );\n",[81,1025,1027,1030,1032,1034,1036,1038,1040,1042,1044],{"class":83,"line":1026},26,[81,1028,1029],{"class":91},"    console.",[81,1031,459],{"class":131},[81,1033,270],{"class":91},[81,1035,464],{"class":98},[81,1037,467],{"class":91},[81,1039,35],{"class":98},[81,1041,472],{"class":118},[81,1043,475],{"class":98},[81,1045,162],{"class":91},[81,1047,1049],{"class":83,"line":1048},27,[81,1050,109],{"emptyLinePlaceholder":108},[81,1052,1054],{"class":83,"line":1053},28,[81,1055,1056],{"class":409},"    \u002F\u002F Download each PDF using the signed-in session\n",[81,1058,1060,1063,1065,1067,1069,1071],{"class":83,"line":1059},29,[81,1061,1062],{"class":131},"    mkdirSync",[81,1064,270],{"class":91},[81,1066,533],{"class":98},[81,1068,536],{"class":91},[81,1070,539],{"class":118},[81,1072,542],{"class":91},[81,1074,1076,1079,1081,1083,1085,1087],{"class":83,"line":1075},30,[81,1077,1078],{"class":87},"    for",[81,1080,554],{"class":91},[81,1082,115],{"class":87},[81,1084,559],{"class":118},[81,1086,562],{"class":87},[81,1088,565],{"class":91},[81,1090,1092,1095,1097,1099,1101,1103,1105],{"class":83,"line":1091},31,[81,1093,1094],{"class":87},"      const",[81,1096,573],{"class":118},[81,1098,122],{"class":87},[81,1100,125],{"class":87},[81,1102,580],{"class":91},[81,1104,583],{"class":131},[81,1106,586],{"class":91},[81,1108,1110,1112,1114,1116,1118,1120,1122,1124,1126,1128,1130,1132,1134,1136,1138],{"class":83,"line":1109},32,[81,1111,1094],{"class":87},[81,1113,593],{"class":118},[81,1115,122],{"class":87},[81,1117,598],{"class":98},[81,1119,601],{"class":131},[81,1121,270],{"class":98},[81,1123,606],{"class":87},[81,1125,609],{"class":131},[81,1127,270],{"class":98},[81,1129,614],{"class":91},[81,1131,617],{"class":98},[81,1133,620],{"class":91},[81,1135,623],{"class":98},[81,1137,626],{"class":98},[81,1139,102],{"class":91},[81,1141,1143,1146,1148,1150,1152,1154],{"class":83,"line":1142},33,[81,1144,1145],{"class":131},"      writeFileSync",[81,1147,637],{"class":91},[81,1149,261],{"class":87},[81,1151,642],{"class":91},[81,1153,645],{"class":131},[81,1155,648],{"class":91},[81,1157,1159,1162,1164,1166,1168,1170,1172],{"class":83,"line":1158},34,[81,1160,1161],{"class":91},"      console.",[81,1163,459],{"class":131},[81,1165,270],{"class":91},[81,1167,661],{"class":98},[81,1169,664],{"class":91},[81,1171,626],{"class":98},[81,1173,162],{"class":91},[81,1175,1177],{"class":83,"line":1176},35,[81,1178,1179],{"class":91},"    }\n",[81,1181,1183,1186,1189],{"class":83,"line":1182},36,[81,1184,1185],{"class":91},"  } ",[81,1187,1188],{"class":87},"finally",[81,1190,800],{"class":91},[81,1192,1194,1196,1198,1201],{"class":83,"line":1193},37,[81,1195,865],{"class":87},[81,1197,180],{"class":91},[81,1199,1200],{"class":131},"close",[81,1202,228],{"class":91},[81,1204,1206],{"class":83,"line":1205},38,[81,1207,1208],{"class":91},"  }\n",[81,1210,1212],{"class":83,"line":1211},39,[81,1213,674],{"class":91},[81,1215,1217],{"class":83,"line":1216},40,[81,1218,109],{"emptyLinePlaceholder":108},[81,1220,1222,1225],{"class":83,"line":1221},41,[81,1223,1224],{"class":131},"run",[81,1226,228],{"class":91},[10,1228,1229,1230,35],{},"Run it with ",[32,1231,1232],{},"node download-invoices.js",[14,1234,1236],{"id":1235},"next-steps","Next steps",[19,1238],{},[22,1240,1241,1244,1250],{},[25,1242,1243],{},"Handle pagination: if invoices span several pages, wrap the collect step in a loop that clicks Next until it disappears, gathering links as you go.",[25,1245,1246,1247,35],{},"Speed up navigation by blocking heavy resources: ",[32,1248,1249],{},"await page.route(\"**\u002F*\", (route) => [\"image\", \"media\", \"font\"].includes(route.request().resourceType()) ? route.abort() : route.continue());",[25,1251,1252,1253,1257],{},"Read the ",[40,1254,1256],{"href":1255},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fcdp","Chrome API"," guide for other connection options.",[1259,1260,1261],"style",{},"html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}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 .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}",{"title":77,"searchDepth":112,"depth":112,"links":1263},[1264,1265,1266,1267,1268,1269,1270],{"id":16,"depth":105,"text":17},{"id":64,"depth":105,"text":65},{"id":245,"depth":105,"text":246},{"id":350,"depth":105,"text":351},{"id":480,"depth":105,"text":481},{"id":688,"depth":105,"text":689},{"id":1235,"depth":105,"text":1236},null,"Connect Playwright to the axiom.ai Chrome API, sign in to a portal, loop over the invoice links, and save each PDF to disk from your own stack.","md",{"metaTitle":1275,"type":32,"format":1276,"intent_type":1277,"intent":1278,"tags":1279,"platfrom":1284,"pinned":108},"Bulk-download files with the Axiom Chrome API","guide","workflow","Upload and download files",[1280,1281,1282,1283],"files","reporting","downloads","claude code",[1277],"\u002Fguides\u002Fdownload-files-using-axiom-chrome-api",{"title":5,"description":1272},"guides\u002Fdownload-files-using-axiom-chrome-api","1R_URxNQQtJYbhYXUNMx8CtH9tbyKrw14r13RV_5ibc",{"id":4,"title":5,"body":6,"date":1271,"description":1272,"extension":1273,"meta":1274,"navigation":108,"order":1271,"path":1285,"seo":1286,"stem":1287,"__hash__":1288,"metaTitle":1275,"type":32,"format":1276,"intent_type":1277,"intent":1278,"tags":1279,"platfrom":1284,"pinned":108},1784824788129]