[{"data":1,"prerenderedAt":2371},["ShallowReactive",2],{"content-\u002Fguides\u002Fdrop-a-scraper-in-your-code":3,"content-doc-\u002Fguides\u002Fdrop-a-scraper-in-your-code-inline":535,"search-dialog-corpus":536,"search-dialog-default-links":2369,"pinned-blogs":2370},{"id":4,"title":5,"body":6,"date":515,"description":516,"extension":517,"meta":518,"navigation":87,"order":530,"path":531,"seo":532,"stem":533,"__hash__":534},"guides\u002Fguides\u002Fdrop-a-scraper-in-your-code.md","The simplest way to scrape a page from your own code",{"type":7,"value":8,"toc":510},"minimark",[9,12,38,43,435,454,475,479,482,486,506],[10,11],"hr",{},[13,14,15,16,20,21,26,27,30,31,30,34,37],"p",{},"This guide drops a scraper straight into your Node code: one ",[17,18,19],"code",{},"axiom.scrape()"," call, structured rows back, no server to stand up. The scrape runs against a real Chromium on the ",[22,23,25],"a",{"href":24},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions","Step API"," — same SDK gives you ",[17,28,29],{},"axiom.enterText",", ",[17,32,33],{},"axiom.click",[17,35,36],{},"axiom.goto",", and the rest of the step library, so logging in before a scrape, walking pagination, or filling a form on the way through is the same shape of code. Point the SDK at a local CDP endpoint instead of the cloud and the exact same calls drive your own browser. No Puppeteer wiring, no container ops, no separate scraping service to maintain.",[39,40,42],"h2",{"id":41},"the-whole-thing","The whole thing",[44,45,50],"pre",{"className":46,"code":47,"language":48,"meta":49,"style":49},"language-javascript shiki shiki-themes github-light-default github-dark-default","\u002F\u002F npm install @axiom_ai\u002Fapi\nimport { AxiomApi } from '@axiom_ai\u002Fapi';\n\nconst API_KEY = \"eyJ1c2VyX2lkIjoyMzI5LCJ0b2tlbiI6IjIzMjkyNjlmY2EwNDlhY2Q0MThkIn0=\";   \u002F\u002F paste your key here\nconst axiom = new AxiomApi(API_KEY);\n\nasync function scrapeWebsite() {\n  await axiom.browserOpen();\n  try {\n\n    \u002F\u002F scrape() returns a 2D array: rows × fields\n    const rows = await axiom.scrape(\n      \"https:\u002F\u002Fbbc.com\", \u002F\u002F scrape() navigates here itself (url is required)\n      \"a\",              \u002F\u002F record selector\n      null,             \u002F\u002F no pagination\n      50,               \u002F\u002F max results\n      {}                \u002F\u002F default settings\n    );\n\n    return rows;        \u002F\u002F hand the data back to your code\n  } finally {\n    await axiom.browserClose();\n  }\n}\n\n\u002F\u002F now it's just data in your app, use it however you like\nconst scrapedData = await scrapeWebsite();\n\nconsole.log(scrapedData);\n\u002F\u002F 2D array, rows × fields:\n\u002F\u002F [\n\u002F\u002F   [\"Headline A\"],\n\u002F\u002F   [\"Headline B\"],\n\u002F\u002F ]\n\nconst firstRow = scrapedData[0][0];   \u002F\u002F first scraped value\n","javascript","",[17,51,52,61,82,89,111,137,142,157,172,181,186,192,214,225,237,249,261,270,276,281,293,304,317,323,329,334,340,356,361,373,379,385,391,397,403,408],{"__ignoreMap":49},[53,54,57],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sU953","\u002F\u002F npm install @axiom_ai\u002Fapi\n",[53,62,64,68,72,75,79],{"class":55,"line":63},2,[53,65,67],{"class":66},"sjeE4","import",[53,69,71],{"class":70},"s4rv2"," { AxiomApi } ",[53,73,74],{"class":66},"from",[53,76,78],{"class":77},"sSVrQ"," '@axiom_ai\u002Fapi'",[53,80,81],{"class":70},";\n",[53,83,85],{"class":55,"line":84},3,[53,86,88],{"emptyLinePlaceholder":87},true,"\n",[53,90,92,95,99,102,105,108],{"class":55,"line":91},4,[53,93,94],{"class":66},"const",[53,96,98],{"class":97},"sHrmB"," API_KEY",[53,100,101],{"class":66}," =",[53,103,104],{"class":77}," \"eyJ1c2VyX2lkIjoyMzI5LCJ0b2tlbiI6IjIzMjkyNjlmY2EwNDlhY2Q0MThkIn0=\"",[53,106,107],{"class":70},";   ",[53,109,110],{"class":59},"\u002F\u002F paste your key here\n",[53,112,114,116,119,121,124,128,131,134],{"class":55,"line":113},5,[53,115,94],{"class":66},[53,117,118],{"class":97}," axiom",[53,120,101],{"class":66},[53,122,123],{"class":66}," new",[53,125,127],{"class":126},"sbjLL"," AxiomApi",[53,129,130],{"class":70},"(",[53,132,133],{"class":97},"API_KEY",[53,135,136],{"class":70},");\n",[53,138,140],{"class":55,"line":139},6,[53,141,88],{"emptyLinePlaceholder":87},[53,143,145,148,151,154],{"class":55,"line":144},7,[53,146,147],{"class":66},"async",[53,149,150],{"class":66}," function",[53,152,153],{"class":126}," scrapeWebsite",[53,155,156],{"class":70},"() {\n",[53,158,160,163,166,169],{"class":55,"line":159},8,[53,161,162],{"class":66},"  await",[53,164,165],{"class":70}," axiom.",[53,167,168],{"class":126},"browserOpen",[53,170,171],{"class":70},"();\n",[53,173,175,178],{"class":55,"line":174},9,[53,176,177],{"class":66},"  try",[53,179,180],{"class":70}," {\n",[53,182,184],{"class":55,"line":183},10,[53,185,88],{"emptyLinePlaceholder":87},[53,187,189],{"class":55,"line":188},11,[53,190,191],{"class":59},"    \u002F\u002F scrape() returns a 2D array: rows × fields\n",[53,193,195,198,201,203,206,208,211],{"class":55,"line":194},12,[53,196,197],{"class":66},"    const",[53,199,200],{"class":97}," rows",[53,202,101],{"class":66},[53,204,205],{"class":66}," await",[53,207,165],{"class":70},[53,209,210],{"class":126},"scrape",[53,212,213],{"class":70},"(\n",[53,215,217,220,222],{"class":55,"line":216},13,[53,218,219],{"class":77},"      \"https:\u002F\u002Fbbc.com\"",[53,221,30],{"class":70},[53,223,224],{"class":59},"\u002F\u002F scrape() navigates here itself (url is required)\n",[53,226,228,231,234],{"class":55,"line":227},14,[53,229,230],{"class":77},"      \"a\"",[53,232,233],{"class":70},",              ",[53,235,236],{"class":59},"\u002F\u002F record selector\n",[53,238,240,243,246],{"class":55,"line":239},15,[53,241,242],{"class":97},"      null",[53,244,245],{"class":70},",             ",[53,247,248],{"class":59},"\u002F\u002F no pagination\n",[53,250,252,255,258],{"class":55,"line":251},16,[53,253,254],{"class":97},"      50",[53,256,257],{"class":70},",               ",[53,259,260],{"class":59},"\u002F\u002F max results\n",[53,262,264,267],{"class":55,"line":263},17,[53,265,266],{"class":70},"      {}                ",[53,268,269],{"class":59},"\u002F\u002F default settings\n",[53,271,273],{"class":55,"line":272},18,[53,274,275],{"class":70},"    );\n",[53,277,279],{"class":55,"line":278},19,[53,280,88],{"emptyLinePlaceholder":87},[53,282,284,287,290],{"class":55,"line":283},20,[53,285,286],{"class":66},"    return",[53,288,289],{"class":70}," rows;        ",[53,291,292],{"class":59},"\u002F\u002F hand the data back to your code\n",[53,294,296,299,302],{"class":55,"line":295},21,[53,297,298],{"class":70},"  } ",[53,300,301],{"class":66},"finally",[53,303,180],{"class":70},[53,305,307,310,312,315],{"class":55,"line":306},22,[53,308,309],{"class":66},"    await",[53,311,165],{"class":70},[53,313,314],{"class":126},"browserClose",[53,316,171],{"class":70},[53,318,320],{"class":55,"line":319},23,[53,321,322],{"class":70},"  }\n",[53,324,326],{"class":55,"line":325},24,[53,327,328],{"class":70},"}\n",[53,330,332],{"class":55,"line":331},25,[53,333,88],{"emptyLinePlaceholder":87},[53,335,337],{"class":55,"line":336},26,[53,338,339],{"class":59},"\u002F\u002F now it's just data in your app, use it however you like\n",[53,341,343,345,348,350,352,354],{"class":55,"line":342},27,[53,344,94],{"class":66},[53,346,347],{"class":97}," scrapedData",[53,349,101],{"class":66},[53,351,205],{"class":66},[53,353,153],{"class":126},[53,355,171],{"class":70},[53,357,359],{"class":55,"line":358},28,[53,360,88],{"emptyLinePlaceholder":87},[53,362,364,367,370],{"class":55,"line":363},29,[53,365,366],{"class":70},"console.",[53,368,369],{"class":126},"log",[53,371,372],{"class":70},"(scrapedData);\n",[53,374,376],{"class":55,"line":375},30,[53,377,378],{"class":59},"\u002F\u002F 2D array, rows × fields:\n",[53,380,382],{"class":55,"line":381},31,[53,383,384],{"class":59},"\u002F\u002F [\n",[53,386,388],{"class":55,"line":387},32,[53,389,390],{"class":59},"\u002F\u002F   [\"Headline A\"],\n",[53,392,394],{"class":55,"line":393},33,[53,395,396],{"class":59},"\u002F\u002F   [\"Headline B\"],\n",[53,398,400],{"class":55,"line":399},34,[53,401,402],{"class":59},"\u002F\u002F ]\n",[53,404,406],{"class":55,"line":405},35,[53,407,88],{"emptyLinePlaceholder":87},[53,409,411,413,416,418,421,424,427,429,432],{"class":55,"line":410},36,[53,412,94],{"class":66},[53,414,415],{"class":97}," firstRow",[53,417,101],{"class":66},[53,419,420],{"class":70}," scrapedData[",[53,422,423],{"class":97},"0",[53,425,426],{"class":70},"][",[53,428,423],{"class":97},[53,430,431],{"class":70},"];   ",[53,433,434],{"class":59},"\u002F\u002F first scraped value\n",[13,436,437,438,441,442,445,446,449,450,453],{},"Open a session, call ",[17,439,440],{},"scrape()"," with the URL you want, and it navigates there and pulls the records. It returns a 2D array, rows by fields, straight into ",[17,443,444],{},"rows",". You hand that back out of the function, and now ",[17,447,448],{},"products"," is plain data sitting in your code: index into it (",[17,451,452],{},"products[0][1]","), map over it, save it, whatever your app needs. Close the session when you're done.",[13,455,456,457,30,460,463,464,467,468,471,472,474],{},"Need to log in or click something first? Run ",[17,458,459],{},"goto()",[17,461,462],{},"enterText()",", and ",[17,465,466],{},"click()"," before the scrape, then pass ",[17,469,470],{},"null"," as the URL so ",[17,473,440],{}," reads the page you're already on.",[39,476,478],{"id":477},"why-its-the-easy-path","Why it's the easy path",[13,480,481],{},"The scrape runs on axiom.ai's infrastructure, so there's no Chromium to install and no Puppeteer to wire up. And because it's just a call inside your code, it goes wherever your code goes: a backend route, a worker, a cron script, a CLI, whatever you're building. Add the step, call the API, use the data.",[39,483,485],{"id":484},"keep-three-things-right","Keep three things right",[487,488,489,500,503],"ul",{},[490,491,492,493,496,497,499],"li",{},"Always ",[17,494,495],{},"browserClose()"," in a ",[17,498,301],{},". An open session keeps burning runtime.",[490,501,502],{},"Keep your API key in the environment, not in the source.",[490,504,505],{},"Grab selectors from the No-Code Tool's selector tool instead of hand-writing them.",[507,508,509],"style",{},"html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}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);}",{"title":49,"searchDepth":84,"depth":84,"links":511},[512,513,514],{"id":41,"depth":63,"text":42},{"id":477,"depth":63,"text":478},{"id":484,"depth":63,"text":485},"2026-06-16","Scrape any web page in a few lines of Node with the axiom.ai API. The scrape runs in the cloud and hands structured data straight back into your code.","md",{"pinned":87,"application":519,"read":520,"level":521,"video":522,"type":17,"format":523,"intent_type":524,"intent":525,"tags":526,"platfrom":529},"Any","1 minutes","Easy","https:\u002F\u002Fwww.youtube.com\u002Fembed\u002Fdl1BVUWix1Q","guide","workflow","Extract data from websites",[527,528],"scraping","csv",[519],null,"\u002Fguides\u002Fdrop-a-scraper-in-your-code",{"title":5,"description":516},"guides\u002Fdrop-a-scraper-in-your-code","20oKjOFbj2hJLaYnl-ACOjnebrrQK91gkJIFzxwfOm8",{"id":4,"title":5,"body":6,"date":515,"description":516,"extension":517,"meta":518,"navigation":87,"order":530,"path":531,"seo":532,"stem":533,"__hash__":534,"pinned":87,"application":519,"read":520,"level":521,"video":522,"type":17,"format":523,"intent_type":524,"intent":525,"tags":526,"platfrom":529},[537,542,547,552,557,562,567,571,576,581,586,591,596,601,606,610,615,620,625,630,635,640,645,650,655,660,665,670,675,680,685,690,695,700,705,710,715,720,725,730,735,740,745,750,755,760,765,770,775,780,785,790,795,800,805,810,815,820,825,830,835,840,845,850,855,860,863,868,873,878,883,888,893,898,903,908,913,918,923,928,933,938,943,948,953,958,963,968,973,978,983,988,993,998,1003,1008,1013,1017,1021,1026,1031,1036,1041,1046,1051,1056,1061,1066,1071,1076,1080,1085,1090,1095,1100,1105,1110,1115,1120,1125,1130,1135,1140,1145,1150,1155,1160,1165,1170,1175,1180,1185,1190,1195,1200,1205,1210,1215,1220,1225,1230,1235,1239,1244,1249,1254,1259,1264,1269,1274,1279,1284,1289,1294,1299,1304,1309,1314,1319,1324,1329,1334,1339,1344,1349,1352,1357,1362,1367,1372,1377,1382,1387,1392,1397,1402,1407,1412,1417,1422,1427,1432,1436,1441,1446,1451,1456,1461,1466,1471,1476,1481,1486,1491,1496,1501,1506,1511,1516,1521,1526,1531,1536,1541,1545,1550,1555,1560,1565,1570,1575,1580,1585,1590,1595,1600,1605,1610,1615,1620,1625,1630,1635,1640,1645,1650,1655,1660,1665,1670,1675,1680,1685,1690,1695,1700,1705,1710,1715,1720,1725,1730,1735,1740,1745,1750,1755,1760,1765,1769,1774,1779,1784,1789,1794,1799,1804,1809,1814,1819,1824,1829,1834,1839,1844,1849,1854,1859,1864,1868,1873,1878,1883,1888,1893,1898,1903,1908,1913,1918,1923,1928,1933,1938,1943,1948,1953,1958,1963,1968,1973,1978,1983,1988,1993,1998,2003,2008,2013,2018,2023,2028,2033,2038,2043,2048,2053,2058,2063,2067,2072,2077,2082,2087,2092,2097,2102,2107,2112,2117,2122,2127,2132,2137,2142,2147,2152,2156,2161,2166,2171,2176,2181,2186,2191,2196,2201,2206,2211,2216,2221,2226,2231,2236,2241,2246,2251,2256,2261,2266,2271,2276,2281,2286,2291,2296,2301,2306,2311,2315,2319,2324,2329,2334,2339,2344,2349,2354,2359,2364],{"id":538,"title":539,"titles":540,"content":541,"level":56},"\u002F_about","About axciom ai",[],"Build and run browser bots to automate website actions and repetitive tasks on any website or web application. Our storySimply point and click on the data you wish to scrape. You can extract different types of data, including HTML, text, links, and images.Our built-in pattern recognition algorithms help group related elements.\nEasily pass your data through other steps, from applying filters to removing or replacing strings to outputting data to Google Sheets.",{"id":543,"title":544,"titles":545,"content":546,"level":56},"\u002F_components","A list of available compoenents and there variables",[],"Build a web page Web componentsComponent-based pages have no built-in layout, by design — this lets components set full-width backgrounds or isometric grids. Each component handles its own content width.Blog and docs pages are exceptions and use a default layout. Hero left Hero Primary page heroPass in a value to set background and vh of the component {minVh=\"50\" class=\"gray\"}. Secondary page 2 col heroPass in a value to set background and vh of the component {minVh=\"50\" class=\"gray\"}. Get data Point and click web scraperAI Extract data or generate text with LLMsWeb actions Click buttons, interact with UILooping and logic Click buttons, interact with UIFilters Proxies and IP rotationFiles Upload and download filesWebhooks Send and receive datadebugging Upload and download filesIntergrations Get past turnstile Code heroPass in a value to set background and vh of the component {minVh=\"50\" class=\"gray\"}. Content Vertical card gridPass in a value to set background and vh of the component {class=\"gray\"}. box gridPass in a value to set background and vh of the component {class=\"gray\"}. Code hero{:showDefaultLogos=\"false\"} - Pass in a value to set background and vh of the component {class=\"gray\"}. Feature listPass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. Feature gridSet grid, solid or transparent. Pass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. FAQPass in data to set. Pass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. Cross linksVary amount of links. Pass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. Integrations Scroll block Fixed content Privacy Pricing Isometric content three col cubesPass in a value to cards and isometric shapes used also set bg {class=\"gray-to-white py-16\"}. Two col cubesPass in a value to cards and isometric shapes used also set bg {class=\"gray-to-white py-16\"}. Social proof Chrome reviewsPass in a value to set baground and spacing on this component {class=\"gray-to-white py-16\"}. Customer QuotePass in text to set the qoute. Pass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. Data Data BarPass in data. Pass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. CTA's Main CTA blockPass in data. Pass in a value to set background and spacing on this component {class=\"gray-to-white py-16\"}. CTA panelPass in data. Pass in a value to set background and spacing on this component {class=\"gray\" ctaBgColor=\"bg-white\"}. Cannot find the guide you need?Inspire us with a great idea if possible we will make a guide showing you how and share it with you. We will also publish it on our website.Get Started",{"id":548,"title":549,"titles":550,"content":551,"level":56},"\u002F_code-dashboard","Code Dashboard for browser automations",[],"Write and run browser automations in code with the axiom.ai code dashboard. Use Puppeteer, Playwright, or Python; trigger runs via API.",{"id":553,"title":554,"titles":555,"content":556,"level":56},"\u002F_integrations\u002F2captcha","Integrate your browser automations with 2Captcha",[],"Automatically solve CAPTCHAs on any webpage using 2Captcha during your bot runs. reCAPTCHA v2 to ZapierreCAPTCHA v3 from ZapierInvisible reCAPTCHA using ZapierUse own 2Captcha key\" from your bot Easily connect your browser automations to a captcha solving service. Simply search for and add the \"Solve Captcha\" step, in your browser automation.\n  With this integration, you can solve a range of captcha using the 2Captcha API, you will need to register for a 2Captcha account and there is a small charge per captcha successfully solved. \n  Learn more about solving Captcha with 2Captcha.",{"id":558,"title":559,"titles":560,"content":561,"level":56},"\u002F_integrations\u002Fexcel","Excel",[],"Use our Microsoft Excel steps to read and write sheet data directly from your automation. Read specific ranges with first\u002Flast cell settings, then write results back using add to next row or clear before write options.\n  \n  Learn more about our Microsoft Excel integration With axiom.ai, you can combine the power of our Microsoft Excel integration and browser automation to create seamless, end-to-end workflows. Whether you're extracting data from websites or sending it to Excel, axiom.ai can help your workflow. Select the step you need from our library of steps, configure your sheet and options in seconds, its as simple as that. Steps can be used in combination with others to create more complex workflows. To access your Excel spreadsheets for reading, writing, and editing, we request access to your Excel work or school accounts. However, we do not access any Excel data outside of the extension. Data is only accessed when an Excel file, worksheet, or table is interacted with by a step. Even then, the information is processed in real time; no data is duplicated or extracted for later use by us or any third parties. No AI is running on your data, and your information is never used for training any AI models.",{"id":563,"title":564,"titles":565,"content":566,"level":56},"\u002F_integrations\u002Fgoogle-sheets","Intergrate Google sheets with your browser automations",[],"Directly connect your Google Sheets to your browser automations to read, write, and delete data. Select a Google Sheets step from our library of steps that suits your needs - read, write or edit rows within your Google Sheet, directly from your automation. Configure your steps to only use the rows you need.\n  \n  Learn more about our integration with Google Sheets. With axiom.ai, you can combine the power of our Google Sheets integration and browser automation to create seamless, end-to-end workflows. Whether you're extracting data from websites or sending it to Google Sheets, axiom.ai can help your workflow. Select the step you need from our library of steps, configure your sheet and options in seconds, its as simple as that. Steps can be used in combination with others to create more complex workflows. To access your Google Sheets for reading, writing, and editing, we request access to your Google Sheets. However, we do not access any Google Sheets data outside of the extension. Data is only accessed when a Google Sheet is interacted with by a step. Even then, the data is processed in real-time; no data is duplicated or extracted for later use by us or any third parties. axiom.ai's Google authentication processes are audited yearly and certified as correctly implemented and secure.",{"id":568,"title":569,"titles":570,"content":49,"level":56},"\u002F_integrations","The axiom.ai runner",[],{"id":572,"title":573,"titles":574,"content":575,"level":56},"\u002F_integrations\u002Fzap","Integrate your browser automations and web scrapers with Zapier in Chrome.",[],"See how you can use Zapier to connect axiom.ai to thousands of other web applications. Post data to ZapierReceive data from ZapierTrigger bot runs using ZapierTrigger Zaps from your bot Connect your Zaps to your axiom.ai automations and send data directly from Zapier to axiom.ai. Add the axiom.ai app in Zapier to get started, then include the trigger webhook step in your axiom.ai automation.\n  Trigger axiom.ai workflows from Zapier while accessing data from any of the 7,000+ services that Zapier supports. \n  Learn how to send data from Zapier. Connect the data you extract from websites to your Zaps using axiom.ai. Use the trigger webhook step to post the scraped data to Zapier. In your Zap, add the \"Webhooks by Zapier\" trigger, then configure it with your axiom.ai API key and endpoint. This allows you to send data to Zapier, such as data from scrape steps. \n  To further process the data, you can use additional actions such as \"Formatter by Zapier\" to parse it.\n  Learn how to send data from axiom.ai to Zapier. Unlock the full potential of your workflows by combining API and browser automation with axiom.ai and Zapier. Automate browser tasks that interact with websites while seamlessly integrating data from over 7,000 apps via Zapier's integration library. Fast to build. Easy to run and scale. Outstanding support.(https:\u002F\u002Fchromewebstore.google.com\u002Fdetail\u002Faxiom-browser-automation\u002Fcpgamigjcbffkaiciiepndmonbfdimbb){class=\"button primary\"}",{"id":577,"title":578,"titles":579,"content":580,"level":56},"\u002F_signup","Get started",[],"Pick your path: install the Chrome extension for no-code automations, open the Code Dashboard for code-first runs, or use our Claude skill to build with AI.",{"id":582,"title":583,"titles":584,"content":585,"level":56},"\u002Faffiliate-program","Affiliate program",[],"Earn 15% commission on every referral payment for the lifetime of their subscription. Join the axiom.ai affiliate program. Join our affiliate program.\n  Earn 15% commission for every payment by your referrals, for an entire subscription's lifetime!\n  \n    \n      Join program\n    \n    \n      Login Program benefits\n        \n          check 15% commission\n          check Monthly payments for a subscription's lifetime\n          check Payments via PayPal\n          check A Slack Channel for support\n          check A Dashboard to track leads & commission\n        \n      \n    \n    \n      How it works\n      \n        Once you register using our affiliate portal, you will receive a unique referral link. Share this link on social media, and you can see the number of clicks and signups in your dashboard.\n      \n      If a user signs up, you'll receive 15% of their payments for a subscription's entire lifetime.\n      Payments are made monthly via PayPal, so you'll need a PayPal account.",{"id":587,"title":588,"titles":589,"content":590,"level":56},"\u002Fai-assistant","Connect browser automation to Claude, ChatGPT, Gemini, and more | axiom.ai",[],"Plug Claude, ChatGPT, Gemini, Grok, DeepSeek, or Perplexity Sonar into a bot to extract data and generate text on the fly. ::",{"id":592,"title":593,"titles":594,"content":595,"level":56},"\u002Fbuild-in-claude","Build browser automations with Claude",[],"Describe a bot in plain English. Claude builds, configures, and runs it on your axiom infrastructure. Edit later in the visual builder or as Puppeteer code.",{"id":597,"title":598,"titles":599,"content":600,"level":56},"\u002Fbuild-with-code","Build browser automations with code",[],"Connect Puppeteer, Playwright, or any CDP-speaking library to axiom. Run browsers on our cloud straight from your stack with no servers to manage and no Chrome to install.",{"id":602,"title":603,"titles":604,"content":605,"level":56},"\u002Fbuild-with-no-code\u002Fclaude","Build in Claude Code",[],"A guided skill builds your no-code bot through a few questions. Export the workflow and upload it straight into the extension, then run it. No code, no manual setup.",{"id":607,"title":608,"titles":609,"content":600,"level":56},"\u002Fbuild-with-no-code\u002Fdescription","Build with code",[],{"id":611,"title":612,"titles":613,"content":614,"level":56},"\u002Fbuild-with-no-code","Build no-code browser bots by describing them to AI",[],"Describe what you want in plain English and AI assembles the bot for you. Review, run, and schedule it inside the Chrome extension. No code, no setup.",{"id":616,"title":617,"titles":618,"content":619,"level":56},"\u002Fbuild-with-no-code\u002Fstep-by-step","Build no-code bots step by step",[],"Place each action yourself in the axiom.ai visual builder. Total control, no code, right inside your Chrome extension. Free to start.",{"id":621,"title":622,"titles":623,"content":624,"level":56},"\u002Fcustomer-support","Customer support — docs, AI help, or talk to a human",[],"Stuck on a browser automation? Search the docs, use our Claude skill, or talk to a human. UK office hours, real humans, Monday to Friday.",{"id":626,"title":627,"titles":628,"content":629,"level":56},"\u002Fdocs\u002Faccount\u002Faccount","Manage your account",[],"Update your axiom.ai email, password, company information, country, and team membership, or delete your account permanently. Open the axiom.ai extension, go to the dashboard, and click the burger menu in the top-right. Select My account to open your account settings. Set up a team account A team account shares a single subscription and runtime allocation between everyone in the team. Team accounts are available on the Ultimate plan only, and we set them up manually within 1 to 2 business days of receiving the request. To request a team account: Click Account in the main menu, accessed from the top-left of the dashboard.In the Typeform, enter the email address of every account you want included in the team plan.Click Submit. A team will be in touch within 1 to 2 business days to finish the setup. Change email Click Account in the main menu, accessed from the top-left of the dashboard.Click Email & password.Replace the value in Email with the new email address.Click Update account. Change password Click Account in the main menu, accessed from the top-left of the dashboard.Click Email & password.Enter your existing password in Current password.Enter your new password in New password.Re-enter the new password in Retype new password. This must match New password exactly.Click Change password. Change company name and role Click Account in the main menu, accessed from the top-left of the dashboard.Enter the new value in Enter company name.Enter the new value in Enter company role.Click Update account. Change your country Click Account in the right-side menu.Select your country from Select country.Click Update account. Delete your account Warning: Account deletion is permanent. Once an account is deleted, it can't be recovered. If you have an active plan, unsubscribe first.Click Delete my account.",{"id":631,"title":632,"titles":633,"content":634,"level":56},"\u002Fdocs\u002Faccount\u002Fcreate-account","Create an account",[],"Create an axiom.ai account with Google or an email address to get 120 minutes of free runtime to start building automations. Every new account gets 120 minutes of free runtime. Open the axiom.ai Chrome extension to get started. The extension prompts you to either create a new account or sign in to an existing one. You can sign up with a Google account, or with an email address and password. Sign up with Google Click Sign up with Google to use a Google account to create your axiom.ai account. This is the quickest option, and Google handles the password and security side. Follow the prompts in the Google sign-in window to finish. Sign up with email and password Click the email sign-up option and follow the prompts to enter your details. When you're done, click Get started. Tip: For advice on choosing a strong password, see CISA's Use Strong Passwords guidance.",{"id":636,"title":637,"titles":638,"content":639,"level":56},"\u002Fdocs\u002Faccount","Account",[],"Create an account to get 120 minutes of free runtime, manage account settings from the dashboard, and manage your subscription, billing, and invoices. New to axiom.ai? Create an account and get 120 minutes of free runtime. Once you're up and running, manage your account settings from the dashboard, or manage your subscription to upgrade your plan, add more runtime, or download invoices. Account pages Start with creating an account if you haven't already. Move on to managing your account for changes to email, password, company details, country, team membership, or account deletion. Use the subscription page to change plan, update payment details, or download invoices. Need help? Contact support or ask a question in our Reddit community.",{"id":641,"title":642,"titles":643,"content":644,"level":56},"\u002Fdocs\u002Faccount\u002Fsubscription","Manage your subscription",[],"Change plan, update payment method and billing details, and download invoices from the Stripe payment portal connected to your axiom.ai account. Manage your axiom.ai subscription to upgrade your plan, add runtime, update billing details, or download invoices. For account settings outside billing, see manage your account. Change your plan Open the axiom.ai Chrome extension and navigate to the Change plan section. The Change plan section shows every plan we offer. Click Change plan on the plan you want to switch to. Manage billing in the payment portal Update your payment method, billing information, and download invoices from the payment portal. The portal is provided by Stripe, our payment partner. To open the portal, follow the payment portal link and enter the email address you used to create your axiom.ai account. Stripe sends a one-time link to that address; click the link in the email to enter the portal. Update your payment method You can add or update payment methods on your account at any time. In the payment portal, click Add payment method.Choose Card or Google Pay.Click Add. Note: If you'd prefer to pay by invoice, contact support@axiom.ai. Update your billing information Update your billing information at any time. This is useful for changes to billing name, address, or VAT details. In the payment portal, click Update information.Edit the fields you need to change.Click Save. Download invoices Past invoices and receipts are available in the payment portal. In the payment portal, find the Invoice history section.Click the date of the invoice you want.Click Download to download the invoice, the receipt, or both.",{"id":646,"title":647,"titles":648,"content":649,"level":56},"\u002Fdocs\u002Fcode\u002Fcreate-scripts","Create scripts",[],"Write Puppeteer scripts in your local environment and connect them to axiom.ai's hosted browser using your API key. Write Puppeteer scripts in your own local environment, then connect them to axiom.ai's hosted browser through a single WebSocket endpoint. This lets you develop and version scripts however you like (your editor, your linters, your AI tooling) and run them on infrastructure that doesn't need any local browser setup. Set up Puppeteer locally Write your script the same way you would with Puppeteer anywhere else. If you're running locally, install Puppeteer in your project: npm i puppeteer Note: If you're testing in the Live editor, you don't need to install Puppeteer. The Live editor includes it by default. Connect to axiom.ai Use puppeteer.connect with axiom.ai's WebSocket endpoint. Generate your API key first; see generate an API key. const browser = await puppeteer.connect({\n    browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=API_TOKEN\"\n}); Replace API_TOKEN with your API key. Worked example Connect to axiom.ai before any other Puppeteer browser interactions. The script below opens https:\u002F\u002Faxiom.ai, waits 5 seconds, and closes the browser: console.log(\"start\");\n\nconst browser = await puppeteer.connect({\n    \u002F\u002F Replace API_TOKEN with your API key.\n    browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=API_TOKEN\"\n});\nconsole.log(\"browser connected\");\n\ntry {\n    const page = await browser.newPage();\n    await page.goto(\"https:\u002F\u002Faxiom.ai\");\n    await new Promise((resolve) => setTimeout(resolve, 5000));\n    await page.close();\n    await browser.close();\n    console.log(\"browser closed\");\n} catch (e) {\n    console.error(e.message);\n    await browser.close();\n} Tip: Wrap browser interactions in a try...catch block (as shown above) and call browser.close() from the catch path. Without this, a failed run can leave the hosted browser open and counting against your runtime allowance until it times out. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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}",{"id":651,"title":652,"titles":653,"content":654,"level":56},"\u002Fdocs\u002Fcode\u002Fdashboard","Dashboard",[],"Navigate the Code Dashboard, including Home, run reports, the Live editor, settings, theme, and remaining runtime. The Code Dashboard is your hub for running scripts on axiom.ai's cloud. From here you can navigate to the Live editor, view run reports, manage settings, and check your remaining runtime. Navigation The left navigation has the following items: Home. The default landing tab when you sign in.Run reports. Lists your recent run reports. For details, see run reports.Live editor. Test and run scripts in the web app. See Live editor.Settings. Account and API key settings. See generate an API key.Color theme. Toggle dark mode for the dashboard. Runtime Your remaining runtime appears at the top-left of the dashboard, shown as used minutes \u002F total minutes. Runtime resets at the start of each billing period; it doesn't carry over.",{"id":656,"title":657,"titles":658,"content":659,"level":56},"\u002Fdocs\u002Fcode","Code Dashboard",[],"The Code Dashboard runs your own Puppeteer scripts on axiom.ai's cloud. Use the Dashboard to create and manage scripts, run them from your own stack, and monitor every execution. Quick start To get a script running, create an account, then connect to axiom.ai using your API key. New accounts get 3 hours of free runtime. Create an account, log in, and copy your API key from the Dashboard.Add the code below to your script and paste in your API key.Open the endpoint URL in your browser to watch the run. const browser = await puppeteer.connect({\n  \u002F\u002F Insert your API key in place of [HIDDEN_KEY]\n  browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=[HIDDEN_KEY]\"\n});\nconst page = await browser.newPage();\nawait page.setViewport({ width: 1960, height: 1080 });\n\n\u002F\u002F Your script here\n\nawait page.close();\nawait browser.close(); html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":661,"title":662,"titles":663,"content":664,"level":56},"\u002Fdocs\u002Fcode\u002Flive-editor","Live editor",[],"The Live editor lets you test scripts and watch them run in a hosted browser, without setting up a local Node.js environment. The Live editor lets you test scripts on axiom.ai's hosted infrastructure without setting up a local Node.js environment. The page splits into two panels: a code editor on one side and a live browser on the other. Code editor The code editor includes sample scripts that show what's possible with axiom.ai and Puppeteer, and you can paste in your own scripts to run them on the hosted infrastructure. Click Run to execute the script. Browser The browser panel opens automatically when you click Run. It shows the hosted browser executing your script, so you can watch each action in real time. Use it to confirm the script behaves as expected and to spot pages that load differently than your script assumed. To move the browser panel to fill the bottom half of the screen, click the three-column button to the left of the close button.",{"id":666,"title":667,"titles":668,"content":669,"level":56},"\u002Fdocs\u002Fcode\u002Frun-reports","Run reports",[],"View in-progress and completed Code Dashboard runs, watch live runs, check durations, and inspect errors and run details from the dashboard. Run reports show every Code Dashboard run you've started, alongside any in-progress runs. Use them to track how long scripts take, watch live runs, and inspect errors after a run fails. Open run reports Click Run reports in the dashboard navigation. You'll see a list of completed and in-progress runs. Each row shows: The run's status.A unique run identifier.The start date and time.The runtime in seconds.A details link. Watch a live run While a run is in progress, the row includes a Watch link. Click it to open a live view of the hosted browser executing your script. This is the same view as the Live editor browser panel, but for a script running outside the Live editor. View run details Click Details on a row to open the full report for that run. The details view shows: The version of axiom.ai used to execute the script.Any errors thrown during execution, with stack traces where available. For background on debugging script errors, see debug developer features.",{"id":671,"title":672,"titles":673,"content":674,"level":56},"\u002Fdocs\u002Fcode\u002Frunning-scripts","Run scripts",[],"Run Code Dashboard scripts from your own development environment using Node.js, or test them in the axiom.ai Live editor without any local setup. There are two ways to run a Code Dashboard script: from your own local environment, or from the axiom.ai Live editor. Run a script locally Once your script is connected to axiom.ai (see create scripts), run it from your local environment with Node.js. Install Puppeteer in your project:npm install puppeteer-core\nSave your script. For example, scrape.js:const puppeteer = require('puppeteer-core');\n\n(async () => {\n  const browser = await puppeteer.connect({\n    browserWSEndpoint: 'wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=YOUR_API_KEY'\n  });\n  const page = await browser.newPage();\n  await page.goto('https:\u002F\u002Faxiom.ai');\n  console.log(await page.title());\n  await browser.close();\n})();\nRun it with Node:node scrape.js The script connects to axiom.ai's hosted browser and runs against it. Sprinkle console.log() calls through your script while you're developing so you can monitor progress and catch issues from the terminal. Tip: To watch the script in action, open run reports in the dashboard. Each in-progress run has a Watch link that opens a live view of the hosted browser. Run a script in the Live editor The Live editor lets you run scripts without any local setup, so it's useful for quick experiments and for sharing a script with someone who doesn't have Node.js installed. Open the Live editor from the dashboard.Paste the script into the code editor.Click Run.Open the browser panel to watch the run. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 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 .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 .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}",{"id":676,"title":677,"titles":678,"content":679,"level":56},"\u002Fdocs\u002Fcode\u002Fsamples\u002Fdata-entry","Enter data into a page",[],"Sample Puppeteer script for the axiom.ai Code Dashboard that connects to the hosted browser, fills a search field on Google, waits, and closes cleanly. This sample script connects to axiom.ai, opens Google, fills the search bar with a query, waits 5 seconds, and closes the browser. What it does: Connect to the axiom.ai hosted browser.Open https:\u002F\u002Fgoogle.com.Enter a search query into the search bar.Wait 5 seconds.Close the browser. const start = async () => {\n    console.log('start');\n\n    const browser = await puppeteer.connect({\n        \u002F\u002F Replace [HIDDEN_KEY] with your API key.\n        browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=[HIDDEN_KEY]\"\n    });\n    console.log('browser connected');\n\n    try {\n        const page = await browser.newPage();\n        await page.goto(\"https:\u002F\u002Fgoogle.com\u002F\");\n\n        \u002F\u002F Locate the search bar and fill it.\n        await page.locator('aria\u002FSearch').fill('Testing axiom.ai');\n\n        await new Promise((resolve) => setTimeout(resolve, 5000));\n\n        await page.close();\n        await browser.close();\n        console.log('browser closed');\n    } catch (e) {\n        console.error(e.message);\n        await browser.close();\n    }\n};\n\nstart(); Note: The search bar selector uses Puppeteer's ARIA selectors (aria\u002FSearch), which match elements by their accessible name. This is more resilient than CSS selectors when a site changes its markup but keeps its accessibility labels. Tip: This sample is also available in the Live editor. Open the Live editor, paste in your API key, and click Run. To generate an API key, see generate an API key. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}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 .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}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);}",{"id":681,"title":682,"titles":683,"content":684,"level":56},"\u002Fdocs\u002Fcode\u002Fsamples","Sample scripts",[],"Sample Puppeteer scripts you can run in the axiom.ai Live editor or adapt for your own automations, covering navigation and data entry. These sample scripts run in the axiom.ai Live editor or your local environment. Use them as a starting point for your own scripts; each one connects to axiom.ai's hosted browser, performs a small task, and exits cleanly. Available samples Navigate to a pageEnter data into a page Need help? Contact support or ask a question in our Reddit community.",{"id":686,"title":687,"titles":688,"content":689,"level":56},"\u002Fdocs\u002Fcode\u002Fsamples\u002Fnavigate-to-page","Navigate to a page",[],"Sample Puppeteer script for the axiom.ai Code Dashboard that connects to the hosted browser, opens a page, waits, and closes the browser cleanly. This sample script connects to axiom.ai, opens the axiom.ai homepage, waits 5 seconds, and closes the browser. What it does: Connect to the axiom.ai hosted browser.Open https:\u002F\u002Faxiom.ai.Wait 5 seconds.Close the browser. console.log('start');\n\nconst browser = await puppeteer.connect({\n    \u002F\u002F Replace [HIDDEN_KEY] with your API key.\n    browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=[HIDDEN_KEY]\"\n});\nconsole.log('browser connected');\n\ntry {\n    const page = await browser.newPage();\n    await page.goto(\"https:\u002F\u002Faxiom.ai\");\n    await new Promise((resolve) => setTimeout(resolve, 5000));\n    await page.close();\n    await browser.close();\n    console.log('browser closed');\n} catch (e) {\n    console.error(e.message);\n    await browser.close();\n} Tip: This sample is also available in the Live editor. Open the Live editor, paste in your API key, and click Run. To generate an API key, see generate an API key. html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}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}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);}",{"id":691,"title":692,"titles":693,"content":694,"level":56},"\u002Fdocs\u002Fcode\u002Ftoken-generation","Generate an API key",[],"Generate the API key used to authenticate Code Dashboard scripts to axiom.ai's hosted browser, with guidance on storing it securely. Every Code Dashboard script needs an API key to authenticate to axiom.ai's hosted browser. Generate the key once and reuse it across your scripts. Generate an API key In the Code Dashboard, navigate to Settings > API key.Click Create API key.Wait a few seconds while the key is generated.Copy the key and store it securely. Warning: The key is shown once and can't be retrieved again. If you lose it, you'll need to generate a new one. We recommend storing it in a password manager or environment variable file before closing the dialog. For an example of using the API key in a Puppeteer script, see create scripts.",{"id":696,"title":697,"titles":698,"content":699,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fauthentication","Authentication",[],"Generate an axiom.ai API key from the Chrome extension or Code Dashboard and use it to authenticate every API request. API requests are authenticated with an API key. The same key authenticates the full API surface, REST endpoints and cloud browser sessions, so you only need to generate one. Generate an API key You can generate a key from three places. They all create the same account-scoped key, use whichever surface you already have open. Signing up from code? If you're writing an agent, a Claude skill, or any tool that needs to onboard its own users without sending them to the dashboard first, see Programmatic signup for the three-call REST flow that creates an account and mints a key end-to-end. From the Chrome extension Open the Dashboard.In the left sidebar, click Credentials and API key.Scroll to Generate Axiom API token.Click Show API Token to reveal an existing key, or Refresh API Token to generate a new one.Copy the value. From the Code Dashboard Open the Code dashboard.Click the Settings cog in the left sidebar.Select API key.Click Delete and re-generate API key.Copy the value. From the Live editor The Live editor has a shortcut so you can paste a key (or generate one) without leaving the script you're testing. Open the Code dashboard.Click Live editor, then Test Puppeteer scripts.Paste your key into the API key field, or click Generate key to create a new one. The key is automatically substituted into the [HIDDEN_KEY] placeholder in the example script, so you can run it immediately. Warning: generating a new key immediately invalidates the previous one. Any external integration using the old key (Zapier, Make, custom scripts, MCP servers, Puppeteer connections) stops working until you update it. Use the key in a request For REST endpoints, pass the key in the JSON body, in the key field. curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Fremaining-runtime \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key\": \"your-api-key-here\"}' Note: the key goes in the request body, not in an Authorization header. This is unusual for REST APIs, watch for it when porting code from other services. For cloud browser sessions, the same key is passed as the token query parameter on the CDP WebSocket endpoint. const browser = await puppeteer.connect({\n  browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=your-api-key-here\"\n}); What the key authenticates A single key authenticates the full API surface: Trigger and manage cloud automation runs (\u002Ftrigger, \u002Fstop, \u002Frun-data).Check account quota (\u002Fremaining-runtime).Drive cloud browser sessions over CDP (Puppeteer, Playwright, or the imperative session functions). Keys are account-scoped: there is no per-automation, per-team, or per-integration key today, and only one active key per account at a time. Security best practices Treat your API key like a password. Don't commit it to git, even in private repos.Store it in environment variables or a secrets manager, not in client-side code. A key in client-side JavaScript is a key the world has.Rotate the key if you suspect it's been exposed. Remember to update every integration immediately afterwards, the old key stops working as soon as the new one is generated.When sharing automations or scripts with teammates, share the source, not the key. Each developer can generate their own. Related Programmatic signup — sign up + mint a key from codeTrigger an automationStart a browser sessionCheck remaining runtime html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}",{"id":701,"title":702,"titles":703,"content":704,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fcdp","Chrome API",[],"Drive a cloud browser from your own code over a Chrome DevTools Protocol WebSocket. Works with Puppeteer, Playwright, raw CDP libraries, or anything else that speaks the protocol. The Chrome API is a Chrome DevTools Protocol WebSocket pointed at a fresh cloud browser. Connect a CDP-speaking client (Puppeteer, Playwright, or any raw CDP library) to drive the browser exactly as you would locally — except it runs on our infrastructure, with no Chromium to install or maintain. This is the right layer when you want full control of every browser action from your own stack, in any language. If you'd rather call high-level actions in Node without writing CDP, see the Step API. If the workflow already exists in the No-Code Tool and you just want to fire it, see the Orchestrate API. Endpoint ProtocolURLwsswss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=YOUR_API_KEY Pass your API key as the token query parameter. See Authentication to generate one. Note: never log the connection URL. The token is the same secret as the REST API key — treat the full URL as a credential. Connect with Puppeteer npm i puppeteer, then point puppeteer.connect() at the endpoint: import puppeteer from \"puppeteer\";\n\nconst browser = await puppeteer.connect({\n  browserWSEndpoint: `wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=${process.env.AXIOM_API_KEY}`\n});\n\ntry {\n  const page = await browser.newPage();\n  await page.goto(\"https:\u002F\u002Fexample.com\");\n  await page.screenshot({ path: \"out.png\", fullPage: true });\n} finally {\n  await browser.close();\n} The cloud browser handles the heavy lifting (a real Chromium with networking, fonts, and resources). Your stack just sends commands and reads results. Drop this into anywhere code runs: a Node service, a serverless function, a cron job, a test suite. Wrap the work in try\u002Ffinally so the session always closes, even on errors. A leaked session continues to count against your remaining runtime until the server reaps it. Connect with Playwright npm i playwright, then use chromium.connectOverCDP(): 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\ntry {\n  const context = browser.contexts()[0];\n  const page = context.pages()[0] ?? await context.newPage();\n  await page.goto(\"https:\u002F\u002Fexample.com\");\n  await page.screenshot({ path: \"out.png\", fullPage: true });\n} finally {\n  await browser.close();\n} Playwright surfaces the connected browser as an existing context. Use the first context's first page (or create one) rather than calling browser.newContext(), which is not supported over CDP. Connect with raw CDP or other languages The endpoint is plain CDP, so any client that speaks the protocol works — including Python (pyppeteer, playwright), Go (chromedp), Ruby (ferrum), or a raw WebSocket library. For raw CDP, open a WebSocket to the endpoint and exchange JSON-RPC messages following the Chrome DevTools Protocol spec. # Python example using playwright\nfrom playwright.sync_api import sync_playwright\nimport os\n\nwith sync_playwright() as p:\n    browser = p.chromium.connect_over_cdp(\n        f\"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token={os.environ['AXIOM_API_KEY']}\"\n    )\n    page = browser.contexts[0].pages[0]\n    page.goto(\"https:\u002F\u002Fexample.com\")\n    page.screenshot(path=\"out.png\")\n    browser.close() Session lifecycle Each successful connection opens a fresh, isolated cloud browser. Sessions consume runtime quota for their entire open lifetime, not just while actively executing commands. Always close the connection when you're done: Puppeteer: await browser.close(). Use browser.disconnect() only if you want to leave the cloud browser running — it keeps consuming runtime until the server reaps it.Playwright: await browser.close().Raw CDP: close the WebSocket. The server reaps the browser shortly after. Idle sessions are eventually timed out by the server, but this is not immediate — a leaked session can rack up several minutes of runtime before being reaped. Check remaining runtime if a script seems to drain quota unexpectedly. How it differs from local Puppeteer The cloud browser behaves like a local Chromium with a few practical differences worth knowing up front: Datacentre IP: some sites detect and block known datacentre ranges. Expect this on a subset of targets.No local filesystem: file:\u002F\u002F URLs, --user-data-dir mounts, and similar local-only features aren't usable. Use page-side downloads or upload buffers through your code instead.No persistent state across sessions: each puppeteer.connect() opens a fresh browser. Cookies, localStorage, and other in-memory state vanish on disconnect. To persist, capture and re-apply in your own code.Concurrency per API key: the number of concurrent open sessions is capped by your plan tier. See Queue and concurrency. Related Quickstart — drive a cloud browser from your codeEndpoints referenceError codesStep API — high-level browser actions wrapped around the Chrome API Need help? Contact support or ask a question in our Reddit community. 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}",{"id":706,"title":707,"titles":708,"content":709,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi","API",[],"Three layered APIs with one key. Chrome API for low-level browser control, Step API for high-level browser actions, and Orchestrate API to trigger any automation — code or no-code. The axiom.ai API has three layers. They can be used together or individually: Chrome API — a long-lived WebSocket to a cloud browser, drivable from Puppeteer, Playwright, or any CDP-speaking client.Step API — our library of step functions wraps the Chrome API with high-level browser actions in Node.Orchestrate API — trigger any pre-built automation, code or no-code, and manage its runs over REST. All three layers are reachable from your own code or from an MCP client. Start with the quickstart, then generate an API key. YOUR CODE\n                                                    │\n                                                [API key]\n                                                    │\n                            ╔═══════════════════════════════════════════════╗\n                            ║                 axiom.ai API                  ║\n                            ╚═══════════════════════════════════════════════╝\n                                                    │\n            ┌───────────────────────────────────────┼───────────────────────────────────────┐\n            │                                       │                                       │\n            ▼                                       ▼                                       ▼\n\n   ╔══════════════════════╗               ╔══════════════════════╗               ╔══════════════════════╗\n   ║      Chrome API      ║               ║       Step API       ║               ║   Orchestrate API    ║\n   ╚══════════════════════╝               ╚══════════════════════╝               ╚══════════════════════╝\n\n   Long-lived WebSocket.                  Node library calling                   REST. Fire pre-built\n   Connect Puppeteer,                     \u002Fapi\u002Fv5\u002Fstep. High-level               automations and\n   Playwright, or any                     browser step functions.                manage their runs.\n   CDP-speaking client.\n\n   wss:\u002F\u002Fcdp-lb.axiom.ai\u002F                 npm install @axiom_ai\u002Fapi              POST \u002Ftrigger\n     ?token=API_KEY                         │                                    POST \u002Frun-data\n                                          new AxiomApi(key)                      POST \u002Frun-reports\n                                            │                                    POST \u002Flist-automations\n                                          browserOpen()                          POST \u002Fstop\n                                            │\n                                          goto(url)\n                                          click(selector)\n                                          enterText(sel, text)\n                                          scrape()\n                                          wait(ms)\n                                            │\n                                          browserClose() Chrome API A long-lived Chrome DevTools Protocol WebSocket pointed at a fresh cloud browser. Connect Puppeteer, Playwright, or any CDP-speaking library and drive it exactly as you would locally — except it runs on our infrastructure, with no Chromium to install or maintain. Best when you want full control of every browser action from your own stack, in any language. const browser = await puppeteer.connect({\n  browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=YOUR_API_KEY\"\n}); Read the full Chrome API guide → Step API The @axiom_ai\u002Fapi Node package gives you high-level browser actions over our \u002Fapi\u002Fv5\u002Fstep REST endpoint — call named step functions instead of speaking CDP yourself. Open a session with browserOpen(), drive it with actions like goto, click, enterText, scrape, wait, …, close with browserClose(). The Step API is a separate surface from the Chrome API above — pick whichever fits your stack. Best when you want code-driven flows in Node but don't want to write Puppeteer or wire up CDP yourself. Orchestrate API Trigger any pre-built automation — code or no-code — and manage its runs over REST. Pass inputs at trigger time, poll status, fetch run history, stop in-flight runs. Best when the automation is already authored in the No-Code Tool or Code Dashboard and you want to wire it into Zapier, Make, a backend service, a cron job, or an MCP client. Use from an MCP client All three layers above are reachable from MCP-aware clients (Claude Desktop, Claude Code, Cursor, and others). Use the built-in server in the axiom.ai desktop app, or build your own in Python or TypeScript to expose the Chrome API, the Step API, or the Orchestrate API's \u002Ftrigger as tools. Usage and limits Check how much cloud runtime your account has left, see how runs are queued when you hit your concurrency limit, and stay inside the per-minute rate limits. Reference Endpoint summaries, request and response payloads, and error codes for the full API surface. Need help? Contact support or ask a question in our Reddit community. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":711,"title":712,"titles":713,"content":714,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fmcp\u002Fbuild-your-own-server-python","Build your own server (Python)",[],"Build a minimal Model Context Protocol server in Python that exposes axiom.ai automation triggers as tools for any MCP client. Build a small Python MCP server that wraps the axiom.ai REST API. The result is a tool any MCP-aware client (Claude Desktop, Claude Code, Cursor) can call to trigger automations and check their status from inside a conversation. Before you begin You need: Python 3.10 or later.uv (recommended) or pip for dependency management.An axiom.ai API key. See Authentication. Step 1: install dependencies uv pip install \"mcp[cli]\" httpx Or with pip: pip install \"mcp[cli]\" httpx Step 2: write the server Create a file called axiom_mcp.py: import os\nimport httpx\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"axiom\")\nAXIOM_BASE = \"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\"\nKEY = os.environ[\"AXIOM_API_KEY\"]\n\n@mcp.tool()\nasync def trigger_automation(name: str, data: list | None = None) -> dict:\n    \"\"\"Trigger an axiom.ai cloud automation by exact name.\n\n    Optional `data` is a 3-D array of [tables][rows][cells] passed as\n    the automation's input.\n    \"\"\"\n    body = {\"key\": KEY, \"name\": name}\n    if data is not None:\n        body[\"data\"] = data\n    async with httpx.AsyncClient(timeout=30) as c:\n        r = await c.post(f\"{AXIOM_BASE}\u002Ftrigger\", json=body)\n        return r.json()\n\n@mcp.tool()\nasync def run_status(run_id: str) -> dict:\n    \"\"\"Check the status of a triggered axiom.ai automation run.\"\"\"\n    async with httpx.AsyncClient(timeout=30) as c:\n        r = await c.post(\n            f\"{AXIOM_BASE}\u002Frun-data\",\n            json={\"key\": KEY, \"run_id\": run_id},\n        )\n        return r.json()\n\nif __name__ == \"__main__\":\n    mcp.run()  # stdio transport by default That's the whole server. Tool descriptions in the docstrings are what the LLM sees when deciding whether to call a tool, write them clearly. Step 3: register it with a client See Register with Claude clients for the full configuration snippets. The shortest version, for Claude Desktop: {\n  \"mcpServers\": {\n    \"axiom\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"\u002Fabsolute\u002Fpath\u002Fto\u002Faxiom_mcp.py\"],\n      \"env\": { \"AXIOM_API_KEY\": \"your-api-key-here\" }\n    }\n  }\n} Restart the client. Your trigger_automation and run_status tools appear and the LLM can call them in conversation. Step 4: extend it The minimal server above is intentionally tiny. Real custom servers usually add: stop_run to cancel misbehaving runs.remaining_runtime so the LLM can check quota before triggering expensive runs.Domain-specific wrappers, for example scrape_amazon_asin(asin: str) that internally calls trigger_automation(\"Amazon ASIN template\", data=[[[asin]]]) and waits for completion. This is where the real value is, the LLM gets a clean, typed tool instead of having to learn each automation's input shape.Polling and completion handling, so the tool returns a finished result rather than a run_id the LLM has to poll itself.Step-function tools, mirroring the Step API if you want the LLM to drive a session step by step instead of just triggering pre-built automations. A typical extended server is 100 to 200 lines and covers the most common workflows for the team using it. Notes Treat your AXIOM_API_KEY like any other secret. Don't commit the env value into the config you check into version control, use a secrets manager or a .env file the client loads.The server runs as a child process of the MCP client. If it crashes, the client restarts it on the next tool call, so transient errors are usually fine.For production, consider switching from stdio to streamable HTTP transport so the server can run remotely. See the Anthropic build-a-server guide. html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":716,"title":717,"titles":718,"content":719,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fmcp\u002Fbuild-your-own-typescript","Build your own server (TypeScript)",[],"Build a minimal Model Context Protocol server in Node and TypeScript that exposes axiom.ai automation triggers as tools for any MCP client. Build a small Node MCP server that wraps the axiom.ai REST API. Use this if your team is already on a Node stack and would rather extend an existing TypeScript codebase than maintain a Python one. Before you begin You need: Node 18 or later.An axiom.ai API key. See Authentication. Step 1: install dependencies npm install @modelcontextprotocol\u002Fsdk zod The SDK is dual-published as both ESM and CJS, so the same install works for either module style. Step 2: write the server Create a file called axiom_mcp.cjs. Using a .cjs extension and dynamic import() keeps the file working across every Node 18+ runtime, regardless of how exports get resolved. const AXIOM_BASE = \"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\";\nconst KEY = process.env.AXIOM_API_KEY;\nif (!KEY) throw new Error(\"AXIOM_API_KEY env var is required\");\n\nasync function postJson(path, body) {\n  const res = await fetch(`${AXIOM_BASE}${path}`, {\n    method: \"POST\",\n    headers: { \"content-type\": \"application\u002Fjson\" },\n    body: JSON.stringify(body),\n  });\n  return res.json();\n}\n\n(async () => {\n  \u002F\u002F Dynamic import so this CJS file can consume the dual-published SDK.\n  const { McpServer } = await import(\"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\");\n  const { StdioServerTransport } = await import(\n    \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\"\n  );\n  const { z } = await import(\"zod\");\n\n  const server = new McpServer({ name: \"axiom\", version: \"0.1.0\" });\n\n  server.registerTool(\n    \"trigger_automation\",\n    {\n      description:\n        \"Trigger an axiom.ai cloud automation by exact name. Optional `data` is a 3-D array of [tables][rows][cells] passed as the automation's input.\",\n      inputSchema: {\n        name: z.string(),\n        data: z.array(z.array(z.array(z.string()))).optional(),\n      },\n    },\n    async ({ name, data }) => {\n      const body = { key: KEY, name, ...(data ? { data } : {}) };\n      const result = await postJson(\"\u002Ftrigger\", body);\n      return { content: [{ type: \"text\", text: JSON.stringify(result) }] };\n    },\n  );\n\n  server.registerTool(\n    \"run_status\",\n    {\n      description: \"Check the status of a triggered axiom.ai automation run.\",\n      inputSchema: { run_id: z.string() },\n    },\n    async ({ run_id }) => {\n      const result = await postJson(\"\u002Frun-data\", { key: KEY, run_id });\n      return { content: [{ type: \"text\", text: JSON.stringify(result) }] };\n    },\n  );\n\n  await server.connect(new StdioServerTransport());\n})(); Step 3: register it with a client See Register with Claude clients for the full configuration snippets. The shortest version, for Claude Desktop: {\n  \"mcpServers\": {\n    \"axiom\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Faxiom_mcp.cjs\"],\n      \"env\": { \"AXIOM_API_KEY\": \"your-api-key-here\" }\n    }\n  }\n} Restart the client. Your trigger_automation and run_status tools appear and the LLM can call them in conversation. Why the dynamic import The MCP SDK ships ESM as primary with a CJS build alongside. A top-level require(\"@modelcontextprotocol\u002Fsdk\u002F...\") works in some Node versions and breaks in others depending on how exports are resolved. A top-level import forces the file to be ESM and is fine if your project is ESM, but breaks in CJS projects. Using await import() from a .cjs file (or a .js file with \"type\": \"commonjs\" in package.json) sidesteps the whole issue and works on every Node 18+ runtime. If your project is ESM, you can use top-level import instead and drop the dynamic loader. Audit the SDK before pinning Worth a five-minute check for anything you're shipping to users: Source: github.com\u002Fmodelcontextprotocol\u002Ftypescript-sdk, MIT-licensed, published by Anthropic.No install or postinstall scripts (verify with npm view @modelcontextprotocol\u002Fsdk@\u003Cversion> scripts).Has SLSA provenance attestations on recent releases (verify with npm audit signatures or the npm web UI).Pin to an exact reviewed version in your lockfile rather than floating, re-audit when bumping. Step 4: extend it The minimal server above is intentionally tiny. Real custom servers usually add: stop_run to cancel misbehaving runs.remaining_runtime so the LLM can check quota before triggering expensive runs.Domain-specific wrappers, for example scrape_amazon_asin(asin) that internally calls trigger_automation and waits for completion. The LLM gets a clean, typed tool instead of having to learn each automation's input shape.Polling and completion handling so the tool returns a finished result rather than a run_id the LLM has to poll itself.Step-function tools, mirroring the Step API if you want the LLM to drive a session step by step. Notes Treat your AXIOM_API_KEY like any other secret. Don't commit it to source control.The server runs as a child process of the MCP client, so its stdout is the protocol channel. Don't console.log debug messages, write them to a file or use console.error (stderr is safe).For production, consider switching from stdio to streamable HTTP transport so the server can run remotely. See the Anthropic build-a-server guide. html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}",{"id":721,"title":722,"titles":723,"content":724,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fmcp\u002Fdesktop-app-server","Desktop app MCP server",[],"The axiom.ai desktop app ships with a built-in MCP server. Toggle it on, paste your API key, and Claude Desktop, Claude Code, Cursor, or any MCP client can trigger axiom.ai automations and step functions in conversation. The axiom.ai desktop app ships with a built-in MCP server. Once it's switched on, any MCP-aware LLM client running on the same machine can call your axiom.ai API: trigger automations, drive a cloud browser through step functions, check remaining runtime, and stop runs. The server speaks the standard Model Context Protocol, so Claude Desktop, Claude Code, Cursor, and every other MCP-compatible client work with it out of the box. This is the easiest way to put axiom.ai inside an LLM. Skip ahead to Before you begin to enable it. What it gives you With the desktop app's MCP server enabled, an LLM client can: Trigger automations by name. Ask Claude to run \"Scrape today's leads\", and it calls \u002Ftrigger under the hood.Pass input data. The LLM can format rows of input and send them in the same call.Check run status. The LLM polls \u002Frun-data and reports back when the run finishes.Drive a cloud browser step by step. The LLM can call step functions (goto, click, enterText, scrape, wait) directly, choosing each action based on what the previous one returned.Read remaining runtime before kicking off expensive runs.Stop runs if a conversation needs to abort one early. No CLI, no SDK installation, no MCP server to write yourself. The desktop app handles the protocol; the LLM handles the conversation. Before you begin You need: A paid axiom.ai account. API access is gated to paid plans. See the pricing page for plans that include the API.The axiom.ai desktop app, installed and running on the same machine as your LLM client. Download from the desktop app page.An axiom.ai API key, generated from the Dashboard. See Authentication. Enable the MCP server Open the axiom.ai desktop app.Open the Claude MCP server panel from the desktop app's settings.Toggle the server on.Paste your axiom.ai API key into the API key field. The key is stored locally on your machine; the desktop app never sends it anywhere else.Confirm the panel reads Connected. Claude (or another MCP client) can now reach the server. To rotate the key later, click Remove and reset and paste a new key. To turn the server off entirely, toggle it back off. Use it from your LLM client The built-in server speaks standard MCP, so any MCP-aware client can talk to it. The most common clients today: Claude Desktop. Anthropic's official desktop app for the Claude chat experience. Once the axiom.ai desktop app's MCP server is on, Claude Desktop discovers it as a tool source. See Register with Claude for the connection details.Claude Code. Anthropic's terminal-native coding agent. Run claude in a project and the agent picks up the MCP server automatically.Cursor. Cursor's chat panel speaks MCP and treats the axiom.ai server like any other tool source.Any other MCP client. The protocol is open, so Cline, Cowork, Continue, Zed's AI panel, and others all work the same way. You don't need to install anything client-side beyond the LLM client itself. Once both the axiom.ai desktop app and the LLM client are running, the LLM can see and call axiom.ai tools. Example conversations A few prompts to try once the server is enabled: \"Run my 'Daily competitor prices' automation and tell me when it's done.\" \"Open a browser session, go to news.ycombinator.com, scrape the front-page titles, and summarise the top three.\" \"How much axiom runtime do I have left this month?\" Claude picks the right MCP tool for each task: \u002Ftrigger for the first, a sequence of step functions for the second, and \u002Fremaining-runtime for the third. What's under the hood The built-in server is implemented with Anthropic's official TypeScript MCP SDK and embedded in the axiom.ai desktop app. The same SDK powers Claude Desktop's own tool integrations, so the server behaves identically to any other MCP server an LLM might encounter. If you want to extend or customise the tool surface, see Build your own (TypeScript) for a standalone server you can fork. The built-in server is the recommended path for almost everyone; the build-your-own pages exist for edge cases (headless servers, non-Anthropic SDKs, custom tool wrappers). Notes The MCP server only runs while the axiom.ai desktop app is open. Quitting the app stops the server.Each API call from the LLM counts against the standard rate limits and runtime allowance. LLMs that poll aggressively can trip rate limits; if you see 429 errors in the desktop app logs, tell the LLM to slow down.The MCP server is local-only. It listens on a port on your machine and isn't reachable from the public internet.API keys are stored in the desktop app's encrypted local config, not in plaintext on disk.",{"id":726,"title":727,"titles":728,"content":729,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fmcp","MCP",[],"Drive axiom.ai from Claude, Cursor, or any MCP client. The axiom.ai desktop app ships with a built-in MCP server; alternatively, build your own in Python or TypeScript. The Model Context Protocol (MCP) is an open standard from Anthropic that lets LLM clients call external tools. With an MCP server in front of the axiom.ai API, Claude Desktop, Claude Code, Cursor, or any other MCP-aware client can trigger your automations and drive cloud browsers in conversation. Two ways to set this up 1. The built-in desktop app server (recommended) The axiom.ai desktop app ships with a Claude MCP server. Toggle it on, paste your API key, and any MCP client on your machine (Claude Desktop, Claude Code, Cursor, and others) can immediately trigger automations and call step functions. No code, no setup, no server to maintain. This is the right path for almost everyone. You'll need a paid axiom.ai account to generate the API key. 2. Build your own server If the built-in server doesn't fit (you want a headless server, a custom tool surface, a different SDK, or you're not running the desktop app), wrap the axiom.ai API yourself. The minimal version is around 30 lines. The pages below walk through \u002Ftrigger and \u002Frun-data wrappers in Python and TypeScript, then how to register the result with the major MCP clients. Anthropic's MCP resources Useful reading regardless of which path you take. The protocol overview, capability model, and SDK quickstarts will save debugging time later. Spec and docsBuild a server guideQuickstartPython SDKTypeScript SDKReference servers (good templates to clone) In this section Need help? Contact support or ask a question in our Reddit community.",{"id":731,"title":732,"titles":733,"content":734,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fmcp\u002Fregister-with-claude","Register with Claude clients",[],"Configure Claude Desktop, Claude Code, Cursor, and Cowork to load your custom axiom.ai MCP server. Once you've built an MCP server (in Python or TypeScript), point your MCP client at it. The configuration is similar across clients but the file location and field names differ. This page shows the snippet for each. Claude Desktop Edit the claude_desktop_config.json file in the platform-specific location: PlatformPathmacOS~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.jsonWindows%APPDATA%\\Claude\\claude_desktop_config.json For the Python server: {\n  \"mcpServers\": {\n    \"axiom\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"\u002Fabsolute\u002Fpath\u002Fto\u002Faxiom_mcp.py\"],\n      \"env\": { \"AXIOM_API_KEY\": \"your-api-key-here\" }\n    }\n  }\n} For the Node server: {\n  \"mcpServers\": {\n    \"axiom\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Faxiom_mcp.cjs\"],\n      \"env\": { \"AXIOM_API_KEY\": \"your-api-key-here\" }\n    }\n  }\n} Restart Claude Desktop. Your tools appear in the tool list and the LLM can call them. Claude Code Claude Code reads MCP servers from a project-level .mcp.json file or from a global config. The simplest setup is a per-project file: {\n  \"mcpServers\": {\n    \"axiom\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Faxiom_mcp.cjs\"],\n      \"env\": { \"AXIOM_API_KEY\": \"your-api-key-here\" }\n    }\n  }\n} Place this at the root of the project and Claude Code picks it up automatically. Cursor Cursor uses a per-project or global mcp.json file. The schema is the same as Claude Desktop's: {\n  \"mcpServers\": {\n    \"axiom\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Faxiom_mcp.cjs\"],\n      \"env\": { \"AXIOM_API_KEY\": \"your-api-key-here\" }\n    }\n  }\n} Restart Cursor. Tools appear in the chat side panel. Cowork Cowork registers MCP servers via its plugin marketplace or via direct config in the desktop app. For a custom server: Open Cowork settings.Go to MCP servers.Click Add server and paste the same config object as above. Cowork hot-reloads the server, no restart needed. Verify the registration worked After adding the config and restarting, ask the LLM: What tools do you have available? It should list trigger_automation and run_status (or whatever names you chose). If they don't appear: Check the path is absolute. Relative paths break because the client runs the server from its own working directory.Check the env var is set. Most failures come from a missing AXIOM_API_KEY. Restart the client after adding it.Check the client logs. Each client surfaces server stdout\u002Fstderr somewhere, look for connection errors or missing dependencies. Security The MCP config file holds your API key in plain text. A few precautions: Don't commit the config file to a public repo.Use a secrets manager or a .env file the server reads, rather than hard-coding the key in the config, if your client supports it.Rotate your axiom.ai API key (see Authentication) if you suspect the config has been exposed. Notes Each client uses the stdio transport by default for local servers. For a server running on another machine, use streamable HTTP and update the config to point at the URL instead of a command.Multiple mcpServers entries can coexist in a single config, your axiom.ai server can sit alongside servers for filesystem, GitHub, Slack, and so on.Restart the client after editing the config. Most clients don't watch the config file for changes. html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":736,"title":737,"titles":738,"content":739,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fprogrammatic-signup","Programmatic signup",[],"Three-call REST flow for code that needs to sign up its own user, log in, and mint an API key — useful for agents, Claude skills, and headless onboarding. For most users, the right path is to sign up in the browser and copy your API key from the dashboard — see Authentication. This page is for code that needs to sign up its own user, typically: Agents and Claude skills that onboard a new caller automatically.CI \u002F test harnesses that mint throwaway accounts.Wrapper tools that abstract the dashboard away from end users. The same three endpoints power the Code Dashboard's sign-up form, so anything you do here matches what a normal user would do in the browser. The three-step flow POST \u002Fapi\u002Fuser\u002Fcreate   →   creates the account (no token yet)\n        │\n        ▼\nPOST \u002Fapi\u002Fuser\u002Flogin    →   returns a Bearer JWT\n        │\n        ▼\nGET  \u002Fapi\u002Fuser\u002Fkey\u002Fcreate   →   returns the long-lived API key All requests go to https:\u002F\u002Flar.axiom.ai. Step 1 — Create the account curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fuser\u002Fcreate \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"name\":     \"Ada Lovelace\",\n    \"email\":    \"ada@example.com\",\n    \"password\": \"\u003Cstrong-password>\",\n    \"company\":  \"\",\n    \"country\":  \"\",\n    \"role\":     \"\",\n    \"campaign\": \"programmatic-signup\",\n    \"language\": \"en-GB\"\n  }' FieldRequiredNotesnameyesFree text. Rejected if it looks like a URL or email address — the server matches [a-z0-9@:%._+~#=]{1,256}\\.[a-z0-9()]{1,6} and bails. Keep names plain.emailyesMust not be from a disposable-email provider (the server runs an isDisposable() check and returns {\"status\": \"To prevent abuse of our free plan, please do not register with an anonymous email provider.\"} on failure).passwordyesNo length minimum enforced server-side at the moment; use something sensible.company, country, rolenoFree text. Used for analytics; pass empty strings if unknown.campaignnoFree text. Use this to mark where the signup came from (code-dashboard-signup, claude-skill, your tool name) so the team can attribute traffic.languagenoBCP 47 tag (e.g. en-GB, de-DE). Defaults to whatever the browser sends; in headless code, pass it explicitly. Response (success): the new user object. {\n  \"id\": 12345,\n  \"name\": \"Ada Lovelace\",\n  \"email\": \"ada@example.com\",\n  \"company\": \"\",\n  \"role\": \"\",\n  \"country\": \"\",\n  \"language\": \"en-GB\"\n} Response (failure): a 200 OK with a status field describing what went wrong. The endpoint doesn't use HTTP status codes for these cases — watch the status field. { \"status\": \"email_exists\" } { \"status\": \"Could not create an account, name field contains a URL or email address\" } { \"status\": \"To prevent abuse of our free plan, please do not register with an anonymous email provider.\" } Welcome email is sent automatically on success. Step 2 — Log in curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fuser\u002Flogin \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"email\": \"ada@example.com\", \"password\": \"\u003Cstrong-password>\"}' Response (success): {\n  \"id\": 12345,\n  \"name\": \"Ada Lovelace\",\n  \"email\": \"ada@example.com\",\n  \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOi...\",\n  \"refresh_token\": \"def502009b...\"\n} token is an OAuth2 access token (Bearer JWT) you'll use to authenticate the next call. It's not the long-lived API key yet — that's step 3. Response (failure): BodyMeaningnullEmail doesn't exist on the platform, or password is wrong. The endpoint deliberately collapses these into one signal to avoid leaking which case applies.\"blocked\"Account is locked out after 29 failed login attempts. Will stay locked until contact support to reset. Don't loop on this. Step 3 — Mint the long-lived API key curl https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fuser\u002Fkey\u002Fcreate \\\n  -H \"Authorization: Bearer \u003CJWT_FROM_STEP_2>\" Response: { \"token\": \"axm_...\" } This token is the long-lived API key you use everywhere else in the API — see Authentication for how it's passed. One key per account. Calling GET \u002Fapi\u002Fuser\u002Fkey\u002Fcreate on an account that already has a key invalidates the old one and returns a new one. Any existing integration using the old key stops working immediately. To check if an account already has a key without invalidating it, call GET \u002Fapi\u002Fuser\u002Fkey\u002Fhas-existing (same Bearer JWT auth) and inspect {\"result\": true|false}. End-to-end example (Node.js) const BASE = 'https:\u002F\u002Flar.axiom.ai';\n\nasync function signUpAndMintKey({ name, email, password, campaign = 'programmatic' }) {\n  \u002F\u002F Step 1 — create\n  const createRes = await fetch(`${BASE}\u002Fapi\u002Fuser\u002Fcreate`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application\u002Fjson' },\n    body: JSON.stringify({\n      name, email, password,\n      company: '', country: '', role: '',\n      campaign,\n      language: process.env.LANG?.split('.')[0]?.replace('_', '-') ?? 'en-GB',\n    }),\n  });\n  const createJson = await createRes.json();\n  if (createJson.status) {\n    \u002F\u002F status field present = an error case (email_exists, disposable, name-looks-like-url, ...)\n    throw new Error(`signup failed: ${createJson.status}`);\n  }\n\n  \u002F\u002F Step 2 — log in\n  const loginRes = await fetch(`${BASE}\u002Fapi\u002Fuser\u002Flogin`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application\u002Fjson' },\n    body: JSON.stringify({ email, password }),\n  });\n  const loginJson = await loginRes.json();\n  if (loginJson === null) throw new Error('login failed: bad credentials');\n  if (loginJson === 'blocked') throw new Error('login failed: account locked (too many failed attempts)');\n\n  \u002F\u002F Step 3 — mint API key (uses the JWT from step 2)\n  const keyRes = await fetch(`${BASE}\u002Fapi\u002Fuser\u002Fkey\u002Fcreate`, {\n    headers: { 'Authorization': `Bearer ${loginJson.token}` },\n  });\n  const keyJson = await keyRes.json();\n\n  return { user: createJson, apiKey: keyJson.token };\n}\n\n\u002F\u002F Usage\nconst { user, apiKey } = await signUpAndMintKey({\n  name: 'Ada Lovelace',\n  email: `ada+${Date.now()}@example.com`,  \u002F\u002F unique email avoids `email_exists`\n  password: process.env.NEW_ACCOUNT_PASSWORD,\n  campaign: 'my-tool-headless-signup',\n});\nconsole.log(`Provisioned ${user.email} with API key (last 6: ${apiKey.slice(-6)})`); If the account already exists Skip step 1 and just do steps 2-3: \u002F\u002F existing email + password → JWT → API key\nconst loginRes = await fetch(`${BASE}\u002Fapi\u002Fuser\u002Flogin`, {\n  method: 'POST',\n  headers: { 'Content-Type': 'application\u002Fjson' },\n  body: JSON.stringify({ email, password }),\n});\nconst { token: jwt } = await loginRes.json();\n\nconst keyRes = await fetch(`${BASE}\u002Fapi\u002Fuser\u002Fkey\u002Fcreate`, {\n  headers: { 'Authorization': `Bearer ${jwt}` },\n});\nconst { token: apiKey } = await keyRes.json(); Remember: step 3 invalidates the previous API key. If the user already had integrations wired up, you'll break them. Use GET \u002Fapi\u002Fuser\u002Fkey\u002Fhas-existing first to avoid surprising them. Abuse & rate-limit considerations Disposable-email check. Step 1 blocks signups from anonymous email providers (mailinator.com, 10minutemail.com, etc.). If your tool legitimately needs to onboard high volumes, work with the team to whitelist your domain rather than trying to bypass the check.Login lockout. 29 failed login attempts puts the account into \"blocked\" state. The lockout is not auto-cleared — the user has to email support. So loops that retry login on a bad password are dangerous.No bulk-create endpoint. If you find yourself signing up thousands of accounts programmatically, talk to the team first — at that point a different account model (team API key, multi-tenant scoping) is the right answer.Welcome email is sent on success. Every successful POST \u002Fapi\u002Fuser\u002Fcreate sends a registered-with-Axiom email. Don't use this flow for ephemeral test accounts at scale without coordinating with the team — it's a deliverability liability. Related Authentication — the manual flow + how the API key is used in subsequent requestsQuickstart — your first run after you have a keyStart a browser session — what to do with the key html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":741,"title":742,"titles":743,"content":744,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fquickstart","Quickstart",[],"Trigger a pre-built No-Code Tool automation with cURL, or drive a cloud browser from your own code with Puppeteer. There are two ways to use the axiom.ai API: trigger a pre-built No-Code Tool automation end-to-end, or connect to a cloud browser and drive it from your own code. Pick whichever matches how you want to work, the same API key authenticates both. Before you begin You need: An API key. See Authentication to generate one.For option 1: a No-Code Tool automation already saved to your account.For option 2: any environment that can open a WebSocket. Examples below use Puppeteer in Node, but Playwright, raw CDP, or any other client works the same way. Option 1: trigger a No-Code Tool automation Use this when you've built an automation in the No-Code Tool and want to run it from outside the Chrome extension, for example from Zapier, a backend service, or a cron job. Trigger the run Send a POST to \u002Ftrigger with your key and the exact name of your saved automation. curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"your-api-key-here\",\n    \"name\": \"My First Automation\"\n  }' Replace your-api-key-here with your API key, and My First Automation with the exact name of your automation. Note: automation names are case-sensitive and whitespace-sensitive. My Automation, my automation, and My  Automation (two spaces) are three different names. If you get Task not found, check the name in the Dashboard matches exactly. A successful response looks like this: {\n  \"OPEN LINK IN BROWSER\": \"\u003CLINK_TO_RUN_VIEWER>\"\n} Open the link to watch the automation run live in a noVNC view of the cloud browser. The trigger call returns as soon as the run starts; it doesn't wait for the run to finish. If your account is at its concurrency limit, the run is queued instead and the response looks like this: {\n  \"status\": \"queued\",\n  \"message\": \"Axiom could not start due to a lack of available resources. The task has been queued and will retry in five minutes.\"\n} If something else goes wrong (the automation name doesn't exist, the key is wrong, your quota is exhausted), the response looks like this: {\n  \"status\": \"error\",\n  \"message\": \"Task not found, please check the name and try again.\"\n} See API responses for every response shape and Error codes for the full list of error messages. Check the status Poll \u002Frun-data with the same name you triggered. It returns the current status of that automation's most recent run, plus any data the run has written out so far. curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Frun-data \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"your-api-key-here\",\n    \"name\": \"My First Automation\"\n  }' The response includes a status field with one of three values: Running, Success, or Failure. If it's still Running, wait a few seconds and poll again. Every 5 to 15 seconds is plenty for most automations and avoids rate limits. When the status reaches Success, the response also includes any data the automation wrote out (rows added to a Google Sheet, values returned from a custom JavaScript step, and so on). Option 2: drive a cloud browser from your code Use this when you'd rather write the automation in code than build it in the No-Code Tool. Point any Chrome DevTools Protocol client at the axiom.ai endpoint and drive the cloud browser exactly like a local one. There's nothing to install on the axiom.ai side, the endpoint is the API. const browser = await puppeteer.connect({\n  browserWSEndpoint: \"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=your-api-key-here\"\n});\n\nconst page = await browser.newPage();\nawait page.setViewport({ width: 1960, height: 1080 });\nawait page.goto(\"https:\u002F\u002Faxiom.ai\");\n\nawait new Promise(resolve => setTimeout(resolve, 5000));\n\nawait page.close();\nawait browser.close(); Replace your-api-key-here with your API key. The script connects to a fresh cloud browser, navigates to a URL, waits five seconds, and tears the session down. Drop this into whatever you already use to run code: a Node service, a serverless function, a cron job, an existing test suite. The cloud browser handles the heavy lifting (a real Chromium with networking, fonts, and resources) so your stack just sends commands and reads results. Note: the API key is passed as the token query parameter on the WebSocket URL, not in a header. Don't log this URL, treat it like a secret. The same endpoint works with Playwright (chromium.connectOverCDP(\"wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=...\")), with raw CDP libraries in Python, Go, or Ruby, or with anything else that speaks the protocol. If you just want to poke at a script before wiring it into your stack, the Live editor in the Code Dashboard runs Puppeteer code in-browser with the key auto-injected, no setup needed. It's a sandbox, not the production path. Next steps Now that you've made your first call, here's where to go next. If you used Option 1: Pass input data into a run so the same automation can act on different inputs.Stop a running automation if it's misbehaving.Wrap the API in Zapier, Make, or Apps Script for no-code integrations. If you used Option 2: See the Step API reference for axiom.ai's higher-level wrappers around the Chrome API.Check remaining runtime so long-running scripts don't run out of quota mid-task. For everyone: Build your own MCP server so Claude or another LLM client can use axiom.ai as a tool. html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}",{"id":746,"title":747,"titles":748,"content":749,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Freference\u002Fdata-payload","Data payload format",[],"Schema reference for the 3-D data array passed in axiom.ai automation triggers. The canonical reference for the data field in \u002Ftrigger requests. For tutorials, examples, and common patterns, see Pass input data. Schema data: array\u003Ctable>\n\ntable: array\u003Crow>\n\nrow: array\u003Ccell>\n\ncell: string Three levels deep, all arrays. The outermost array holds tables, each table holds rows, each row holds cells. Cells are strings. Minimal example One table, one header row, one data row: \"data\": [\n  [\n    [\"header1\", \"header2\"],\n    [\"value1\", \"value2\"]\n  ]\n] Validation rules RuleDetaildata is optionalOmit it entirely if your automation doesn't expect input.data is an arrayThe outermost element is always an array of tables, even if there's only one table.Each table is an array of rowsA table with no rows ([]) is allowed but unusual, the automation receives an empty input.Each row is an array of cellsEmpty rows ([]) cause unpredictable behaviour, avoid them.Cells are stringsNumbers and booleans are coerced to strings on the server. Pass \"42\" for clarity.Cells must not be nullUse \"\" for missing values. A null cell breaks the row.Cells must not contain nested arrays or objectsCells are flat scalars. To pass structured data, flatten across columns.All rows in a table should have the same lengthRagged rows cause column-index references to misalign. Multiple tables If the automation reads from two distinct inputs, pass them in order: \"data\": [\n  [\n    [\"url\"],\n    [\"https:\u002F\u002Fexample.com\u002Fa\"]\n  ],\n  [\n    [\"search_term\"],\n    [\"browser automation\"]\n  ]\n] The first table is the first input, the second table is the second input. Order matters and is matched positionally to the automation's input sources. Header rows Whether a header row is required depends on how the automation references columns: Automation references columns byHeader row requiredName (e.g. [url], [search_term])YesPosition (e.g. column 1, column 2)No Match the convention the automation was authored with. If unsure, open it in the Builder and inspect how the input source step references columns. Encoding The data field is JSON, sent as part of the application\u002Fjson request body.UTF-8 throughout. Non-ASCII characters in cell values are passed through unchanged.No size limit is documented per cell or per request, but very large payloads (multiple megabytes) may hit timeout or rate limit issues. For high-volume input, batch across multiple \u002Ftrigger calls instead of one giant payload. Related Pass input data (tutorial with examples and common patterns)Trigger an automation html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":751,"title":752,"titles":753,"content":754,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Freference\u002Fendpoints","Endpoints",[],"Every axiom.ai API endpoint at a glance, with method, path, required parameters, and links to full reference pages. A single-page lookup of every axiom.ai API endpoint. For full request and response details, follow the link in the rightmost column. REST endpoints The base URL for all REST endpoints is https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3. All requests are POST with a JSON body. Authentication is by API key in the key field of the body, see Authentication. MethodPathRequired body fieldsOptionalReferencePOST\u002Ftriggerkey, namedataTrigger an automationPOST\u002Flist-automationskeyList automationsPOST\u002Frun-reportskeycountList run reportsPOST\u002Frun-datakey, nameCheck run statusPOST\u002Fstoppid, pwStop a runPOST\u002Fremaining-runtimekeyCheck remaining runtime CDP endpoint For driving a cloud browser from your code, connect a Chrome DevTools Protocol client to the WebSocket endpoint below. The API key is passed as the token query parameter. ProtocolEndpointReferencewsswss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=YOUR_API_KEYStart a session Versioning The API version is part of the path. The current version is v3. Older versions are deprecated and not maintained, always use v3 in new integrations. When a future major version ships, both the new and old paths will be served in parallel for a transition period. Breaking changes within a version are avoided wherever possible. Transport and headers All requests use HTTPS, plain HTTP is not supported.The Content-Type header must be application\u002Fjson.No other custom headers are required. Specifically, the API key does not go in an Authorization header, it goes in the JSON body.All responses are JSON. Related Error codesData payload formatRate limits",{"id":756,"title":757,"titles":758,"content":759,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Freference\u002Ferrorcodes","Error codes",[],"Every axiom.ai API error response, what it means, and how to resolve it. A reference of every error response the axiom.ai API can return, with the most likely cause and how to fix it. For programmatic handling, branch on the HTTP status code first, then on the error string. Errors by HTTP status StatusMeaningCommon cause200SuccessRequest was accepted and processed. The response body indicates the actual outcome (run started, run failed, and so on).400Bad requestA required field is missing, or the request body isn't valid JSON.401UnauthorisedThe key field is missing or doesn't match an active API key.403ForbiddenYour account is over its quota for the billing period.404Not foundThe named automation doesn't exist, or the run_id is invalid or expired.429Too many requestsYou've exceeded the rate limit on this API key. Back off and retry. See Rate limits.5xxServer errorA transient issue on the axiom.ai side. Retry with backoff. Common error messages The API returns a JSON body with an error string for failures. The exact wording is subject to change, so treat the HTTP status as the canonical signal and use the error string for diagnosis. Error stringHTTP statusCauseFixTask not found, please check the name and try again.404The name in your \u002Ftrigger request doesn't match any automation in your account. Almost always a case or whitespace mismatch.Open the Dashboard and copy the automation name exactly. Names are case- and whitespace-sensitive.Invalid key401The key field is missing or doesn't match any active API key.Generate a new key, see Authentication. Remember that generating a new key invalidates the old one.Quota exceeded403Your account has used its full cloud runtime allowance for the billing period.Wait for the next billing cycle, or upgrade your plan. Check usage with \u002Fremaining-runtime.Rate limit exceeded. Try again in a few seconds.429You're calling the API faster than your tier allows.Implement exponential backoff. See Rate limits.Run not found404The run_id you passed to \u002Frun-data or \u002Fstop is invalid, expired, or wasn't created by this API key.Check the run_id matches what \u002Ftrigger returned. Run IDs are tied to the key that created them. Run status: Failure A successful API call (HTTP 200) can still report that the run itself failed. Check the status field in the \u002Frun-data response: StatusMeaningRunningRun is queued or actively executing.SuccessRun completed without errors.FailureRun hit an error inside the automation and stopped. When status is Failure, the API doesn't return the underlying error message in the response, the run failed inside the cloud browser, not at the API layer. To diagnose: Open the run in the Dashboard, every run has a detailed report with screenshots and step-level error messages.Open the viewer_url returned by \u002Ftrigger if the run is still recent enough to be available.Add an Add error metadata step to your automation. Any data it captures is included in error reports for steps after it. Browser session errors Errors driving a cloud browser via CDP appear as exceptions in your client library (Puppeteer, Playwright), not as HTTP responses. The most common: SymptomCauseFixWebSocket connection failedThe endpoint URL is wrong, or the API key in the token parameter is invalid.Check the URL is exactly wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=YOUR_API_KEY. Generate a new key if needed.Navigation timeout exceededThe target page is slow or unreachable from a datacentre IP.Increase the timeout: page.goto(url, { timeout: 60_000 }). For sites that block datacentre IPs, this won't help, the page is simply unreachable.No element found for selectorThe selector doesn't match anything on the page, or the element hasn't rendered yet.Use page.waitForSelector(selector) before clicking or typing.Browser has disconnectedYour session timed out, was closed by the server, or the API key was rotated mid-session.Reconnect with a fresh puppeteer.connect(). Wrap long-running scripts in retry logic. Always retry on A small number of error categories are safe to retry blindly with exponential backoff: HTTP 429 (rate limited).HTTP 5xx (transient server error).WebSocket connection drops on the CDP endpoint that aren't due to an invalid key. Never retry on These won't get better with retries, treat them as permanent failures and surface to your application: HTTP 400 (your request is malformed, fix the request).HTTP 401 (the key is invalid, rotate and update).HTTP 403 (out of quota, wait or upgrade).HTTP 404 (the automation or run doesn't exist, fix the reference). Related Rate limitsEndpoints",{"id":761,"title":762,"titles":763,"content":764,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Freference","Reference",[],"Lookup tables for every axiom.ai API endpoint, every error response, and the data payload schema used by triggers. The Reference section is the dev-lookup view of the axiom.ai API. Use it when you already know what you're looking for and just need the signature: a method and path on the Endpoints page, an HTTP status or error string on the Error codes page, or the schema of the input array on the Data payload format page. For tutorials and worked examples, see the per-endpoint pages under Run automations and Browser sessions. In this section Need help? Contact support or ask a question in our Reddit community.",{"id":766,"title":767,"titles":768,"content":769,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Freference\u002Fresponses","API responses",[],"Every JSON response shape returned by the axiom.ai API, including success, queued, and error variants. Every axiom.ai API endpoint returns JSON. Successful responses always include the data the endpoint promised. Queued and error responses use a status field so your code can branch on it cleanly. The full set of shapes is below, grouped by endpoint. \u002Ftrigger Three possible responses. Inspect the keys to know which one you got. Success: run started {\n  \"OPEN LINK IN BROWSER\": \"\u003CLINK_TO_RUN_VIEWER>\"\n} The link opens a live noVNC view of the cloud browser. Queued: waiting for a concurrency slot {\n  \"status\": \"queued\",\n  \"message\": \"Axiom could not start due to a lack of available resources. The task has been queued and will retry in five minutes.\"\n} See Queue and concurrency for how queueing works. Error: run did not start {\n  \"status\": \"error\",\n  \"message\": \"Task not found, please check the name and try again.\"\n} Common message values are listed in Error codes. \u002Fremaining-runtime {\n  \"status\": \"success\",\n  \"data\": {\n    \"used\": 0.47,\n    \"allowance\": 15000,\n    \"remaining\": 14999.53\n  }\n} All values are in minutes. See Check remaining runtime for field descriptions. \u002Flist-automations {\n  \"status\": \"success\",\n  \"data\": {\n    \"names\": [\n      \"Automation 1\",\n      \"Automation 2\"\n    ]\n  }\n} names are the exact strings you pass to \u002Ftrigger as the name parameter. See List automations. \u002Frun-reports {\n  \"status\": \"success\",\n  \"data\": {\n    \"reports\": [\n      {\n        \"task_name\": \"Automation Name\",\n        \"status\": \"Success\",\n        \"description\": \"Execution started with Axiom cloud version 4.6.0 (remotely triggered)\\n\\nAxiom run completed successfully!\",\n        \"created_at\": \"2025-04-10T15:14:51.000000Z\",\n        \"updated_at\": \"2025-04-10T15:15:00.000000Z\"\n      }\n    ]\n  }\n} Reports are sorted most-recent first. status is one of Running, Success, or Failure. Default is 5 reports, override with the optional count parameter. See List run reports. \u002Frun-data {\n  \"status\": \"Success\",\n  \"data\": {\n    \"google-sheet-data\": [\n      [\"A1\", \"B1\", \"C1\"],\n      [\"A2\", \"B2\", \"C2\"]\n    ]\n  }\n} status is one of Running, Success, or Failure. data is an object keyed by the token name of each writer step (typically a Google Sheet). Each value is a 2D [row][col] array of what the step wrote. See Check run status. Reading any response A robust client checks for the status field first: const data = await res.json();\n\nif (data.status === \"error\") {\n  throw new Error(data.message);\n}\nif (data.status === \"queued\") {\n  console.log(\"Queued:\", data.message);\n  return;\n}\nif (data.status === \"success\") {\n  return data.data;\n}\n\n\u002F\u002F \u002Ftrigger success has no `status` field, just the viewer link.\nif (data[\"OPEN LINK IN BROWSER\"]) {\n  return data[\"OPEN LINK IN BROWSER\"];\n} Related EndpointsError codesData payload html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":771,"title":772,"titles":773,"content":774,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Fcheck-run-status","Check run status",[],"Poll the axiom.ai API for the current status of an automation by name and retrieve any data it wrote out. The \u002Frun-data endpoint returns the current status of an automation and any data it wrote out (for example, rows added to a Google Sheet, or values returned from a custom JavaScript step). Identify the run by the automation's name, the same string you pass to \u002Ftrigger. Poll this endpoint after triggering to know when the run is finished. Request POST \u002Fapi\u002Fv3\u002Frun-data ParameterTypeRequiredDescriptionkeystringYesYour API key. See Authentication.namestringYesExact name of the automation, as it appears in the Dashboard. Case-sensitive and whitespace-sensitive. Same string you pass to \u002Ftrigger. Request payload {\n  \"key\": \"\u003CAPI_KEY>\",\n  \"name\": \"\u003CAUTOMATION_NAME>\"\n} Response {\n  \"status\": \"Success\",\n  \"data\": {\n    \"google-sheet-data\": [\n      [\"A1\", \"B1\", \"C1\"],\n      [\"A2\", \"B2\", \"C2\"]\n    ]\n  }\n} FieldTypeDescriptionstatusstringOne of Running, Success, or Failure.dataobjectData the automation wrote out, keyed by the token name of each Google Sheet (or other writer step). Each value is a 2D array of [row][col]. Status values ValueMeaningRunningThe run is in the queue or actively executing.SuccessThe run completed without errors. The data field contains any output.FailureThe run hit an error and stopped. Check the run report in the Dashboard for details. Example curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Frun-data \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"your-api-key-here\",\n    \"name\": \"My First Automation\"\n  }' A typical polling loop: async function waitForRun(name, key) {\n  while (true) {\n    const res = await fetch(\"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Frun-data\", {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application\u002Fjson\" },\n      body: JSON.stringify({ key, name }),\n    });\n    const result = await res.json();\n\n    if (result.status === \"Success\") return result.data;\n    if (result.status === \"Failure\") throw new Error(\"Run failed\");\n\n    await new Promise(r => setTimeout(r, 10_000)); \u002F\u002F poll every 10s\n  }\n} Polling cadence Poll every 5 to 15 seconds for most automations. Faster polling won't make the run finish any quicker, and may trip rate limits. For long-running automations (those that take more than a few minutes), increase the interval to 30 seconds or use exponential backoff: start at 5 seconds, double each time, cap at 60. When there's no completion webhook The API doesn't push a notification when a run finishes; polling \u002Frun-data is the only way to detect completion from outside. If you want a push-style notification, add a Trigger webhook step inside the automation itself. The automation will POST to your URL when it reaches that step, which you can place at the end of the flow to get a \"done\" signal. Notes \u002Frun-data returns the status of the most recent run of an automation with the given name. To see runs further back in history, use \u002Frun-reports.The data object is keyed by the token name of each writer step (most commonly a Google Sheet token). One automation can write to several sheets, in which case data has several keys. Each value is the 2D [row][col] content of that sheet.An automation that doesn't write any data returns data as an empty object.A run that's been queued reports Running, the same as a run that's actively executing. There's no separate Queued state today. See Queue and concurrency for ways to tell the two apart.Names are matched exactly. Case and whitespace must match the Dashboard. 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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":776,"title":777,"titles":778,"content":779,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations","Orchestrate API",[],"Trigger pre-built automations — code or no-code — pass input data, poll for results, and stop runs from outside the Chrome extension. The Orchestrate API's endpoints let you fire any pre-built automation — code or no-code — from outside the Chrome extension, then track it through to completion. Use them to wire automations into your backend, into a Zapier or Make scenario, into an MCP server, or into anywhere else that can make an HTTP request. This is the right layer when the workflow already exists in the No-Code Tool. If you'd rather author the flow in code, see the Step API — the layer below. In this section Need help? Contact support or ask a question in our Reddit community.",{"id":781,"title":782,"titles":783,"content":784,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Flist-automations","List automations",[],"Fetch the names of every saved No-Code Tool automation on your account, useful for building UIs or validating an automation name before triggering it. The \u002Flist-automations endpoint returns the names of every saved No-Code Tool automation on your account. Use it to populate a dropdown in your own UI, validate an automation name before calling \u002Ftrigger, or audit what's available to the integration. Request POST \u002Fapi\u002Fv3\u002Flist-automations ParameterTypeRequiredDescriptionkeystringYesYour API key. See Authentication. Response {\n  \"status\": \"success\",\n  \"data\": {\n    \"names\": [\n      \"Automation 1\",\n      \"Automation 2\"\n    ]\n  }\n} FieldTypeDescriptionstatusstringsuccess on a successful call, otherwise an error string.data.namesarrayArray of automation names, exactly as they appear in the Dashboard. Example curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Flist-automations \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key\": \"your-api-key-here\"}' Use the returned names to drive an automation picker in your own application: const res = await fetch(\"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Flist-automations\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n  body: JSON.stringify({ key: process.env.AXIOM_API_KEY }),\n});\nconst { data } = await res.json();\n\nconsole.log(`You have ${data.names.length} automations available.`);\ndata.names.forEach(n => console.log(` - ${n}`)); Notes Names returned here are the exact strings to pass to \u002Ftrigger as the name parameter. They're case-sensitive and whitespace-sensitive.The list includes every automation saved to the cloud on your account, including ones you haven't run recently. 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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}",{"id":786,"title":787,"titles":788,"content":789,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Fpass-input-data","Pass input data",[],"Send dynamic input into a No-Code Tool automation when triggering it via the API, using the table-shaped data payload. The \u002Ftrigger endpoint accepts an optional data field that's passed into the automation as if you'd uploaded a spreadsheet. This lets the same automation act on different inputs each time it runs, fetching different URLs, filling forms with different values, scraping different search terms, and so on. The data shape The data field is an array of tables. Each table is an array of rows, and each row is an array of cell values. Three levels deep: data\n└── tables (array)\n    └── rows (array)\n        └── cells (array of strings) A minimal payload with one table and one data row: \"data\": [\n  [\n    [\"header1\", \"header2\"],\n    [\"value1\", \"value2\"]\n  ]\n] The outermost array is the list of tables. Most automations only consume one table, but you can pass several if the automation reads from multiple sources. Why three levels deep The shape mirrors how the No-Code Tool handles spreadsheets and CSVs internally. When you upload a Google Sheet to an automation in the Builder, you're handing it a table of rows and cells. The API just lets you skip the upload step, you pass the same shape directly. This means you don't pass key-value objects like { \"email\": \"x@y.com\" }. You pass rows of values, and the automation's steps reference them positionally (column 1, column 2, and so on). A complete example An automation called Scrape product page that visits a list of URLs and writes results back to a Google Sheet: curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"your-api-key-here\",\n    \"name\": \"Scrape product page\",\n    \"data\": [\n      [\n        [\"url\"],\n        [\"https:\u002F\u002Fexample.com\u002Fproduct\u002F1\"],\n        [\"https:\u002F\u002Fexample.com\u002Fproduct\u002F2\"],\n        [\"https:\u002F\u002Fexample.com\u002Fproduct\u002F3\"]\n      ]\n    ]\n  }' The automation receives a single table with one column (url) and three data rows, then loops over them. Multiple tables If the automation reads from two distinct inputs, pass two tables in order: \"data\": [\n  [\n    [\"search_term\"],\n    [\"browser automation\"],\n    [\"web scraping\"]\n  ],\n  [\n    [\"target_url\"],\n    [\"https:\u002F\u002Fexample.com\u002Flog\"]\n  ]\n] The first table is referenced as the first input in the automation, the second table as the second input. Header rows Whether the automation expects a header row depends on how it was authored. Match what you'd upload as a Google Sheet for the same automation: if you'd include a header row in the sheet, include one here. When in doubt, open the automation in the Builder and look at how the input source is configured. If it references columns by name, you need a header row. If it references them by position, you don't. Cell value rules Use strings. Numbers and booleans are coerced to strings on the server, so passing \"42\" and 42 produces the same result.Use empty strings for missing values, not null. A null cell breaks the row alignment.Don't nest objects or arrays inside a cell. Cells are flat scalar values. To pass structured data, flatten it across multiple columns. Common pitfalls Forgetting the outer array. Sending [[\"a\",\"b\"],[\"c\",\"d\"]] (two levels) instead of [[[\"a\",\"b\"],[\"c\",\"d\"]]] (three levels) is silently misinterpreted as multiple single-cell rows. Always count the brackets.Mismatched row lengths. Every row should have the same number of cells as the header row. Ragged rows cause unpredictable behaviour in steps that reference columns by index.Trailing empty rows. Some authors strip trailing empties; others count them. If your automation processes \"every row,\" include only the rows you actually want processed. Related Trigger an automationCheck run status html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}",{"id":791,"title":792,"titles":793,"content":794,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Frun-reports","List run reports",[],"Fetch a list of recent automation runs on your account, each with its status, description, and timestamps. The \u002Frun-reports endpoint returns recent runs on your account, each with the automation name, status, description, and timestamps. Use it to check whether a recently triggered run has finished, to build a run-history view in your own dashboard, or to audit what your integration has been doing. Request POST \u002Fapi\u002Fv3\u002Frun-reports ParameterTypeRequiredDescriptionkeystringYesYour API key. See Authentication.countnumberNoNumber of reports to return. Defaults to 5. Request payload {\n  \"key\": \"\u003CAPI_KEY>\",\n  \"count\": 10\n} Response {\n  \"status\": \"success\",\n  \"data\": {\n    \"reports\": [\n      {\n        \"task_name\": \"Automation Name\",\n        \"status\": \"Success\",\n        \"description\": \"Execution started with Axiom cloud version 4.6.0 (remotely triggered)\\n\\nAxiom run completed successfully!\",\n        \"created_at\": \"2025-04-10T15:14:51.000000Z\",\n        \"updated_at\": \"2025-04-10T15:15:00.000000Z\"\n      }\n    ]\n  }\n} FieldTypeDescriptionstatusstringsuccess on a successful call, otherwise an error string.data.reportsarrayArray of run reports, most recent first.reports[].task_namestringName of the automation that ran, matching the name passed to \u002Ftrigger.reports[].statusstringOne of Running, Success, or Failure.reports[].descriptionstringHuman-readable run summary, including the cloud version and any failure details.reports[].created_atstringISO 8601 UTC timestamp of when the run started.reports[].updated_atstringISO 8601 UTC timestamp of the most recent status change. Example curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Frun-reports \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key\": \"your-api-key-here\"}' A common pattern is to trigger a run, then poll \u002Frun-reports until your task's most recent report shows Success or Failure: const KEY = process.env.AXIOM_API_KEY;\nconst TASK = \"My First Automation\";\n\nawait fetch(\"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n  body: JSON.stringify({ key: KEY, name: TASK }),\n});\n\nwhile (true) {\n  await new Promise(r => setTimeout(r, 10000));\n  const res = await fetch(\"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Frun-reports\", {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application\u002Fjson\" },\n    body: JSON.stringify({ key: KEY }),\n  });\n  const { data } = await res.json();\n  const latest = data.reports.find(r => r.task_name === TASK);\n  if (latest && latest.status !== \"Running\") {\n    console.log(`Run finished with status: ${latest.status}`);\n    break;\n  }\n} Notes Reports are returned most-recent first based on created_at.Each call to \u002Frun-reports counts against the 100-per-minute rate limit. Don't poll faster than once every 5 to 15 seconds.description can contain multi-line text including stack traces for failed runs. Render it as preformatted text, not HTML, to preserve formatting.The endpoint returns recent runs only. There's no historical archive accessible over the API today. 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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}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 .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}",{"id":796,"title":797,"titles":798,"content":799,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Fstop-a-run","Stop a run",[],"Cancel a triggered automation that's still running in the cloud, freeing the concurrency slot for other runs. The \u002Fstop endpoint cancels an in-flight cloud run. Use it when an automation is taking longer than expected, when your application logic determines the run is no longer needed, or when you need to free a concurrency slot for a more urgent run. Unlike most other axiom.ai endpoints, \u002Fstop does not take your API key plus an automation name. It takes two values that are unique to a single live run: pid and pw. Both are extracted from the viewer URL that \u002Ftrigger returns. Request POST \u002Fapi\u002Fv3\u002Fstop ParameterTypeRequiredDescriptionpidstringYesInternal run identifier. The last two digits of the host name in the viewer URL. See How to get pid and pw below.pwstringYesUnique password for the run, also extracted from the viewer URL. Changes for every run. Request payload {\n  \"pid\": \"\u003CPID>\",\n  \"pw\": \"\u003CPASSWORD>\"\n} Example curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Fstop \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"pid\": \"02\",\n    \"pw\": \"your-run-password\"\n  }' How to get pid and pw When you trigger a run, the response includes a viewer URL. The viewer URL contains a longer host that embeds both values. Example: dev-c-0002-v4-proxy.axiom.ai&port=443&password=abc123xyz&taskId=22842 From this URL: pid is the last two digits of the host name. In the example above, the host is dev-c-0002-v4-proxy.axiom.ai, so pid is 02.pw is the value of the password query parameter. In the example, pw is abc123xyz. Both values are tied to one specific run. They change every time you trigger. When to stop a run Common reasons to call \u002Fstop: The user cancelled the request that triggered the run. If your application kicked off a run for a user-initiated action and the user backs out, stop the run rather than letting it complete.The run is taking too long. Some runs hang on a slow page or a captcha. If you have an SLA, stop the run after a deadline and surface the failure to your application.You triggered duplicates. If your trigger logic accidentally fires the same run twice, stop the duplicate before it starts consuming runtime.You need a concurrency slot for something more urgent. Stopping a queued or low-priority run frees a slot immediately for the next trigger. What happens to a stopped run A stopped run reports Failure from \u002Frun-data after cancellation. Any partial output the automation had already written (rows added to a Google Sheet, files downloaded) stays where it was written; the cleanup is your responsibility. Stopped runs still count against your runtime allowance for the time they were actually executing. A queued run that's stopped before it starts uses no runtime. Notes You must extract pid and pw from the viewer URL at trigger time. There's no way to look them up later from your API key alone, so store them if you might need to stop the run.Stopping a run that's already finished (status Success or Failure) is a no-op; the call returns successfully without doing anything.There's no way to \"pause\" a run today, only stop. If you need to interrupt a long-running flow and resume later, design the automation around \u002Ftrigger calls that pick up where the previous one left off (for example, by reading a checkpoint from a Google Sheet).Stopping a run doesn't undo any external side effects the automation produced before the stop signal arrived. If the automation sent emails, made API calls, or moved money, those actions are not reversed. 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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}",{"id":801,"title":802,"titles":803,"content":804,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Ftrigger-an-automation","Trigger an automation",[],"Start a saved No-Code Tool automation in the cloud by name, with optional input data passed in the request body. The \u002Ftrigger endpoint starts a cloud run of a saved No-Code Tool automation. The automation must already exist in your account and be saved to the cloud. The call returns immediately with a viewer link, or with a queued\u002Ferror response if the run could not start. Request POST \u002Fapi\u002Fv3\u002Ftrigger ParameterTypeRequiredDescriptionkeystringYesYour API key. See Authentication.namestringYesExact name of the automation, as it appears in the Dashboard. Case-sensitive and whitespace-sensitive.dataarrayNoInput data passed into the automation. See Pass input data for the shape. Response The response shape depends on what happened. Three variants: Success: run started {\n  \"OPEN LINK IN BROWSER\": \"\u003CLINK_TO_RUN_VIEWER>\"\n} FieldTypeDescriptionOPEN LINK IN BROWSERstringURL to a live noVNC view of the cloud browser. Useful for watching the run in real time or sharing a screencast with support. Queued: run accepted but waiting for a slot {\n  \"status\": \"queued\",\n  \"message\": \"Axiom could not start due to a lack of available resources. The task has been queued and will retry in five minutes.\"\n} FieldTypeDescriptionstatusstringqueued when the call was accepted but no concurrency slot is free yet.messagestringHuman-readable description of what's happening and when the run will be retried. See Queue and concurrency for details on how queueing works. Error: run did not start {\n  \"status\": \"error\",\n  \"message\": \"Task not found, please check the name and try again.\"\n} FieldTypeDescriptionstatusstringerror when the call failed.messagestringDescription of what went wrong. See Errors below for common messages. Example curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"your-api-key-here\",\n    \"name\": \"My First Automation\"\n  }' With input data: curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"your-api-key-here\",\n    \"name\": \"Scrape product page\",\n    \"data\": [\n      [\"url\"],\n      [\"https:\u002F\u002Fexample.com\u002Fproduct\u002F1\"],\n      [\"https:\u002F\u002Fexample.com\u002Fproduct\u002F2\"]\n    ]\n  }' data is a 2D array of [row][col]. The first row is typically a header. See Pass input data for the full format and how to consume it inside an automation with the Receive data from another app step. Errors ResponseCauseTask not found, please check the name and try again.The name doesn't match any automation in your account. Almost always a case or whitespace mismatch.Invalid keyThe key is missing or doesn't match an active API key. Generate a new one in the Dashboard.Quota exceededYour account has used its full cloud runtime allowance for the billing period. See Check remaining runtime. Notes Triggering a run never returns a \"concurrency limit\" error. If your account is already at its concurrent-run limit, the new run is queued and the call returns a queued response (see above). See Queue and concurrency.To track a run after triggering, poll \u002Frun-data with the same name you triggered. It returns the current status of that automation's most recent run.Names are matched exactly. My Automation, my automation, and My  Automation (two spaces) are three different names. If you keep getting Task not found, copy the name directly from the Dashboard rather than retyping it.Only the latest saved version of the automation runs. There's no way to pin to an older revision via the API today. 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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}",{"id":806,"title":807,"titles":808,"content":809,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Frun-automations\u002Fwebhooks-from-a-step","Webhooks from a step",[],"Use webhook steps inside an automation to push data to external services or trigger an automation from inbound webhooks. Webhooks in axiom.ai are not part of the REST API surface, they are step types you add inside an automation. This page explains the two webhook step types and how they relate to \u002Ftrigger. Trigger vs webhook steps Two different directions, two different mechanisms: DirectionUse thisWhat it doesExternal system → axiom.ai\u002Ftrigger (REST endpoint)An external service tells axiom.ai to start an automation.External system → axiom.aiReceive data from another app (step)An automation step waits for inbound data from a webhook URL axiom.ai provides.axiom.ai → external systemTrigger webhook (step)An automation step POSTs collected data to a URL you provide, mid-run. Use \u002Ftrigger when your code is the orchestrator and axiom.ai is one of many things it kicks off. Use webhook steps when the automation itself is the orchestrator, calling out to other services as it runs. Send data to an external service mid-run Add a Trigger webhook step anywhere in your automation. When the run reaches it, axiom.ai POSTs the configured payload to your URL. Common patterns: End-of-run notification. Place a Trigger webhook step at the end of the automation. Your service receives a POST when the run finishes, removing the need to poll \u002Frun-data.Streaming results. Inside a Loop through data step, add a Trigger webhook step. Each iteration of the loop POSTs its result to your service, useful for processing scraped data in real time rather than waiting for the whole automation to finish.Branching to external logic. Use Trigger webhook to hand off to a serverless function that does something axiom.ai can't, then continue the automation with the function's response. Receive data from an external service Add a Receive data from another app step at the start of your automation (or wherever you want to consume external data). The step provides a webhook URL you give to your external service. Data POSTed to that URL is available to subsequent steps as if it had been entered manually. This is separate from \u002Ftrigger. The differences: \u002Ftrigger starts a run and accepts an optional data payload.Receive data from another app runs as part of an automation that's already executing, pulling data in mid-flow. If you need to start a run AND pass data, use \u002Ftrigger with the data parameter, see Pass input data. Use Receive data from another app when you want a step inside a longer automation to pause and wait for external input. Configuration and security Both webhook step types are configured inside the Builder, not via the API. Open the relevant step's reference page for the configuration fields and authoring details: Trigger webhookReceive data from another app For inbound webhook URLs, treat the URL itself as a secret. Anyone who knows the URL can POST data into your automation. Rotate the URL (by re-creating the step) if you suspect it's been exposed. Related Trigger an automationCheck run status",{"id":811,"title":812,"titles":813,"content":814,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fclick","Click",[],"Click a button, link, or any other element in a cloud browser session by passing a CSS selector to axiom.click(). axiom.click(select) clicks the first element on the page that matches a CSS selector. The same step type as the No-Code Tool's Click element, called from your code with a selector you choose at runtime. Signature await axiom.click(select, leftClickRightClick, optionalClick); ParameterTypeRequiredDefaultDescriptionselectstringYes—CSS selector for the element to click.leftClickRightClickstringNo\"left\"\"left\" or \"right\". Use \"right\" to fire a context-menu click.optionalClickbooleanNofalseWhen true, the call resolves successfully even if the selector matches zero elements. Useful for \"click if present\" cleanups (close-banner, accept-cookies). If the selector matches multiple elements, only the first is clicked. For batched clicks, use axiom.clickMultiple(). Example await axiom.browserOpen();\nawait axiom.goto(\"https:\u002F\u002Fexample.com\u002Flogin\");\nawait axiom.click(\"button[type=submit]\"); Common patterns Optional dismiss. Cookie banners and consent modals only appear sometimes. With optionalClick, the step is a no-op when they're absent: await axiom.click(\"#cookie-accept\", \"left\", true); Right-click for context menus. await axiom.click(\".file-row\", \"right\"); Notes Hidden, zero-size, or disabled elements throw an error unless optionalClick is true.Selectors operate on the top-level document only. Elements inside iframes are not reachable today.For elements without a stable selector (no ID, no class), use a more specific path like nav > ul > li:nth-child(3) > a. Related Click multipleHoverEnter text 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 .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 .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}",{"id":816,"title":817,"titles":818,"content":819,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fclick-and-drag","Click and drag",[],"Press the mouse at one coordinate, drag to another, and release using axiom.clickAndDrag(). Useful for sliders, range pickers, drag-and-drop UIs, and slider captchas. axiom.clickAndDrag(startCoordinates, endCoordinates) presses the mouse at one coordinate, drags to another, and releases. Use it for sliders, drag-and-drop UIs, and any control that responds to a press-move-release rather than a click. The same step type as the No-Code Tool's Mouse click & drag. Signature await axiom.clickAndDrag(startCoordinates, endCoordinates); ParameterTypeRequiredDescriptionstartCoordinatesobjectYes{ scrollX, scrollY, clientX, clientY }. Where the mouse-down event fires.endCoordinatesobjectYes{ scrollX, scrollY, clientX, clientY }. Where the mouse-up event fires. scrollX \u002F scrollY are the page-relative coordinates (the document position). clientX \u002F clientY are viewport-relative. For most ordinary drag operations on a page that isn't scrolled in either axis, the four values are equal pairwise. Example Slide a range control from x=100 to x=300 on the same horizontal line (y=400): await axiom.clickAndDrag(\n  { scrollX: 100, scrollY: 400, clientX: 100, clientY: 400 },\n  { scrollX: 300, scrollY: 400, clientX: 300, clientY: 400 }\n); Notes This step works in raw coordinates, not selectors. To anchor a drag to an element, compute the element's bounding box in a previous step (in the No-Code Tool the selector tool does this for you) and pass the result.For drag operations that depend on HTML5 drag-and-drop events (dragstart, dragover, drop), some sites won't respond to a synthesized mouse drag. Test before relying on this for HTML5 drag UIs. Related ClickHover 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 .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 .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}",{"id":821,"title":822,"titles":823,"content":824,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fclick-engagement-button","Click engagement button",[],"Click a like, follow, subscribe, or similar toggle only when it isn't already in the target state, using axiom.clickEngagementButton(). axiom.clickEngagementButton(select, setValueToCheck) clicks a toggle button (like, follow, subscribe) only when its visible label doesn't already match the target state. Use it to make like\u002Ffollow steps idempotent — running them twice won't accidentally unlike or unfollow. Signature await axiom.clickEngagementButton(select, setValueToCheck); ParameterTypeRequiredDescriptionselectstringYesCSS selector for the button.setValueToCheckstringYesText that indicates the button is already in the target state. If the button's text matches, the step is a no-op. Example Follow a user, but only if they're not already followed: await axiom.clickEngagementButton(\"button.follow-action\", \"Following\"); If the button reads \"Follow\", the step clicks it. If it already reads \"Following\", the step is a no-op. The same step type as the No-Code Tool's Click engagement button. Notes The match is on the button's visible text. Aria-pressed or other state attributes are ignored.For non-toggle buttons (where clicking again does something different rather than reverting), use axiom.click() instead. Related Click 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":826,"title":827,"titles":828,"content":829,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fclick-multiple","Click multiple",[],"Click every element matching a CSS selector, up to a maximum, using axiom.clickMultiple(). axiom.clickMultiple(select) clicks every element that matches a CSS selector, up to a cap. The same step type as the No-Code Tool's Click multiple elements, called from your code. Signature await axiom.clickMultiple(select, leftClickRightClick, maxClicks); ParameterTypeRequiredDefaultDescriptionselectstringYes—CSS selector matching the elements to click.leftClickRightClickstringNo\"left\"\"left\" or \"right\".maxClicksnumberNounlimitedCap on how many elements to click. Use this to bound runtime on pages that match more elements than you want to act on. Example Expand every collapsed section on a page (up to 20): await axiom.clickMultiple(\".section-header.collapsed\", \"left\", 20); Notes Elements are clicked in document order.Hidden, zero-size, or disabled elements throw — there's no \"skip if not clickable\" mode on this method. For a defensive pass, loop on axiom.click() with optionalClick: true instead.For per-element work (read state, decide whether to click, click), drive the loop in your own code with axiom.click() rather than clickMultiple. Related ClickClick engagement button 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 .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 .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}",{"id":831,"title":832,"titles":833,"content":834,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fclose-a-session","Close a session",[],"Close the cloud browser session to free its resources and stop consuming runtime quota. axiom.browserClose() closes the session and frees its resources. Cloud sessions consume runtime quota for their entire open lifetime, so always close yours when you're done. The cleanest pattern is to wrap your work in a try \u002F finally block so the close happens even if your code throws. Signature await axiom.browserClose(cdpLink); ParameterTypeRequiredDefaultDescriptioncdpLinkstringNoaxiom.cdpLink cached from the last browserOpen()Pod CDP endpoint to close. Pass an explicit value only when closing a session you opened from a different AxiomApi instance (rare). Returns the server's confirmation message string. The standard pattern import { AxiomApi } from 'axiom-api';\n\nconst axiom = new AxiomApi(process.env.AXIOM_API_KEY);\nawait axiom.browserOpen();\ntry {\n  await axiom.goto(\"https:\u002F\u002Fexample.com\");\n  \u002F\u002F ... your automation\n} finally {\n  await axiom.browserClose();\n} The finally block runs whether your code succeeds or throws, so the session always closes. Without it, an unhandled error leaks the session and you keep paying for runtime until the server reaps it. What happens when a session is closed The cloud Chromium instance shuts down immediately.Any in-flight network requests are cancelled.Cookies, localStorage, and any other in-memory state for the session is discarded.Runtime stops accruing against your remaining runtime.Subsequent calls on the same axiom instance throw until you call browserOpen() again. Notes Idle sessions are eventually timed out by the server, but this is not immediate. A leaked session can rack up several minutes of runtime before being reaped.There's no way to reconnect to a closed session. If you need to resume work later, store the relevant state (URL, form values) in your own code and re-apply it on the next session.For long-running scripts that do many independent tasks, prefer opening and closing a session per task rather than holding one open for the whole duration. Fresh sessions are more reliable and easier to reason about. Related Start a sessionCheck remaining runtime 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 .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 .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 .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":836,"title":837,"titles":838,"content":839,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fdate-picker","Date picker",[],"Navigate a calendar widget month by month and pick a target day using axiom.datePicker(). axiom.datePicker(selectMonth, selectMonthChangeButton, changeMonthTo, changeDayOfMonthTo) drives a calendar-widget date picker: it advances the calendar until the visible month matches your target, then clicks the day. The same step type as the No-Code Tool's Date picker. Signature await axiom.datePicker(selectMonth, selectMonthChangeButton, changeMonthTo, changeDayOfMonthTo); ParameterTypeRequiredDescriptionselectMonthstringYesCSS selector for the element that displays the currently shown month (e.g. the calendar's header).selectMonthChangeButtonstringYesCSS selector for the \"next month\" button on the widget. The step clicks it until the displayed month matches changeMonthTo.changeMonthTostringYesThe target month name (e.g. \"June 2026\"). Matched fuzzily against the text of selectMonth so a small format difference is tolerated.changeDayOfMonthTostringYesThe target day (e.g. \"15\"). The step clicks the closest matching day cell. Example await axiom.click(\"#checkin-date\");           \u002F\u002F open the picker\nawait axiom.datePicker(\n  \".calendar .month-header\",                  \u002F\u002F selectMonth\n  \".calendar .next-month-button\",             \u002F\u002F selectMonthChangeButton\n  \"June 2026\",\n  \"15\"\n); Notes This step is built for forward navigation only — it clicks selectMonthChangeButton repeatedly. If your target month is in the past relative to the picker's initial month, pass the \"previous month\" button as selectMonthChangeButton instead.The day match picks the calendar cell closest in document order. On months where the first\u002Flast few cells belong to the previous\u002Fnext month, this can occasionally pick the wrong cell — verify your selector targets only the current month's day cells.For non-widget date inputs (\u003Cinput type=\"date\">), use axiom.enterText() with an ISO date string instead. Related ClickSelect list 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":841,"title":842,"titles":843,"content":844,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fenter-text","Enter text",[],"Enter text into an input, textarea, or other focusable element in a cloud browser session using axiom.enterText(). axiom.enterText(selectTextField, text) enters text into the first element matching a CSS selector. The same step type as the No-Code Tool's Enter text, called from your code. Signature await axiom.enterText(selectTextField, text, delay, appendExisting, customLineBreak, optionalText); ParameterTypeRequiredDefaultDescriptionselectTextFieldstringYes—CSS selector for the input.textstringYes—Text to enter into the input.delaynumberNo0Per-keystroke delay in milliseconds. Use a non-zero value (e.g. 50–100) when target sites debounce input or run keystroke-based validation.appendExistingbooleanNofalseWhen true, appends to the field's current value instead of replacing it.customLineBreakstring | nullNonullToken in text to translate into a real newline keypress. Use this when the field treats Enter as \"submit\" but you want literal multi-line input.optionalTextbooleanNofalseWhen true, the call resolves successfully even if the selector matches zero elements. Example await axiom.browserOpen();\nawait axiom.goto(\"https:\u002F\u002Fexample.com\u002Flogin\");\nawait axiom.enterText(\"#email\", \"user@example.com\");\nawait axiom.enterText(\"#password\", process.env.PW);\nawait axiom.click(\"button[type=submit]\"); Common patterns Slow down for picky inputs. Search-as-you-type fields and React-controlled inputs sometimes drop characters when typed instantly. A small per-character delay fixes most cases: await axiom.enterText(\"#search\", \"ergonomic keyboard\", 60); Append rather than replace. By default enterText replaces the field's contents. Set appendExisting to true to add to it: await axiom.enterText(\"textarea#notes\", \"\\n\\nUpdated \" + new Date().toISOString(), 0, true); Multi-line text without submitting. If the form treats Enter as submit, escape line breaks with a custom token and pass it as customLineBreak: await axiom.enterText(\"textarea\", \"line one\u003CBR>line two\u003CBR>line three\", 0, false, \"\u003CBR>\"); Notes Best results on \u003Cinput> and \u003Ctextarea>. Behaviour on contenteditable divs and custom controls (rich-text editors, code editors) varies — test before relying on it.For control keys (Tab, Enter, arrow keys) on their own, use axiom.pressKeys().The element must be focusable. Disabled, hidden, or zero-size inputs throw an error unless optionalText is true. Related Press keysClickSelect list 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 .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 .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}",{"id":846,"title":847,"titles":848,"content":849,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fget-clipboard-contents","Get clipboard contents",[],"Read the contents of the cloud browser's clipboard, useful for pages that put their copy output on the clipboard rather than in the DOM. axiom.getClipboardContents() returns the current contents of the cloud browser's clipboard as a string. Use it to retrieve data from pages that respond to a \"copy\" button by putting the result on the clipboard rather than rendering it into the DOM. Signature const text = await axiom.getClipboardContents(); No parameters. Returns the clipboard contents as a string. Example Trigger a page's \"copy share link\" button and read the link off the clipboard: await axiom.click(\"button.copy-share-link\");\nconst shareLink = await axiom.getClipboardContents();\nconsole.log(shareLink); Notes The clipboard belongs to the cloud browser session, not your local machine. Reading the clipboard from your machine after the session finishes is a separate problem (use a sheet, an HTTP call, or any other output channel from your code).The clipboard is shared across all tabs in the session. Successive clicks that each copy to the clipboard will overwrite each other — read between clicks.Returns an empty string when the clipboard is empty. Related ClickScrape html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":851,"title":852,"titles":853,"content":854,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fgoto","Go to URL",[],"Send the cloud browser session to a URL using axiom.goto() and wait for the page to load. axiom.goto(url) sends the session's page to a URL and resolves once the page has loaded. The same step type as the No-Code Tool's Go to page, called from your code. Signature await axiom.goto(url, doNotShareLocalstorage, openInNewTab); ParameterTypeRequiredDefaultDescriptionurlstringYes—URL to navigate to. Must use http or https scheme.doNotShareLocalstoragebooleanNofalseWhen true, isolates localStorage from any previously visited origins in the session.openInNewTabbooleanNofalseWhen true, opens the URL in a new tab rather than reusing the current page. Example await axiom.browserOpen();\nawait axiom.goto(\"https:\u002F\u002Fexample.com\u002Flogin\"); URL constraints Only http and https URLs are accepted. Other schemes are rejected: file:\u002F\u002F: the cloud sandbox has no local filesystem.data:: not supported.chrome:\u002F\u002F: browser-internal pages are not exposed. Notes The cloud browser uses a datacentre IP. Some sites block known datacentre ranges with bot detection, expect this on those targets.The call resolves once the page's load event fires. For pages that finish their real work after load (single-page apps, lazy-loaded content), insert an axiom.wait() before the next step, or retry the next step with your own loop.There's no wait-for-selector method today. Use axiom.wait() for a fixed pause, or retry your next call until it stops throwing. Related ClickWaitSwitch browser tab 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":856,"title":857,"titles":858,"content":859,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fhover","Hover",[],"Move the mouse over an element to trigger hover-only UI (dropdown menus, tooltips, lazy-loaded content) using axiom.hover(). axiom.hover(select) moves the mouse pointer over the first element matching a CSS selector and fires the corresponding mouseover events. Use this to open dropdown menus, surface tooltips, or trigger lazy-loaded content that only appears on hover. The same step type as the No-Code Tool's Rollover element. Signature await axiom.hover(select); ParameterTypeRequiredDescriptionselectstringYesCSS selector for the element to hover over. Example Open a hover-only navigation menu, then click an item inside it: await axiom.hover(\"nav .menu-trigger\");\nawait axiom.click(\".dropdown-menu .item-settings\"); Notes The hover persists until the next mouse move. A subsequent axiom.click() elsewhere on the page will move the mouse and dismiss any hover-revealed UI — chain hover and click without other interleaved steps.Some sites use focus-based dropdowns rather than hover. For those, axiom.click() the trigger instead.Selectors operate on the top-level document only. Related ClickClick and drag 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":24,"title":25,"titles":861,"content":862,"level":56},[],"Drive a cloud browser session step by step (goto, click, enter text, wait, scrape) choosing each action based on what the previous one returned. The Step API is our library of step functions wrapping the Chrome API with high-level browser actions you call against a cloud browser session, one at a time, choosing each step based on what the previous one returned. Open a session, fire goto, click, enterText, scrape, and so on, then close the session when you're done. Use this when you want to drive a browser dynamically from your code rather than running a pre-built automation end to end. Under the hood, the step functions run as HTTP calls against the cloud browser's pod. Each call goes to POST \u002Fapi\u002Fv5\u002Fstep (or \u002Fapi\u002Fv5\u002Fbrowser\u002Fopen \u002F \u002Fapi\u002Fv5\u002Fbrowser\u002Fclose for lifecycle). You have three ways to drive a session — pick whichever fits your stack. How to call them axiom-api Node library The canonical wrapper. npm install, instantiate, and call the named methods: axiom.goto(), axiom.click(), axiom.enterText(), axiom.scrape(), and so on. Node only; not required, but saves you from writing the HTTP boilerplate and handles transparent retries when a long-running step's request times out. npm install axiom-api See Start a session for the full instantiate-and-open flow. Puppeteer or any CDP client If you'd rather have full Chrome DevTools Protocol control than the high-level step-function helpers, point any CDP-speaking client at the cloud browser WebSocket directly. You get every Puppeteer method, just running on our infrastructure instead of your own. wss:\u002F\u002Fcdp-lb.axiom.ai\u002F?token=YOUR_API_KEY See Authentication for how the key is passed, and Endpoints for the canonical list. MCP server Expose step functions as MCP tools so Claude or another LLM client can drive a session step by step. See Build your own MCP server for the patterns and reference implementations. When to use this vs other layers You want toUseRun a pre-built No-Code Tool automation from start to finish\u002FtriggerRun a pre-authored Puppeteer \u002F CDP script in the cloudRun a Code Dashboard automationDrive a session step by step, choosing each action based on the pageThis section \u002Ftrigger and the Code Dashboard path are fully pre-authored (the workflow is baked in). The Step API gives you scripted high-level actions with the dynamism of choosing each call at runtime. Session lifecycle A session is an isolated cloud browser. Open one with axiom.browserOpen(), drive it with the action methods, then close it with axiom.browserClose(). Sessions left open consume runtime quota, so always close yours. new AxiomApi(key)   →   axiom.browserOpen()\n                              │\n                              ├─ axiom.goto(url)\n                              ├─ axiom.click(selector)\n                              ├─ axiom.enterText(selector, text)\n                              ├─ axiom.pressKeys(\"Enter\")\n                              ├─ axiom.scrape(url, selector, ...)\n                              ├─ axiom.wait(2000)\n                              │\n                              ▼\n                         axiom.browserClose() Available step methods MethodPurposebrowserOpen() \u002F browserClose()Open \u002F close the session.goto(url, ...)Navigate the page to a URL.click(select, ...)Click an element.clickMultiple(select, ...)Click every matching element up to a max.clickEngagementButton(select, ...)Toggle a like\u002Ffollow\u002Fsubscribe-style button only if it isn't already in the target state.hover(select)Hover the mouse over an element.clickAndDrag(start, end)Mouse-press at one coordinate, release at another.enterText(selectTextField, text, ...)Enter text into an input.pressKeys(key, ...)Fire keyboard events (Enter, Tab, arrow keys, …).selectList(select, text)Pick an option in a \u003Cselect> dropdown.datePicker(...)Navigate a calendar widget and pick a date.getClipboardContents()Read the cloud browser's clipboard (after a copy step).switchBrowserTab(selectTab)Switch the active tab in the session.scrape(url, selector, pager, max_results, settings)Smart-scrape a list of records, optionally paginating.scrapeMetadata(metadata)Pull structured fields (title, description, OG tags, …) from the current page.integrateAI(aiOptions)Run an LLM call inline (summarise, classify, extract).solveCaptcha(apiKey)Hand the current page's captcha to a solver.wait(time)Pause the session on the pod for time milliseconds (keeps the session alive).restartBrowser()Restart the cloud browser within the same session. End-to-end example A canonical \"log in, scrape, store\" flow: import { AxiomApi } from 'axiom-api';\n\nconst axiom = new AxiomApi(process.env.AXIOM_API_KEY);\n\nawait axiom.browserOpen();\ntry {\n  await axiom.goto(\"https:\u002F\u002Fexample.com\u002Flogin\");\n  await axiom.enterText(\"#email\", \"user@example.com\");\n  await axiom.enterText(\"#password\", process.env.PW);\n  await axiom.click(\"button[type=submit]\");\n  await axiom.wait(2000);\n\n  const rows = await axiom.scrape(\n    null,                       \u002F\u002F stay on the current page\n    \".product-card\",            \u002F\u002F record selector\n    null,                       \u002F\u002F no pagination\n    50,                         \u002F\u002F max results\n    {}                          \u002F\u002F default settings\n  );\n  \u002F\u002F ... persist `rows` somewhere\n} finally {\n  await axiom.browserClose();\n} Synchronous-feeling, with async safety net Each step method makes a single HTTP request that blocks until the pod returns the step's result. If the request times out at the network layer or the pod reports that a step is already in flight, the library transparently polls POST \u002Fapi\u002Fv5\u002Fstep\u002Fresult with exponential backoff until the step finishes (default deadline: 1 hour). You write straight-line code; the library handles long-running steps and flaky connections. What's not exposed yet The step-trigger surface is intentionally focused on common interaction primitives. Things you'd need to work around today: Raw page text \u002F HTML readout. No getText() \u002F getHtml() method. Use axiom.scrape() for record extraction or axiom.scrapeMetadata() for page-level fields. For anything more bespoke, fall back to \u002Ftrigger with a Get data step.Screenshots. Not exposed. Use a No-Code Tool automation with Save screenshot locally and trigger via \u002Ftrigger.File upload \u002F download. Not exposed.Iframe traversal. Selectors operate on the top-level document only.Direct JS evaluation. No evaluate() method. For arbitrary JS, use \u002Ftrigger with a Write javascript step inside an automation, or drop down to the CDP socket and call Runtime.evaluate yourself.Cookie \u002F storage management. Sessions are stateless across browserOpen() calls. The doNotShareLocalstorage flag on axiom.goto() isolates a single navigation; for finer-grained cookie handling, fall back to \u002Ftrigger. If you need any of the above, the typical workaround is to author a small No-Code Tool automation that includes the missing capability and call it via \u002Ftrigger instead. In this section Need help? Contact support or ask a question in our Reddit community. html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .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 .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 pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":864,"title":865,"titles":866,"content":867,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fintegrate-ai","Integrate AI",[],"Run an LLM call inline within a step-function session for prompt completion, classification, or extraction using axiom.integrateAI(). axiom.integrateAI(aiOptions) runs an LLM call inline within the session. Two modes are supported: generate (prompt → completion) and extract (prompt → structured fields from supplied data). The same step type as the No-Code Tool's Generate text with ChatGPT \u002F extraction-AI step. Signature const result = await axiom.integrateAI(aiOptions); FieldTypeRequiredDescriptionaiOptions.aiFunction\"generate\" | \"extract\"YesSelects mode.aiOptions.keystringNoYour LLM API key. Leave unset to use the API key stored against your axiom.ai account.aiOptions.modelstringNoModel identifier (provider-specific). Defaults to the account-level default.aiOptions.promptstringgenerate onlyThe prompt.aiOptions.extractDatastringextract onlyThe source text (typically scraped earlier in the run).aiOptions.promptExtractstringextract onlyThe extraction prompt (e.g. \"Return a JSON object with keys name, price, sku\"). Examples Generate a summary of scraped content: const rows = await axiom.scrape(null, { hierarchy: \"article\" }, null, 1, {});\nconst result = await axiom.integrateAI({\n  aiFunction: 'generate',\n  prompt: `Summarise this in one sentence:\\n\\n${rows[0][0]}`\n}); Extract structured fields from a page: const rows = await axiom.scrape(null, { hierarchy: \"body\" }, null, 1, {});\nconst result = await axiom.integrateAI({\n  aiFunction: 'extract',\n  extractData: rows[0][0],\n  promptExtract: 'Return a JSON object with keys: company_name, ceo_name, founded_year.'\n}); Notes For arbitrary LLM workflows (chains, tool use, streaming), call your LLM provider's API directly from your code rather than going through this step. This step is best when you want the LLM call to count against your axiom.ai runtime quota and to keep the whole flow in one place.The exact set of supported model values depends on which provider keys are configured on your account. See API integrations for the current list. Related ScrapeScrape metadata html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":869,"title":870,"titles":871,"content":872,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fpress-keys","Press keys",[],"Send keyboard key presses (Enter, Tab, arrow keys, modifier combinations) to the currently focused element using axiom.pressKeys(). axiom.pressKeys(key) fires a keyboard event on the currently focused element. Use it for control keys (axiom.enterText() handles ordinary typed text), modifier combinations, and keyboard navigation. The same step type as the No-Code Tool's Press key(s). Signature await axiom.pressKeys(key, delimiter, delay); ParameterTypeRequiredDefaultDescriptionkeystring | stringYes—A single key name (\"Enter\", \"Tab\", \"ArrowDown\"), an array of keys to press as a chord ([\"Control\", \"a\"]), or a delimited string parsed via delimiter.delimiterstringNo—When key is a string, split it on this delimiter into multiple keys to be pressed in sequence.delaynumberNo10Milliseconds between successive key presses. Key names follow the Chrome DevTools key constants (Enter, Tab, Escape, ArrowLeft, Control, Meta, etc.). On cloud Linux pods, \"Meta\" is automatically rewritten to \"Control\" so the same script works regardless of the underlying OS. Examples Submit a form by pressing Enter: await axiom.click(\"input#search\");\nawait axiom.enterText(\"input#search\", \"ergonomic keyboard\");\nawait axiom.pressKeys(\"Enter\"); Select-all in the focused field: await axiom.pressKeys([\"Control\", \"a\"]); Navigate a custom listbox with arrow keys, then commit: await axiom.pressKeys(\"ArrowDown,ArrowDown,Enter\", \",\", 80); Notes The event targets whatever element currently has focus. Click an input first (or use axiom.enterText() to focus by selector) before pressing keys that the page should treat as field input.For ordinary text input, prefer axiom.enterText() — it handles focusing the element for you. Related Enter textClick 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 .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 .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}",{"id":874,"title":875,"titles":876,"content":877,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Frestart-browser","Restart browser",[],"Restart the cloud browser within the current session to recover from a wedged state without losing the session itself, using axiom.restartBrowser(). axiom.restartBrowser() restarts the cloud browser within the current session. Use it when the browser is wedged (an unrecoverable dialog, a hung page, leaked memory from a previous run) but you want to keep using the same session — and the same quota of concurrent slots — rather than browserClose()-ing and browserOpen()-ing. Signature await axiom.restartBrowser(); No parameters, no return value. Example try {\n  await axiom.goto(\"https:\u002F\u002Fexample.com\u002Fheavy-page\");\n  await axiom.click(\".main-action\");\n} catch (e) {\n  \u002F\u002F Browser may be stuck. Restart and retry once.\n  await axiom.restartBrowser();\n  await axiom.goto(\"https:\u002F\u002Fexample.com\u002Fheavy-page\");\n  await axiom.click(\".main-action\");\n} What's preserved, what's lost A restart spins up a fresh Chrome instance inside the same session: Lost: cookies, localStorage, open tabs, in-flight network requests, anything else held in browser memory.Preserved: the session itself — your axiom instance keeps the same cdpLink, you don't need to re-authenticate, and the session's runtime quota and concurrency slot are unchanged. If you need to retain cookies across the restart, save what you need with axiom.scrape() before calling restartBrowser(), and re-apply them on the new browser. Notes For most error-recovery flows, simply browserClose() + browserOpen() on a new instance is cleaner. Reach for restartBrowser() only when you want to avoid waiting in the session queue again.This step is rare in normal flows. Use it as a recovery primitive, not a routine reset. Related Start a sessionClose a session 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":879,"title":880,"titles":881,"content":882,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fscrape","Scrape",[],"Smart-scrape a list of records from one or more pages, with optional pagination and a maximum-results cap, using axiom.scrape(). axiom.scrape(url, selector, pager, max_results, settings) extracts a list of structured records from a page (or a sequence of pages, if you supply a pager). The same step type as the No-Code Tool's Get data from bot's current page, called from your code with selectors you choose at runtime. Signature const rows = await axiom.scrape(url, selector, pager, max_results, settings); ParameterTypeRequiredDescriptionurlstring | string | nullYesURL (or array of URLs) to scrape. Pass null to scrape the page currently loaded in the session. Multiple URLs are scraped in sequence.selectorobjectYesSelector definition for the records to extract. Use the No-Code Tool's selector tool (or a recorded selector from a previous run) to produce this.pagerobject | nullYesSelector for the \"next page\" link. Pass null for single-page scraping. With a pager, the scraper paginates until max_results is hit or the pager stops resolving.max_resultsnumber | nullYesCap on the number of records returned. Must be a positive whole number (or null for unlimited).settingsobjectYesBehavioural tuning (output format, minimum wait, …). Pass {} for defaults. Returns a 2D array of records (rows × fields). Example Scrape product cards from a category page, paginating until 100 results: const products = await axiom.scrape(\n  null,                                  \u002F\u002F stay on the current page\n  { hierarchy: \".product-card\" },        \u002F\u002F record selector\n  { hierarchy: \"a.pagination-next\" },    \u002F\u002F pager selector\n  100,                                   \u002F\u002F max results\n  {}                                     \u002F\u002F default settings\n); Notes The selector and pager shapes match the selector tokens emitted by the No-Code Tool's selector tool. If you're authoring by hand, capturing them once via the No-Code Tool and copy-pasting is the lowest-friction approach.For single-record extraction (page title, OG image, single field), use axiom.scrapeMetadata() — it's faster and simpler.The scraper handles lazy-loaded content by waiting briefly after each pager click. Sites with slow infinite-scroll may need a higher minWait in settings.Multiple URLs in url are scraped sequentially and the results concatenated; failures on one URL fail the whole call. Related Scrape metadataGo to URL html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":884,"title":885,"titles":886,"content":887,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fscrape-metadata","Scrape metadata",[],"Extract page-level metadata (title, analytics IDs, schema.org structured data, or any meta-tag content) using axiom.scrapeMetadata(). axiom.scrapeMetadata(metadata) extracts page-level metadata fields from the current page: the document title, common analytics IDs (Google Analytics, Facebook Pixel), schema.org structured data, and the content of arbitrary \u003Cmeta> tags. Use it when you want a few specific page-level fields rather than a list of records. Signature const values = await axiom.scrapeMetadata(metadata); ParameterTypeRequiredDescriptionmetadataarrayYesArray of { id, value, description } items describing which fields to extract. See Field types below. Returns a 2D array of extracted values, in the same order as the input items. Field types Each item in the metadata array has an id that selects an extractor. The built-in extractors are: idDescriptiongeneral_metadata_titleThe page's \u003Ctitle>.analytics_and_tracking_google_analytics_idThe first GA measurement ID found in inline scripts (G-…, UA-…).analytics_and_tracking_facebook_pixel_idThe first Facebook Pixel ID found in inline scripts.schema.org_structured_data_\u003CTYPE>A \u003Cscript type=\"application\u002Fld+json\"> block whose @type matches the @type named in the item's description.any other idThe extractor falls back to value as a CSS selector, returning the matched element's content attribute, href attribute, or outerHTML (in that order of preference). Example Pull the page title, GA ID, and the contents of \u003Cmeta name=\"description\">: const [title, gaId, description] = await axiom.scrapeMetadata([\n  { id: 'general_metadata_title' },\n  { id: 'analytics_and_tracking_google_analytics_id' },\n  { id: 'meta_description', value: 'meta[name=\"description\"]' }\n]); Pull a specific schema.org block: const [product] = await axiom.scrapeMetadata([\n  { id: 'schema.org_structured_data_Product', description: '@type: Product' }\n]);\nconst parsed = JSON.parse(product[0]); Notes Each item returns a single value. For multi-row extraction, use axiom.scrape() instead.Schema.org extraction parses the matched JSON-LD block and returns its serialised form. Parse it on your side.The fallback selector extractor reads content first (for \u003Cmeta> tags), then href (for \u003Clink> tags), then outerHTML. This is convenient for the common cases but means the same selector can return different shapes depending on the element type. Related Scrape html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":889,"title":890,"titles":891,"content":892,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fselect-list","Select list",[],"Pick an option in a native HTML \u003Cselect> element by visible text using axiom.selectList(). axiom.selectList(select, text) picks an option in a native HTML \u003Cselect> element by matching on the option's visible text. The same step type as the No-Code Tool's Select list. Signature await axiom.selectList(select, text); ParameterTypeRequiredDescriptionselectstringYesCSS selector for the \u003Cselect> element.textstringYesVisible text of the option to pick (matched case-sensitively against \u003Coption> text content). Example await axiom.selectList(\"select#country\", \"United Kingdom\"); Notes Only works on native \u003Cselect> elements. Custom-built dropdowns (divs styled as dropdowns, headless-UI listboxes, React-Select, etc.) don't respond to this — drive them with axiom.click(): click the trigger, then click the option.Matching is on the option's visible text, not its value attribute. If the visible text and the underlying value diverge, use the visible text.If no option matches text exactly, the step throws. Related ClickEnter text 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":894,"title":895,"titles":896,"content":897,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fsolve-captcha","Solve captcha",[],"Send the current page's captcha to a third-party solver and submit the result using axiom.solveCaptcha(). axiom.solveCaptcha(apiKey) sends the captcha on the current page to a third-party solver (2Captcha by default), waits for the result, and submits it into the captcha field. The same step type as the No-Code Tool's Solve Captcha. Signature await axiom.solveCaptcha(apiKey); ParameterTypeRequiredDescriptionapiKeystringNoAPI key for the captcha solver. If omitted or empty, the step uses the 2Captcha key stored on your axiom.ai account (set under API integrations). Example await axiom.goto(\"https:\u002F\u002Fexample.com\u002Flogin\");\nawait axiom.enterText(\"#email\", \"user@example.com\");\nawait axiom.solveCaptcha();                  \u002F\u002F uses the stored 2Captcha key\nawait axiom.click(\"button[type=submit]\"); Notes Captcha solving is billed by the third-party solver, not by axiom.ai. Your axiom.ai runtime quota covers only the time the session spends waiting for the result.The step detects the captcha type on the page (reCAPTCHA v2, hCaptcha, image captchas) and routes it appropriately. If the page's captcha widget loads slowly, insert an axiom.wait() before this step.Solver response times vary from a few seconds to a couple of minutes. The library's transparent polling fallback handles requests that exceed the default HTTP timeout — you don't need to do anything special on the client. Related ClickWait 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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":899,"title":900,"titles":901,"content":902,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fstart-a-session","Start a session",[],"Install axiom-api, instantiate the AxiomApi class with your API key, then open a cloud browser session. axiom.browserOpen() opens a fresh, isolated cloud browser session. Once open, every other axiom.* method drives that session until you call axiom.browserClose(). Install npm install axiom-api Instantiate the client Pass your API key into the constructor. See Authentication to generate one. import { AxiomApi } from 'axiom-api';\n\nconst axiom = new AxiomApi(process.env.AXIOM_API_KEY); Note: never hard-code the key. Store it in an environment variable or a secrets manager. Open the session await axiom.browserOpen(); The call resolves once the cloud browser is ready to accept commands. There's nothing to capture from the return value, the axiom instance itself holds the session. Standard pattern Wrap the work in a try \u002F finally so the session always closes, even on errors: import { AxiomApi } from 'axiom-api';\n\nconst axiom = new AxiomApi(process.env.AXIOM_API_KEY);\nawait axiom.browserOpen();\ntry {\n  await axiom.goto(\"https:\u002F\u002Fexample.com\");\n  \u002F\u002F ... your automation\n} finally {\n  await axiom.browserClose();\n} Notes Each AxiomApi instance manages one session at a time. To run multiple sessions in parallel, create multiple instances.browserOpen() returns the session's CDP endpoint string and caches it on the instance as axiom.cdpLink. Subsequent step methods automatically pass this through, so you don't need to capture it for normal use.Sessions consume runtime quota for the entire time they're open, not just when actively executing a command. Always close sessions when you're done. See Close a session.The number of concurrent sessions per API key is limited by your plan tier. See Queue and concurrency. Related Go to URLClose a session html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .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 .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 pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":904,"title":905,"titles":906,"content":907,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fstep-function-vs-no-code-step","Step function vs No-Code step",[],"Find the axiom-api method equivalent of every No-Code Tool step, useful when porting a visual automation to code. If you've built an automation in the No-Code Tool and want to drive the equivalent flow via the axiom-api library, this table maps each step to its closest method. Steps without a direct equivalent are flagged in the Notes column with the recommended workaround. Mapping table No-Code Tool stepaxiom-api methodNotesGo to pageaxiom.goto(url, ...)Direct equivalent.Click elementaxiom.click(select, ...)Direct equivalent. Supports left\u002Fright click and \"click if present\" via the optionalClick flag.Click multiple elementsaxiom.clickMultiple(select, ...)Direct equivalent.Click engagement buttonaxiom.clickEngagementButton(select, setValueToCheck)Direct equivalent for like\u002Ffollow\u002Fsubscribe-style toggles.Enter textaxiom.enterText(selectTextField, text, ...)Direct equivalent. Per-character delay, append-vs-replace, and a custom-line-break token are all supported.Press key(s)axiom.pressKeys(key, delimiter, delay)Direct equivalent.Rollover elementaxiom.hover(select)Direct equivalent.Mouse click & dragaxiom.clickAndDrag(start, end)Direct equivalent.Select listaxiom.selectList(select, text)Direct equivalent for native \u003Cselect> elements.Date pickeraxiom.datePicker(...)Direct equivalent for calendar-widget date pickers.Waitaxiom.wait(time)Direct equivalent. Pauses on the pod so the session's inactivity timer stays reset.Random waitCompose in codeCompute the delay in your code, then call axiom.wait(delay).Switch browser tabaxiom.switchBrowserTab(selectTab)Direct equivalent.Open a new tabaxiom.goto(url, false, true)Pass openInNewTab: true (third arg) to goto.Close browser tabaxiom.browserClose()Closes the whole session. There is no single-tab close today.Get data from bot's current pageaxiom.scrape(url, selector, pager, max_results, settings)Direct equivalent. Pass null for url to scrape the page already loaded.Get page metadataaxiom.scrapeMetadata(metadata)Direct equivalent for title\u002Fdescription\u002FOG-tag style fields.Get a list of links to pages from bot's current pageaxiom.scrape(...)Pass a selector that targets the links you want.Read clipboardaxiom.getClipboardContents()Direct equivalent.Save screenshot locallyNot exposedFall back to a No-Code Tool automation triggered via \u002Ftrigger, or take the screenshot yourself over CDP (Page.captureScreenshot).Save page HTMLNot exposedUse axiom.scrape() for structured extraction, or drop down to CDP and read DOM.getOuterHTML.Download file from URLNot exposedUse a normal HTTP client in your code.Write javascriptNot exposedFall back to \u002Ftrigger for arbitrary JS execution, or use CDP Runtime.evaluate.Clear cookiesNot exposedOpen a fresh session for cookie isolation. The doNotShareLocalstorage flag on axiom.goto() handles the localStorage case for a single navigation.Current UrlNot exposedTrack URLs in your own code from each axiom.goto() call.Solve Captchaaxiom.solveCaptcha(apiKey)Direct equivalent. You supply the solver API key.Generate text with ChatGPT \u002F AIaxiom.integrateAI(aiOptions)Direct equivalent for the inline-AI step. For arbitrary OpenAI\u002FAnthropic usage, call those APIs from your code instead.Try \u002F CatchNative language constructtry { ... } catch (e) { ... }If conditionNative language constructBranch based on data returned by previous calls.Loop through dataNative language constructfor loop in your code.Read data from a Google SheetNot exposedUse the Google Sheets API directly from your code.Write data to a Google SheetNot exposedUse the Google Sheets API directly from your code.Send an emailNot exposedUse your language's email library or a service like SendGrid.Trigger webhookNative HTTP callfetch(url, { method: \"POST\", body }) from your code. When to fall back to \u002Ftrigger The step-trigger surface covers the common interaction and extraction steps directly. For everything else (screenshots, raw HTML readout, arbitrary JS, file downloads, sheet I\u002FO, email), the recommended workaround is: Build the missing capability into a No-Code Tool automation.Trigger that automation via \u002Ftrigger from your code. This gives you the imperative control of axiom-api for the parts of the flow that need it, plus the full No-Code Tool step library for the parts that don't. When to port and when not to Porting a No-Code Tool automation to axiom-api makes sense when: The flow needs to branch based on what each step returned.The flow needs to live alongside other code in your stack (in a backend service, a CI job, a scheduled function).You want version control, code review, and tests on your automation logic. Stick with the No-Code Tool when: The flow is short and stable, with no runtime branching.The person maintaining it isn't a developer.Triggering it via \u002Ftrigger from your code already covers your needs. The two surfaces aren't either-or. A common pattern is keeping the visual automation as the source of truth for stable workflows, then using axiom-api for the dynamic, branchy parts of your application.",{"id":909,"title":910,"titles":911,"content":912,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fswitch-browser-tab","Switch browser tab",[],"Switch the cloud browser session's focus to another tab using axiom.switchBrowserTab(). axiom.switchBrowserTab(selectTab) switches the session's active tab. Use it after axiom.goto(url, false, true) (or any other action that opens a new tab) to drive the newly opened tab. The same step type as the No-Code Tool's Switch browser tab. Signature await axiom.switchBrowserTab(selectTab); ParameterTypeRequiredDescriptionselectTabstringYesA substring of the target tab's title or URL. The session switches to the first tab whose title or URL contains this string. Example Open a second tab and switch focus to it: await axiom.goto(\"https:\u002F\u002Fexample.com\u002Fdashboard\");\nawait axiom.goto(\"https:\u002F\u002Fexample.com\u002Freports\", false, true);   \u002F\u002F opens in new tab\nawait axiom.switchBrowserTab(\"reports\");                          \u002F\u002F focus the new tab\nawait axiom.click(\".export-csv\"); Notes The match is a substring search against tab title and URL. Use a string that's unique to the target tab — if multiple tabs match, the first match wins.After a switch, subsequent step methods act on the newly active tab. The previous tab stays open until the session closes (or you switch back and close it).All tabs share runtime quota and the same axiom instance. For genuine parallelism, create multiple AxiomApi instances. Related Go to URLClose a session 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 .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 .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 .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":914,"title":915,"titles":916,"content":917,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fstep-functions\u002Fwait","Wait",[],"Pause the session for a fixed duration on the pod, keeping the session alive while you wait for content to render or for a server-side process to finish. axiom.wait(time) pauses the session for time milliseconds. Use it between steps to let content render, to throttle a sequence of clicks, or to wait out a server-side process before the next action. The same step type as the No-Code Tool's Wait. Signature await axiom.wait(time); ParameterTypeRequiredDescriptiontimenumberYesDuration to wait, in milliseconds. Example await axiom.click(\"button.export\");\nawait axiom.wait(5000);                   \u002F\u002F give the export job time to finish\nawait axiom.click(\"a.download-link\"); Why this and not a local setTimeout? axiom.wait() pauses on the pod, not in your client process. The cloud session has an inactivity timer that closes the browser after a period without step traffic — a local setTimeout from your code wouldn't reset that timer, so a long local sleep would let the session idle out and auto-close while your client thought everything was fine. For waits where there is no session open yet (rare — typically before browserOpen()), axiom.wait() falls back to a local sleep, so the same call is safe in both cases. Notes For \"wait until X is on the page\" rather than a fixed pause, the library doesn't expose a wait-for-selector step today. Loop on axiom.click() with optionalClick: true and re-check, or fall back to a No-Code Tool automation with a proper wait step via \u002Ftrigger.Long waits still count against your runtime quota. Related ClickGo to URL 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 .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 .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 .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":919,"title":920,"titles":921,"content":922,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fusage-and-limits","Usage and limits",[],"Check remaining runtime, understand queueing and concurrency, and stay within rate limits when calling the axiom.ai API. These endpoints let your code check how much cloud runtime is left, see how runs are queued when you hit your concurrency limit, and avoid tripping rate limits. Use them to build dashboards, gate expensive runs behind a quota check, or back off cleanly when the API tells you to slow down. In this section Need help? Contact support or ask a question in our Reddit community.",{"id":924,"title":925,"titles":926,"content":927,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fusage-and-limits\u002Fqueue-and-concurrency","Queue and concurrency",[],"Understand how axiom.ai handles concurrent cloud runs, when triggers get queued, and how the queue clears. Cloud runs are queued per account. Your plan determines how many runs can execute at the same time, and any trigger above that limit waits its turn instead of failing. How it works When you call \u002Ftrigger, the API always accepts the request and returns a run_id, even if your account is already at its concurrency limit. The new run is added to the back of your account's queue and starts as soon as a running slot frees up. This means: Triggering a run never returns \"too many concurrent runs\" as an error. The call succeeds and you get a run_id regardless.The run_id you receive is real and pollable from the moment it's returned, but \u002Frun-data will report Running only once the run actually starts executing.Queued runs are processed in the order they were triggered. There's no priority queue or fast-track tier today. Check whether a run is queued or executing The \u002Frun-data endpoint returns a status field. A run that's been triggered but is still waiting in the queue reports Running, the same as one that's actively executing in the cloud browser. There's no separate Queued state today, so you can't programmatically distinguish \"waiting for a slot\" from \"actively running\" without additional signals (for example, checking whether the bot has produced any output yet). If you need to tell the two apart, the most reliable approach is to call \u002Fremaining-runtime before and after the trigger, queued runs don't consume runtime until they start executing. Cloud concurrency limits per plan PlanMax concurrent cloud runsStarter1Pro1Pro Max2Ultimate20 Note: exact concurrency limits per plan tier are confirmed on the pricing page. Use that as the source of truth, the table above is for quick reference. Tips for high-volume callers Stay inside the 100-per-minute rate limit. The API allows 100 calls per minute per key (see rate limits). Past that, calls return 429: Too Many Requests and the automation does not run. Throttle on your side so excess calls back up in your own queue instead of being silently rejected.Use exponential backoff on polling. If a run has been Running for several minutes, double your polling interval each time. A 5-second initial interval that backs off to 30 seconds works well for most automations and keeps polling clear of the rate limit.Cap concurrency in your own code. If your integration occasionally spikes, add a semaphore on your side so you don't queue hundreds of runs that won't complete for hours.Stop runs you no longer need. If your application logic determines a queued run is no longer relevant (for example, the user cancelled a request), call \u002Fstop to cancel it and free the slot for something else.",{"id":929,"title":930,"titles":931,"content":932,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fusage-and-limits\u002Frate-limits","Rate limits",[],"The axiom.ai API allows 100 calls per minute per API key. Calls past that limit return a 429 error and the requested automation does not run. The axiom.ai API allows up to 100 calls per minute per API key. This protects our infrastructure and keeps resources available for every user. We recommend that you limit calls in the application that triggers your automations to prevent failures. The limit 100 calls per 1 minute window, counted per API key.Applies to every endpoint, not just \u002Ftrigger. \u002Frun-data, \u002Fstop, \u002Fremaining-runtime, and all step functions count against the same allowance.The window is rolling, not aligned to wall-clock minutes. What happens when you hit it Calls past the limit return a 429: Too Many Requests error. The automation does not run, and the failed call does not appear in your run reports. That means a 429 isn't logged anywhere in the Dashboard, so if you're missing runs you'd expect to see, check your own application logs for 429 responses first. How to stay inside the limit Throttle on your side. Add a 100-per-minute cap (or lower) in the application that calls the API, so excess calls back up in your own queue instead of being rejected.Use exponential backoff when you do hit a 429. Wait, retry, wait longer, retry. Don't fire the same call again in a tight loop.Spread calls evenly. A burst of 100 calls in the first second of the window is still over the limit. Pace them across the full minute.Cache responses you don't need to refetch. \u002Fremaining-runtime doesn't change second to second. Poll it once a minute, not once a second. Related Queue and concurrencyCheck remaining runtimeError codes",{"id":934,"title":935,"titles":936,"content":937,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fapi\u002Fusage-and-limits\u002Fremaining-runtime","Check remaining runtime",[],"Query the axiom.ai API for your account's cloud runtime allowance, used minutes, and remaining minutes for the current billing period. The \u002Fremaining-runtime endpoint returns your account's cloud runtime allowance and usage for the current billing period. Use it to surface a \"you've used X of Y minutes this month\" widget in a dashboard, or to block expensive runs when you're nearly out of quota. Request POST \u002Fapi\u002Fv3\u002Fremaining-runtime ParameterTypeRequiredDescriptionkeystringYesYour API key. See Authentication. Response {\n  \"status\": \"success\",\n  \"data\": {\n    \"used\": 12.25,\n    \"allowance\": 15000,\n    \"remaining\": 14987.75\n  }\n} FieldTypeDescriptionstatusstringsuccess on a successful call, otherwise an error string.data.usednumberMinutes of cloud runtime used in the current billing period.data.allowancenumberTotal minutes of cloud runtime included in your plan for the current billing period.data.remainingnumberMinutes left (allowance - used). All values are in minutes. Example curl -X POST https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Fremaining-runtime \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key\": \"your-api-key-here\"}' A common pattern is to call this before triggering a long-running automation, so your code can fail fast rather than starting a run that will be killed mid-way through. const res = await fetch(\"https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Fremaining-runtime\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n  body: JSON.stringify({ key: process.env.AXIOM_API_KEY }),\n});\nconst { data } = await res.json();\n\nif (data.remaining \u003C 5) {\n  throw new Error(`Only ${data.remaining} minutes left, skipping run.`);\n} Notes The billing period resets monthly on your subscription anniversary, not the calendar month. Usage figures reflect the current cycle.Cloud runtime is consumed by \u002Ftrigger runs and by browser sessions opened against wss:\u002F\u002Fcdp-lb.axiom.ai. Local browser runs (the No-Code Tool running on your machine) don't draw from this allowance.A long-open browser session counts against your allowance even if it's idle. Always close sessions when you're done with them. 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 .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}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 .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}",{"id":939,"title":940,"titles":941,"content":942,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fdeep-dives\u002Faxiom-structure","Automation JSON structure",[],"Reference for the JSON structure of an exported axiom.ai automation, covering identifiers, step data, parameters, settings, and notification fields. When you export an axiom.ai automation, you get a JSON file containing the inner workings of the automation. The export is useful for sharing automations with the support team, with a colleague, or with anyone you're collaborating with. Most of the file is data axiom.ai uses to reconstruct the automation, but some of it is interesting on its own. This page documents the most useful fields. We've left out fields that relate to deprecated features, internal extension state, or rarely-used settings. You can think of an exported automation as a snapshot of the automation's current state, including every step variable, error setting, and configuration value. Warning: Don't edit an exported automation by hand. Errors in the JSON prevent the file from being imported back into the extension. Identifiers The first few fields in the JSON identify the automation: \"id\": 938717,\n\"name\": \"Send to Supabase\",\n\"templateId\": 0,\n\"triggers\": [ ... ] KeyDescriptionidThe automation's unique ID.nameThe automation name, as shown in the dashboard.templateIdThe ID of the template the automation was created from, if any.triggersConfigured triggers, such as schedules. If the automation has a schedule, the triggers array contains an entry like this: {\n    \"id\": 10126,\n    \"interval_type\": \"seconds\",\n    \"name\": \"\",\n    \"starting_time\": \"2025-02-26 16:26:23+00\",\n    \"status\": \"ready\",\n    \"time_criteria\": 86400,\n    \"type\": \"schedule\"\n} KeyDescriptionidThe schedule's unique ID.interval_typeThe interval unit. Always seconds.starting_timeThe time the schedule was set to start.time_criteriaThe number of seconds between runs. For example, 86400 is one day.typeThe trigger type. Data The data key holds everything about the automation's behaviour: steps, settings, and the configurations that drive each run. The top of the data object looks like this: \"builderTemplateId\": 0,\n\"context\": [{ \"context\": \"url\", \"url\": \"\" }],\n\"continueOnError\": true,\n\"disablePageChangeMonitoring\": true,\n\"executablePath\": \"...\",\n\"extensionToLoad\": \"...\",\n\"form\": [ ... ] KeyDescriptionDefaultDocscontinueOnErrorContinue after the automation hits an error.falseContinue on errordisablePageChangeMonitoringSkip page-change monitoring between steps.falseDisable page monitoringexecutablePathPath to a local Chrome installation.nullSet executable pathextensionToLoadPath to a Chrome extension to load.nullLoad another extensionformThe list of steps. See Step data. Step data Step data lives in the form key. It's an array of step objects shaped like this: {\n    \"description\": \"Instruct the bot to go to a new page.\",\n    \"hasErrors\": false,\n    \"index\": 0,\n    \"machine_name\": \"WidgetDriverGoto\",\n    \"metadata\": \"\",\n    \"name\": \"google.com\",\n    \"original_name\": \"Go to page\",\n    \"params\": [ ... ],\n    \"stepNumber\": \"1\",\n    \"token\": \"\"\n} KeyDescriptiondescriptionThe description of the step at the time it was created.machine_nameaxiom.ai's internal name for the step.metadataSearch keywords used by the step finder.nameThe customisable display name.original_nameThe canonical step name without customisations.paramsThe step's configuration. See Params.stepNumberThe step's position in the automation.tokenThe data token output by the step, if any (the token name only, not the data). Note: The description and parameter description fields are stored at creation time so older steps continue to make sense if the canonical step description changes in a later release. Params The params array inside each step object holds every parameter the step has, plus the value you've configured. For example, a single parameter on the Read data from a Google Sheet step looks like this: {\n    \"collapsible\": 0,\n    \"configurable\": true,\n    \"default_value\": \"\",\n    \"description\": [\"Select a google sheet to read from, or paste its URL here.\"],\n    \"help\": [],\n    \"image\": \"\",\n    \"name\": \"Spreadsheet\",\n    \"sheetName\": \"Your Google Sheet\",\n    \"type\": \"spreadsheet_picker\",\n    \"value\": \"...\"\n} KeyDescriptiondefault_valueThe default value, if the step has one.descriptionThe parameter's description (preserved from the step's creation time, see the note above).nameThe parameter name.sheetNameThe name of the Google Sheet selected for this parameter.typeThe parameter type. The example above is a spreadsheet_picker.valueThe configured value. Each parameter type may include extra fields specific to that parameter or step. The example above is a single parameter; most steps have several. Automation settings The remaining keys are the automation's settings, the same ones you configure from the Cog icon in the Builder. \"headless\": false,\n\"iframesAllowed\": true,\n\"incognitoMode\": true,\n\"injector\": { \"injector\": \"dom\", \"magic_btn_status\": true, \"selector\": \"\" },\n\"maximumRuntime\": 600,\n\"mode\": \"browser\",\n\"notifications\": { ... },\n\"proxyAuth\": null,\n\"storeCookies\": true,\n\"templateId\": 0,\n\"templateItem\": null,\n\"templateMode\": false,\n\"templateStarted\": false,\n\"tokens\": null,\n\"useLocalTimezone\": true,\n\"userDataDir\": \"...\",\n\"viewport\": null KeyDescriptionDefaultDocsheadlessRun the browser in headless mode.falseRun headlessiframesAllowedAllow the selector tool to interact with iframes.falseInteract with iframesincognitoModeRun the automation in incognito mode.falseRun in incognito modemaximumRuntimeMaximum runtime in seconds.720Set maximum runtimenotificationsNotification configuration. See Notifications.nullSet up notificationsproxyAuthProxy configuration, if a proxy is set up.nullUse a proxystoreCookiesUse stored cookies and local storage.nullStore cookiestemplateIdThe template ID the automation was created from, if any.0useLocalTimezoneUse the local timezone for scheduling.falseConfigure timezoneuserDataDirPath to a custom Chromium profile, if one is set.nullSet a custom Chromium profile Notifications The notifications key holds the email and webhook notification configuration: {\n    \"emailAddress\": \"...\",\n    \"emailOn\": true,\n    \"onFailure\": true,\n    \"onSuccess\": false,\n    \"webhookOn\": false,\n    \"webhookPayload\": \"\",\n    \"webhookURL\": \"\"\n} KeyDescriptionemailAddressThe email addresses to send notifications to.emailOnWhether email notifications are enabled.onFailureWhether to notify on a failed run.onSuccessWhether to notify on a successful run.webhookOnWhether webhook notifications are enabled.webhookPayloadThe auto-generated webhook payload.webhookURLThe URL the webhook payload is sent to. Wrapping up Understanding the JSON structure of an automation can help when you need to share an automation with support or read someone else's exported file. We don't recommend editing an automation through the JSON, but if you do, work from the table above to know what each key controls. Any malformed JSON will prevent the file from being imported back into the extension. html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sZcZs, html code.shiki .sZcZs{--shiki-default:#82071E;--shiki-default-font-style:italic;--shiki-dark:#FFA198;--shiki-dark-font-style:italic}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 .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}",{"id":944,"title":945,"titles":946,"content":947,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fdeep-dives\u002Fchromium","Chromium",[],"A deep dive into Chromium, how its multi-process architecture and V8 engine affect performance, and how axiom.ai uses Chromium to run automations. Chromium is the open-source browser project that axiom.ai uses to run every automation. This page covers what Chromium is, how axiom.ai relies on it, and the architectural decisions that affect performance and memory usage during runs. Introduction Chromium is an open-source web browser project developed and maintained by the Chromium Project, primarily backed by Google. It's the foundation for Google Chrome, Microsoft Edge, Brave, and many other popular browsers. Chromium provides a fast, lightweight, and secure browsing experience with a minimal interface and full support for modern web standards. Unlike Chrome, it has no proprietary additions: no automatic updates, no built-in media codecs, and no Google services integration. Developers and tech enthusiasts often use Chromium directly for its transparency, flexibility, and customisation potential 1 2. According to StatCounter, at the time of publishing, 72.28% of browser market share belonged to Chromium-based browsers, with Chrome leading the pack 3. Because of this dominance, Chromium remains an important platform for any tool that automates the browser, including axiom.ai. How axiom.ai uses Chromium axiom.ai ships with a bundled version of Chromium and runs every automation inside it. Local runs open a Chromium window on your computer; cloud runs open a Chromium window on axiom.ai's infrastructure. Either way, the automation executes inside that Chromium instance. Building on Chromium gives axiom.ai a few baseline advantages: Compatibility with most Chromium-based browsers.Faster pages without Google service integrations.A high level of customisation through Chromium's APIs. These translate into specific axiom.ai features: Setting a custom Chromium profile to handle authentication or carry over browser settings.Routing traffic through a proxy server.Storing cookies and local storage for use across runs. These are a handful of examples; many other features depend on Chromium under the hood. Puppeteer and Chromium Puppeteer is a JavaScript library that provides a high-level API to control Chromium over the DevTools Protocol and WebDriver BiDi 4. It uses Chromium's built-in APIs to expose a clean automation interface, and axiom.ai uses Puppeteer internally. You can also call Puppeteer directly from a Write javascript step using the Puppeteer snippets. Puppeteer is developed by Google, so its primary target is Chromium, though a Firefox build is also available. The integration with Chromium gives Puppeteer the ability to: Use the DevTools Protocol to render pages, take screenshots, automate form submissions, and capture network requests.Ship with a stable Chrome version, giving developers a consistent runtime.Run in headless mode, without a graphical interface, for faster automations.Support every major operating system. Chromium architecture Chromium's architecture prioritises user experience, often at the cost of memory. That trade-off explains why Chromium-based browsers are often associated with high RAM usage. It's a sensible trade for an everyday browser, but it has implications for automation. Here are the main architectural decisions: Multi-process architecture. Each tab and extension (including axiom.ai) runs in a separate process. This isolates crashes and improves security but uses more RAM. To see the impact on your machine, open Task Manager (Windows) or Activity Monitor (macOS) and count the Chromium processes.Preloading and caching. Chromium aggressively caches content and preloads pages to keep things responsive.JavaScript and rendering engine. Chromium uses the V8 JavaScript engine and Blink rendering engine, which compile and execute JavaScript efficiently.Tab and session management. Recently improved with Memory Saver (formerly Data Saver), which puts inactive tabs to sleep. Without that feature on, Chromium keeps inactive tabs in memory so you can switch back instantly without a reload.Garbage collection. V8 uses aggressive garbage collection to manage memory but sometimes retains unused memory to speed up future tasks. Each of these decisions improves the user experience at the cost of memory. V8 JavaScript engine A big chunk of Chromium's speed comes from the V8 JavaScript engine, which compiles JavaScript Just-In-Time (JIT). V8 is written in C++, runs on every major operating system, and implements ECMAScript and WebAssembly 5. SpiderMonkey, Firefox's engine, also uses a C++ JIT compiler with overlapping optimisations 6. V8 has seen significant advances over the past few years: a new optimising compiler called Maglev (which sits between Sparkplug and TurboFan), a redesigned TurboFan architecture, a faster HTML parser, and improved DOM allocations 7. Garbage collection improvements have added further performance gains. For axiom.ai, this matters because Puppeteer runs inside Chromium and benefits from every V8 improvement. Each release makes the platform a little bit faster and more reliable for automation. Process model As mentioned, Chromium isolates each tab and extension into its own process. This stops a single bad tab from taking down the browser and improves security between tabs. Each rendered page runs in its own process with a RenderProcess object that communicates with the parent browser process. The browser keeps a RenderProcessHost for each renderer, which manages browser-side state and communication 8. When a new tab or window opens, Chromium creates a new process and a single RenderFrame that uses Mojo (an IPC service) to talk to the corresponding RenderFrameHost in the browser process. The RenderFrame represents a page, including any iframes inside it. Some windows opened with window.open share a RenderFrame with the page that opened them. To rein in process counts, Chromium can also adopt existing tabs into another tab's RenderFrame once the total number of tabs hits a limit. This has direct implications for automation. When you run an automation, Chromium loads the page, all its resources, and the resources axiom.ai needs to drive it. axiom.ai's own footprint is small, but on heavy pages Chromium can hit the memory limit of the tab's process. When that happens, the tab crashes but the rest of the browser doesn't. Long-running browser sessions with long-running automations can run into the same issue. Reloading the page usually clears it. Security model Chromium uses a sandbox to protect against vulnerabilities in the rendering engine. The sandbox blocks the rendering engine from making system calls that could exploit a vulnerability, and uses security tokens to make sure a compromised renderer can't reach the host operating system 9. The sandbox pairs with the multi-process model: encapsulated processes plus restricted system access. Think of the sandbox as a sealed box where error-prone work happens. The Chromium team runs an active vulnerability management process: Vulnerabilities are found through automated fuzzing, security audits, and external reports.A public bug tracker documents security issues.Patches are developed, tested, and shipped on the schedule defined by the security risk mitigation plan. Chromium uses ClusterFuzz to run fuzzing infrastructure that continuously tests for crashes and vulnerabilities. AddressSanitizer and UndefinedBehaviorSanitizer detect memory corruption and undefined behaviour during development, and Syzkaller handles kernel fuzzing for sandboxed processes 10. Chromium ships security updates on a fast release cadence, and most Chromium-based browsers (including Chrome) auto-update so users get the patches as soon as they're available. Updates are tracked publicly on Google's Chrome Releases blog. References FootnotesChromium Project, Home. ↩Chromium Project, Core Principles. ↩StatCounter, Browser Market Share. ↩Puppeteer, What is Puppeteer?. ↩V8, v8.dev. ↩SpiderMonkey, spidermonkey.dev. ↩V8, \"V8 is Faster and Safer than Ever!\". ↩Chromium, \"Multi-process Architecture\". ↩Adam Barth, Collin Jackson, Charles Reis, and the Google Chrome Team, \"The Security Architecture of the Chromium Browser\", 2008. ↩Chromium, libfuzzer documentation. ↩",{"id":949,"title":950,"titles":951,"content":952,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fdeep-dives\u002Fcookies","Cookies in axiom.ai",[],"A deep dive into how axiom.ai stores cookies for automations, how cookies behave when an automation is duplicated, and why resyncing is sometimes required. axiom.ai uses stored cookies to keep an automation signed into a target site between runs. The behaviour is straightforward most of the time, but a few corners (especially around duplication and the local browser state) catch users out. This page covers how cookies are stored, when they're applied, and what to do when something goes wrong. For the user-facing how-to on enabling cookie storage, see store cookies. How axiom.ai stores cookies When the store cookies setting is enabled for an automation, axiom.ai pulls the relevant cookies from your local browser and stores them in its database. The stored copy is: Encrypted at rest. Cookies are written to the database in encrypted form. Nobody at axiom.ai can read the cookie values directly.Bound to the automation. Each automation has its own copy. Two automations storing cookies for the same site each get their own encrypted entry.Sourced from the local browser. The cookies axiom.ai stores come from your local browser at the moment you save the automation or click Resync cookies. There's no other source. Cookies are applied to the cloud browser before each cloud run, so the automation's session matches your local one. Local runs use your local browser session directly without going through stored cookies. How duplication affects cookies When you duplicate an automation, axiom.ai re-reads cookies from your local browser and stores a fresh encrypted copy against the new automation. The original and the duplicate end up with separate copies. This usually works seamlessly. The cases where it doesn't: The cookies aren't in your local browser at duplication time. If you've cleared cookies, signed out of the target site, or used a different browser profile since the original was created, the local source is gone. The duplicate gets stored against the new automation, but with empty or stale values.You signed out of and back into the target site. Logging out invalidates the original cookie, even though it's still stored in axiom.ai's database. The next run uses an invalid cookie and fails authentication. In both cases the fix is to resync the cookies on the duplicated automation. Resyncing pulls the current cookies from your local browser into the duplicate's encrypted storage, replacing whatever was there. Resync cookies Resync whenever you suspect the stored cookie is out of date. Common triggers: After signing out and back into the target site.After clearing cookies in your browser.After duplicating an automation that depends on cookies.After moving to a different machine or browser profile. To resync: Open the automation and click the Cog icon in the toolbar on the left.Open the Store cookies section.Click Resync cookies for the URL you want to refresh, or Globally resync cookies to refresh every automation that uses the same URL. For step-level details, see store cookies. Inspecting stored cookies axiom.ai doesn't expose stored cookie values, domains, or expiry through the UI. Cookies are stored encrypted, and the UI only shows which URLs have cookies stored against them, not what's inside. For developer-level inspection, you can use Chrome DevTools to watch the GraphQL tasks query the dashboard makes when loading an automation. The query response contains the cookie metadata for each automation. The cookie values themselves remain encrypted and unreadable. Note: Inspecting the GraphQL response is for development debugging only. Don't rely on this for day-to-day cookie management; use Resync cookies instead. Common scenarios A duplicated automation works at first, then fails Most likely cause: the original cookie expired or was invalidated by signing out of the target site. The original automation may also be failing for the same reason, just less obviously if it's run more recently. Fix: Resync cookies on both the original and the duplicate. A duplicated automation fails immediately Most likely cause: the cookies for the target site weren't in your local browser at the moment you duplicated. axiom.ai stored an empty or stale copy. Fix: Sign in to the target site in your local browser to refresh the cookies there, then resync cookies on the duplicate. Two duplicates of the same automation behave differently This is consistent with the storage model: each duplicate gets its own encrypted copy at duplication time. If your local browser state was different between duplications (different sign-in state, different time, different profile), the copies stored against each duplicate will differ. Fix: Resync cookies on each duplicate so they all use the current local browser state. A duplicated automation works, but cookie storage feels fragile This is the recommended pattern for any automation that depends on stored cookies, especially after duplication: resync cookies as part of your duplication workflow, not as something you only do when something breaks. It's a one-click action, and it removes the largest source of cookie-related failures. Best practices Enable run notifications for automations that depend on cookies. You'll find out as soon as a cookie expires rather than discovering it in run reports days later.Resync cookies after duplication. Don't rely on the duplicate inheriting working cookies from the original.Don't sign out of the target site in your local browser if you have automations that use stored cookies for that site. Signing out invalidates the cookies in axiom.ai's storage too.Use one browser profile for cookie sources. Cookies stored against an automation come from whichever browser profile was active when you saved or resynced. Switching profiles can invalidate the source. Limitations Cookie values, domains, and expiry can't be inspected directly from the UI.Cookies are bound to the automation that stored them. There's no shared cookie pool across automations except via the Globally resync cookies action, which still produces separate copies.axiom.ai can't refresh cookies on its own. If the source cookies in your local browser are gone or expired, the automation needs a manual resync.",{"id":954,"title":955,"titles":956,"content":957,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fdeep-dives\u002Fdata-handling","Data handling",[],"A deep dive into what data axiom.ai stores, what stays in your environment, how desktop and cloud runs differ, and how to use axiom.ai safely with sensitive data. axiom.ai is designed so that customer data (the data your automations work with) stays out of axiom.ai's systems by default. This page covers what axiom.ai stores, what it doesn't, how desktop and cloud runs differ in practice, and the patterns to follow when handling sensitive data. Note: axiom.ai is a data processor. The user controls what data flows into and out of axiom.ai through the steps they configure. axiom.ai doesn't access, copy, or share customer data with third parties. What axiom.ai stores The only data axiom.ai keeps is what's needed to run the platform itself. There are three categories. Account data The information needed to maintain your account: Names and email addresses on the account.Plan and billing metadata. Account data is stored encrypted at rest and accessed only by the team to provide support and maintain the service. Automation structure When you save an automation, axiom.ai stores its structure so it can run later. This includes: The automation's name.The list of steps in the automation.The configuration of each step (selectors, target URLs, options, and any literal text typed into step fields).The order of the steps.Any settings configured on the automation (schedule, proxy, notifications, stored cookies, and so on). This is what gets exported when you download an automation as JSON. For the full structure, see automation JSON structure. Important: Anything you manually type into a step input is stored as part of the automation. This includes search queries, URLs, default values, and any text you've typed instead of inserting a data token. Don't type sensitive values like passwords, API keys, or personally identifiable information directly into step fields. Use a data source (Google Sheet, webhook, API call) instead. See use data safely below. Run metadata For every run, axiom.ai records: Run status (success, warning, failure).Start and end times.Runtime used.Any error messages thrown by steps. This metadata appears in run reports. It doesn't include the data your automation processed. What axiom.ai doesn't store By default, the data your automation actually processes (what it scrapes, what gets passed through it, what it writes elsewhere) isn't stored. Specifically: Data scraped from web pages.Data passed in through Receive data from another app (Zapier, Make, n8n, the API).Data read from Google Sheets or Excel.Data written out through any step. axiom.ai doesn't train AI or machine learning models on user data. There's no pipeline that ingests it, no analytics layer that aggregates it, no internal use of it. Desktop runs vs cloud runs The boundary between the two execution modes matters when you're thinking about data flow. Desktop runs Desktop runs execute in a browser on your own machine. The data the automation handles never leaves your network unless your automation explicitly sends it somewhere (a webhook, an AI step, a third-party integration). This means: Scraped data, page content, and intermediate values stay on your machine.axiom.ai's servers don't see the run's data.Run metadata (status, runtime, errors) is still sent to axiom.ai so you can see runs in the dashboard. For data-sensitive workflows, the desktop app is the deployment of choice. Cloud runs Cloud runs execute in a private browser container on axiom.ai's infrastructure. The container is created at the start of the run and permanently deleted when the run ends. Nothing persists between runs. While the run is in progress: The data flowing through the automation lives only inside the container.The container has no shared storage with other accounts or other runs.axiom.ai engineers can't reach into the container. When the run ends: The container is destroyed.Run metadata (status, runtime, errors) is retained for run reports.The processed data is gone unless your automation wrote it somewhere (a Google Sheet, an export step, a webhook). Use data safely axiom.ai handles your data safely by default. The remaining surface area for accidental data exposure is in how you configure your automations. A few patterns to follow: Don't type sensitive values into step fields Anything typed directly into a step's text input is stored as part of the automation's structure. For sensitive values (passwords, API keys, customer data), pass the value in dynamically instead. Read sensitive inputs from a Google Sheet or Excel sheet the user controls.Pass them in via Receive data from another app so the value comes from a webhook or API call.For credentials specifically, use stored cookies or your browser's password manager rather than entering passwords as text. Egress is opt-in Data only leaves an automation when a step is configured to send it out. Examples: A Trigger webhook step sends data to an external URL.An AI step sends prompt content to OpenAI.A Write data to a Google Sheet step writes to your Google account. None of these are present by default. If your automation has none of these steps, data doesn't leave it. When you do add an egress step, the destination is also yours: the third-party service receiving the data is bound by its own terms with you, not with axiom.ai. Run sensitive workflows on the desktop If a workflow handles regulated or highly sensitive data, run it on the desktop app rather than in the cloud. The data never reaches axiom.ai's servers, removing axiom.ai from the data flow entirely. Security practices A few specifics on how axiom.ai handles the data it does store: Encryption at rest. All user data on axiom.ai's systems is stored encrypted.Restricted admin access. Only a small number of team members can access production systems, and access is logged.Regular penetration testing. axiom.ai runs penetration tests on a regular cadence.Annual CASA review. Google reviews axiom.ai's data handling annually through their Cloud Application Security Assessment (CASA), which verifies secure handling and processing of data.No customer-data access for support. axiom.ai's support process doesn't require access to your customer data. If we ever ask for context to debug an issue, you decide what to share. Compliance and certifications axiom.ai is designed to be compliant with common data-handling standards but is not formally certified for any of them. Specifically: Not SOC 2 certified. The system is built around the principle of not handling customer data (so most controls are not applicable), but no formal SOC 2 audit has been completed.Not HIPAA certified, no BAA offered. axiom.ai doesn't sign Business Associate Agreements. For why this can still work for HIPAA-regulated workflows, see HIPAA and axiom.ai below.CASA-verified annually. Google's CASA review confirms that axiom.ai handles and processes data securely. If you have a security questionnaire to complete, contact support. The team has filled these in for several enterprise users. HIPAA and axiom.ai axiom.ai doesn't sign BAAs, but the desktop deployment can still be appropriate for workflows that touch Protected Health Information (PHI). The reasoning, drawn from HHS guidance and 45 CFR 160.103: Under HIPAA, a software vendor only becomes a business associate if it creates, receives, maintains, or transmits PHI on behalf of a covered entity.Selling software that runs in your environment doesn't trigger business-associate status.When you run automations on the desktop app, PHI stays inside your network. axiom.ai doesn't see, store, or transmit any of it.In that deployment model, axiom.ai isn't a business associate, and no BAA is required. The cloud deployment is a different story: cloud runs process data on axiom.ai's infrastructure. If your workflows handle PHI, run them on the desktop app only. Important: This is a summary, not legal advice. HIPAA compliance is your organisation's responsibility, and the right deployment depends on your specific workflow. If you're unsure whether the desktop deployment fits your compliance needs, consult your privacy or compliance team before deploying. Summary axiom.ai stores account information, automation structure, and run metadata. It doesn't store the data your automations process.Anything typed manually into a step is stored as part of the automation. Don't type sensitive values directly; pass them in through a data source.Data only leaves an automation through steps you configure to send it out (webhooks, AI steps, integrations). None of these are present by default.Desktop runs keep data inside your network. Cloud runs use private, ephemeral containers that are destroyed when the run ends.For sensitive or regulated data, the desktop app is the recommended deployment.axiom.ai is designed to be compliant with common standards (not formally certified), CASA-verified annually, and supports security questionnaires on request.",{"id":959,"title":960,"titles":961,"content":962,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fdeep-dives","Deep dives",[],"In-depth articles on the tools and concepts behind axiom.ai, including Chromium, Puppeteer, cookie handling, data handling, and the structure of an exported automation. The deep dives explore tools and concepts behind axiom.ai in more detail than the main reference docs. Useful when you want to understand how something works, not just how to use it. Articles Read these as reference articles rather than a single path. Each is self-contained and answers a specific class of question: how axiom.ai's underlying browser works, how cookies are stored and applied, how data is handled across desktop and cloud runs, and what's inside an exported automation file. Pick whichever matches the question you have. Need help? Contact support or ask a question in our Reddit community.",{"id":964,"title":965,"titles":966,"content":967,"level":56},"\u002Fdocs\u002Fdeveloper-hub","Developer Hub",[],"Use axiom.ai as a developer platform with the API, the Code Dashboard, and custom JavaScript steps inside no-code automations, plus guides and troubleshooting. axiom.ai supports two developer paths: the API for triggering and integrating automations, and custom code (JavaScript and the Code Dashboard) for extending what an automation can do. The links below cover both. FAQ Do I need a subscription to use the API? Yes. The API requires a paid plan. See the pricing page for plans that include API access. Free plans don't include the API. Do I need a subscription to use JavaScript in my automations? No. The Write javascript step is available on every plan, including free. Does the API have rate limits? Yes. Every account is rate-limited to keep the platform stable. See the rate limits documentation for the current limits. Does the API have a queue? Yes. The queue lets a small number of requests through even when your account has hit its concurrency limit. See the queue documentation for the details. Feedback We're always looking for ideas to improve the developer experience. Got feedback, a feature request, or work to share? Post in the Reddit community or contact us. The team reviews feedback weekly.",{"id":969,"title":970,"titles":971,"content":972,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets","Code snippets",[],"Tried-and-tested JavaScript and Puppeteer snippets for the Write javascript step, plus guidance on when to use the Run in app option. The Write javascript step lets you extend axiom.ai with custom code. The snippets in this section have been tried and tested in real automations, and many came from user requests. They're split into two categories: standard JavaScript that runs against the page, and Puppeteer snippets that drive the browser through Puppeteer's API. Snippet categories Run in app The Run in app toggle on the Write javascript step runs your code inside the desktop application instead of inside the page. This is required for any snippet that uses the Puppeteer API. It's also useful when: You don't want your code to interact with the page's own scripts. Running in the page can trigger the page's event listeners or clash with its function and variable names.You need access to Node.js APIs (the fs module, for example) that aren't available in a browser context. There are trade-offs: You can't access elements, functions, or variables from the page being automated.Console output isn't visible during the run when Run in app is enabled. Note: Run in app only works on desktop runs. Cloud runs always execute scripts in the page context. Need help? Contact support or ask a question in our Reddit community.",{"id":974,"title":975,"titles":976,"content":977,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript\u002Fdata","Data snippets",[],"JavaScript snippets for manipulating data in axiom.ai automations, including dates, timestamps, constants, CSV exports, and regex transformations. Data snippets help you manipulate data in your automations so it matches the format the next step (or downstream system) expects. Get the date and time Get the date a number of days in the past: const yesterday = new Date();\nyesterday.setDate(yesterday.getDate() - 1); \u002F\u002F Change '1' to your desired number of days\nreturn [[yesterday.toLocaleDateString('en-US')]]; Get the date a number of days in the future: const targetDate = new Date();\ntargetDate.setDate(targetDate.getDate() + 14); \u002F\u002F Change '14' to your desired number of days\nreturn [[targetDate.toLocaleDateString('en-US')]]; Append a timestamp to scraped data: let data = [all-interaction-data]; \u002F\u002F Token from a previous scrape step\nlet dt = new Date().toLocaleString('en-GB', { timeZone: 'Europe\u002FLondon' });\n\nfor (var i = 0; i \u003C data.length; i++) {\n    data[i].push([dt]);\n}\n\nreturn data; For locale options, see Mozilla's Intl reference. Get the current day of the week Return the day of the week in the locale you pass in: const locale = 'en-US';\nconst options = { weekday: 'long' };\nconst now = new Date();\nreturn new Intl.DateTimeFormat(locale, options).format(now); For locale options, see Mozilla's Intl reference. Add a placeholder for blank cells Blank cells in scraped data are silently dropped by the Google Sheets API, which can shift columns left when the data is written. For example, the array [[\"1\", \"2\"], [\"\", \"4\"]] writes to a sheet like this: AB124 To prevent the shift, replace blank cells with a placeholder before writing: var data = [scrape-data];\nconst placeholder = '-';\n\nfor (var i = 0; i \u003C data.length; i++) {\n    for (var j = 0; j \u003C data[i].length; j++) {\n        if (data[i][j] === '') {\n            data[i][j] = placeholder;\n        }\n    }\n}\n\nreturn data; Change the placeholder value to suit your needs. The output goes into the code-data token, ready to write into a Google Sheet: AB12-4 Add a constant value to the last column Append a fixed value to every row of an array, useful for tagging exports with a category, source, or run timestamp: var scrapeData = [scrape-data];\nvar data = 'example';\n\nscrapeData.forEach((item) => item.push(data));\n\nreturn scrapeData; Replace [scrape-data] with the token from the previous step, and data with the constant value to append. Create and download a CSV file Build a CSV from automation data and write it to a local path. Read export to CSV before using this; the built-in step is simpler for most use cases. \u002F\u002F Replace [google-sheet-data] with the data token containing the rows to export.\nconst data = [google-sheet-data];\n\nfunction arrayToCSV(array) {\n    return array.map(row =>\n        row.map(value => {\n            if (typeof value === 'string' && (value.includes(',') || value.includes('\"'))) {\n                return `\"${value.replace(\u002F\"\u002Fg, '\"\"')}\"`;\n            }\n            return value;\n        }).join(',')\n    ).join('\\n');\n}\n\nfunction writeCSVFile(directory, filename, csvData) {\n    const fullPath = `${directory}\u002F${filename}`;\n    fs.writeFile(fullPath, csvData, 'utf8', (err) => {\n        if (err) {\n            console.error('Error writing CSV file:', err);\n        } else {\n            console.log(`CSV file saved as ${fullPath}`);\n        }\n    });\n}\n\nconst csvData = arrayToCSV(data);\n\n\u002F\u002F Change to the desired download path. Use forward slashes.\nconst downloadDirectory = 'C:\u002FUsers\u002FAxiom\u002FDocuments\u002FAxiom';\n\n\u002F\u002F Optional: the name of the output file.\nconst filename = 'output.csv';\n\nwriteCSVFile(downloadDirectory, filename, csvData); Manipulate data with regex Regular expressions match, search, and transform text. Each example below assumes the snippet is inside a Loop through data step so the script runs once per row, but you can also build the loop into the snippet itself. Extract data Use match to pull out the bit you want. The example pulls a number out of a string like 115 Records: \u002F\u002F Data scraped from a page, e.g. \"115 Records\".\nconst data = '[scrape-data?all&0]';\n\n\u002F\u002F Extract the digits.\nconst records = data.match(\u002F\\d+\u002F)[0];\n\n\u002F\u002F Return for the 'code-data' token.\nreturn records; Replace data Use replace to swap one substring for another. The example replaces an email domain: \u002F\u002F Data scraped from a page, e.g. \"axiom@example.com\".\nconst data = '[scrape-data?all&0]';\n\n\u002F\u002F Replace the domain.\nconst newEmail = data.replace(\u002F@[\\w.-]+$\u002F, '@newdomain.com');\n\n\u002F\u002F Return for the 'code-data' token.\nreturn newEmail; Validate data Use test to check whether a value matches a pattern. The example checks for a valid email: \u002F\u002F Data scraped from a page, e.g. \"example@example.com\".\nconst data = '[scrape-data?all&0]';\n\n\u002F\u002F Check if the email is valid.\nconst isValid = \u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F.test(data);\n\n\u002F\u002F Return for the 'code-data' token.\nreturn isValid; Reformat data Use replace with capture groups to restructure a value. The example reformats a date: \u002F\u002F Data scraped from a page, e.g. \"01-02-2025\".\nconst data = '[scrape-data?all&0]';\n\n\u002F\u002F Reformat to \"01\u002F02\u002F2025\".\nconst formatted = data.replace(\u002F(\\d{4})-(\\d{2})-(\\d{2})\u002F, '$1\u002F$2\u002F$3');\n\n\u002F\u002F Return for the 'code-data' token.\nreturn formatted; html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sa8KN, html code.shiki .sa8KN{--shiki-default:#116329;--shiki-default-font-weight:bold;--shiki-dark:#7EE787;--shiki-dark-font-weight:bold}",{"id":979,"title":980,"titles":981,"content":982,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript","JavaScript snippets",[],"Ready-to-use JavaScript snippets for the Write javascript step, organised by category covering data, interaction, navigation, network, and scraping. The Write javascript step lets you extend axiom.ai with custom JavaScript. The snippets in this section cover common patterns you can drop straight into a step, organised by category. Snippet categories Data for manipulating dates, scraped values, and CSV exports.Interaction for clicking, typing, and reaching into the Shadow DOM.Navigation for moving through browser history.Network for capturing network requests.Scrape for pulling data from a page.Page manipulation for hiding or modifying page elements. Need help? Contact support or ask a question in our Reddit community.",{"id":984,"title":985,"titles":986,"content":987,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript\u002Finteraction","Interaction snippets",[],"JavaScript snippets for interacting with page elements in axiom.ai automations, including clicks, dropdowns, text entry, Shadow DOM access, and event listeners. Interaction snippets drive elements on the current page. Most of these are covered by the Interact step category, but JavaScript is useful when the no-code steps can't reach what you need. Click a button by text Find a button by its visible text, click it, wait 5 seconds, and repeat until the button is no longer on the page. Useful for \"Load more\" buttons that pull in more results each click: const delay = ms => new Promise(res => setTimeout(res, ms));\n\nlet element = document.evaluate(\n    \"\u002F\u002Fbutton[contains(., 'Load more')]\",\n    document,\n    null,\n    XPathResult.FIRST_ORDERED_NODE_TYPE\n).singleNodeValue;\n\nwhile (element) {\n    element.click();\n    await delay(5000);\n    element = document.evaluate(\n        \"\u002F\u002Fbutton[contains(., 'Load more')]\",\n        document,\n        null,\n        XPathResult.FIRST_ORDERED_NODE_TYPE\n    ).singleNodeValue;\n} Interact with a dropdown using arrow keys For dropdowns the Select option step can't drive directly, simulate arrow-key presses instead. Open the dropdown first (with a click or by tabbing into it), then arrow down the right number of times: \u002F\u002F First either 1) click to open the difficult select-list,\n\u002F\u002F or 2) use the Tab key to focus the element.\nlet marital = 'Single';\n\nasync function arrowDownTimes(times) {\n    for (var i = 0; i \u003C times; i++) {\n        await page.keyboard.press('ArrowDown');\n        await page.waitForTimeout(250);\n    }\n}\n\nswitch (marital) {\n    case 'Married':\n        break;\n    case 'Single':\n        arrowDownTimes(1);\n        break;\n    case 'Divorced':\n        arrowDownTimes(2);\n        break;\n} Note: This snippet uses the Puppeteer API, which means it only runs when Run in app is enabled on the Write javascript step. Enter text from a data token Set the value of an input directly from a data token: document.querySelector('input[placeholder=\"Search the BBC\"]').value = '[custom-data]'; Note: Setting .value directly bypasses any input event listeners on the field. If the page relies on input or change events firing (most modern frameworks do), use the Enter text step or dispatch the events manually after setting the value. Reach into the Shadow DOM Some pages attach a Shadow DOM tree to an element, hiding the internals from regular JavaScript and CSS. The selector tool can't reach inside Shadow DOM, but you can drill in manually: const shadowHost = document.querySelector('\u003CSELECTOR>');\n\nif (shadowHost) {\n    const shadowRoot = shadowHost.shadowRoot;\n\n    \u002F\u002F Locate the element inside the shadow root that you want to interact with.\n    const innerElm = shadowRoot.querySelector('\u003CSELECTOR>');\n\n    if (innerElm) {\n        \u002F\u002F Example: innerElm.click();\n    }\n} Add an event listener Run code in response to events on the page. The example logs to the console every time an element is clicked: document.getElementById('custom-element').addEventListener('click', (e) => {\n    console.log('Custom element clicked');\n}); You can also dispatch your own custom events: document.addEventListener('my-custom-listener', (e) => {\n    console.log('Custom event triggered:', e.detail);\n});\n\n\u002F\u002F Trigger the listener manually.\ndocument.dispatchEvent(new CustomEvent('my-custom-listener', { detail: { data: 'Test data' } }));\n\n\u002F\u002F Or trigger it from another listener.\ndocument.getElementById('custom-element').addEventListener('click', (e) => {\n    document.dispatchEvent(new CustomEvent('my-custom-listener', { detail: { data: 'Test data' } }));\n}); Note: Event listeners don't survive page navigations. If the automation moves to a new page, you'll need to set the listeners up again. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}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 .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}",{"id":989,"title":990,"titles":991,"content":992,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript\u002Fnavigation","Navigation snippets",[],"JavaScript snippets for moving through browser history in axiom.ai automations, including going back one or several pages. Navigation snippets move the current tab through its history. Move through browser history Go back one page, equivalent to the Back step but available in JavaScript: window.history.back(); Go back a specific number of pages. The argument is a negative number for backward navigation, positive for forward: window.history.go(-2); html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}",{"id":994,"title":995,"titles":996,"content":997,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript\u002Fnetwork","Network snippets",[],"JavaScript snippets for inspecting and capturing network activity in axiom.ai automations using the Performance API. Network snippets help you inspect, log, and react to the requests a page makes during a run. Capture network requests Capture every network request a page has made using the Performance API. Add this snippet after a Go to page step: var resources = [];\nconst entries = window.performance.getEntriesByType('resource');\n\nentries.forEach(entry => {\n    resources.push([entry.entryType, entry.name]);\n});\n\nreturn resources; The list of resources is available in the code-data token for use in later steps. 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 .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 pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}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);}",{"id":999,"title":1000,"titles":1001,"content":1002,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript\u002Fpage-manipulation","Page manipulation snippets",[],"JavaScript snippets for manipulating the current page during an axiom.ai automation, including hiding elements that block other interactions. Page manipulation snippets modify the current page directly, useful when something on the page (a popup, an overlay, an autoplaying video) is getting in the automation's way. Hide page elements Hide the first element matching a selector. Useful for popups or overlays that block elements you need to click: document.querySelector('\u003CSELECTOR>').style.display = 'none'; Hide every element matching a selector: var els = document.querySelectorAll('\u003CSELECTOR>');\nfor (var i = 0; i \u003C els.length; i++) {\n    els[i].style.display = 'none';\n} html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}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 .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}",{"id":1004,"title":1005,"titles":1006,"content":1007,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fjavascript\u002Fscrape","Scrape snippets",[],"JavaScript snippets for scraping data in axiom.ai automations, including HTML tables, element attributes, page body, and meta tags. Scrape snippets pull data out of the current page when the no-code scrape steps don't fit the shape of the data. Scrape an HTML table Pull header cells and row data from an HTML table, returning headers and rows as a single 2D array ready to write to a Google Sheet: const headers = Array.prototype.map.call(\n    document.querySelectorAll('#org-insight__a11y-table tr'),\n    function (tr) {\n        return Array.prototype.map.call(tr.querySelectorAll('th'), function (th) {\n            return th.textContent.trim();\n        });\n    }\n);\n\nconst table = Array.prototype.map.call(\n    document.querySelectorAll('#org-insight__a11y-table tr'),\n    function (tr) {\n        return Array.prototype.map.call(tr.querySelectorAll('td'), function (td) {\n            return td.textContent.trim();\n        });\n    }\n);\n\nconst data = headers.concat(table);\n\nreturn data; Scrape element attributes Pull a specific attribute from every element matching a selector. The example collects the name attribute from every input inside a div: let results = [];\nlet els = document.querySelectorAll('div:nth-child(1) > input');\n\nfor (const el of els) {\n    results.push([el.getAttribute('name')]);\n}\n\nreturn results; Scrape the entire page body Return the page's full HTML, useful for AI-driven extraction or downstream parsing: return [[document.querySelector('body').innerHTML]]; Get meta tags from a page Read meta tags (Open Graph and others) from the current page. Make sure the automation is on the page you want to scrape before this snippet runs. Return a single meta attribute by name: let ogTitle = document.querySelector(\"meta[property='og:title']\").getAttribute('content');\nreturn ogTitle; Return the name and content of every meta tag on the page: let metaTags = document.getElementsByTagName('meta');\nlet metaContent = [];\n\nfor (var i = 0; i \u003C metaTags.length; i++) {\n    metaContent.push([\n        metaTags[i].getAttribute('name'),\n        metaTags[i].getAttribute('content')\n    ]);\n}\n\nreturn metaContent; Note: Some meta tags don't have a name attribute (Open Graph tags use property instead). The second snippet returns null for those, which is fine for most uses, but worth handling if your downstream step is strict about empty values. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}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);}",{"id":1009,"title":1010,"titles":1011,"content":1012,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fpuppeteer","Puppeteer snippets",[],"Ready-to-use Puppeteer snippets for the Write javascript step in axiom.ai, organised into interaction and network categories. Puppeteer is a Node.js library that provides a high-level API for controlling Chrome and Chromium. axiom.ai exposes Puppeteer's Page class inside the Write javascript step, so you can use it to extend the no-code Interact steps when you need behaviour those steps don't cover. For background on what Puppeteer can do with a page, see the Page interactions reference. Note: Puppeteer snippets only work when Run in app is enabled on the Write javascript step, and only on desktop runs. Cloud runs can't use Puppeteer. Snippet categories Interaction for scrolling, locating, and filtering elements with Puppeteer's locator API.Network for intercepting and blocking network requests during a run. Tip: For event-driven workflows, the EventEmitter class is also accessible from the Write javascript step. For a worked example, see Nitay Neeman's Puppeteer event handling examples. Need help? Contact support or ask a question in our Reddit community.",{"id":1014,"title":985,"titles":1015,"content":1016,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fpuppeteer\u002Finteraction",[],"Puppeteer snippets for interacting with page elements in axiom.ai automations, including scrolling and filtering elements with the locator API. Interaction snippets drive elements on the current page using Puppeteer's locator API. Use these when the no-code Interact steps don't cover the pattern you need. Scroll a container Scroll a specific element by its CSS class. Useful for elements that scroll independently of the page itself, such as modal contents or chat panels: await page.locator('container').scroll({\n    scrollLeft: 30,\n    scrollTop: 10\n}); Filter elements by text When several elements share the same selector, filter them by their content before interacting. The example clicks only the button whose inner text is Add to basket: await page.locator('button').filter(button => button.innerText === 'Add to basket').click(); This pattern is useful for e-commerce pages, search results, and any UI where multiple elements share a class but have different text. 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 .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}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 .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 .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}",{"id":1018,"title":995,"titles":1019,"content":1020,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Fsnippets\u002Fpuppeteer\u002Fnetwork",[],"Puppeteer snippets for axiom.ai automations to intercept, log, or block network requests by URL, file extension, or resource type. Network snippets intercept network requests during a run. Use them to block specific resources for speed, or to log and test requests during development. Block resources Blocking unnecessary resources (images, fonts, ad libraries) speeds up runs by skipping content the automation doesn't need. Add this snippet at the start of a Write javascript step that runs before the Go to page step: Warning: Blocking resources can break pages, particularly if scripts are blocked. Test thoroughly after changing what's blocked. await page.setRequestInterception(true);\n\npage.on('request', request => {\n    \u002F\u002F Skip if another listener already handled the request.\n    if (request.isInterceptResolutionHandled()) return;\n\n    \u002F\u002F Block any request ending in '.png' or '.jpg'.\n    if (request.url().endsWith('.png') || request.url().endsWith('.jpg')) {\n        request.abort('failed', 0);\n    } else {\n        request.continue();\n    }\n}); The example above blocks images by file extension. The same pattern works for blocking by URL prefix: if (request.url().startsWith('https:\u002F\u002Fgoogle.com')) {\n    request.abort('failed', 0);\n} Or by resource type: if (request.resourceType() === 'font') {\n    request.abort('failed', 0);\n} Common resource types you might want to block: font blocks fonts.image blocks images.media blocks audio and video.script blocks JavaScript files. Not recommended on most pages, since it usually breaks them. For the full list of resource types, see Mozilla's ResourceType reference. Tip: For non-Puppeteer alternatives, see the block resources setting, which gives you a no-code way to block resources by domain or URL pattern. 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 .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}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);}",{"id":1022,"title":1023,"titles":1024,"content":1025,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Ftroubleshooting\u002Fapi","API errors",[],"Errors returned by the axiom.ai API when triggering automations, including authentication failures, missing fields, and incorrect data formats. The errors on this page are returned by the axiom.ai API when triggering automations. For background on the API, see the API documentation. Missing API key Error: Unable to authenticate, you must send an API key. Problem: The request payload doesn't contain a key field. Fix: Add \"key\": \"\u003CAPI_KEY>\" to the payload. See API requests for the full payload format. Invalid API key Error: Unable to authenticate, please check your API key and try again. Problem: The API key in the payload doesn't match a valid axiom.ai key. Common causes are an expired or regenerated key, or a copy-paste error. Fix: Open the axiom.ai extension, navigate to the API key dashboard, and copy the current key into your request. Missing automation name Error: Missing task name, you must send the name of the task that you wish to trigger. Problem: The request payload doesn't contain a name field. The API needs the automation name to know which automation to trigger. Fix: Add \"name\": \"\u003CAUTOMATION_NAME>\" to the payload. See API requests for the full payload format. Automation not found Error: Task not found, please check the name and try again. Problem: The name field in the payload doesn't match any automation in the connected account. The match is case-sensitive. Fix: Open the axiom.ai extension and copy the automation name exactly as it appears in the dashboard, including capitalisation and spacing. Data format incorrect Error: Data must be sent as an array of arrays. Problem: The data field in the payload isn't formatted as a 2D array. The API expects every row to be its own array, even when there's only one row. Fix: Wrap the payload data as an array of arrays, where each inner array is one row: {\n  \"data\": [\n    [\"Row 1 - Column 1\", \"Row 1 - Column 2\"],\n    [\"Row 2 - Column 1\", \"Row 2 - Column 2\"]\n  ]\n} For the full payload structure, see API requests. html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":1027,"title":1028,"titles":1029,"content":1030,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Ftroubleshooting\u002Fdebug","Debug developer features",[],"Test the axiom.ai API with Postman or cURL, and debug custom code in Write javascript steps using console logs and conditional checks. Debugging the API and any custom code is essential when extending axiom.ai with the API or Write javascript step. The pages here cover patterns specific to those tools. For general automation debugging that applies to every plan, see Debug an automation. Test the API Postman and cURL are both good tools for testing the API outside your automation or production system. Both are free. For common errors when calling the API, see API errors. Debug custom code Custom code in the Write javascript step extends axiom.ai with logic the no-code steps don't cover. Two patterns help when something goes wrong: console logging and returning values for conditional checks. Use console logs console.log() works inside the Write javascript step and shows output in Chrome DevTools. Note: Console logs are only visible during desktop runs. Cloud runs close the browser when they finish, so the console is gone before you can read it. To inspect console output after a desktop run completes, add a Wait step at the end of the automation so the browser stays open long enough. For background on opening DevTools and reading the console, see use Chrome DevTools. Return values for conditional checks The Write javascript step can return a value, which you can then route on with a Continue only if a condition is met step. This is useful when the script can succeed in different ways and the rest of the automation needs to react accordingly. For example, a script might extract an email address from a page, returning the string no email found when nothing matches. Add a Continue only if a condition is met step after it that checks for no email found and stops or branches the automation when that string is returned.",{"id":1032,"title":1033,"titles":1034,"content":1035,"level":56},"\u002Fdocs\u002Fdeveloper-hub\u002Ftroubleshooting","Developer troubleshooting",[],"Debug and fix issues specific to the axiom.ai API and custom code, including JavaScript and Puppeteer steps, plus a reference of common API errors. The pages in this section cover debugging the developer-facing parts of axiom.ai: the API and the Write javascript step. For general automation debugging that applies to every plan, see Debug an automation. Developer troubleshooting pages Start with the debugging guide for patterns and tools that apply across the API and custom code. Use the API errors reference when you need to look up a specific error message returned by the API and find its fix. Need help? Contact support or ask a question in our Reddit community.",{"id":1037,"title":1038,"titles":1039,"content":1040,"level":56},"\u002Fdocs\u002Ffaq\u002Fgeneral","General FAQ",[],"Answers to common general questions about axiom.ai including affiliate program, API, desktop app, data handling, HIPAA compliance, and screen recording. Do you have an affiliate program? Yes. To learn more and join, see the axiom.ai affiliate program page. Do you have an API? Yes. The axiom.ai API lets you trigger automations and pass data to them. The API requires a Pro subscription or higher. Does axiom.ai come with a desktop app? The desktop application is optional. It's required for automations that upload or download files. Every subscription tier can use it. The desktop app is available for macOS, Windows, and Linux. Does axiom.ai work with Zapier? Yes. Pro subscribers and above can trigger automations from Zapier and pass data between axiom.ai and Zapier in either direction. Any tool that can send or receive webhooks can be integrated. Can you help me build an automation? Yes. To help you efficiently, send us as much context as possible: A screen recording of the task you want to automate.Any Google Sheets used in the automation, shared with support@axiom.ai with editor permission.The target webpage exported as HTML (the Save Page WE extension works well for this).The axiom.ai automation file if you've started one. See import or download an automation. Contact support with the details. How does axiom.ai handle my data? axiom.ai doesn't store user data and doesn't train models on user data. When automations run on the desktop app, no data leaves your network. When automations run in the cloud, the data is processed in a private container that's destroyed when the run finishes. axiom.ai stores only essential information: automation names, runtime usage, and basic account details. Text typed manually into an Enter text step is stored encrypted, so no one at axiom.ai can read it. Data passed in from a data source (a Google Sheet, a webhook, an API call) isn't stored. For full details, see the privacy policy. What if axiom.ai doesn't have the feature I need? Email feature requests to support@axiom.ai. User feedback drives the roadmap. How can I record my screen to share with support? Use the built-in screen recorder for your operating system. Windows 10 and Windows 11 Press Win + G to open the Game Bar.Click Start recording, or press Win + Alt + R.When you're done, click Stop recording.The video saves to Videos → Captures. macOS Press Cmd + Shift + 5 to open the screenshot toolbar.Click Record entire screen or Record selected portion, then click Record.To stop, click the Stop button in the menu bar.The video saves to your Desktop, or wherever you've configured screenshots to save. Email the recording to support, or share it via Google Drive (with support@axiom.ai granted access). Loom is a good cross-platform alternative. Is axiom.ai HIPAA compliant? No. axiom.ai does not offer HIPAA compliance, doesn't sign Business Associate Agreements (BAAs), and shouldn't be used to handle, store, or process protected health information in the cloud. If your organisation requires HIPAA compliance, use the desktop app only and never run automations in the cloud. With the desktop app, data stays on your network and never reaches axiom.ai's servers, but HIPAA compliance still remains your organisation's responsibility. For details on how axiom.ai handles user data in general, see How does axiom.ai handle my data? above. Can I host axiom.ai on a server? Yes. Running axiom.ai on a server is a good option when you need unattended runs combined with desktop-only features (file downloads, file uploads, local session storage, or specific JavaScript steps). To set up axiom.ai on a server: Install Chrome.Install the axiom.ai extension.If you'll use Download a file or Upload a file steps, also install the desktop application. Once installed, axiom.ai works on the server just as it does on a local computer. When scheduling automations, enable Run on this computer so they run locally on the server rather than in the cloud. How do I uninstall the desktop app? macOS: Navigate to the Applications folder and remove the axiom-desktop application.Windows: Navigate to Control Panel → Programs → Programs and Features. Find axiom-desktop, right-click it, and choose Uninstall. If you have problems after uninstalling, see installation errors.",{"id":1042,"title":1043,"titles":1044,"content":1045,"level":56},"\u002Fdocs\u002Ffaq","FAQ",[],"Answers to common questions about axiom.ai across general use, runtime and scheduling, subscriptions and accounts, the Builder, and third-party tools. The FAQ is split into five sections: general questions, runtime and scheduling, subscriptions and accounts, the Builder, and third-party tools. Browse the full list below. If you can't find an answer here, contact support or post in the Reddit community. All questions The categories below group questions by topic. General covers data handling, the desktop app, and screen recording. Builder covers the no-code Builder, JavaScript, and login automation. Runtime and scheduling covers running, scheduling, scraping, and triggering automations. Subscriptions and accounts covers plans, billing, and team setup. Third-party tools covers questions specific to apps that need a particular setup, like Slack. Need help? Contact support or ask a question in our Reddit community.",{"id":1047,"title":1048,"titles":1049,"content":1050,"level":56},"\u002Fdocs\u002Ffaq\u002Fno-code-builder","Builder FAQ",[],"Answers to common questions about the axiom.ai No-Code Tool, including JavaScript support, captchas, login automation, loops, and Chrome extension automation. Can I write code to control automations or process data? Yes. axiom.ai supports JavaScript and a subset of Google's Puppeteer API. How do I bypass captchas? axiom.ai doesn't have an in-house captcha solver but integrates with 2Captcha for the most common captcha types. How do I get started building an automation? Follow the guide for your first automation in the browser and pick a starting point that matches your use case. How do I get my automation to log in to a site? When you trigger an automation from the Chrome extension on the desktop, axiom.ai uses your local browser session, so you're already logged in. When triggering remotely (via the API, a webhook, or a schedule), you'll need to handle login as part of the automation. See the full login guide for the available approaches. How do I make a loop? axiom.ai supports conditional logic, a dedicated Loop through data step, and complex patterns built with jump steps. For details, see the loop documentation. Can a deleted automation be restored? No. Deleted automations are permanently removed and can't be recovered. Can I share an automation with another user? Yes. Download the automation as a JSON file and the other user can import it into their own account. See import or download an automation. How do I deal with Google token expiry? Google revokes tokens periodically as a security measure. The most common triggers are password changes and high-frequency reads or writes. When a token expires: Re-authenticate. Reconnect your Google account in axiom.ai. Token expiry can't be resolved automatically.Set up notifications. Enable run notifications so you find out as soon as a token-related run fails.Reduce read\u002Fwrite frequency. Frequent reads and writes correlate with token expiry. If your token expires often, run the automation less frequently. If you're not sure how to reduce frequency without breaking the automation, contact support with details of your sheet usage. Can I automate a Chrome extension? Limited support. axiom.ai can interact with extensions that modify pages directly (for example, by injecting buttons or fields into the DOM). Extensions whose UI lives in popups or dedicated windows aren't accessible to axiom.ai. Can I use Python? No. JavaScript is the only scripting language supported in steps. For the JavaScript step, see Write javascript. How do I insert line breaks in the Enter text step? In the Enter text step, toggle Custom line break on and record a unique key sequence. Make sure all whitespace is removed from the recording, then use the recorded sequence wherever you want a line break in the text. For step-by-step instructions, see the insert line breaks guide. Can I trigger an automation from a Google Apps Script? Yes. Use the axiom.ai API from your Apps Script. For a worked example, see the Google Apps Script trigger guide. How can I send multiple paragraphs in one message? When I add spaces, they send separately. This is common on social platforms like Instagram and Facebook, where pressing Enter sends the message instead of inserting a line break. Follow the insert line breaks guide for the workaround.",{"id":1052,"title":1053,"titles":1054,"content":1055,"level":56},"\u002Fdocs\u002Ffaq\u002Fruntime-and-scheduling","Runtime and scheduling FAQ",[],"Answers to common questions about runtime allowances, scheduling, automation speed, concurrency, queueing, and triggering automations from external tools. Do failed or stopped runs use up runtime? No. Only successful runs count against your runtime allowance, on both desktop and cloud. How do I stop axiom.ai from auto-starting on my computer? Every operating system has its own way to remove apps from the startup list. Search \"remove from startup\" plus your operating system name for current instructions. My automation is slow. How do I speed it up? The right fix depends on what's slowing things down. axiom.ai prioritises reliability and accuracy over raw speed, so always test changes after applying them. For a full walkthrough, see speed up an automation run. Common quick wins: Use block resources to skip images, fonts, and ads on heavy pages.Lower the Number of retries in the step's scraper configuration. How do I continue when a button isn't always present? A Click element step throws an error if the button isn't found. To skip the error and continue to the next step, enable optional click in the step settings. My scheduled automation runs at the wrong time. What should I do? Cloud runs use UTC by default. If the time of the run doesn't match the timezone of the site you're automating, change the timezone setting: Open the automation and click the Cog icon in the toolbar on the left.Open the Run options section.Open the Configure timezone section.Pick the timezone the schedule should use. How do I speed up the scraper? The scraper has configuration settings that affect speed. The most impactful is Number of retries. Lowering it makes the step faster but less tolerant of slow-loading pages. Can axiom.ai run in my current Chrome tab? By default, axiom.ai launches a new Chromium window. To attach to an existing Chrome window instead, use bypass bot detection with the Attach to existing Chrome option. This requires starting Chrome with the remote-debugging flag. Does unused runtime carry over between billing periods? No. Runtime resets at the start of each billing period and unused minutes don't roll over. Every period starts with the full runtime allowance for your plan. When does runtime refresh? Runtime refreshes on the day of the month you subscribed. For example, if you subscribed on the 4th of January, your runtime refreshes on the 4th of every following month, or the closest available date in months with fewer days. Unused runtime doesn't roll over. Can I schedule an automation more than once a day? Locally, yes. The desktop scheduler can run automations as often as every minute. In the cloud, the maximum frequency depends on your plan; some plans cap cloud runs at once per day. My new runtime isn't showing after upgrading. What should I do? Try these in order: Restart your browser. Close Chrome completely and reopen it.Sign out and back in. Sign out of axiom.ai, then sign in again.Contact support. If neither of the above works, email support@axiom.ai. Which plans support scheduling? Scheduling is available on the Pro plan and higher. My automation runs but no data is written to Google Sheets The most common cause is that the Write data to a Google Sheet step has no Data value set. Open the step, click Insert data in Data, and pick the variable from the previous step you want to write. For background on moving data between steps, see pass data between steps. Page elements load slowly. How do I make the scraper wait? axiom.ai waits for page changes by default, but some pages load slower than the detection allows. To force a longer wait, increase Minimum wait before scraping (ms) in the step's scraper configuration: Open the automation.Open the scrape step you want to adjust.Click Configure scraper.Set Minimum wait before scraping (ms) to your desired wait. 1000 ms equals 1 second. The scraper returns inconsistent results across pages This is most often caused by CSS selectors that don't generalise across pages. Try these in order: Switch to custom CSS selectors that target stable attributes.Use the AI web scraper template (requires an OpenAI API key).Contact support with examples of pages that work and pages that don't. My automation is stuck on Running The most common cause is that the computer or network connection dropped while the automation was running. The run actually stopped, but the extension didn't receive the status update. Try these in order: Refresh the dashboard tab and reopen axiom.ai.If that doesn't work, restart Chrome.If that doesn't work, see stop a run. If the run is still stuck after all three, contact support. Pages don't load through my proxy If a proxy is configured correctly but the target page won't load, the most likely cause is that the proxy's IP has been blocked or blocklisted by the target site. Many sites maintain lists of known proxy and datacenter IPs and refuse traffic from them. To confirm, change the Go to page step to a different URL (something like https:\u002F\u002Fexample.com) and run the automation again. If the test page loads, your proxy works in general but is blocked by the original target site. Try these in order: Switch to a different proxy or proxy region. Residential proxies are less likely to be blocked than datacenter proxies.Ask your proxy provider whether they offer a region or pool tuned for the target site.If the issue persists across multiple proxies, the target site may simply not allow proxied traffic. If the test page also fails to load, the issue is with the proxy connection itself. See the proxy troubleshooting section for the next steps. How do I make an automation ignore all errors? Enable continue on error: Open the automation and click the Cog icon.Open the Continue on error section.Toggle Continue on error on. Note: With this setting on, every run reports as successful at the end regardless of how many errors occurred. Errors appear as warnings in run reports. Are runs ever queued? Yes. Runs triggered by Zapier, Make, n8n, or the API are queued when your account exceeds its concurrency limit. Queued runs retry every five minutes until they can run. If you regularly hit the concurrency limit, runs may take a long time to complete or never run at all. For a custom concurrency package, email support@axiom.ai. Can I run multiple instances of the same automation in parallel? By default, no. Each automation can only have one instance running at a time. The same account can run different automations in parallel up to its concurrency limit, but not the same automation twice. To run the same logic concurrently, use Save as duplicate from the Builder menu to create as many copies of the automation as you need parallel runs. Each duplicate counts as a separate automation and can run independently of the others. Can I trigger an automation with Apple Shortcuts? Yes. You can trigger axiom.ai automations from Apple Shortcuts on macOS or iOS. You can also run shortcuts from the command line, or pin them to the macOS Dock. Can I run an automation on an iPhone? You can trigger an automation from an iPhone (typically via Apple Shortcuts), but the automation itself runs on the axiom.ai cloud, not on the iPhone. See the Apple Shortcuts guide. Can I pause an automation mid-run? Use the Wait step to pause for a fixed duration. There's no manual pause control during a run. Can I interact with the browser during a run? On the desktop and on a VPS, yes. In the cloud, no. Interaction with the cloud browser isn't permitted for security reasons. When interacting with the desktop browser during a run, consider adding a Wait step so the automation pauses while you act. Can Zapier trigger a desktop run? Not directly, because Zapier triggers are web-based and the desktop runner doesn't have a public webhook endpoint. The standard workaround uses Google Sheets as a middleman: In Zapier, write a new row to a Google Sheet when you want the automation to run.Schedule the axiom.ai automation to run every minute on the desktop.The first step in the automation reads the sheet with Read data from a Google Sheet. If a row exists, the automation continues.The last step deletes the row with Delete rows from a Google Sheet so the same trigger doesn't fire twice. For more, see trigger a desktop run with webhooks. Can I share my runtime with my team? Yes. Ultimate subscribers can share runtime by setting up a team account.",{"id":1057,"title":1058,"titles":1059,"content":1060,"level":56},"\u002Fdocs\u002Ffaq\u002Fsubscriptions-and-accounts","Subscriptions and accounts FAQ",[],"Answers to common questions about axiom.ai subscriptions, including free trials, cancellation, upgrades, downgrades, team accounts, and Stripe portal access. Does axiom.ai have a free tier? axiom.ai has a free trial, not a free tier. You can build an automation and run it successfully for up to 2 hours. Failed runs don't count against the trial. How do I cancel my subscription? Cancel from the Stripe payment portal. The portal is also accessible from the account page in the Chrome extension. For the full process, see manage your subscription. How do I download invoices? Download invoices from the Stripe payment portal. The portal is also accessible from the account page in the Chrome extension. For step-by-step instructions, see download invoices. How do upgrades work? When you upgrade mid-cycle, the unused portion of your current plan applies as a discount toward the new plan. This is called proration. For example, if you've paid $15 on Starter and immediately upgrade to Pro ($50), the full $15 applies as credit and you pay $35 to upgrade. If you upgrade two-thirds of the way through the month, only $5 of the $15 remains, so you pay $45 to upgrade. Can I manage other users from my account? axiom.ai doesn't have built-in user management. You can share account credentials so multiple users access the same subscription and the same automations, but there's no per-user permissioning. For shared usage, see the team account feature on the Ultimate plan. Note: Sharing credentials means everyone who has them can read and modify everything in the account. Use a team account on Ultimate for properly shared access. If I downgrade, will my scheduled automations still work? Downgrades to Starter or Free cancel all scheduled runs. Downgrades from Ultimate or Pro Max to Pro can change the maximum scheduling frequency you have access to. Can an axiom.ai account be shared? Yes. Multiple users can sign in with the same credentials and access the shared subscription and shared automations. Warning: Sharing credentials means everyone who has them has full access. For team usage with proper separation, set up a team account on Ultimate. Do you offer student discounts? Not at this time. Do you offer yearly subscriptions? Yes. Email customer support to set one up. I can't sign in to the Stripe payment portal The most common cause is that you're using a different email address than the one your subscription is registered against. Try signing in with your other email addresses. If none of them work, contact customer support. Is there a team subscription? Yes. Ultimate subscribers can share their account using the team account feature.",{"id":1062,"title":1063,"titles":1064,"content":1065,"level":56},"\u002Fdocs\u002Ffaq\u002Fthird-party","Third-party tools FAQ",[],"Answers to common questions about using axiom.ai with third-party services, including Slack, that have specific browser or platform restrictions. Can I use axiom.ai to automate Slack? Yes, but only on the desktop. Slack blocks Chromium, which is the browser axiom.ai uses by default both locally and in the cloud. To automate Slack, run the automation on the desktop pointed at your local Chrome installation. See set executable path for the setup. Note: This isn't currently possible in the cloud. The cloud runner uses Chromium and the browser can't be swapped.",{"id":1067,"title":1068,"titles":1069,"content":1070,"level":56},"\u002Fdocs","Browser Automation Documentation: No-Code, Code, API | axiom",[],"Official documentation for axiom.ai. Build browser automations in the no-code Chrome extension, in code with our SDK, or against our REST and MCP APIs. Step references, guides, and integrations.",{"id":1072,"title":1073,"titles":1074,"content":1075,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fget-started\u002Fform-filling","Fill a form from a spreadsheet",[],"Read rows from a spreadsheet and, for each row, fill a form on a website. A good second bot, once you're comfortable with scraping. You'll read rows from a Google Sheet and, for each row, fill in a form on a website. This is where you meet Loop for the first time - the step that repeats work across every row of data. What you'll build A bot with four steps: Read data from a Google Sheet - pulls in the rows.Loop through data - repeats the next steps once per row.Inside the loop: Go to page, Enter text, Click element - the steps that fill the form.Optionally, a final Send an email or log step to confirm each submission. Build the bot Add a Read data from a Google Sheet step. Point it at the sheet that contains your form data - one row per form submission.Add a Loop through data step. Reference the sheet data from step 1 with Insert Data. Every step you place inside this loop runs once per row.Inside the loop, add a Go to page step pointing at the form.Add an Enter text step for each form field. Use Insert Data to pull the value from the current loop row.Add a Click element step for the submit button.Run the bot. Check the form submissions. The shape: read data → loop once per row → do the work → repeat. Things worth knowing Loops run steps once per row in the data you passed in. Inside the loop, [sheet-data] refers to the current row, not all rows.Between iterations you may need a Wait step - some forms rate-limit fast submissions.If a form uses CAPTCHAs, dropdowns that load dynamically, or multi-step wizards, you'll need extra steps. See Browser actions. Next Read the Loop through data reference for the loop mechanics.Follow a full walkthrough with a template: see the form-filling guides on the Guides site.",{"id":1077,"title":578,"titles":1078,"content":1079,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fget-started",[],"Three short starting points for your first bot - scrape a page, fill a form, or loop through a list of URLs. Three common starting points for your first bot. Each one walks through the main moves, links to the relevant reference pages when you want more depth, and points you to a full walkthrough in our Guides. Jump to scrape a page into a Google Sheet, fill a form from a spreadsheet, or loop through a list of URLs. Web scraping Data entry Looping Ready for a full walkthrough with a downloadable template? Browse all browser automation guides.",{"id":1081,"title":1082,"titles":1083,"content":1084,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fget-started\u002Floop-urls","Loop through a list of URLs",[],"Start with a list of URLs, visit each one, and do something on every page. When the thing you're automating needs to happen on lots of pages, not one. You'll pass in a list of URLs, visit each one, and run the same actions on every page. Useful for product-page scraping, bulk screenshots, and any \"do this thing 200 times\" task. What you'll build A bot with three or four steps: A data source - a Google Sheet, a CSV, or a Get a list of links from a URL scrape.Loop through data - repeats the next steps once per URL.Inside the loop: Go to page - opens each URL.Inside the loop: whatever you want the bot to do on each page. Build the bot Get your URLs into a step. The three usual sources:\nA Read data from a Google Sheet step pointing at a column of URLs.An Import CSV file step if the URLs live in a CSV.A Get a list of links from a URL step if you want to scrape the URLs off a listing page first.Add a Loop through data step. Reference the URL data with Insert Data.Inside the loop, add a Go to page step. Insert the current loop value as the URL - this is what makes the bot visit a different page each iteration.Add whatever steps should run on each page - scrape, click, fill, screenshot - below the Go to page step, still inside the loop.Run the bot and watch it work through the list. The shape: get URLs → loop once per URL → go to that URL → do the work. Things worth knowing The whole job of the Go to page step inside a loop is to use the current URL, not the first or last one. Always use Insert Data to reference the loop row, never paste a hard-coded URL.Lots of sites rate-limit or detect bots when hit in quick succession. A Wait step inside the loop is usually a good idea.If any single URL fails, the whole loop stops. Wrap the page work in a Try \u002F Catch if you'd rather skip bad URLs and keep going. Next Loop through data reference covers the loop mechanics.Try \u002F Catch for handling failures mid-loop.Full walkthroughs with templates: browser automation guides.",{"id":1086,"title":1087,"titles":1088,"content":1089,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fget-started\u002Fscrape-to-sheet","Scrape a page into a Google Sheet",[],"Pull structured data off any webpage and write it straight to a Google Sheet in five steps. A good first bot. You'll scrape a table or list off a page and write every row into a Google Sheet. By the end you'll understand how data flows from one step to another in axiom.ai - the mental model that underpins every bot you build after this. What you'll build A bot with three steps: Get data from a URL - scrapes the page.Write data to a Google Sheet - saves each scraped row.Optionally, a scheduler so the bot runs every hour, day, or week. Build the bot Add a Get data from a URL step. Enter the URL of the page you want to scrape, then use the selector tool to click on the data. Axiom auto-detects repeating rows.Connect your Google account and add a Write data to a Google Sheet step. Point it at a sheet.In the sheet step, use the Insert Data button to reference the scraped data from step 1. Pick which columns you want written.Click Run to test. Check the sheet.If it works, schedule the bot to run automatically. That's the whole shape. Scrape data → reference it in the next step → write it out. Things worth knowing Scraped data is returned as a 2D array (rows and columns). Every step that reads data from another step reads it in this shape.The selector tool looks for repeating patterns. Click one item and the bot finds the rest. Click a second example if the first click doesn't capture everything.If the page loads slowly, the Configure scraper settings on the scrape step let you add wait time. Worth knowing if you see missing rows. Next Read the full Scrape data reference for every scraper option.Follow the full guide with a downloadable template: How to scrape links to a Google Sheet on the Guides site.",{"id":1091,"title":1092,"titles":1093,"content":1094,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fget-started\u002Fwebforms","How to automate web forms",[],"Learn how to automate data entry into web forms by combining steps using the axiom.ai No-code tool. To get started automating your web form, we have a choice of great starting points, including snippets, templates, or starting from blank. Start from Snippet Snippets are step combinations useful for starting an automation. We have a snippet called \"Fill in a form\" that adds steps you can build on. To add this snippet: Click \"New Automation\".Then click \"Add first step\".Finally, select the \"Fill in a form\" snippet. Start from Template We have some pre-made templates with video guides to help get you started. These templates have a base set of steps you can add to complete your automation. You can add templates from the builder or our website: How to automate data entry from a Google Sheet.How to automate data entry without an API using Zapier. How to start from blank We recommend when automating forms to focus on the web form itself as a starting point. Ignore importing the data for now. It may sound counterintuitive, but it’s better to set up the steps required to automate your form with dummy data. Test and prove you can automate the form in the browser. Then, when it’s working, invest your time in connecting your data source. To get started, click \"New Automation\" then \"Add first step\". Make sure you have axiom.ai open on the web page with the form open. Add a \"Go to page\" step The first step to add is the \"Go to page\" step. This loads the URL of the web form you wish to automate. To add this step: Open the step finder and search for \"Go\".Click and add the \"Go to page\" step.Insert the web form URL. Now add the steps to automate the form We have a range of steps you can select from, including steps to enter text, click buttons, and interact with select lists. Open the step finder, scroll down and click \"Interact\".Select the step you wish to use from the interact list. For example, you can add the \"Enter text\" step to input data into a text field. Testing We recommend testing at regular intervals when adding steps as you set up the automation. It's best to test your automation running locally so you can observe the run and resolve any issues that may occur. Connecting your data When ready to connect your data, choose from one of the steps below. Once added, you can easily pass data into the steps you have already added by going back through them and clicking \"Insert Data\". Pass data from a Google Sheet.From a webhook or Zapier. Advanced techniques for web forms When automating large forms, there are some steps\u002Ftechniques that will prove helpful. Try catch The try catch lets you attempt to execute a set of steps. If successful, the automation continues; if unsuccessful, it will execute a different set of steps. \"Get data from bot's current page\" and \"Conditionally jump to another step\" steps If you need to check for a value and present a different set of steps, we recommend using a \"Get data from bot's current page\" to scrape for that value. Then use the \"Conditionally jump to another step\" to execute a specific set of steps if the value is found. Grouping steps If you are automating a form with multiple pages, we recommend using the \"Loop data\" step to nest steps and arrange your automation by the pages of the web form.",{"id":1096,"title":1097,"titles":1098,"content":1099,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fcheckbox","Tick a checkbox",[],"Tick checkboxes in a web form using the Click element step, with fallback methods for tricky cases. To tick a checkbox, use the Click element step. Use the Click element step Open the step finder, search for click, and add the Click element step. Click Select and choose the checkbox. Fallback methods If the Click element step doesn't work for your checkbox, try these alternatives. Press key(s) step The Press key(s) step records keystrokes. For example, press Tab to move focus to the checkbox and Space to tick it. JavaScript The Write javascript step can tick checkboxes directly.",{"id":1101,"title":1102,"titles":1103,"content":1104,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fclicks","Automate a button click",[],"Click buttons in a web app using the Click element step, the Press key(s) step, or custom JavaScript. There are several ways to automate clicking a button in a web app. The primary method is the Click element step, but you can also record key presses or fall back to JavaScript. Click with the Click element step Open the step finder, search for click, and add the Click element step. Then choose the button using one of the methods below. Choose the button with the selector tool Point and click on the page to select the button. Click Select to open the single selector tool.Hover over the button and click to select it.Click Complete. Select by text If a button has unique text on the page (for example Submit or Message), select it by its text. This is the most reliable method when it's available. Click Select to open the single selector tool.Click Custom.Tick Use element text instead of HTML.Click Complete. Use a custom CSS selector If you're comfortable with CSS, use a custom selector. Click Select to open the single selector tool.Click Custom.Enter your CSS selector in the text box.Click Complete. Click only if the button is present (optional click) If a button doesn't always appear on the page, the Click element step throws an error and stops the run. To make the click optional, tick Optional click. The run continues regardless, and the button is clicked only when present. Click with the Press key(s) step The Press key(s) step records and replays keystrokes. For example, record Tab to move focus to a button and Return to click it. See the keyboard shortcut examples. Click with JavaScript If you're comfortable with JavaScript, the Write javascript step can click elements that the no-code steps can't. Use this as a last resort. Click every element containing some text Useful when you want to click items in a list that share a common pattern. document.querySelectorAll(\"INPUT SELECTOR HERE\").forEach(function(el) {\n    if (el.outerHTML.includes(\"TEXT\")) {\n        el.click();\n    }\n}); Replace INPUT SELECTOR HERE with the selector for the elements you want to scan, and TEXT with the text you want to match. You can also pass data into this step from earlier steps to replace the hardcoded value. Click a link or button inside a row containing text document.querySelectorAll(\"CUSTOM SELECTOR HERE\").forEach(function(el) {\n    if (el.outerHTML.includes('TEXT')) {\n        el.getElementsByTagName('a')[0].click();\n    }\n}); This clicks the first a tag inside each matching row. To click a different one, change the index: el.getElementsByTagName('a')[1].click(); To click a different element type, change the tag name: el.getElementsByTagName('button')[0].click(); To select by class name: el.getElementsByClassName('red')[0].click(); html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}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 .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}",{"id":1106,"title":1107,"titles":1108,"content":1109,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fcurrent-url","Get the current URL",[],"Use the Get current URL step to capture the URL of the page the automation is on, for use in later steps. To capture the URL of the page the automation is on, use the Get current URL step. Use the Get current URL step Open the step finder, search for current, and add the Get current URL step. The step doesn't need any configuration. It outputs the URL as a variable that any later step can use.",{"id":1111,"title":1112,"titles":1113,"content":1114,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fdate-picker","Use a date picker",[],"Pick dates from a calendar widget or text input using the Date picker step or the Enter text step. Date pickers vary widely. Some accept typed input, others are calendar widgets that need clicking through. axiom.ai handles both. For more on the topic, see the blog post on automating date pickers. Type the date into an input field If the date picker is a regular input field that accepts typed dates, use the Enter text step. Open the step finder, search for enter, and add the Enter text step.Click Select and choose the date input field.Type the date into Text, or click Insert data to pass a date in from earlier steps. Click through a calendar widget When the date picker is a calendar widget, use the Date picker step. Open the step finder, search for date, and add the Date picker step.Click Select and choose the text element showing the current month on the picker.Click Select and choose the Previous month or Next month button (depending on whether you're going back or forward in time).Type the name of the target month in Month.Type the target day in Day. For a step-by-step walkthrough, see the date picker blog post. If you find a date picker that none of these methods can handle, email it to support@axiom.ai. We enjoy a challenge.",{"id":1116,"title":1117,"titles":1118,"content":1119,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fdownload-cloud","Download files to Google Drive",[],"Use the Download a file to Google Drive step to save files from any webpage to a Google Drive folder, including looped downloads. To save files to Google Drive from a cloud automation, use the Download a file to Google Drive step. It works without code and runs in the cloud or on the desktop. Download a single file Add a Go to page step that loads the page containing the file, then add Download a file to Google Drive below it. Open the step finder and add Download a file to Google Drive.Set Select file by clicking Select and choosing the file element on the page.Set Drive folder URL to the URL of the destination folder in Google Drive.Set File name to the name you want the saved file to have. Download files from multiple pages To download a file from each page in a list, store the URLs in a Google Sheet and loop through them. The pattern works best when every page uses the same template. Add a Read data from a Google Sheet step pointing at a sheet of page URLs.Add a Loop through data step using the sheet data.Inside the loop, add a Go to page step. Set the URL by clicking Insert data and choosing the URL column.Add Download a file to Google Drive as the next sub-step.Set Select file to the file element. Set Drive folder URL to the destination folder. Set File name as desired. Download multiple files from one page To download several files from a single page, list their custom CSS selectors in a Google Sheet and loop through them. Add a Read data from a Google Sheet step pointing at a sheet of one CSS selector per row.Add a Loop through data step using the sheet data.Inside the loop, add a Go to page step (only needed once per loop iteration if the URL changes; skip if it doesn't).Add Download a file to Google Drive as a sub-step.In Select file, click Select, choose Custom, tick Set selector from data, and pick the column with the CSS selectors.Set Drive folder URL and File name. axiom.ai appends a unique number to each file when the name is reused. Advanced settings Force download Some files open in the browser instead of downloading. Toggle Force download on and tick the box to force them. If the issue persists, contact support. Auto convert Toggle Auto convert on and tick the box to convert the file into a Google Docs editor format on download. Download start wait time Toggle Download start wait time on to set how long axiom.ai waits for the download to begin. The value is in hundredths of a second. Troubleshooting If the file doesn't download, the most common cause is an incorrect Drive folder path. Double-check the folder URL is correct and you have write access. Download to a local folder instead The Download a file to Google Drive step can also save files locally when running in the desktop app. See download files locally for instructions.",{"id":1121,"title":1122,"titles":1123,"content":1124,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fdownload-local","Download files to your computer",[],"Save files from any website to a local folder using the Download file, Download files, or Download file from URL steps. To save files to a local folder, use one of three steps: Download file, Download files, or Download file from URL. All three require running the automation in the axiom.ai desktop app. Download files from the current page Add a Go to page step that loads the page containing the file, then add Download file (single file) or Download files (multiple). Click Select and choose the file element on the page.Click Click to select and choose the destination folder, or enter a path.Set File name to the name you want the saved file to have. Download files from multiple pages To download a file from each page in a list, store the URLs in a Google Sheet and loop through them. Add a Read data from a Google Sheet step pointing at a sheet of page URLs.Add a Loop through data step using the sheet data.Inside the loop, add a Go to page step. Set the URL using Insert data to pick the column.Add Download file or Download files as the next sub-step.Click Select and choose the file element. Click Click to select for the folder. Set File name. Download a file from a URL When you have direct file URLs (rather than pages that contain files), use the Download file from URL step. Open the step finder and add Download file from URL.Enter the file URL in URL.Click Click to select and choose the destination folder.Set File name. Download files from multiple URLs To download files from a list of URLs: Add a Read data from a Google Sheet step pointing at a sheet of file URLs.Add a Loop through data step using the sheet data.Inside the loop, add a Download file from URL step.Set URL by clicking Insert data and selecting the URL column.Click Click to select and choose the destination folder.Set File name. axiom.ai appends a unique number when the name is reused. Download locally with the Google Drive step The Download a file to Google Drive step can also save files locally when running in the desktop app. This is useful when you want a single step that works in both cloud and desktop modes. Add a Go to page step that loads the page containing the file.Open the step finder and add Download a file to Google Drive.Click Select and choose the file element.Set Drive folder URL to the destination folder in Google Drive.Set File name.Toggle Local folder on and set a local folder path. Note: The Local folder setting only takes effect when running the automation in the desktop app. Advanced settings Overwrite existing file Toggle Overwrite existing file on and tick the box to replace files with the same name instead of renaming the new download. Force download Some files open in the browser instead of downloading. Toggle Force download on and tick the box to force them. If the issue persists, contact support. Download start wait time Toggle Download start wait time on to set how long axiom.ai waits for the download to begin. The value is in hundredths of a second. Troubleshooting If the file doesn't download, check that the file path is correct and the destination folder has write permission set for the local user.",{"id":1126,"title":1127,"titles":1128,"content":1129,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fenter-text","Enter text into an input field",[],"Use the Enter text step to type into form fields, with optional support for line breaks and dynamic data. To type text into a form field, use the Enter text step. You can type a static string, or pass data in from an earlier step. Use the Enter text step Open the step finder, search for enter, and add the Enter text step. Click Select and choose the input field.Type the text into Text, or click Insert data to pass data in from an earlier step. Insert line breaks Some fields accept a regular Return key as a line break, others need a different key combination (for example Shift + Enter). Use the Custom line break setting to map your line breaks to whatever the site expects. For a worked example, see How to insert line breaks when entering text. In the Enter text step, click Custom line break.Record the key sequence the site uses for line breaks.Use regular line breaks in the Text field. axiom.ai converts them to the recorded sequence at runtime. Enter text with JavaScript For cases where the Enter text step doesn't fit, the Write javascript step can set field values directly. Use this as a last resort.",{"id":1131,"title":1132,"titles":1133,"content":1134,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions","Interact with the browser",[],"Tutorials for automating the most common browser actions, including clicks, text input, file uploads, downloads, tabs, and date pickers. These tutorials cover the most common browser actions you'll automate in axiom.ai, from clicks and text input to file uploads, downloads, and date pickers. If there's an action you'd like to automate that isn't covered here, contact support or post in our Reddit community. Browser action tutorials Need help? Contact support or ask a question in our Reddit community.",{"id":1136,"title":1137,"titles":1138,"content":1139,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fkey-strokes","Record keystrokes",[],"Record any single key or combination of keys using the Press key(s) step, then replay it during an automation. To automate any keystroke or key combination, record it with the Press key(s) step. Use the Press key(s) step Open the step finder, search for press, and add the Press key(s) step. Click Record.Press the key or combination you want to record.Click Stop recording. For worked examples, see the keyboard shortcut guide. Send keystrokes with JavaScript The Write javascript step can also simulate keystrokes. For security reasons, JavaScript-based keystrokes only work on the current web page.",{"id":1141,"title":1142,"titles":1143,"content":1144,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fmouse-drag","Drag the mouse",[],"Emulate a click-and-drag mouse interaction using start and end coordinates with the Mouse click and drag step. To click and drag an element on a page, use the Mouse click & drag step. It emulates the action between two sets of coordinates. Use the Mouse click & drag step Open the step finder, search for drag, and add the Mouse click & drag step. Set the coordinates of the initial mouse click.Set the coordinates to drag the mouse to.",{"id":1146,"title":1147,"titles":1148,"content":1149,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fmulti-click","Click multiple buttons",[],"Click many buttons at once with Click multiple elements, loop through CSS selectors, or use jump steps to repeat a click. axiom.ai gives you several ways to click more than one button in a single automation, depending on whether the buttons share a pattern or you need to repeat the same click many times. Use the Click multiple elements step The Click multiple elements step clicks every element matching a selector. Useful for clicking each item in a list. Open the step finder and add Click multiple elements.Click Select and use the selector tool to choose the elements.Set the click action to Left click or Right click.Set Maximum clicks to cap the number of clicks. This step doesn't support clicking a button, doing some other actions, then clicking the next button. For that pattern, loop through CSS selectors instead. Loop through CSS selectors When you need to click a button, perform actions, then move on to the next button, store the buttons' CSS selectors in a Google Sheet and loop through them. Create a Google Sheet with one CSS selector per row.Add a Read data from a Google Sheet step pointing at the sheet.Add a Loop through data step using the [google-sheet-data] token.Inside the loop, add a Click element step.In the Click element step, click Select, choose Custom, tick Set selector from data, and pick the [google-sheet-data] token.Click Complete. For more on this pattern, see custom CSS selectors. Repeat a single click with a jump step To click the same button several times in a row, pair Click element with a Jump to another step or Conditionally jump to another step step. Add a Click element step and configure it with the selector tool.Add a Jump to another step or Conditionally jump to another step step. Set Jump to step to the Click element step.Set Maximum cycles (or, for the conditional version, configure the condition). Click with JavaScript The Write javascript step gives you full control when the no-code steps don't fit. Two common approaches: The native HTMLElement.click() method.The Puppeteer integration for more complex interactions. For starting points, see the JavaScript snippets reference.",{"id":1151,"title":1152,"titles":1153,"content":1154,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fradio-buttons","Click a radio button",[],"Click radio buttons in a web form using the Click element step, with fallback methods for tricky cases. To click a radio button, use the Click element step. Use the Click element step Open the step finder, search for click, and add the Click element step. Click Select and choose the radio button. Fallback methods If the Click element step doesn't work for your radio button, try these alternatives. Press key(s) step The Press key(s) step records keystrokes. For example, press Tab to move focus to the radio button and Space to select it. CSS selector loop Use the attribute selector or another custom CSS selector to match the right radio button when the visual picker can't. JavaScript The Write javascript step can click radio buttons directly.",{"id":1156,"title":1157,"titles":1158,"content":1159,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Frollover","Trigger a rollover",[],"Trigger a mouseover event on a dropdown menu or other hover-activated element using the Rollover element step or JavaScript. To trigger a mouse hover or rollover (for example, to reveal a dropdown menu), use the Rollover element step. Use the Rollover element step Open the step finder, search for roll, and add the Rollover element step. Click Select and choose the element to hover over. Trigger a rollover with JavaScript When the Rollover element step doesn't trigger the desired behaviour, dispatch a mouseover event from the Write javascript step. Example HTML \u003Cnav>\n    \u003Cul>\n        \u003Cli class=\"menu-item\">\n            \u003Ca href=\"#\" class=\"your-hover-element\">Menu\u003C\u002Fa>\n            \u003Cul class=\"submenu\">\n                \u003Cli>\u003Ca href=\"#\">Option 1\u003C\u002Fa>\u003C\u002Fli>\n                \u003Cli>\u003Ca href=\"#\">Option 2\u003C\u002Fa>\u003C\u002Fli>\n                \u003Cli>\u003Ca href=\"#\">Option 3\u003C\u002Fa>\u003C\u002Fli>\n            \u003C\u002Ful>\n        \u003C\u002Fli>\n    \u003C\u002Ful>\n\u003C\u002Fnav> Example JavaScript \u002F\u002F Select the menu item\nconst menuItem = document.querySelector('.your-hover-element');\n\n\u002F\u002F Trigger mouseover event\nconst mouseOverEvent = new MouseEvent('mouseover', {\n    bubbles: true,\n    cancelable: true,\n    view: window\n});\n\nmenuItem.dispatchEvent(mouseOverEvent);\n\n\u002F\u002F Optionally, click the first submenu option after hover\nsetTimeout(() => {\n    const firstOption = document.querySelector('.submenu li a');\n    if (firstOption) {\n        firstOption.click();\n    }\n}, 1000); This script triggers the rollover, reveals the submenu, then clicks the first option after a one-second delay. html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}",{"id":1161,"title":1162,"titles":1163,"content":1164,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fselect-lists","Use a select list",[],"Pick an option from a dropdown using the Select list step, or fall back to combinations of Click element with Enter text or Press key(s). The primary way to interact with a dropdown menu is the Select list step. When that doesn't work (for example, on custom dropdowns that don't use a real \u003Cselect> element), there are two fallback patterns. Use the Select list step Open the step finder, search for select, and add the Select list step. Click Select and choose the dropdown.Set Option to the value you want to select, or click Insert data to pass a value in from earlier steps. Type the value with Click element and Enter text If the dropdown is searchable (it filters as you type), click into it and type the option you want. Add a Go to page step (or another step that loads the page).Add a Click element step and select the dropdown.Add an Enter text step.In Text, enter the option you want. Navigate with Click element and Press key(s) If the dropdown isn't searchable, open it with a click and use arrow keys to pick an option. Add a Go to page step (or another step that loads the page).Add a Click element step and select the dropdown to open it.Add a Press key(s) step.Record the keys needed to reach the right option. For example, Arrow down, Arrow down, Enter to select the second option. Use a select list with JavaScript For cases where none of the steps above fit, the Write javascript step can set the value directly.",{"id":1166,"title":1167,"titles":1168,"content":1169,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fsocial-media-buttons","Click likes and follows",[],"Use the Click social media buttons step to like and follow posts, with detection so already-liked content isn't clicked twice. To automate likes and follows on social media, use the Click social media buttons step. It detects whether the content is already liked or followed, so it won't click twice. Use the Click social media buttons step Open the step finder, search for social, and add the Click social media buttons step. Click Select and choose the like or follow button.Set Value to check so the step can detect the already-clicked state. Use the Click element step If the targeted button doesn't have a clear \"already-clicked\" state, the standard Click element step works just as well. Click likes and follows with JavaScript For cases where neither step fits, fall back to the Write javascript step.",{"id":1171,"title":1172,"titles":1173,"content":1174,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fsolve-captcha","Solve a captcha",[],"Solve reCAPTCHA and similar challenges using the 2Captcha integration, manual interaction, or anti-bot blocking settings. There are three ways to handle a captcha during an automation: solve it automatically through the 2Captcha integration, solve it manually using the desktop app, or avoid triggering it by enabling anti-bot blocking. Solve a captcha with 2Captcha Use the Solve Captcha step to solve captchas automatically. You'll need a 2Captcha account, and there's a small per-captcha charge. Sign up for a 2Captcha account.Open the step finder, search for solve, and add the Solve Captcha step.Enter your 2Captcha API key in the step. The integration supports reCAPTCHA v2, reCAPTCHA v3, and invisible reCAPTCHA. For more, see the 2Captcha integration docs. Solve a captcha manually When running on the desktop app, you can interact with the browser during a run. This is called attended automation. Add a Wait step before the captcha so you have time to solve it manually before the automation continues. Avoid captchas with anti-bot blocking The bot blocking setting can stop captchas from appearing in the first place. If a captcha is triggered every run, try enabling anti-bot blocking before reaching for one of the methods above.",{"id":1176,"title":1177,"titles":1178,"content":1179,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Ftabs","Switch and close browser tabs",[],"Use the Switch browser tab and Close browser tab steps to interact with multiple tabs during a run. When pages open or close tabs during a run, use these no-code steps to manage them. Switch to a tab To switch to a different tab during a run, open the step finder, search for tab, and add the Switch browser tab step. Set Tab position to Last opened tab, or specify the tab number. 1 is the leftmost tab, 2 is the second from the left, and so on. Close a tab To close a tab during a run, open the step finder, search for tab, and add the Close browser tab step. Set Tab position to Last opened tab, or specify the tab number. 1 is the leftmost tab, 2 is the second from the left, and so on. Manage tabs with JavaScript The Write javascript step can also open and close tabs. To open a tab: window.open('https:\u002F\u002Fwww.example.com'); To close a tab: window.close(); html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":1181,"title":1182,"titles":1183,"content":1184,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fupload-cloud","Upload files from Google Drive",[],"Use the Upload a file from Google Drive step to upload files from Google Drive to any web form, including looped uploads. To upload files from Google Drive in a cloud automation, use the Upload a file from Google Drive step. This step requires running the automation in the cloud. To upload from local storage instead, see upload files from your computer. Upload a single file Add a Go to page step that loads the page with the upload field, then add Upload a file from Google Drive below it. Open the step finder and add Upload a file from Google Drive.Click File input field and select the file field on the page.Set Google Drive file URL to the URL of the file in Google Drive. Upload multiple files to the same field To upload several files to a single input field, store the file URLs in a Google Sheet and loop through them. Add a Read data from a Google Sheet step pointing at a sheet of file URLs.Add a Go to page step that loads the page with the upload field.Add a Loop through data step using the sheet data.Inside the loop, add an Upload a file from Google Drive sub-step.Click File input field and select the file field on the page.Click Insert data in Google Drive file URL and pick the column with the file URLs. Upload files to multiple pages To upload files to a series of pages that share the same template (for example, product pages in a CMS), loop through both URLs and file paths. Add a Google Sheet with one row per page, containing the page URL and the file URL.Add a Read data from a Google Sheet step pointing at the sheet.Add a Loop through data step using the sheet data.Inside the loop, add a Go to page step. Click Insert data and pick the URL column.Add an Upload a file from Google Drive sub-step.Click File input field and select the upload field.Click Insert data in Google Drive file URL and pick the file URL column. Troubleshooting If the file doesn't upload, check that the filename and Google Drive URL are correct, and that the file is present at the specified location.",{"id":1186,"title":1187,"titles":1188,"content":1189,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fupload-local","Upload files from your computer",[],"Use the Upload a file step to upload files from your local computer to any web form, with optional support for loops. To upload files from your local computer, use the Upload a file step. This step requires running the automation in the axiom.ai desktop app. To upload from Google Drive in the cloud instead, see upload files from Google Drive. Upload a single file Add a Go to page step that loads the page with the upload field, then add Upload a file below it. Open the step finder and add Upload a file.Click File input field and select the file field on the page.Set File path. Click Insert data to use a path from earlier steps, or click Click to select to pick a file manually. Upload multiple files to the same field To upload several files to a single input field, store the file paths in a Google Sheet and loop through them. Add a Read data from a Google Sheet step pointing at a sheet of file paths.Add a Go to page step that loads the page with the upload field.Add a Loop through data step using the sheet data.Inside the loop, add an Upload a file sub-step.Click File input field and select the upload field on the page.Click Insert data in File path and pick the column with the file paths. Upload files to multiple pages To upload files to a series of pages that share the same template (for example, product pages in a CMS), loop through both URLs and file paths. Add a Google Sheet with one row per page, containing the page URL and the file path.Add a Read data from a Google Sheet step pointing at the sheet.Add a Loop through data step using the sheet data.Inside the loop, add a Go to page step. Click Insert data and pick the URL column.Add an Upload a file sub-step.Click File input field and select the upload field.Click Insert data in File path and pick the file path column. Upload local files with the Google Drive step The Upload a file from Google Drive step can also upload from a local folder when running in the desktop app. This is useful when you want a single step that works in both cloud and desktop modes. Add a Go to page step that loads the page with the upload field.Open the step finder and add Upload a file from Google Drive.Click File input field and select the upload field.Set Google Drive file URL to the file URL.Toggle Local folder on and enter a local folder path. Warning: Don't use this configuration when running in the cloud. The Local folder setting only works in the desktop app. Troubleshooting If the file doesn't upload, check that the filename and path are correct, the file is present at that location, and your local user has read access to the folder. Note: The Upload a file step only runs in the desktop app. To upload in the cloud, use the Upload a file from Google Drive step.",{"id":1191,"title":1192,"titles":1193,"content":1194,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fbrowser-actions\u002Fwait","Pause an automation",[],"Pause an automation to interact with the page, give content time to load, or mimic human-like timing. There are several reasons to pause an automation: to interact with the page (for example to enter a password), to give a slow-loading page time to render, or to vary timing to look more human. Note that you can only interact with the browser when running on the desktop, not in the cloud. Use the Wait step To pause an automation, open the step finder, search for wait, and add the Wait step. Set Wait type to Fixed length for a specific duration, or Random length to vary it. The automation pauses when it reaches the Wait step, not before.",{"id":1196,"title":1197,"titles":1198,"content":1199,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fdata\u002Fdynamically_write","How to write data to a specific row",[],"Learn how to select and write data to a specific row in a Google Sheet when automating the browser. Learn how to append data to a specific row in a Google Sheet by combining a few steps using our builder. This design pattern is useful when you have a list of links and want to append some data to the same row where the link is located. Design pattern: Write to same Google Sheet row Read data from Google SheetScrape data (or other actions)Write data to the correct row in Google Sheet Set up a Google Sheet Prepare your Google Sheet by creating a separate column with the row numbers. Add the following steps in your bot 1.0 Read data from Google Sheet Spreadsheet: Select your Google Sheet.Sheet name: Choose the relevant worksheet.First cell: Specify the starting cell (e.g. A2 if your sheet has headers).Last cell: Specify the last cell to limit your test range (e.g. B5 for columns A and B, rows 2–5). 2.0 Loop through data Token: Select the [google-sheet-data] token. 2.1 Add browser actionsAdd any steps needed between reading and writing, such as scraping a page or clicking buttons.2.2 Write to Google Sheet Spreadsheet: Select the same Google Sheet as above.Sheet name: Use the same worksheet, or a different one if needed.DATA: Select the token containing the data to write (often [scrape-data]).Write options: Choose the target column (e.g. C or D). Click \"Insert data\", then use the row number token from the \"Read data\" step to write to the correct row. Wrapping up Create an automation that reads your sheet, processes data, and writes results to the exact row using.",{"id":1201,"title":1202,"titles":1203,"content":1204,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fdata\u002Fexport","How to export data from axiom.ai",[],"Learn how to extract data from your automation into CSVs and Google Sheets, and even post to apps like Zapier, Retool, Airtable, and Make using our API and webhooks. You can export data from axiom.ai using various methods, such as writing data to a Google Sheet or posting data via apps like Zapier, Make, or Airtable. Export data using \"Write data to a Google Sheet\" To extract data to a Google Sheet, use the Step Finder to search for \"Write data\" and add the step. First, select a Google Sheet to write to.Next, specify a sheet name to write to.Lastly, select the data to write, click and select the variable to use. If looping your automation, we recommend inserting the step inside the loop. Export using \"Export to CSV\" To write data into a CSV file, use the Step Finder to search for \"Export to\" and add the step. First, select \"Export to CSV,\" click \"Insert Data,\" and choose the variable to use.Next, enter a name to save the file as. The file will be saved in your downloads folder. Note that this step is only for the desktop runner. Export data using a webhook Integrate with any site that supports webhooks by sending them whatever data you want using our \"Trigger webhook\" step. Use the Step Finder to search for \"Webhook\" and add the step. Set your Endpoint.Enter your payload, valid JSON only. To see examples and learn more about webhooks click here.",{"id":1206,"title":1207,"titles":1208,"content":1209,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fdata\u002Fimport","How to import data to use in your automation",[],"Learn how to import data from Google Sheets, CSVs, and web apps like Zapier, Make, Retool, and Airtable. You can import data into axiom.ai for your browser automation through various methods, such as web scraping, reading data from Google Sheets or posting data via apps like Zapier, Make, or Airtable. Import using \"Read data from a Google Sheet\" To import data from a Google Sheet, use the Step Finder to search for \"Read\" and add the step. First, select a Google Sheet to read from.Next, specify the sheet name to read from.Lastly, if you wish to set a cell range, enter values in \"First cell\" and \"Last cell\". Once set up, you will see a preview output of the first three rows, and a token will be available to pass that data into any other step. If you wish to loop through your data, see here. Import using \"Import CSV file\" To import data from a CSV, use the Step Finder to search for \"CSV\" and add the step. First, select CSV file to upload.Next, if you wish to set a cell range, enter values in \"First cell\" and \"Last cell\". Once set up, you will see a preview output of the first three rows, and a token will be available to pass that data into any other step. This step only works with the desktop runner. Import data using \"Get data from a URL\" To scrape data from a webpage, use the Step Finder to search for \"Get data from a URL\" and add the step. First, set the URL to scrape.Second, select the data to scrape.Lastly, set the number of results to scrape. Once set up, you will see a preview output of the first three rows, and a token will be available to pass that data into any other step. To learn more about scraping data, click here. Import data from other web apps To import data from other apps such as Zapier, Make, Retool, and Airtable, use the \"Receive data from another app\" feature and the axiom.ai API. Use the Step Finder to search for \"Receive data\" and add the step. For examples and to learn more about passing data from other apps, click here. If you need help or want to suggest an alternative way of importing data into axiom.ai, please let support know.",{"id":1211,"title":1212,"titles":1213,"content":1214,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fdata","Work with data",[],"Import data from a CSV or Google Sheet, pass it between steps, and transform it along the way. Working with data is central to building effective bots. These tutorials cover the full data lifecycle — from importing data into your bot and passing it between steps, to transforming and exporting the results. Data tutorials Need help? Contact support or ask a question in our Reddit community.",{"id":1216,"title":1217,"titles":1218,"content":1219,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fdata\u002Ftransform","Transforming data during the run",[],"Learn how to use a range of steps to help you transform your data, including appending, filtering, replacing, removing, and deduplication. We offer a range of steps to help you transform your data, including appending, filtering, replacing, removing, and deduplication. Data can be passed into all of these steps simply by clicking \"Insert Data\" when configuring the step. This group of steps also output their transformed data in a variable. How to append or merge two or more data variables Merge two pieces of data together by appending one to the other. You can append either horizontally, which merges rows, or vertically, which adds all the columns in the second set to the end of the first. To do this add the \"Append or merge data\" step, use the Step Finder to search for \"Append\" and add the step. Append or merge data step Data A: Click \"Insert data\" and select the data to append to.Data B: Click \"Insert data\" and select the data to append. The variable output of this step will be the joined data in a list or table. To append more data use additional steps. Example of using the \"Append or merge data\" step We often use this step to combine data from two different sources. For example, we have created an automation that reads URLs from a Google Sheet, then scrapes data from those pages. We use an \"Append\" step to merge the URLs with the scraped data before writing it to a Google Sheet. How to join different data sources based on matching columns Join data gathered from different sources together using a shared column. For example, you can use this to join product information from different e-commerce sites. To do this add the \"Join different data sources based on matching columns\" step, use the Step Finder to search for \"Join\" and add the step. Join different data sources based on matching columns step Base data: Enter the base data to join with another.Base data column: Set column of data to use as the basis of the join.Join data: Enter the data you want to join with the base data.Column: Specify a particular column of the base data to always match against. The variable output of this step will be the merged data. Example We often see users utilizing this step to merge CSV files together before entering data into a webform. How to remove duplicates from your data Remove duplicates from the specified data. This can be limited to particular columns. To do this add the \"Remove duplicates\" step, use the Step Finder to search for \"Remove\" and add the step. Remove duplicates step Data: Select the data to deduplicate. The variable output of this step will be the deduplicated data. Example This step can be useful for deduplicating data sets before you run your browser automations. How to remove results that contain certain words Filter out rows from your data that contain particular words. To do this, add the \"Remove results that contain certain words\" step using the Step Finder to search for \"Remove\" and add the step. Remove results that contain certain words step Data: Select the data you wish to remove rows from.Words (comma separated): Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row.Word matching mode: Set to \"All\" or \"Any\".Match on word boundary: Check this to match only when the complete word appears in the data. The variable output of this step will be the data minus the rows matching the words. Example When doing large scale scrapes of sites, whilst searching for particular data this step can be used to filter out data that you do not want written to the Google Sheet. How to remove results which do not contain certain words Filter out rows from your data that do not contain particular words. To do this, add the \"Remove results which do not contain certain words\" step using the Step Finder to search for \"Do not\" and add the step. Remove results that do not contain certain words step Data: Select the data you wish to remove rows from.Words (comma separated): Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row.Word matching mode: Set to \"All\" or \"Any\".Match on word boundary: Check this to match only when the complete word appears in the data. The variable output of this step will be the data with the matching words. Example This is often used when extracting product data from e-commerce sites, to isolate products with SKUs from the scraped data. How to select data randomly Select random rows from a given data set and create a new data set containing them. To do this, add the \"Select random rows\" step using the Step Finder to search for \"andom\" and add the step. Select random rows step Rows: Enter the number of rows to select.DATA: Select the data to get rows from. The variable output of this step will be the specified number of rows, randomly picked from the data source. Example This step can be used to randomly enter a number value into an input field. How to extract data from a string Split data into parts using a delimiter that you specify. To do this, add the \"Split by character\" step using the Step Finder to search for \"Split\" and add the step. Split by character step Character: Enter a character or word to split on.DATA: Select the data that should be split. The variable output of this step will be the characters before or after the split. Example This step is useful when you need to extract specific data from within a string. For instance, if you are scraping data that is embedded within a larger string, you can use two \"Split by character\" steps. The first step removes the unwanted characters before your desired data, and the second step removes the unwanted characters after your desired data, effectively isolating the information you need. How to replace text Replace one piece of text with another within a dataset. To do this, add the \"Replace text\" step using the Step Finder to search for \"Replace\" and add the step. Replace text step Data to replace words: Select the data within which you want to replace text.Text to replace: Enter the text you want to replace.Replace with: Enter what you want to replace the text with, or leave blank to whipe clean. The variable output of this step will be the data with the specified text replaced. Example Often, when extracting data for reporting, the data needs to be relabeled before being placed in the report. This step can be used to relabel the data. How to split names for use in text Split any full name into its parts: title, first name, last name, and additional names. To do this, add the \"Split a name into columns\" step using the Step Finder to search for \"Name\" and add the step. Split a name into columns step DATA: Select data to expand.Column: Enter the column in the data where the names can be found. You can enter either a number (starting from 1) or a capital letter (starting from A).Fields: Select the fields to split the name into. The variable output of this step will be the data split into columns. This can be used for data other than names. Example of using the \"Split a name into columns\" step This step is useful when sending DMs in LinkedIn Sales Navigator. We scrape the whole name to record the data, then split the name and use the first name to personalize the message. How to remove HTML code Strip all the HTML from a set of data. To do this, add the \"Remove HTML code\" step using the Step Finder to search for \"HTML\" and add the step. Remove HTML code step DATA: Select the data to remove HTML from. The variable output of this step will be the data minus any HTML. Example of using the \"Remove HTML code\" step If you are scraping hidden data often it will be tangled in HTML this step can be used to remove the code. Using Javascript to transform data If you wish, you can use all of JavaScript's functions to transform and manipulate your data in axiom.ai. To do this, add the \"Write javascript\" step using the Step Finder to search for \"Javascript\" and add the step. Data can be passed into this step by clicking \"Insert Data\". To learn more about using JavaScript in your automation, click here. If you need help or want to suggest an alternative way of transforming data in axiom.ai, please let support know. Concatenate strings without code Concatenate strings using the \"Custom data\" step - to add dynamic data, use the \"Insert data\" option to insert data tokens containing the information you wish to concatenate. For example, dynamically creating file names.",{"id":1221,"title":1222,"titles":1223,"content":1224,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fget-data","Scrape data",[],"Extract data from any webpage using browser automation, then tune the scraper for speed and accuracy. Use the web scraping steps to pull structured data (tables, lists, product grids, search results) from any webpage. This page walks you through adding a scrape step, selecting the data you want, handling pagination, and tuning the scraper for speed. Add Get data from a URL Open the step finder and add Get data from a URL. It includes a built-in Go to page field so you can enter the URL directly. If your automation already has a Go to page step, add Get data from bot's current page instead. It scrapes whichever page the automation is on when it runs. Select the data Use the selector tool to tell the automation which data to extract. Click Select.Click the first piece of data on the page.Click a second matching element. The selector tool uses both clicks to generate a selector that matches every similar element on the page.For the most reliable selector, pick one element near the top of the list and another near the bottom. This helps capture the full set. Note: For a deeper walkthrough, see the selector tool guide. Set a pager If the results span multiple pages, set a pager so the automation moves through all of them. Click Set pager.Select the pagination element, usually a Next button or a page number link.Selecting the pager by its text (for example, the word Next) is often the most reliable option. Learn more about setting a pager. Cap the number of rows Use the Max results field to cap how many rows the step returns. Set it to 1 when you only need a single row of data. This is much faster than scraping the full page.Leave it blank to scrape every match the selector finds.Set it dynamically from data in a previous step when the limit changes per run. Configure the scraper for speed The web scraping steps default to settings that favour accuracy over speed. Pages often keep loading data for several seconds after they first appear, and scraping too quickly can miss content. Toggle Configure scraper on to expose the options below. After changing any of them, run your automation and check that the output is correct. Wait time between scrolls (ms) How long the automation waits between scrolls. Some pages load more content as you scroll, and the default handles most of them. Increase this value if content is loading too slowly to be captured. Number of attempts when results not found How many times the step retries the scrape when it can't find matching elements. Many dynamic sites update content after the page first appears, so retries improve accuracy. Reducing retries is the single biggest speed improvement you can make. If the earlier steps in your automation already give the page time to load, try setting this to 0. Test the result carefully: too few retries can cause missed data. Minimum wait before scraping (ms) How long the step pauses before each scrape. Lower values run faster. If content is still loading when the scrape starts, it can be missed, so test any reduction. Page number to start scraping on On paginated pages, set the page number to start scraping from. Useful for resuming a partial run or skipping early pages. Specify exact number of pixels to scroll instead of auto-scrolling By default, the step auto-scrolls: it scrolls down to load content, waits, scrapes, then scrolls again. Use this field to override that behaviour and scroll a fixed number of pixels each time instead. You rarely need to change this. Force a re-scrape after each page change Tick this box when the step returns the same data on every loop iteration. It's a rare edge case, but forcing a re-scrape resolves it. Use the output The step renders a preview of up to three rows below it in the Builder, so you can check the shape of what you scraped before running the full automation. Scraped data is returned as a 2D array of rows and columns. Each matching element on the page becomes a row; each piece of data you selected becomes a column. Reference the output with the Insert data button in any later step and pick either a single column or multiple columns to pass through.",{"id":1226,"title":1227,"titles":1228,"content":1229,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fget-started","Make automations with our no-code tool",[],"Learn how to start making your first bot to automate your tasks in the chrome browser. This guide walks you through installation, creating your account, offers starting points for your first automation, shows you how to use our No-code tool, and helps you run your first automation. If you're a novice eager to Learn how, explore our tutorials on all of axiom.ai's features. Experts aiming for mastery should check out our How to guides for design patterns. Install axiom.ai in seconds As a Chrome extension, axiom.ai is very quick to install - visit our chrome store page. It's free to try, no credit card required, and all new accounts get 120 minutes of runtime. Learn how Create an account After the extension is installed, create a free account to start automating. Learn how Start your first automation Scaffold your automations with the Quick builder. Alternatively if you're a beginner, start with a snippet or template. Experts can begin from scratch. To find the best starting point for you, please read our getting started guide. Learn how Using our dashboard Learn the basics of axiom.ai's No-code tool, starting with how to open the builder, create a new automation, combine steps to replicate your tasks, and export your automation to share with colleagues. Learn how Using our No-code tool Learn the basics of axiom.ai's No-code tool, starting with how to open the builder, create a new automation, combine steps to replicate your tasks, and export your axiom.ai to share with colleagues. [Learn how](\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fbuilder Running your automations Once you've built your automation, running it is straightforward; click \"Run\" and choose between the desktop or the cloud. If you want to learn how about scheduling your automations or understanding runtime options, please read on. Learn how How to share your automation You can share automations you make with collegaues as often as you like. Need help get in touch We always love hearing from our customers. Your feedback helps us improve our product. Whether you need support, want a new feature, or are curious about how to automate your use case, please get in touch. We offer varying degrees of support, including a dedicated Slack channel. Learn how",{"id":1231,"title":1232,"titles":1233,"content":1234,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works","How it works",[],"Learn how bots click, scrape, loop, branch on logic, handle logins, and run on a schedule in axiom.ai. Everything a bot can do in axiom.ai, grouped by topic. Jump to browser actions, scrape data, work with data, loop through data, logic, log in, integrate AI, webhooks, custom code, or schedule and run - each section below links to a guide for that capability. Browser actions Control what the bot does on a page - click buttons, type into fields, scroll, navigate between tabs, and upload files. Scrape data Pull structured data out of any webpage - tables, lists, product grids, search results - and hand it off to the next step. Work with data Import data from a CSV or Google Sheet, pass it between steps, transform it, and export the result. Loop through data Repeat a set of steps for every row of data - scrape every page of results, message every contact, or process every row in a sheet. Logic Branch a bot based on data, jump to another step, or stop a run early when a condition is met. Log in Keep a bot signed in to the sites it visits, so runs don't break on login walls. Integrate AI Plug Claude, ChatGPT, or another LLM into a bot to extract fields from unstructured text or generate new content. Webhooks Trigger a bot from another app, or send data out to Zapier, Make, or any webhook URL when a run finishes. Custom code Drop into JavaScript when the no-code steps don't cover what you need - transform data, control flow, or reach parts of a page the visual steps can't. Schedule and run Run a bot manually, on a schedule, or trigger it from Zapier, Make, or an incoming webhook. Need help? Contact support or ask a question in our Reddit community.",{"id":1236,"title":865,"titles":1237,"content":1238,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fintegrate-ai",[],"Pass data to Claude, ChatGPT, or another LLM inside an automation to extract structured fields or generate new content. Use the Integrate AI step to plug a large language model into your automation. Pass in data from an earlier step and either extract structured fields from it or generate new content. The result is returned as data that any later step can use. Add the step Open the step finder and add Integrate AI. Pick a function Use the Function toggle at the top of the step to choose what the model does with your data: Extract data or Generate data. Your choice changes what the prompt area below looks like. Choose a model Pick an LLM provider from the LLM dropdown. Supported providers include Claude and ChatGPT. You'll need an API key for the provider you choose. Write the prompt Reference data from an earlier step with the Insert data button, or pick a built-in template from the template dropdown. What you enter depends on the function you picked. Extract data Give the model a comma-separated list of items to extract. The step returns each item as its own column. Example: You scrape a page of job listings as a single block of text. Pass it into Integrate AI and ask for job title, company, salary, location. The step returns a row with those four columns, ready to write to a Google Sheet. Generate data Write a free-form prompt describing what you want the model to produce. Use the Insert data button to drop in tokens that reference data from previous steps. The tokens are replaced with real values when the automation runs. The step returns the generated text. Example: A previous Scrape data step pulls a list of new customer sign-ups, with columns for name and product. Inside a loop over that data, you pass those columns into Integrate AI with a prompt like: Write a short welcome email to [scrape-data?all&0] who just signed up for [scrape-data?all&1] The tokens [scrape-data?all&0] and [scrape-data?all&1] are inserted via the Insert data button and reference the first and second columns of the scraped data. The step returns the drafted email, which the next step sends via Send an email. Use the output The step's output is available to every step that runs after it. Reference it with the Insert data button. The shape depends on the function you picked. Extract data The output is a 2D array with one column per item in your extraction list. Asking for job title, company, salary, location gives you a four-column dataset where each row is one item extracted from the source text. Each column is referenceable on its own in later steps. Generate data The output is a string containing whatever the model produced from your prompt.",{"id":1240,"title":1241,"titles":1242,"content":1243,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fjavascript","Run custom JavaScript",[],"Use the Write javascript step to run your own code inside an automation, transform data, call APIs, and reach parts of a page the no-code steps can't. Mix no-code and code in the same automation. The Write javascript step lets you drop into a JavaScript editor to manipulate data, call APIs, or reach parts of a page the visual steps can't. For the best experience, run automations that use this step in the axiom.ai desktop app. For more ready-to-use code, see the JavaScript snippets reference. Add the step Open the step finder and add Write javascript. The step provides a basic code editor where you write a standard JavaScript script. const greeting = \"Hello, World!\";\n\nif (greeting === \"Hello, World!\") {\n  return greeting;\n} You can also paste code in from your usual IDE. Define functions Use functions to keep complex scripts readable. const data = [scrape-data];\n\nfunction evaluate(item1, item2) {\n  return item1 === item2;\n}\n\nconst duplicate = evaluate(data[0][0], data[1][0]);\nif (duplicate) {\n  console.log(`${data[0][0]} is a duplicate of ${data[1][0]}`);\n} Use data tokens Reference data from earlier steps in your script using data tokens. Click Insert data and select a token, or type the token in manually. axiom.ai replaces each token with the data from the referenced step at run time, just like in any other step. const data = [scrape-data];\nreturn data[0]; Arrays When a token references multiple rows, axiom.ai replaces it with a 2D array: const data = [scrape-data];\nconsole.log(data);\n\n\u002F\u002F Output: [[\"A\", \"B\", \"C\"], [\"D\", \"E\", \"F\"]] Strings When a token references a single value, axiom.ai replaces it with a string. Wrap the token in quotes so the replacement is syntactically valid JavaScript: const data = '[scrape-data]';\nconsole.log(data);\n\n\u002F\u002F Output: \"A\" Manipulate data Once a token has been replaced with a variable, manipulate the data however you need to. let data = [scrape-data];\ndata[0][1] = \"X\";\nconsole.log(data);\n\n\u002F\u002F Original: [[\"A\", \"B\", \"C\"], [\"D\", \"E\", \"F\"]]\n\u002F\u002F Output:   [[\"A\", \"X\", \"C\"], [\"D\", \"E\", \"F\"]] Return data Return any variable you want to pass to later steps. axiom.ai accepts two output shapes: a 2D array or a string. Any other type is coerced to a string when later steps read it. A returned boolean arrives downstream as the string \"true\" or \"false\", a number arrives as its string form, and so on. Return a 2D array when the data is tabular: let data = [scrape-data];\ndata[0][1] = \"X\";\nreturn data;\n\n\u002F\u002F Returned: [[\"A\", \"X\", \"C\"], [\"D\", \"E\", \"F\"]] Return a string when the data is a single value: let data = [scrape-data];\nreturn data[0][0];\n\n\u002F\u002F Returned: \"A\" Run in the app Toggle Run in app on to run the code inside the axiom.ai desktop app instead of the browser. Running in the app unlocks: The Node.js filesystem API (fs) for reading and writing local files.The Puppeteer API for browser control beyond the no-code steps. Run in app is off by default. With it off, console.log() writes to the browser console, which is useful when debugging. With it on, console.log() is disabled because the code no longer runs in the browser. Use cases A few things developers commonly reach for Write javascript to do. Send data to an API Use JavaScript when you need more control than the Trigger webhook step offers. This snippet sends scraped data to an endpoint and returns the response as the code-data token for later steps: const data = [scrape-data];\n\nasync function postData() {\n  try {\n    let response = await fetch('\u003CAPI_ENDPOINT>', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify(data),\n    });\n\n    if (response.ok) {\n      const result = await response.json();\n      return [[JSON.stringify(result)]];\n    } else {\n      console.error(\"Error:\", response.status, response.statusText);\n    }\n  } catch (error) {\n    console.error(error);\n    return error;\n  }\n}\n\nreturn postData(); Use the Puppeteer API Requires Run in app to be on. See the Puppeteer integration page for setup and examples. Use the Node.js filesystem API Requires Run in app to be on. The fs module lets an automation read and write files on the local machine. axiom.ai's JavaScript step uses promises, while fs uses callbacks. Wrap fs calls in a promise so await works: let result = await new Promise(resolve => {\n  fs.readFile('\u002FUsers\u002Fjoe\u002Ftest.txt', 'utf8', (err, data) => {\n    if (err) {\n      resolve([[err.message]]);\n    } else {\n      resolve([[data]]);\n    }\n  });\n});\nreturn result; For a full reference, see the Node.js fs documentation. Call ChatGPT directly Requires Run in app to be on. When the Extract data with ChatGPT and Generate text with ChatGPT steps don't fit, call ChatGPT from JavaScript instead. const key = '\u003CAPI_KEY>';\nconst prompt = 'Write a short introduction to browser automation.';\n\nlet result = await chatGPT(key, prompt);\nreturn [[result]]; Get an API key from your OpenAI account. Use the output The step returns whatever your script returns, coerced to one of the two shapes axiom.ai supports: 2D array. A table of rows and columns. Reference it with the Insert data button in any later step and pick one or multiple columns.String. A single value. Reference it directly in any later step. Anything else the script returns (booleans, numbers, objects) is converted to its string form before later steps see it. A returned true becomes the string \"true\", a returned 42 becomes \"42\". If the script returns nothing, the step produces no output for later steps to reference. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}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 .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"id":1245,"title":1246,"titles":1247,"content":1248,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogic","Use logic",[],"Branch an automation based on data, loop until a condition is met, or stop a run early using If, Try \u002F Catch, and jump steps. Use logic steps to change what an automation does based on data. Every logic step takes a piece of data and checks it against a condition. The data can come from a scrape step, a Google Sheet, a previous user input, or anywhere else data flows through the automation. Branch on a condition with If condition Use If condition to run a group of sub-steps only when a condition is met. Compare strings or numbers, run the sub-steps when the condition evaluates true (or when Reverse condition flips it false), and carry on with the rest of the automation either way. Open the step finder and add If condition.Set Data to check.Set Condition to check.Toggle Reverse condition if you want the sub-steps to run when the condition is false.Add the sub-steps to run when the condition is met. Example: On Instagram profile pages, scrape the message button. If the text message is found, the sub-steps click the button and send a message. If not, the automation skips those sub-steps and carries on with the rest of the run. Branch either way with If \u002F Else Use If \u002F Else when you need to run one set of sub-steps if a condition is met and a different set if it isn't. Open the step finder and add If \u002F Else.Set Data to check.Set Condition to check.Toggle Reverse condition if needed.Add sub-steps to the If branch.Add sub-steps to the Else branch. Example: Form filling where the form changes based on an earlier selection. The If branch fills the fields shown for option A; the Else branch fills the different fields shown for option B. Stop the run unless a condition is met Use Continue only if a condition is met to check a condition and either keep the run going or end it. Open the step finder and add Continue only if a condition is met.Set Data to check.Set Condition to check.Toggle Fail if condition not met to treat a failed condition as an error instead of a clean stop.Toggle Reverse condition if needed. Example: Check whether a Google Sheet contains data before continuing. If the sheet is empty, stop the run instead of wasting time on later steps that depend on that data. Jump to another step with Conditionally jump to another step Use Conditionally jump to another step to skip forward or loop back in the automation based on a condition. Setting Maximum cycles caps how many times the automation can loop back through the same jump. Open the step finder and add Conditionally jump to another step.Set Data to check.Set Condition to check.Set Jump to step to the step you want to jump to.Set Maximum cycles to cap how many times the automation can loop back.Toggle Reverse condition if needed. Example: Click a Next button and jump back to the click step until a target value appears on the page, capped at some maximum so the automation doesn't loop forever. Catch errors with Try \u002F Catch Use Try \u002F Catch to run a set of sub-steps and, if any of them fail, run a different set instead of ending the run. Unlike the other logic steps, Try \u002F Catch doesn't take a condition. The Catch branch triggers whenever the Try branch throws an error. Open the step finder and add Try \u002F Catch.Add the sub-steps that might fail to the Try branch.Add recovery sub-steps to the Catch branch. Example: A site occasionally triggers a popup that blocks the automation. Put the main sub-steps in the Try branch and, in the Catch branch, add the click needed to dismiss the popup before retrying. Build custom logic with JavaScript When the no-code logic steps don't fit, use the Write javascript step to build your own. Any value your script returns (a 2D array or a string) is available to later steps and can drive an If condition, If \u002F Else, or any other logic step that reads data.",{"id":1250,"title":1251,"titles":1252,"content":1253,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin\u002F2fa","Log in with 2FA",[],"Run an automation on a site that requires two-factor authentication using the desktop app or a private VPS. When two-factor authentication (2FA) is required, the automation has to be supervised at the start of the run so a human can enter the 2FA code. This is known as attended automation, and it requires running on the desktop app or on the axiom.ai VPS. For other login methods, see Google Sheet steps, sessions, VPS, password managers, or secure login. Run an automation with 2FA A 2FA login can only be completed by a person, since for security reasons you can't interact with the cloud browser. Run the automation in the desktop app or on the VPS (available on Ultimate plans), then add a Wait step before the 2FA prompt to give yourself time to enter the code manually. 2FA in the cloud or via webhook You can't currently use 2FA when running automations in the cloud or triggering them via a webhook (for example from Zapier). The only workaround is to disable 2FA on the account. Warning: If you disable 2FA, use a dedicated account with restricted permissions, set up specifically for axiom.ai. Don't disable 2FA on your main account.",{"id":1255,"title":1256,"titles":1257,"content":1258,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin","Log in to sites",[],"Methods for keeping an automation signed in to the sites it visits, from session sharing to dedicated password managers. There are several ways to keep an automation signed in to the web apps it visits. The simplest is to share your browser session. For organisations that need stricter isolation, a secure login setup keeps everything on a controlled PC. Don't store sensitive passwords directly in step fields, even though all step data is encrypted. Methods for automating login Need help? Contact support or ask a question in our Reddit community.",{"id":1260,"title":1261,"titles":1262,"content":1263,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin\u002Fpassword-manager","Log in using a password manager",[],"Store passwords in a dedicated password manager or vault and retrieve them at runtime using the axiom.ai webhook or JavaScript step. For tighter security than a Google Sheet, store passwords in a dedicated password manager or vault that exposes an API. At runtime, retrieve each password using a webhook or the Write javascript step inside the automation, so the password is only ever held in memory for the length of the run. For other login methods, see Google Sheet steps, sessions, VPS, 2FA, or secure login. Recommended password managers Any vault that offers an HTTP API works. One example is HashiCorp Vault.",{"id":1265,"title":1266,"titles":1267,"content":1268,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin\u002Fsecure","Secure login automation",[],"Run login automations on a secured PC using the desktop app so no data ever leaves your network. For organisations that need a hyper-secure environment, run login automations on a dedicated PC inside a controlled network. The setup below keeps every byte of automation data on your own hardware. For other login methods, see Google Sheet steps, sessions, VPS, 2FA, or password managers. Use a PC in a secure environment Run automations from a PC stored in a secure location and connected to a controlled network, for example one in your workplace. Use the desktop app Install the axiom.ai desktop app on the PC and run all automations from it. None of the data you process leaves the machine. axiom.ai only sends account information and run metadata such as start time and duration. Your data stays behind your network. Automate the login When you run an automation in the desktop app, it shares the browser cookie automatically and you stay signed in. All cookies are double-encrypted. Why this method works No private data leaves the network.The PC is physically secured.Session data is encrypted at rest and in transit.The setup meets common data privacy and security requirements.",{"id":1270,"title":1271,"titles":1272,"content":1273,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin\u002Fsessions","Log in by sharing your session",[],"Store browser cookies in axiom.ai so an automation stays signed in to a web app on desktop and cloud runs. The simplest way to automate login is to share your browser session. axiom.ai stores your cookie, and when the automation runs, you're already signed in. For other login methods, see Google Sheet steps, VPS, 2FA, password managers, or secure login. Store cookies for desktop runs The desktop runner shares your browser cookie by default. Run the automation from a window where you're already signed in to the web app, and the session is reused automatically. Store cookies for cloud runs For cloud runs, you have to opt in to cookie sharing on a per-automation basis. In the automation, click the kebab menu in the top right corner and select Settings.Click Store cookies under run options.Toggle Local cookies are used to Stored cookies are used.Click Populate from Axiom to fetch the cookies. Sessions expire Sessions can last up to 100 days but eventually expire. To renew, resync the cookies using the button in the Store cookies settings panel. Turn on error notifications When using cookies for cloud runs, turn on error notifications so you find out as soon as a session expires. In the automation, click the kebab menu in the top right corner and select Settings.Click Set up notifications under run options.Toggle Notify when run fails on.Choose to be notified by email or webhook.",{"id":1275,"title":1276,"titles":1277,"content":1278,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin\u002Fsteps","Log in using a Google Sheet",[],"Store usernames and passwords in a Google Sheet and read them into an automation at runtime to sign in to web apps. There are several ways to automate actions behind a login. The simplest is sharing your session. This page covers an alternative: storing login details in a Google Sheet and reading them in at runtime. We don't recommend storing passwords directly in step fields. All step data is encrypted at rest and in transit, but a Google Sheet is a more isolated store. For other login methods, see sessions, VPS, 2FA, password managers, or secure login. Why a Google Sheet Not everyone is comfortable storing passwords in Google Sheets, but Google operates one of the most heavily monitored security infrastructures on the internet, used by enterprises and governments worldwide. For most teams it is a reasonable trade-off between convenience and isolation. Set up the Google Sheet Create a Google Sheet and add columns for your login details. Don't share the sheet with anyone who doesn't need access. Build the login automation The pattern is five steps: Read data from a Google SheetGo to pageEnter text (username)Enter text (password)Click element (submit) To build it: Add a Read data from a Google Sheet step and select the sheet that contains your login details.Add a Go to page step and set its URL to the sign-in page.Add an Enter text step. Select the username field, click Insert data, choose the Google Sheet variable, and pick the column with the username.Add another Enter text step. Select the password field, click Insert data, choose the Google Sheet variable, and pick the column with the password.Add a Click element step and select the submit button using Select by text. Loop through multiple logins To sign in to several accounts in a single run, wrap the login steps in a Loop through data step. The pattern becomes: Read data from a Google SheetLoop through dataGo to pageEnter text (username)Enter text (password)Click element (submit)Loop through data (the actions to perform once signed in)Clear cookies To build it: Tick the boxes next to the Go to page, both Enter text steps, and the Click element step. The Move toolbar appears at the top.In the toolbar, click Loop. The selected steps are wrapped in a Loop through data step.In the new Loop through data step, set Data to loop through to the Google Sheet variable.Inside the loop, after the Click element step, add a nested Loop through data step. Add the actions to perform once signed in to each account.At the end of the outer loop, add a Clear cookies step. This signs the automation out before the next iteration. Control how many accounts to sign in to In the Read data from a Google Sheet step, set First cell and Last cell to limit the rows read. For example, A1 to B3 reads three rows from columns A and B, so the automation signs in to three accounts.",{"id":1280,"title":1281,"titles":1282,"content":1283,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Flogin\u002Fvps","Log in using the VPS",[],"Store logins on your private axiom.ai VPS and run automations remotely with full scheduling support. The Ultimate subscription tier includes a private VPS, which is an alternative way to store logins for automation runs. The VPS is a private browser with the axiom.ai Chrome extension installed. It behaves like axiom.ai on the desktop and supports every feature, including scheduling. For other login methods, see Google Sheet steps, sessions, 2FA, password managers, or secure login. Use the VPS to automate logins In the VPS browser, open the web apps you want to automate and sign in. When you run an automation on the VPS, it shares the session and signs in automatically. Tip: For security, create dedicated accounts with only the permissions the automation needs.",{"id":1285,"title":1286,"titles":1287,"content":1288,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Floop","Loop through data",[],"Repeat a set of steps for every row of data using Loop through data, or build conditional loops with Jump and Conditionally jump steps. Looping is one of the most useful patterns in axiom.ai. A loop repeats a group of steps, usually once per row of data. For example, loop through a list of URLs to scrape data from each page, or loop through rows of a Google Sheet to fill in a web form. There are three steps you can use to build a loop. The primary one is Loop through data. The Jump to another step and Conditionally jump to another step steps can also create loops, and you can use logic inside any of them. Loop using the Loop through data step The Loop through data step repeats its sub-steps once for each row of data passed into it. To use it, add the step and select the data you want to loop through. Add a Loop through data step There are two ways to create a loop: use the step finder, or use the Move toolbar to wrap existing steps. To add a loop with the step finder: Open the step finder, search for loop, and add Loop through data.Add the steps you want to repeat as sub-steps of the loop. To turn existing steps into a loop with the Move toolbar: Tick the checkboxes next to the steps you want to loop.In the Move toolbar, click Loop.Select Loop through data to wrap the highlighted steps in a loop. Select data to loop through A loop won't iterate until you give it data. There are two ways to set the loop data. From the loop step. Set Data to loop through by clicking Insert data and choosing the data variable.From a sub-step. Edit a sub-step inside the loop and click Insert data. The variable you pick is automatically set as the loop's Data to loop through. Note: A loop returns an error if its data source is empty. Insert sub-steps Add the steps you want to repeat inside the loop using Add sub-step. Steps outside the loop are not repeated. Nest loops You can nest loops up to five levels deep. Three levels is usually enough, even for complex automations. Output data from a loop Every Loop through data step outputs a token that other steps can read. The token contains the data output by every sub-step in every iteration, assembled into a 2D array (a table). Group data with a loop You can use a loop to group the output of several steps into a single token, even if the loop only iterates once. Wrap the steps in a loop to combine their outputs. End a loop early Use the End loop step to stop a loop before it finishes its iterations. Combined with a control flow step, this lets you exit a loop when a condition is met (or not met). Loop design patterns These are common loop patterns. Each one starts by reading data from a Google Sheet and ends by deleting the processed row, so a re-run picks up where the last run left off. Loop through links and scrape each one Read data from a Google SheetLoop through dataGo to pageGet data from current pageWrite data to a Google SheetDelete row from Google Sheet Enter data into a web form Read data from a Google SheetLoop through dataGo to pageEnter textPress keysClick elementDelete row from Google Sheet AI web scraper Read data from a Google SheetLoop through dataGo to pageGet data from current pageExtract data with ChatGPTWrite data to a Google SheetDelete row from Google Sheet For full walkthroughs of each pattern, see: Loop through links and scrape dataEnter text into a search fieldScrape HTML and extract data with AI Loop using the Jump to another step The Jump to another step step creates a simple loop with two parameters: the step to jump to, and the number of cycles to run. Use Jump to another step The most common pattern is to add the jump step at the end of a series of steps you want to repeat. Open the step finder and add Jump to another step.Set Jump to step to the step number you want to return to.Set Maximum cycles to the number of times the loop should run. Note: If you reorder the steps in your automation, check the Jump to step value still points at the right step. Loop using the Conditionally jump to another step The Conditionally jump to another step step works like Jump to another step but only jumps when a condition is met. Use it to behave differently based on data, for example pairing it with a scrape step to keep clicking Next until a target value appears on the page. Use Conditionally jump to another step Set Data to check to the data you want to evaluate (for example scraped data or a Google Sheet value).Set Condition to check to the value to compare against. Strings and numbers are accepted; advanced users can use JavaScript.Set the matching rules: match any word, all words, or an exact match.Set Jump to step to the step number you want to return to.Set Maximum cycles to cap how many times the loop can run.Toggle Reverse condition to jump when the condition is false instead of true.",{"id":1290,"title":1291,"titles":1292,"content":1293,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Fadvanced-running-methods","Advanced running methods",[],"Run multiple automations concurrently, trigger from Zapier, or run Axiom across multiple computers. Learn advanced methods for running your automation, such as running across multiple computers or using an API. If you are a beginner getting started and unsure how to run an automation, click here. Run multiple bots at once locally To run multiple bots simultaneously, you can set up multiple installs of the desktop application. The standard way to do this is to use multiple computers or virtual machines, install axiom.ai on each of them, and run the desired bots from there. If you are using local scheduling to run multiple bots, you will additionally need to set up multiple accounts. Only if the bots are being run manually will you be able to run multiple bots at the same time with a single account. How to run multiple instances of the same automation Each individual bot can only have one instance of itself running. This means you can run multiple different bots at the same time, but you cannot run multiple instances of the same bot at the same time. If you need this functionality, then you should duplicate the bot you wish to run concurrently. You can do this using the \"Save as duplicate\" feature, which you can find in the menu at the top of the builder. Create as many duplicates as you need concurrency. Each duplicate will be a separate item and so will be able to run concurrently along with the other duplicates. Run multiple bots at once on cloud (concurrency) Subscribers at the Pro Max tier and higher are allowed to run multiple bots at once on our cloud infrastructure. This applies to manual runs, Zapier and Make connections, API calls and cloud scheduling runs. Use Incognito mode, or use axiom.ai on local file URLs By default, axiom.ai does not have permission to run in Incognito Mode, or access local HTML files. To let axiom.ai run Incognito, or on local files: 1. Type in `chrome:\u002F\u002Fextensions` in your browser. \n2. Click on `Details`.\n    \u003Cimg src=\"\u002Fimg\u002Fchrome-extensions.png\"\u002F>\n3. Toggle to `Allow in Incognito`, or `Allow access to file URLs`:\n    \u003Cimg src=\"\u002Fimg\u002Fchrome-permissions.png\"\u002F> Run a headless automation To run an automation in headless mode, in the builder, click the kebab menu at the top right, then click \"Settings\". Then, under \"Run options\", click \"Run Headless\" and toggle the setting to 'on'. Read more about headless mode here. Run an automation from Zapier Trigger an automation from Zapier, please see Working with Zapier and Webhooks Run an automation via API To learn how to run an automation via API, please see Webhook &  API Documentation Run an automation using Make To learn how to run an automation via Make, please see Working with Make and webhooks",{"id":1295,"title":1296,"titles":1297,"content":1298,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Fautomation","Schedule an automation",[],"Run automations on a schedule in the cloud or on your local computer. Schedule your automation to run when you want it to. You can schedule an automation to run in the cloud or locally on your desktop. You have the flexibility to set the start date, time, and frequency. However, scheduling is only available on paid subscriptions from the Pro tier upwards. By default scheduled automations run in the cloud. How to schedule an automation To access the scheduler, edit an automation. Once in the builder: First, click the kebab menu icon (three dots) top right hand corner.Next, Click on the gear icon ‘Settings’.Finally in the settings menu click \"Schedule\". Turn the scheduler on Toggle the scheduler from \"Off\" to \"On\". To disable the scheduler, simply toggle it back to \"Off.\" Set the start date Click the \"Set the date\" button to open a popup window containing a calendar. If necessary, select a month by clicking the right arrow to change months. The default is set to today. Then select a day. Once done, click \"Set date\". Dates in the past cannot be set. Set the start time Next click the \"Set the time\" button to open a popup window containing a clock. If necessary, select AM and PM times to set a start time. The default is set to now. Once done, click \"Set time\". Times in the past cannot be set. Set schedule frequency Choose the frequency from the dropdown list, ‘daily’ frequency will be the default option. After configuring the frequency, the scheduler will be active. Depending on your subscription frequency options will vary. Schedule automations locally To run a schedule locally rather than in the cloud, toggle the ‘Run on this computer’ option. Ignore this setting to run in the cloud.",{"id":1300,"title":1301,"titles":1302,"content":1303,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run","Run and schedule bots",[],"Run a bot manually, on a schedule, or trigger it from Zapier, Make, or a webhook. Learn how to schedule and manage scheduled bots, as well as log in with scheduled bots on the cloud and on the desktop, through these tutorials. Run Schedule",{"id":1305,"title":1306,"titles":1307,"content":1308,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Flogin","Login with a scheduled automation",[],"How to handle login when running a scheduled automation in the cloud. When running your bot in the Cloud, automating a task behind a login, you will need to either pass the cookie from your browser or add steps to log into the application you are automating. If you do not, the automation will most likely fail when scheduled to run in the Cloud because it cannot get past the login. Don't worry; it's simple enough to do. Setting up your scheduler Set up your scheduler as normal when done choose one of the methods below. How to use Cookies to login By storing cookies, you can share a logged-in session with the cloud runner. This means your automation will be logged in when it runs, without adding any login steps to the automation. To share your cookies, follow these steps: In the scheduled automation, click the kebab menu in the top right corner or the setting cog in the vertical toolbar on the left and select \"Settings\".Next, select \"Store cookies\" and toggle \"Local cookies are used\" to \"Stored cookies are used\".Enter the URLs of the sites for which you wish to add cookies for.If the cookies expire, click \"Resync cookies\". Now you can run your automations in the cloud while being logged in. Please note, all stored cookies are encrypted. However, cookies do expire and will need renewing periodically. How to use steps to login 1 Read data from a Google Sheet2 Go to page3 Enter text4 Enter text5 Click element To log in using steps, you will need to store the username and password. We do not recommend doing this directly within the automation, but the data in the fields is encrypted. Whenever possible, we recommend creating accounts with limited permission sets and storing your password in a Google Sheet. Please note that Google Sheets, and the security Google provides, is among the most secure systems available. The only argument against this method is that Google could potentially read the password. However, in all honesty, how could they read millions of Google Sheets? Anyway, the choice is yours. To use this method, follow these steps: Create a Google Sheet to store the username and password, and do not share the sheet with others.Use a  \"Read data from a Google Sheet\" step to fetch the login information.Add a  \"Go to page\" step, two \"Enter text\" steps, and one  \"Click element\" step.Insert the login URL, select the username and password fields, and then the submit button.Finally, insert the data from the Google Sheet into the \"Enter text\" fields. Please do test the login steps before scheduling the automation.",{"id":1310,"title":1311,"titles":1312,"content":1313,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Flong-bot-runs","Structure automations for long runs",[],"Best practices for building automations that run reliably over long periods. For large bots, processing large data sets, or scraping many pages, we recommend following these guidelines to produce robust automations. Use Google Sheets for large runs We recommend using Google Sheets as your primary data source in nearly all cases. This applies even if you have files like CSVs (they can be imported into Sheets), and even if you are sending data from Zapier or Make. Please avoid reading and writing to a single sheet for your whole automation - this makes your automations harder to structure. Instead, we recommend using separate \"INPUT\" and \"OUTPUT\" sheets, with the following  (example) structure. Structure a bot for large runs The advantage of this design pattern is that both \"Write data to a Google Sheet\" and \"Delete rows from Google Sheet\" operations are performed inside the loop. This means that for every iteration of the loop, new data is saved, and the processed row is deleted. If the bot stops, it can be restarted and will pick up from where it left off. 1.0 Read data from a Google SheetSpreadsheet: Search for the Google Sheet you created. Once found, click to select.Sheet name: Choose the sheet tab that contains your input data.2.0 Loop through data2.1 Go to pageEnter URL: Click Insert Data, select your Google Sheet, and choose the column with the links.2.2 Insert steps hereInsert scraping, downloading, or extraction steps depending on your task.2.3 Write data to a Google SheetSpreadsheet: Search for and select your output Google Sheet.Sheet name: Choose the target tab.DATA: Select the variable holding your extracted or generated data (e.g. chatgpt-data).Clear data before writing | Add to existing data: Set to \"Add to existing data\".2.4 Delete row from Google SheetSpreadsheet: Select the same Google Sheet you used for input.Sheet name: Choose the same tab used in Step 1.0.First row: Set to 1.Last row: Set to 1. Set a maximum runtime axiom.ai contains a setting for maximum runtime. This is useful if you have a large bot and don't want it to accidentally use up all of the runtime for your plan. You can alter this setting from the configuration page for your individual axiom. For the cloud, the maximum runtime cannot exceed the single run limit for your plan. Send data from Zapier, Make & other platforms When sending data from Zapier or Make, it's possible to either send data directly, or to write data to Google Sheets first. Sending data directly works fine for small quantities of data. However, if your data-set contains many columns, or more than 1 row, we recommend using Google Sheets to transfer data: First, structure your bot to read from a Google Sheet.Secondly, write data to Google Sheets from Zapier \u002F Make.Finally, trigger bots from Zapier \u002F Make. Sending data is not required, as your bot will use the Google Sheet instead.",{"id":1315,"title":1316,"titles":1317,"content":1318,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Fmanage","Manage scheduled automations",[],"Edit, pause, stop, or change the timezone of a scheduled automation from your dashboard. Learn how to view, stop and edit scheduled runs and change your scheduler to a local time zone. If you want to learn how to schedule a run or login when scheduling a run click the links. View upcoming scheduled runs To view a list of all scheduled automations, navigate back to the dashboard if you are in the builder. Then, using the left-hand side menu, click on \"Scheduled Axioms\". You will see a timeline of their upcoming schedules, as well as the date of their last run. Edit scheduled automations Additionally, you can edit the automations by clicking on the ‘Edit’ link which will take you to the axiom.ai No-code tool. Disable local schedules on this PC If you have installed axiom.ai on multiple PC's and you want to disable a run, tick the box. Watch a scheduled run You can watch any automation running on a scheduler by doing one of the following: From the dashboard, on the \"My Axioms\" listing page, search for the automation and click \"Watch\".Inside the builder, to the left of the save button, click \"Watch\". This can be helpful when trying to understand why a bot run failed. Stop a scheduled run The best method for stopping a scheduled run is to click \"Scheduled Axioms\" on the dashboard, then click \"Edit\" for the automation you want to stop. Once in the builder, click \"Stop\". Changing Timezone By default, Axiom Cloud will run scheduled automations using the UTC timezone. You can change your scheduler to run from your local timezone. To edit the timezone: From the builder, click the kebab menu in the top left corner.Click the 'Settings' option from the dropdown.Finally, click \"Configure Timezone\" and toggle to the local timezone.",{"id":1320,"title":1321,"titles":1322,"content":1323,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Fother","Schedule on a specific computer",[],"Run a scheduled automation on a specific PC when using Axiom across multiple computer. You are not limited to scheduling using just axiom.ai's scheduler; you can use external tools such as Zapier or Make to trigger\u002Fschedule runs. How to schedule from Zapier Trigger axiom.ai automations via Zapier. Please see our guide here. How to schedule from Make Trigger axiom.ai automations via Make. Please see our guide here. How to schedule from a Webhook Trigger axiom.ai automations via a webhook. Please see our guide here.",{"id":1325,"title":1326,"titles":1327,"content":1328,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Frun","Run your automation",[],"How to run or trigger automations from the desktop runner or in the cloud. There are four ways to run an automation: from the dashboard, the builder, scheduled, and triggered via a webhook from apps such as Zapier or Make. When you are ready to run your automation, you will have the choice of using either a desktop or cloud platform. Run an automation from the dashboard Click the \"Run\" button next to the axiom.ai's row on the dashboard. Run an automation from the builder Click the \"Run\" button in the builder when creating or editing an automation. After clicking the \"Run\" button, choose if you would like to \"Run in cloud\" or \"Run w\u002F desktop app\". If an automation is running, the button will turn red and show a \"Stop\" button with an icon. Clicking it stops the bot. Once your automation starts running, you will see a window open up and you can watch the bot complete your steps. When running via the cloud, you can see on the left sidebar which step your bot is currently on and how long each of the steps has taken so far to complete. If the bot hits an error, it will show you a message to help you debug what's wrong. Concurrency, running multiple automations at once To learn about running multiple bots at once click concurrency. Run a bot via scheduling To schedule bot runs, please see Scheduling Automations. Run your bot from Zapier, Make, or via a webhook To trigger runs from webhooks, take a look at these links for Zapier and Make. View currently running bots Currently running bots can be viewed by clicking the \"play\" icon in the sidebar. Any currently running bots will be shown, along with the last 3 completed runs. You can watch bot runs in progress (if they are running in cloud) or stop a run from this overlay.",{"id":1330,"title":1331,"titles":1332,"content":1333,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Fspeed-up-run","Speed up your automations",[],"Techniques to make your automations run faster and get results more quickly. No two websites load in the same amount of time, and not all web pages load all their content before the site is rendered. Some websites load content on scroll. To manage these complexities, we have developed algorithms that calculate wait times to allow content to load before the bots execute your actions. Through extensive testing, it became obvious there is a correlation between time and accuracy: the longer you wait, the more accurate the bots are. By default, we value accuracy over speed. However, for users wishing to increase the speed of bot runs, there are settings you can experiment with. We strongly recommend that each time you change a setting, you test your bot to ensure accuracy has not been affected. Disable page change monitoring By default Axiom waits for a page to finish making changes. This is to make sure that page contents which load in dynamically have fully loaded. Sometimes, this can slow down an automation. This is most common when there are animated elements, and axiom.ai must take a while to determine whether the animation is related to page loads or not. In these cases, you can turn off the page monitoring to skip it. Note you may need to add back manual waits in these cases, in case axiom.ai starts jumping ahead. Open the automation.Navigate to the settings in the top right menu.Click \"Disable change monitoring\".Toggle the option to on. Reduce the wait time on Get data steps If your bot seems to be taking a long time over scraping, there are several things you can do to try and speed it up. Please note that the axiom.ai scraper is configured by default to maximise accuracy across a wide range of sites, so by changing these options you might introduce some inaccuracies - the scraper can be configured to go too fast for the website! To configure these options, open the \"Configure scraper\" optional parameter on the scrape step. There are two options to choose from which can help speed up your bot: Wait time between scrolls (ms): This controls the default amount of time the scraper wait between each scroll. Lower this to increase speed.Number of attempts when results not found: When no results are found, the scraper will try again to make doubly sure that the scrape has finished. You can set the number of times this happens; 0 will never re-check. When scraping, set a maximum number of results If you know you need to scrape 1 result per page (or 5, or 10 etc.) set \"Max results\" to the number of results you need to scrape. This means axiom.ai will stop once it has scraped 1 result, then move to the next iteration of the loop. Use the Keyboard Using Keyboard shortcuts and \"Tabbing\" between inputs can be faster than selecting \"Enter text\" to enter data. Please see our tips on using the keyboard. Jump ahead with conditional logic This may only apply to some scenarios. Let's look at the example of entering data into multi-step form with 5 steps. If at step 2, it is evident steps 3 and 4 are not required, you can jump ahead to step 5 using conditional logic.",{"id":1335,"title":1336,"titles":1337,"content":1338,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fschedule-and-run\u002Fstop-bot-runs","Stop a running automation",[],"Best practices for building automations that run reliably over long periods. When scheduling bots, or running bots via Webhook, Zapier or Integromat, you may find multiple bots start simultaneously and you need to stop these. Stop bots using the extension We automatically track remote-running bots and allow you to stop them within the extension. Any running bot will be indicated from the axiom.ai dashboard, and you can click the \"Stop\" button to stop it at any time. Stop bots via API When you trigger axiom.ai via the API, you'll be sent a URL to visit, which will contain the following pattern: c-00$POD-v4-proxy.axiom.ai&port=443&password=$PASSWORD Note down the $POD and the $PASSWORD in the URL you are sent. To stop a bot at the URL you've been given, visit the following URL: lar.axiom.ai\u002Fapi\u002Fv3\u002Fstop?pid=$POD&pw=$PASSWORD You should see: {\"stopped\":\"$POD\"} If you are unable to use the methods above to stop your bots, please email support@axiom.ai and we'll handle it. html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}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 .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 .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}",{"id":1340,"title":1341,"titles":1342,"content":1343,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fvps","VPS Guide",[],"Learn how to use your own VPS server to schedule and run bots remotely. Your VPS is accessible through a web browser via a dedicated URL. The link to access your VPS is accessible via \"My VPS\" in the axiom.ai extension. Please logout and login again to see this link after we setup your VPS for the first time, or you will not see the link. Your VPS is like running axiom.ai Desktop on a dedicated machine Your VPS is a private browser that can store sessions and run bots on a schedule (see\nbelow). From this link you have keyboard and mouse control over your VPS, unlike in regular axiom.ai\ncloud. When doing this axiom.ai on the VPS will behave just like a desktop application with the bot\nrunning locally on the VPS. The VPS contains its own version of axio.aim that opens on every page. This is necessary for\nChrome to keep axiom.ai active and to run schedules. VPS reboots Your VPS will reboot once daily (by default this is at 3 am UTC). This occurs to prevent problems with Chrome after it is left running for too long. VPS connection issues If your VPS link fails to connect this (usually) means another user is logged in, or you’ve left a\ntab open with the VPS connection active. This can happen when a company has multiple people using the same axiom.ai account. Multiple people cannot use the VPS simultaneously. To logout of a VPS session simply close the browser tab in which the VPS is open. For users with many tabs open finding out where the VPS is being used can be a problem. Please email support if you are unable to connect to your VPS and we can close any active sessions for you to restore access. File downloads The VPS is not subject to same file download restrictions as running on the cloud. Files can be saved to and uploaded from the VPS file system during bot runs. If you'd like to access files on the VPS outside of bot runs, they are located in \u002Fhome\u002Fseluser\u002FDownloads. You'll need to use a service with a web interface, like Google Drive, Dropbox or similar, to transfer files into and out of the VPS. Scheduling on the VPS Please ensure that: Your schedule is set to ‘Run on this computer (this labelling is currently confusing - it arises\nbecause the run will be ‘local’ to the VPS).You are logged into any websites on the VPS that require session access. If you have added login steps to your bot already these can be removed. If you have any issues, please contact support.",{"id":1345,"title":1346,"titles":1347,"content":1348,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fwebhooks\u002Fexport","Import data with a webhook",[],"Externally trigger an axiom.ai automation and pass data into it with a webhook from Zapier, Make, or any other app. Use a webhook to trigger an axiom.ai automation from another app and pass data into it at the same time. For background on the API and how to find your API key, see the API reference. For a worked example using Zapier forms, see the Zapier forms guide. Build and test the automation Build the automation with dummy data first, then connect the webhook once it works. To start a new automation, click New automation then Add first step on the Dashboard. Add a Receive data from another app step This step receives data from the webhook and returns a token ([webhook-data-1]) that later steps can use. Open the step finder, search for receive, and add the step.Toggle Test data on and add a 2D array of test data, for example [[\"Row 1 colA\", \"Row 1 colB\", \"Row 1 colC\"], [\"Row 2 colA\", \"Row 2 colB\", \"Row 2 colC\"]]. Add a Go to page step This step loads the web page you want to interact with. Open the step finder, search for go, and add the step.Click Insert data and select [webhook-data-1] to pass a URL in from the Receive data from another app step. Build out the rest of the automation Add any further steps you need. Click Insert data and select the [webhook-data-1] token to pass values from the webhook into later steps. Test with dummy data Run the automation to confirm it works end to end with the test data. Failed runs do not count against your usage. Set up the POST request To trigger the automation from outside axiom.ai, send a POST request to https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger with your API key, the automation's name, and the data as a 2D array. {\n    \"key\": \"1jf8SSbf73gfa\",\n    \"name\": \"My Axiom\",\n    \"data\": [[\"A1\", \"B1\", \"C1\"], [\"A2\", \"B2\", \"C2\"]]\n} Go live When the automation is working with dummy data, switch the Receive data from another app step to live data. For details on rate limits and authentication, see the API reference. html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":1350,"title":1346,"titles":1351,"content":1348,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fwebhooks\u002Fimport",[],{"id":1353,"title":1354,"titles":1355,"content":1356,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fhow-it-works\u002Fwebhooks","Send and receive webhooks",[],"Trigger a bot from another app, or send data out to Zapier, Make, or any webhook URL when a run finishes. How to import and export data with webhooks. Working with Webhooks",{"id":1358,"title":1359,"titles":1360,"content":1361,"level":56},"\u002Fdocs\u002Fno-code-tool","No-Code Tool",[],"Build browser automations visually with the axiom.ai Chrome extension — no coding required. The No-Code Tool is a visual Builder inside the axiom.ai Chrome extension. Drag and drop steps to record clicks, scrape data, fill forms, and connect to Google Sheets — without writing code. Once your automation works, schedule it to run on a recurring basis or trigger it from another app.",{"id":1363,"title":1364,"titles":1365,"content":1366,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002F2captcha","2Captcha",[],"Use the Solve Captcha step to outsource reCAPTCHA challenges to 2Captcha, with optional support for other captcha types via JavaScript. axiom.ai integrates with 2Captcha, a captcha-solving service. Use the Solve Captcha step in your automation, and 2Captcha handles the challenge in the background. Sign up for 2Captcha Register for a 2Captcha account at 2captcha.com. 2Captcha only charges for successfully solved captchas, and each captcha typically takes 30–60 seconds to solve since the work is done by humans. Note: The service can fail on custom captcha implementations or when 2Captcha returns an incorrect answer. Plan your automation so it can recover from a failed solve. Use the Solve Captcha step Add the Solve Captcha step in your automation. It supports these captcha types: reCAPTCHA v2reCAPTCHA v3 If a captcha doesn't appear when the step runs, the step takes no action and the automation continues. This makes it safe to use for captchas that only appear sometimes. Open the step finder, search for solve, and add the Solve Captcha step.Enter your 2Captcha API key, available on the 2Captcha settings page. Solve other captcha types with JavaScript For captcha types not supported by the Solve Captcha step (for example, image-to-text captchas), call the 2Captcha API directly from a Write javascript step. The example below uses the Puppeteer API to screenshot the captcha image, sends the screenshot to 2Captcha as base64, then polls until the solution is ready. The script returns the solved text, which you can pass to an Enter text step to fill the field. const apiKey = 'XXX'; \u002F\u002F Your 2Captcha API key\nconst ele = await page.$('#captcha_image'); \u002F\u002F Selector for the captcha image\n\nconst base64 = await ele.screenshot({ encoding: 'base64' });\nconst delay = ms => new Promise(res => setTimeout(res, ms));\n\nlet options = {\n  clientKey: apiKey,\n  task: {\n    type: 'ImageToTextTask',\n    body: base64,\n    case: true,\n  },\n  languagePool: 'en',\n};\n\nlet postData = { method: 'POST', body: JSON.stringify(options) };\nlet response = await fetch('https:\u002F\u002Fapi.2captcha.com\u002FcreateTask', postData);\nlet json = await response.json();\nconst taskId = json.taskId;\n\n\u002F\u002F Poll for the result every 20 seconds.\ndo {\n  await delay(20000);\n  postData = { method: 'POST', body: JSON.stringify({ clientKey: apiKey, taskId }) };\n  response = await fetch('https:\u002F\u002Fapi.2captcha.com\u002FgetTaskResult', postData);\n  json = await response.json();\n} while (json.status && json.status === 'processing');\n\nreturn [[json.solution.text]]; Sign up for 2Captcha to get started. html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sU953, html code.shiki .sU953{--shiki-default:#6E7781;--shiki-dark:#8B949E}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}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);}",{"id":1368,"title":1369,"titles":1370,"content":1371,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fchatgpt","ChatGPT",[],"Connect ChatGPT (OpenAI) to your axiom.ai automations through the Integrate AI step. Generate text or extract structured data using your own OpenAI API key. ChatGPT is one of the LLM providers supported by the Integrate AI step. Drop the step into any automation, choose OpenAI as the provider, and either generate text or extract structured fields from data flowing through earlier steps. You supply your own OpenAI API key, so billing happens directly on your OpenAI account. For step usage and how to write extract or generate prompts, see Integrate AI. The rest of this page covers OpenAI-specific setup and gotchas. Sign up and get an API key Create an account at platform.openai.com if you don't have one.Add a payment method in Billing. OpenAI's API requires a positive balance separate from a ChatGPT Plus subscription.Open the API keys page and click Create new secret key. Copy the key once; OpenAI doesn't show it again.Paste the key into the API key field of the Integrate AI step in your automation. Choose a model The Integrate AI step lets you pick the OpenAI model in the Model field. Use a smaller, cheaper model for high-volume extraction; use a larger one for nuanced generation. See OpenAI's pricing page for current per-token costs. What to use it for Common patterns when OpenAI is the provider: Extract structured data from messy scraped HTML. Pair with Get data from a URL or Receive data from another app, then ask Integrate AI for the fields you want as a comma-separated list.Generate replies, emails, or DMs using data from earlier steps. Insert tokens into the prompt with Insert data, then pass the output to Send an email or a posting step.Pull metrics out of reporting sites that have no API by scraping the page text and asking ChatGPT to isolate specific values. For a worked example, try the ChatGPT web scraper template and the related blog post. Limit API spending OpenAI doesn't support per-user or per-API-key spending limits. To keep usage isolated and predictable: Create a dedicated OpenAI account just for axiom.ai so your automation's usage is separated from any other apps using the API.Set a monthly budget in OpenAI's billing settings so the API stops responding when the cap is hit.Rotate keys periodically and revoke anything you're no longer using.Follow OpenAI's security guidance for the latest best practices. Other LLM providers The Integrate AI step also supports: Claude (Anthropic)Gemini (Google)Sonar (Perplexity)DeepSeek The step behaves the same way; only the model list and API key change.",{"id":1373,"title":1374,"titles":1375,"content":1376,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fclaude","Claude",[],"Connect Claude (Anthropic) to your axiom.ai automations through the Integrate AI step. Generate text or extract structured data using your own Anthropic API key. Claude is one of the LLM providers supported by the Integrate AI step. Drop the step into any automation, choose Claude as the provider, and either generate text or extract structured fields from data flowing through earlier steps. You supply your own Anthropic API key, so billing happens directly on your Anthropic account. For step usage and how to write extract or generate prompts, see Integrate AI. The rest of this page covers Claude-specific setup and gotchas. Sign up and get an API key Create an account at console.anthropic.com.Add a payment method in Plans & billing. API access is separate from a claude.ai chat subscription.Open API Keys and click Create Key. Copy the key once; Anthropic doesn't show it again.Paste the key into the API key field of the Integrate AI step in your automation. Choose a model Pick a Claude model in the Model field of Integrate AI. Anthropic publishes the current model lineup (Opus, Sonnet, Haiku) on their models page. Use Haiku for fast, cheap, high-volume extraction; use Sonnet or Opus for complex reasoning or longer generation. See Anthropic's pricing for current per-token costs. What Claude is good at Claude tends to outperform other models when the automation needs to: Follow long, precise instructions without drifting. Strict extraction schemas hold up well.Process long inputs like full HTML pages or long PDFs (Claude has a large context window).Refuse to invent data the source doesn't contain, which makes it a safer pick for extraction tasks where hallucinated fields would corrupt downstream data. Common patterns: Extract structured fields from scraped HTML or PDF text.Summarise long pages or reports into a fixed format.Draft contextual replies in customer-service or outreach workflows. Limit API spending Anthropic exposes spending controls directly in the console: Set a monthly limit in Plans & billing. The API stops responding when the cap is hit.Create a dedicated workspace for axiom.ai usage to keep its spend isolated from other apps.Rotate keys periodically and revoke any you're no longer using. Other LLM providers The Integrate AI step also supports: ChatGPT (OpenAI)Gemini (Google)Sonar (Perplexity)DeepSeek The step behaves the same way; only the model list and API key change.",{"id":1378,"title":1379,"titles":1380,"content":1381,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fdeepseek","DeepSeek",[],"Connect DeepSeek to your axiom.ai automations through the Integrate AI step. Generate text or extract structured data using your own DeepSeek API key. DeepSeek is one of the LLM providers supported by the Integrate AI step. Drop the step into any automation, choose DeepSeek as the provider, and either generate text or extract structured fields from data flowing through earlier steps. You supply your own DeepSeek API key, so billing happens directly on your DeepSeek account. For step usage and how to write extract or generate prompts, see Integrate AI. The rest of this page covers DeepSeek-specific setup and gotchas. Sign up and get an API key Create an account at platform.deepseek.com.Open Billing and top up the account balance. DeepSeek bills against a prepaid balance.Go to API keys and click Create new API key. Copy the key once; DeepSeek doesn't show it again.Paste the key into the API key field of the Integrate AI step in your automation. Choose a model Pick a DeepSeek model in the Model field of Integrate AI. The two main families are: DeepSeek-V3 for general chat, generation, and extraction tasks.DeepSeek-R1 for tasks that benefit from explicit step-by-step reasoning, such as complex extraction schemas or logic-heavy decisions. See DeepSeek's pricing for current per-token costs. DeepSeek is typically the cheapest provider supported by Integrate AI, often by an order of magnitude. What DeepSeek is good at DeepSeek's strengths inside an axiom.ai automation: Very low per-token cost, useful for high-volume extraction or generation where the same prompt runs hundreds or thousands of times.Reasoning models (R1 family) when an automation needs to follow a multi-step decision tree rather than a single instruction.OpenAI-compatible API surface so models behave predictably if you've used ChatGPT before. Common patterns: High-volume scraped-page extraction where ChatGPT or Claude would be too expensive per run.Bulk content generation (product descriptions, ad variants, email drafts) at a scale that would push other providers' bills up.Reasoning over structured data with R1 when a single-shot prompt won't reliably produce the right answer. Data residency note DeepSeek is operated from China and routes API traffic to servers there. If your automation handles personal data, customer data, or anything subject to a data residency requirement, confirm DeepSeek's terms fit your needs before sending production traffic. Anonymise or scrub sensitive fields where possible. Limit API spending DeepSeek bills against a prepaid balance, which is itself a built-in spending cap: Only top up the balance you're willing to spend. When the balance hits zero, the API stops responding.Watch usage on the usage page and refill in small increments to keep a hard cap.Rotate keys periodically and revoke any you're no longer using. Other LLM providers The Integrate AI step also supports: ChatGPT (OpenAI)Claude (Anthropic)Gemini (Google)Sonar (Perplexity) The step behaves the same way; only the model list and API key change.",{"id":1383,"title":1384,"titles":1385,"content":1386,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fexcel","Microsoft Excel",[],"Connect a Microsoft work or school account to axiom.ai to read data from and write data to Excel sheets in your automations. Connect Microsoft Excel to axiom.ai to read data into your automations and write results back. The integration uses Microsoft's Graph API and currently requires a work or school Microsoft account. Connect a Microsoft account Important: A work or school Microsoft account is required. Microsoft's API restricts file availability for personal Microsoft accounts. Open axiom.ai.Navigate to Credentials and API key.In the Microsoft section, click Connect Microsoft.Follow the on-screen instructions to sign in. Disconnect a Microsoft account Open axiom.ai.Navigate to Credentials and API key.In the Microsoft section, click Disconnect Microsoft.Follow the on-screen instructions. Excel steps Two steps are available once Microsoft is connected: Read data from ExcelWrite data to an Excel sheet Microsoft token expiry When you connect Microsoft to axiom.ai, axiom.ai stores a token from Microsoft instead of your password. Microsoft sometimes expires these tokens with no notice. This is controlled entirely by Microsoft. The most common pattern we've seen is high-frequency reads and writes triggering the expiry. If your token expires often, consider running the automation less frequently.",{"id":1388,"title":1389,"titles":1390,"content":1391,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fgemini","Gemini",[],"Connect Gemini (Google) to your axiom.ai automations through the Integrate AI step. Generate text or extract structured data using your own Google AI Studio API key. Gemini is one of the LLM providers supported by the Integrate AI step. Drop the step into any automation, choose Gemini as the provider, and either generate text or extract structured fields from data flowing through earlier steps. You supply your own Google AI Studio API key, so billing happens directly on your Google account. For step usage and how to write extract or generate prompts, see Integrate AI. The rest of this page covers Gemini-specific setup and gotchas. Sign up and get an API key Go to Google AI Studio and sign in with a Google account.Open the API keys page and click Create API key.Choose an existing Google Cloud project or create a new one to attach the key to.Copy the key. Google AI Studio lets you view existing keys later, but treat them as secrets and don't share or commit them.Paste the key into the API key field of the Integrate AI step in your automation. Choose a model Pick a Gemini model in the Model field of Integrate AI. Google publishes the current model lineup (Pro, Flash, and variants) on the Gemini models page. Use Flash for fast, cheap, high-volume work; use Pro for harder reasoning or longer outputs. See Gemini API pricing for current per-token costs. What Gemini is good at Gemini's strengths inside an axiom.ai automation: Free tier for development. Google AI Studio includes a generous free tier on most models, useful for prototyping before turning on paid quotas.Long context. The Pro models support very large inputs, useful for long scraped HTML or PDF text.Multimodal input when paired with a screenshot or image from an earlier step. Common patterns: High-volume extraction from scraped pages where cost matters and Flash is fast enough.Summarising long documents pulled in by Read local file or Read file from Google Drive.Drafting content where you want a different tone or style than ChatGPT or Claude produce. Limit API spending Gemini billing runs through Google Cloud, so the standard Google Cloud controls apply: Set a budget on the Google Cloud project the API key is attached to. See Cloud billing budgets.Stay on the free tier during development by capping usage well below the free-tier limits.Rotate keys periodically in AI Studio and delete unused ones. Other LLM providers The Integrate AI step also supports: ChatGPT (OpenAI)Claude (Anthropic)Sonar (Perplexity)DeepSeek The step behaves the same way; only the model list and API key change.",{"id":1393,"title":1394,"titles":1395,"content":1396,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fgoogle-sheets","Google Sheets",[],"Connect a Google Sheets account to axiom.ai to read, write, find, and delete rows from your sheets during an automation. Connect Google Sheets to axiom.ai to read data into your automations, write results back, find or update specific rows, and create new sheets on the fly. Connect a Google Sheets account Open axiom.ai.Navigate to Google Sheets and API key.In the Google Sheets section, click Connect Google Sheets. Disconnect Google Sheets Open axiom.ai.Navigate to Google Sheets and API key.In the Google Sheets section, click Disconnect Google Sheets. Create a new Google Sheet The Create a new Google Sheet step creates a sheet in your Google Drive and returns the sheet URL as a variable. Use the variable in later steps to read or write to the new sheet. Read data from a Google Sheet The Read data from a Google Sheet step pulls data from a sheet into your automation. Configuration options: Spreadsheet: start typing the sheet name to autocomplete, or paste in the URL. Can be set from a variable.Sheet name: pick a specific tab from the dropdown.First cell: when enabled, set the first cell to read from. For example, A2 skips a header row.Last cell: when enabled, set the last cell to read up to. For example, B10.Continue when empty: when enabled, the automation continues if the sheet has no data instead of erroring. The step outputs a variable containing the sheet data. Use it in a Loop through data step to iterate row by row, or pass it to any other step that accepts data. Write data to a Google Sheet The Write data to a Google Sheet step writes data into a sheet from your automation. Configuration options: Spreadsheet: start typing the sheet name to autocomplete, or paste in the URL. Toggle Set sheet URL from data to drive this from a variable.Sheet name: pick a specific tab from the dropdown.Data: the variable containing the data to write. Pick it from the dropdown.Write options: choose Clear data before writing to overwrite the sheet, or Add to existing data to append.Write method: defaults to Raw, which writes data as-is. User entered simulates typing into the cell, which is useful for adding formulas. Edit a specific row You can use the Write data to a Google Sheet step to update a particular row instead of appending or overwriting: Set Write options to Add to existing data so existing rows aren't cleared.Set First cell to the cell you want to write from, for example A2. Combine with the Find row in a Google Sheet step to target dynamically. Find a row in a Google Sheet The Find row in a Google Sheet step looks up rows that match a set of values. Configuration options: Spreadsheet: start typing the sheet name to autocomplete, or paste in the URL.Sheet name: pick a specific tab from the dropdown.Values: a comma-separated list of values to search for.Exact match: tick to match whole values rather than partial matches.Value matching mode: choose Any to match rows containing any value, or All to require all values.Columns: a comma-separated list of column numbers to search. For example, 1,2 searches columns A and B. The step outputs a variable that includes the row number when a match is found. Delete rows from a Google Sheet The Delete rows from a Google Sheet step removes a contiguous range of rows. Configuration options: Spreadsheet: start typing the sheet name to autocomplete, or paste in the URL.Sheet name: pick a specific tab from the dropdown.First row to delete: the row number to start from.Last row to delete: the row number to end at. Clear data from a Google Sheet The Clear data from a Google Sheet step empties a range of cells without deleting the rows themselves. Configuration options: Spreadsheet: start typing the sheet name to autocomplete, or paste in the URL.Sheet name: pick a specific tab from the dropdown.First cell: the start of the range to clear, for example A3.Last cell: the end of the range to clear, for example B33. Convert Excel to Google Sheets axiom.ai's Google Sheets steps don't read native Microsoft Excel files. To use an Excel file, convert it first: Upload the .xls or .xlsx file to a Google Drive folder.Open the file in Google Sheets.Click File > Save as Google Sheets. For native Excel support, see the Excel integration. Google token expiry When you connect Google Sheets to axiom.ai, axiom.ai stores a token from Google instead of your password. Google sometimes expires these tokens with no notice. This is controlled entirely by Google. The most common pattern we've seen is high-frequency reads and writes triggering the expiry. If your token expires often, consider running the automation less frequently.",{"id":1398,"title":1399,"titles":1400,"content":1401,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations","Integrations",[],"Connect axiom.ai to Zapier, Make, n8n, Google Sheets, Excel, ChatGPT, Claude, Gemini, Sonar, 2Captcha, Puppeteer, and Relay.app to extend your automations. The axiom.ai Chrome extension integrates with workflow tools like Zapier, Make, n8n, and Relay.app; spreadsheets like Google Sheets and Excel; LLM providers like ChatGPT, Claude, Gemini, Sonar, and DeepSeek (all via the Integrate AI step); and developer tools like 2Captcha and Puppeteer. For anything else, build your own integration with the Trigger webhook step. If you'd like an integration that isn't listed, contact support. Available integrations Need help? Contact support or ask a question in our Reddit community.",{"id":1403,"title":1404,"titles":1405,"content":1406,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fmake","Make",[],"Trigger Make scenarios from axiom.ai automations and trigger axiom.ai automations from Make using webhooks and HTTP requests. Make is a workflow builder you can connect to axiom.ai in either direction. Trigger a Make scenario when an axiom.ai automation runs, or trigger an automation from any Make scenario. Trigger a Make scenario from an axiom.ai automation Use the Trigger webhook step to start a Make scenario when your automation runs. You'll need a Make account. In Make: Click Create new scenario.Add a trigger and search for Webhooks, then choose Custom webhook.Click Create a webhook, enter a name, and click Save.Copy the webhook URL Make gives you. It starts with https:\u002F\u002Fhook.... Save it for the next section.Optionally, edit the advanced settings to define a data structure.Build out the rest of your scenario with the modules you need. In axiom.ai: Open your automation and add a Trigger webhook step.Set Endpoint to the webhook URL you copied from Make.Set Payload to the data you want to send. For Make's side of the setup, see Make's receiving a webhook docs. Trigger an axiom.ai automation from a Make scenario Note: This setup uses the axiom.ai webhook API. A subscription that includes Webhooks is required to use the Receive data from another app step. See pricing for details. Note: We're aware of an issue with the official Make integration that can prevent new users from adding connections. Use the HTTP request setup below in the meantime. You'll need: API key. Find it on the API key dashboard.Automation name. The exact name of the automation you want to trigger.Endpoint. https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger. In Make: Add a new module to your scenario. Search for HTTP and add Make a request.Set URL to the axiom.ai endpoint above.Set Method to POST.Set Body type to Raw.Set Content type to JSON (application\u002Fjson).Add the JSON body in Request content. See sending data with the API for the format. In axiom.ai: Add a Receive data from another app step at the start of your automation. When the run is successful, axiom.ai returns a JSON response Make can use in later modules. See understanding the API response for the format. Test the integration To test the axiom.ai → Make direction, click Run in the axiom.ai extension, wait a few seconds, then check History in Make. To test the Make → axiom.ai direction, click Run once in Make, wait a few seconds, then check run reports in axiom.ai. Future plans We have an official Make integration but are aware of issues with new connections, likely related to the Integromat-to-Make migration. We hope to restore full integration support soon, which will make this setup simpler than the HTTP request workaround above.",{"id":1408,"title":1409,"titles":1410,"content":1411,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fn8n","n8n",[],"Trigger n8n workflows from axiom.ai and trigger axiom.ai automations from n8n using webhooks and HTTP requests. n8n is a workflow builder you can connect to axiom.ai in either direction. Trigger an n8n workflow when an axiom.ai automation runs, or trigger an automation from any n8n workflow. Trigger an n8n workflow from an axiom.ai automation Use the Trigger webhook step to start an n8n workflow when your automation runs. You'll need an n8n instance. In n8n: Create a new workflow.Add a trigger node and select Webhook.Set the webhook to listen for POST requests.Copy the webhook URL n8n provides. Save it for the next section.Optionally configure the webhook to accept specific data or parameters.Build out the rest of your workflow with the nodes you need. In axiom.ai: Open your automation and add a Trigger webhook step.Set Endpoint to the webhook URL you copied from n8n.Set Payload to the data you want to send. For n8n's side of the setup, see n8n's webhook documentation. Trigger an axiom.ai automation from an n8n workflow Note: A subscription that includes Webhooks is required to use the Receive data from another app step. See pricing for details. You'll need: API key. Find it on the API key dashboard.Automation name. The exact name of the automation you want to trigger.Endpoint. https:\u002F\u002Flar.axiom.ai\u002Fapi\u002Fv3\u002Ftrigger. In n8n: Add an HTTP Request node to your workflow.Set URL to the axiom.ai endpoint above.Set Method to POST.Set Content Type to JSON.Add the JSON request body. See sending data with the API for the format. In axiom.ai: Add a Receive data from another app step at the start of your automation. When the run is successful, axiom.ai returns a JSON response n8n can use in later nodes. See understanding the API response for the format. Test the integration To test the axiom.ai → n8n direction, click Run in the axiom.ai extension, wait a few seconds, then check the execution history in n8n. To test the n8n → axiom.ai direction, manually execute the workflow in n8n, wait a few seconds, then check run reports in axiom.ai. Future plans axiom.ai doesn't yet have a dedicated n8n node, but webhooks and HTTP requests cover both directions reliably. We plan to expand the docs with more examples over time.",{"id":1413,"title":1414,"titles":1415,"content":1416,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fpuppeteer","Puppeteer",[],"Call Puppeteer's page interaction methods from a Write javascript step to control the browser in ways the no-code steps can't. The axiom.ai desktop app is built on top of Puppeteer, Google's library for controlling Chrome over the DevTools Protocol. From the Write javascript step, you can call a subset of Puppeteer's methods to do things the no-code steps can't. Enable Puppeteer in a script Puppeteer methods only work when the script runs in the desktop app, not in the browser: Add a Write javascript step.Toggle Run in app on.Tick the Run in app confirmation checkbox. Supported methods axiom.ai supports the Page Interactions methods from Puppeteer. Other methods aren't available inside the Write javascript step. Examples To use Puppeteer, you'll need a CSS selector for the element you want to interact with. Open Chrome DevTools (right-click the element and choose Inspect) to find one. Replace the selectors in the snippets below with your own. Click a button await page.click('#button'); Fill a text input await page.locator('input.name').fill('Hello, world!'); Find an element by its text For more on text selectors, see the Puppeteer text selector docs. const element = await page.waitForSelector('div ::-p-text(Submit)'); Use a custom selector const mySelector = 'input';\nconst element = await page.waitForSelector(`form.${mySelector}`); 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 .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}",{"id":1418,"title":1419,"titles":1420,"content":1421,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Frelay-app","Relay.app",[],"Trigger Relay.app workflows from axiom.ai automations and trigger axiom.ai automations from Relay.app, with built-in field mapping support. Relay.app is a workflow builder for AI agents that connects services like Zapier and Make. The axiom.ai integration works in either direction. Get started with Relay.app Sign up at Relay.app and complete their onboarding to learn the basics. Workflows are created from the Relay.app dashboard by clicking + New workflow. Trigger a Relay.app workflow from an axiom.ai automation In Relay.app: Click + Add trigger and select Webhook is called from the list.Leave the HTTP method as POST (the default).Copy the webhook URL Relay.app provides. In axiom.ai: Build out your automation as normal. When you're ready to fire the Relay.app workflow, add a Trigger webhook step.Set Endpoint to the Relay.app webhook URL. Run the automation to test. The trigger may take a few seconds. Check the Relay.app dashboard to confirm the workflow ran. Trigger an axiom.ai automation from Relay.app Note: This integration is built and maintained by the Relay.app team. axiom.ai's support is limited to issues on our side. For axiom.ai-specific errors, see common errors. In Relay.app, after adding a trigger, click + Add step, search for axiom.ai, and select Run automation. In axiom.ai, make sure the automation starts with a Receive data from another app step. Connect your axiom.ai account In Relay.app, click Connect on the axiom.ai step. Enter your axiom.ai API key when prompted. To find your API key, see the API key documentation. Pick the automation to trigger Enter the automation's name in Automation name. The value is case-sensitive and must match the name shown in the axiom.ai dashboard exactly. Pass data into the run Use the Fields to populate section of the Run automation step in Relay.app to map data into the run. Mapped fields become available in the Receive data from another app step at the start of your axiom.ai automation. Wrapping up Relay.app's catalog of integrations gives you a quick way to wire axiom.ai automations into a much larger ecosystem of apps and AI agents.",{"id":1423,"title":1424,"titles":1425,"content":1426,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fsonar","Sonar",[],"Connect Sonar (Perplexity) to your axiom.ai automations through the Integrate AI step. Generate text or extract structured data using your own Perplexity API key. Sonar is Perplexity's API-accessible model family, and one of the LLM providers supported by the Integrate AI step. Drop the step into any automation, choose Sonar as the provider, and either generate text or extract structured fields from data flowing through earlier steps. You supply your own Perplexity API key, so billing happens directly on your Perplexity account. For step usage and how to write extract or generate prompts, see Integrate AI. The rest of this page covers Sonar-specific setup and gotchas. Sign up and get an API key Create an account at perplexity.ai.Open API settings and add a payment method.Click Generate API key and copy the key. Treat it like a secret.Paste the key into the API key field of the Integrate AI step in your automation. Choose a model Pick a Sonar model in the Model field of Integrate AI. Perplexity publishes the current model lineup (Sonar, Sonar Pro, and reasoning variants) on the Perplexity API models page. See Perplexity's pricing for current per-token and per-request costs. What Sonar is good at Sonar's distinguishing feature is live web search built into the model. Where other LLMs only know what was in their training data, Sonar can pull in current information at inference time. Useful when an automation needs: Real-time facts like today's prices, scores, or news.Citations alongside generated answers, since Sonar can return source URLs.Research-style summaries of topics that change frequently. Common patterns: Generate a market update with up-to-date competitor pricing pulled in by Sonar itself, no separate scrape step needed.Enrich scraped leads with recent news about their company.Produce briefings that need to reference recent events. Sonar is usually less useful for pure extraction from data you've already scraped; for that, ChatGPT, Claude, or Gemini Flash are typically cheaper and faster. Limit API spending Perplexity exposes spending controls in the API settings: Set usage limits in API settings so the API stops responding past a monthly cap.Use a dedicated account for axiom.ai if you want strict isolation from other apps.Rotate keys periodically and delete any you're no longer using. Other LLM providers The Integrate AI step also supports: ChatGPT (OpenAI)Claude (Anthropic)Gemini (Google)DeepSeek The step behaves the same way; only the model list and API key change.",{"id":1428,"title":1429,"titles":1430,"content":1431,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fintegrations\u002Fzapier","Zapier",[],"Trigger Zaps from your axiom.ai automations and trigger axiom.ai automations from Zapier, with optional support for passing data between them. Connect axiom.ai and Zapier in either direction. Trigger a Zap when an automation runs, or trigger an automation from any Zap. You can also pass data between the two. Trigger a Zap from an axiom.ai automation Use the Trigger webhook step or the Write javascript step to fire a Zap when your automation runs. For step-by-step walkthroughs: Trigger a Zap from axiom.ai with Trigger webhookTrigger a Zap from axiom.ai with JavaScript To send data with the trigger, see the Sending data to Zapier examples. Trigger an axiom.ai automation from Zapier Use Zapier as a middleman between its library of apps and axiom.ai. When a Zap fires, it triggers your automation and passes data into it. Trigger an axiom.ai automation from ZapierSend data from Zapier to axiom.ai Trigger local runs with Zapier The axiom.ai API always runs automations in the cloud. To run on the desktop instead, use the trigger a desktop run with webhooks workaround. Got more questions? Ask in our Reddit community.",{"id":1433,"title":762,"titles":1434,"content":1435,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference",[],"To learn more about axiom.ai's steps, read our reference documention. Learn in depth about the range of axiom.ai steps and settings.",{"id":1437,"title":1438,"titles":1439,"content":1440,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fchrome\u002Fbypass-bot-detection","Bypass bot detection",[],"Get past Cloudflare and similar bot blockers by attaching axiom.ai to an existing Chrome window that has already passed the challenge. Many websites use automated bot detection (most commonly Cloudflare) to block automated traffic. axiom.ai automations can get caught in those blocks even though they're not malicious. The bypass bot detection setting helps in two ways: it can solve common challenges automatically, or attach axiom.ai to an existing Chrome window that has already been validated as a real user. Install the desktop app Bypass bot detection requires the axiom.ai desktop application. Download it from the downloads page. Choose a bypass method Bot detection bypass is off by default because the checks slow automations down. To turn it on, open the automation, click the Cog icon in the toolbar on the left, and select the Bypass bot detection section. There are three options: No bot detection bypass. The default. axiom.ai runs without any bot detection workarounds.Use automatic bot detection bypassing. axiom.ai detects and solves bot challenges automatically where it can.Attach to existing Chrome. axiom.ai connects to a Chrome window you've manually validated. Use automatic bot detection bypassing With this mode on, axiom.ai detects bot challenges and solves them automatically. It works for many sites but isn't infallible. When automatic bypass can't solve a challenge, you'll need to solve it manually. For complex challenges, use the Solve Captcha step from the 2Captcha integration. For simple checkbox challenges, record the keystrokes to solve them with the Press key(s) step: Record Tab the correct number of times to move focus onto the checkbox.Record Space to tick the box and complete the challenge. For more on keystroke automation, see record keystrokes. Attach to existing Chrome This method connects axiom.ai to a Chrome window you've already validated as a real user, so the bot blocker sees legitimate-looking traffic. Open Chrome with remote debugging enabled Chrome needs to be started with the remote debugging port flag for axiom.ai to attach to it. The Bypass bot detection settings panel includes a button to open one for you. To start one manually instead, run a command like this in a terminal: \u002Fpath\u002Fto\u002FChrome\u002Fchrome --remote-debugging-port=21222 Adjust the path to your Chrome executable. You can also create a shortcut or symbolic link with the flag built in for easier reuse. Solve the challenge in your Chrome window In the new Chrome window, navigate to the site you're trying to automate, then to the page where bot blocking happens. The site validates the session, often automatically, sometimes by asking you to solve a captcha. Once you've passed the validation, the session is ready for axiom.ai to take over. Adjust the automation start point The automation needs to start on the page you've validated, not before it. If validation happens after a login, sign in manually first, then change the automation so it only contains the steps that come after sign-in. When you click Run, axiom.ai picks up the validated browser window and runs from the configured start step. Note: In this mode, the Chrome window doesn't close when the automation stops. The automation finishes its current action, then leaves the window open for you to close manually. html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}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);}",{"id":1442,"title":1443,"titles":1444,"content":1445,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fchrome\u002Fexecutable-path","Set executable path",[],"Point axiom.ai at your local Chrome installation so automations run in Chrome instead of the built-in Chromium browser. By default, axiom.ai runs automations in a built-in Chromium window. Set an executable path to use your local Chrome installation instead. This can help with sites that detect or behave differently in Chromium. Set the executable path Open a new tab in Chrome.Navigate to chrome:\u002F\u002Fversion.Copy the Executable path value.In the automation, click the Cog icon, open the Set executable path section, and paste the path into Executable path. The path looks similar to these examples: Windows: C:\\Program Files\\Google\\Chrome\\Application\\chrome.exemacOS: \u002FApplications\u002FGoogle Chrome.app\u002FContents\u002FMacOS\u002FGoogle ChromeLinux: \u002Fusr\u002Fbin\u002Fgoogle-chrome",{"id":1447,"title":1448,"titles":1449,"content":1450,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fchrome\u002Fincognito","Run in incognito mode",[],"Force axiom.ai to run an automation in a fresh incognito window with no stored cookies, useful when sessions need to start clean. Run an automation in incognito mode to start every run in a fresh window with no stored cookies. Useful when sessions need to be clean each time, for example when sign-in cookies from a previous run would interfere. Allow incognito mode for the extension The Chrome extension needs explicit permission to run in incognito mode. This is a one-time setup per machine. In Chrome, navigate to chrome:\u002F\u002Fextensions.Find the axiom.ai extension and click Details.Toggle Allow in incognito on. Without this permission, axiom.ai can't start in an incognito window. Enable incognito mode on the automation Open the automation and click the Cog icon in the toolbar on the left.Open the Run in incognito mode section.Toggle Run in incognito mode on.",{"id":1452,"title":1453,"titles":1454,"content":1455,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fchrome","Chrome",[],"Configure how axiom.ai launches Chrome or Chromium, including bot detection bypass, profiles, executable path, extensions, and incognito mode. The Chrome settings control how axiom.ai launches the browser for an automation. Use them to bypass bot detection, use a custom Chromium profile, point at a specific Chrome executable, load another extension, or run in incognito mode. Chrome settings Need help? Contact support or ask a question in our Reddit community.",{"id":1457,"title":1458,"titles":1459,"content":1460,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fchrome\u002Fload-extension","Load another extension",[],"Load a Chrome extension into the Chromium window axiom.ai uses, with one extension at a time and known limitations on interactivity. By default, axiom.ai runs in a clean Chromium window with no extensions installed. Load another extension to bring its functionality (an ad blocker, a tracking blocker, a password manager, and so on) into the automation's browser session. Note: Only one extension can be loaded at a time. Not all extensions work in Chromium. Ad blockers and other resource-blocking extensions can affect axiom.ai itself; if one is loaded, ask the developer to whitelist axiom.ai. Note: You can't interact with the extension's UI during a run. You can interact with elements the extension inserts into the page's HTML, but only if those elements are inserted before axiom.ai's script runs. Tip: As an alternative, run the automation in your local Chrome instead with set executable path. You won't be able to drive the extension's UI, but extensions tend to behave more reliably in your real Chrome. Load an extension The extension needs to already be installed in your local Chrome (or another Chromium-based browser) via the Chrome Web Store or a manual install. Open Chrome and navigate to chrome:\u002F\u002Fextensions. Find the extension and copy its ID.Navigate to chrome:\u002F\u002Fversion and copy the Profile path.In your file system, open the profile path and find the Extensions folder.Open the folder named with the extension ID from step 1.Open the version folder inside it (the most recent version of the extension).Copy the full file path of that version folder.In the automation, click the Cog icon, open the Load another extension section, and paste the path into Extension path. Note: Extension paths can change when the extension updates. If the path includes a version number, you may need to update the path after each update. Understand the file path The path looks similar to these examples, where \u003CEXTENSION_ID> is from step 1 and \u003CEXTENSION_VERSION> is the latest version folder: Windows: C:\\Users\\\u003CUSER>\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\\u003CEXTENSION_ID>\\\u003CEXTENSION_VERSION>macOS: \u002FUsers\u002F\u003CUSER>\u002FLibrary\u002FApplication Support\u002FGoogle\u002FChrome\u002FDefault\u002FExtensions\u002F\u003CEXTENSION_ID>\u002F\u003CEXTENSION_VERSION>Linux: \u002Fhome\u002F\u003CUSER>\u002F.config\u002Fgoogle-chrome\u002FExtensions\u002F\u003CEXTENSION_ID>\u002F\u003CEXTENSION_VERSION> Troubleshooting The extension isn't loading Double-check the file path points at the correct extension and the latest version folder. Update the path if the extension has been updated since you set it. The extension loads but doesn't work The extension may not work in Chromium, may need configuration that isn't possible in this context, or may require a sign-in (which isn't supported here). Try running the automation in your local Chrome instead. See set executable path. Browser could not be started See Browser could not be started.---\ntitle: Load another extension\nmetaTitle: Load a Chrome extension into an axiom.ai automation\ndescription: Load a Chrome extension into the Chromium window axiom.ai uses, with one extension at a time and known limitations on interactivity.\norder: 4 By default, axiom.ai runs in a clean Chromium window with no extensions installed. Load another extension to bring its functionality (an ad blocker, a tracking blocker, a password manager, and so on) into the automation's browser session. Note: Only one extension can be loaded at a time. Not all extensions work in Chromium. Ad blockers and other resource-blocking extensions can affect axiom.ai itself; if one is loaded, ask the developer to whitelist axiom.ai. Note: You can't interact with the extension's UI during a run. You can interact with elements the extension inserts into the page's HTML, but only if those elements are inserted before axiom.ai's script runs. Tip: As an alternative, run the automation in your local Chrome instead with set executable path. You won't be able to drive the extension's UI, but extensions tend to behave more reliably in your real Chrome. Load an extension The extension needs to already be installed in your local Chrome (or another Chromium-based browser) via the Chrome Web Store or a manual install. Open Chrome and navigate to chrome:\u002F\u002Fextensions. Find the extension and copy its ID.Navigate to chrome:\u002F\u002Fversion and copy the Profile path.In your file system, open the profile path and find the Extensions folder.Open the folder named with the extension ID from step 1.Open the version folder inside it (the most recent version of the extension).Copy the full file path of that version folder.In the automation, click the Cog icon, open the Load another extension section, and paste the path into Extension path. Note: Extension paths can change when the extension updates. If the path includes a version number, you may need to update the path after each update. Understand the file path The path looks similar to these examples, where \u003CEXTENSION_ID> is from step 1 and \u003CEXTENSION_VERSION> is the latest version folder: Windows: C:\\Users\\\u003CUSER>\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\\u003CEXTENSION_ID>\\\u003CEXTENSION_VERSION>macOS: \u002FUsers\u002F\u003CUSER>\u002FLibrary\u002FApplication Support\u002FGoogle\u002FChrome\u002FDefault\u002FExtensions\u002F\u003CEXTENSION_ID>\u002F\u003CEXTENSION_VERSION>Linux: \u002Fhome\u002F\u003CUSER>\u002F.config\u002Fgoogle-chrome\u002FExtensions\u002F\u003CEXTENSION_ID>\u002F\u003CEXTENSION_VERSION> Troubleshooting The extension isn't loading Double-check the file path points at the correct extension and the latest version folder. Update the path if the extension has been updated since you set it. The extension loads but doesn't work The extension may not work in Chromium, may need configuration that isn't possible in this context, or may require a sign-in (which isn't supported here). Try running the automation in your local Chrome instead. See set executable path. Browser could not be started See Browser could not be started.",{"id":1462,"title":1463,"titles":1464,"content":1465,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fchrome\u002Fprofile","Set a custom Chromium profile",[],"Point axiom.ai at a custom Chromium profile so automations carry over browser settings, downloads behaviour, and other preferences. By default, axiom.ai uses Chromium's default profile. Set a custom profile to carry over browser settings (download behaviour, default file locations, and so on) into your automation runs. Note: This setting is only available in the axiom.ai desktop app. Profiles must be created in Chromium, not Chrome. Warning: If you run an automation without a profile, then run it again with a profile set, the custom profile is deleted. This appears to be a Chromium bug. To avoid it, restart the axiom.ai desktop app before running an automation that uses a custom profile. Warning: Chromium must be fully closed before the automation runs. Chromium can crash if it tries to load a profile that's already open in another window. Set a custom Chromium profile You'll need Chromium installed in addition to Chrome. Open Chromium and navigate to chrome:\u002F\u002Fversion.Copy the Profile path value.In the automation, click the Cog icon, open the Set profile section, and paste the path into Profile path. If chrome:\u002F\u002Fversion shows an empty Profile path, Chromium may be installed in the same location as profiles. In that case, the profile is in one of these default locations: Windows 7, 8.1, 10, 11: C:\\Users\\\u003CUSER>\\AppData\\Local\\Google\\Chrome\\User Data\\DefaultmacOS: \u002FUsers\u002F\u003CUSER>\u002FLibrary\u002FApplication Support\u002FGoogle\u002FChrome\u002FDefaultLinux: \u002Fhome\u002F\u003CUSER>\u002F.config\u002Fgoogle-chrome\u002Fdefault Modify settings inside the profile To change browser settings the automation will use, open Chromium (with the profile loaded), make the changes, then close Chromium before the next run. Common settings worth changing: Whether downloaded PDFs save to disk or open in the browser.The default download location. Troubleshooting Chromium opens to about:blank and the automation doesn't start Close Chromium completely and start the automation again. Chromium can't load a profile already open in another window. Chromium prompts you to select a user Compare the profile path in your automation against the value in chrome:\u002F\u002Fversion. The two must match exactly. Trailing slashes count: \u002FProfile works, but \u002FProfile\u002F does not. The profile was removed Restart the axiom.ai desktop app before running the automation again. This is the most reliable workaround for the Chromium bug described in the warning above. The profile reports as corrupt Set the executable path to your downloaded version of Chromium and try again.",{"id":1467,"title":1468,"titles":1469,"content":1470,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Ferror-handling\u002Fcontinue-on-error","Continue on error",[],"Toggle Continue on error to keep an automation running past failures instead of stopping, with errors shown as warnings in run reports. By default, axiom.ai stops an automation as soon as a step throws an error. This protects against unexpected side effects, like writing partial data to a Google Sheet. The continue on error option overrides that behaviour and lets the automation keep running through errors. Note: When Continue on error is enabled, every run reports as successful at the end, regardless of how many errors occurred. Errors appear as warnings in run reports. Don't use this setting on automations where it matters whether a run actually succeeded. Enable Continue on error Open the automation and click the Cog icon in the toolbar on the left.Open the Continue on error section under Error handling.Toggle Continue on error on.",{"id":1472,"title":1473,"titles":1474,"content":1475,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Ferror-handling\u002Fiframes","Interact with iframes",[],"Enable iframe support so an automation can scrape and click inside embedded iframes, which axiom.ai ignores by default. By default, axiom.ai ignores iframes (embedded frames within a page) when scraping or clicking. Iframes are usually unnecessary for the task and can introduce inconsistencies if the automation reaches into them by accident. Enable iframe support when you need to interact with content inside an iframe. Enable iframe support Open the automation and click the Cog icon in the toolbar on the left.Open the Interact with iframes section under Error handling.Toggle Interact with iframes on.",{"id":1477,"title":1478,"titles":1479,"content":1480,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Ferror-handling","Error handling",[],"Configure how an automation reacts to errors, slow-loading pages, and iframes using continue on error, page monitoring, and iframe support. Error handling settings change how an automation reacts to errors and edge cases during a run. Use continue on error to keep going past failures, iframe support to interact with embedded frames, and page monitoring to control how axiom.ai detects when a page has finished loading. Error handling settings Need help? Contact support or ask a question in our Reddit community.",{"id":1482,"title":1483,"titles":1484,"content":1485,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Ferror-handling\u002Fpage-monitoring","Disable page monitoring",[],"Disable page monitoring so axiom.ai stops waiting for page changes between steps, useful when monitoring slows automations significantly. By default, axiom.ai watches the page for changes and only continues to the next step once the page has finished loading. This makes automations more reliable, but in rare cases it can slow them down significantly. Disable page monitoring when you've confirmed the wait is unnecessary and the automation is being held back by it. Warning: Disabling page monitoring can make an automation less reliable. Test thoroughly after changing this setting; if a page is still loading when the next step runs, that step may fail or pick up incomplete data. Disable page monitoring Open the automation and click the Cog icon in the toolbar on the left.Open the Disable page monitoring section under Error handling.Toggle Disable page monitoring on.",{"id":1487,"title":1488,"titles":1489,"content":1490,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fimport-export","Import and export",[],"Download an automation as a JSON file to share or back up, or import a previously downloaded automation into the Builder. You can download an automation as a .json file to share with another user or keep as a backup, and you can import a previously downloaded .json file back into axiom.ai. Import and export Need help? Contact support or ask a question in our Reddit community.",{"id":1492,"title":1493,"titles":1494,"content":1495,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Fimport-export\u002Fsharing","Import or download an automation",[],"Import a previously downloaded automation as a JSON file, or download an automation as JSON to share or back up. axiom.ai stores each automation as a JSON file. Use these settings to download an automation as a file you can share or back up, or to import a previously downloaded file into the Builder. Import an automation Importing replaces the current automation with the one in the file. Open the automation you want to overwrite first, or create a new automation and import into that instead. Warning: Importing overwrites the current automation as soon as you save. There's no undo, so make sure you're in the right automation before importing. Open the automation and click the Cog icon in the toolbar on the left.Open the Import or download section.Click Select file and choose the .json file to import.Save the automation to apply the change. Download an automation Downloading exports the current automation as a .json file you can share or back up. Open the automation and click the Cog icon in the toolbar on the left.Open the Import or download section.Click Download. The file saves to your usual downloads folder. To use it elsewhere, follow the import steps above.",{"id":1497,"title":1498,"titles":1499,"content":1500,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings","Automation settings",[],"Configure how each bot runs, handles errors, uses Chrome, and gets shared as a template. Every automation has its own settings. Control how a bot runs, import or export bots as templates, decide how errors are handled, and manage how the bot uses Chrome. Running Control how a bot runs - start page, run speed, scroll behaviour, and scheduling. Import and export Share a bot as a template or download it as a JSON file others can import. Error handling Decide what happens when a step fails - retry, skip, log, or stop the run. Chrome Manage how the bot uses Chrome - bypass bot detection, run in incognito mode, and load other extensions. Need help? Contact support or ask a question in our Reddit community.",{"id":1502,"title":1503,"titles":1504,"content":1505,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fblock-resources","Block resources",[],"Block images, fonts, scripts, and other webpage resources during a run to cut bandwidth and speed up automations. Block resources stops an automation from loading images, fonts, scripts, media, and other webpage assets it doesn't need. Skipping these cuts bandwidth, reduces network traffic, and speeds up runs, especially on heavy pages where the automation only needs the HTML. Warning: Blocking some resources, like JavaScript, can break the page. Always test the automation after changing these settings. Block resources for an automation Open the automation and click the Cog icon in the toolbar on the left.Open the Block resources section.Toggle Block individual resources on.Enter a domain or URL pattern in Domain or path and click Add.For each entry, pick which resource types to block (images, fonts, scripts, media, and so on). Repeat for every domain or path the automation loads during a run. Domain and URL patterns Use * as a wildcard to match a group of URLs: * blocks all URLs.axiom.ai\u002F*\u002Fscripts blocks any path matching that pattern on axiom.ai.*.axiom.ai\u002F* blocks every subdomain of axiom.ai. Specific patterns let you block bandwidth-heavy resources on third-party domains (analytics, ad servers, image CDNs) while leaving the main site you're scraping untouched. When to use it Scraping text-heavy pages. Block images, fonts, and media to load pages faster.Avoiding tracking and ads. Block known analytics or advertising domains so they don't slow the run.Working around heavy third-party scripts. Block embedded widgets, chat boxes, or video players that aren't needed for the task. Don't block resources the page genuinely depends on, particularly JavaScript, unless you've tested that the automation still works without them.---\ntitle: Block resources\nmetaTitle: Block images, fonts, and scripts to speed up automations\ndescription: Block images, fonts, scripts, and other webpage resources during a run to cut bandwidth and speed up automations.\norder: 9 Block resources stops an automation from loading images, fonts, scripts, media, and other webpage assets it doesn't need. Skipping these cuts bandwidth, reduces network traffic, and speeds up runs, especially on heavy pages where the automation only needs the HTML. Warning: Blocking some resources, like JavaScript, can break the page. Always test the automation after changing these settings. Block resources for an automation Open the automation and click the Cog icon in the toolbar on the left.Open the Block resources section.Toggle Block individual resources on.Enter a domain or URL pattern in Domain or path and click Add.For each entry, pick which resource types to block (images, fonts, scripts, media, and so on). Repeat for every domain or path the automation loads during a run. Domain and URL patterns Use * as a wildcard to match a group of URLs: * blocks all URLs.axiom.ai\u002F*\u002Fscripts blocks any path matching that pattern on axiom.ai.*.axiom.ai\u002F* blocks every subdomain of axiom.ai. Specific patterns let you block bandwidth-heavy resources on third-party domains (analytics, ad servers, image CDNs) while leaving the main site you're scraping untouched. When to use it Scraping text-heavy pages. Block images, fonts, and media to load pages faster.Avoiding tracking and ads. Block known analytics or advertising domains so they don't slow the run.Working around heavy third-party scripts. Block embedded widgets, chat boxes, or video players that aren't needed for the task. Don't block resources the page genuinely depends on, particularly JavaScript, unless you've tested that the automation still works without them.",{"id":1507,"title":1508,"titles":1509,"content":1510,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fconcurrency","Concurrency",[],"Allow more than one instance of an automation to run at the same time on the cloud or desktop, or keep them sequential when order matters. Concurrency lets multiple instances of the same automation run at the same time. Useful when an automation is triggered repeatedly (by a webhook, a schedule, or a manual rerun) and you don't want each run to wait for the last one to finish. Turn it off when runs depend on each other, for example when both write to the same Google Sheet and would clash if they ran in parallel. Cloud concurrency Toggle Allow cloud concurrency on to let multiple cloud runs of the automation fire at the same time. Use it when: A webhook triggers the automation more often than a single run takes to finish.A schedule overlaps with manual runs.Each run is independent. It doesn't read or write data another run also touches. Keep it off when runs share state, especially when both runs read from or write to the same Google Sheet, since simultaneous writes can overwrite each other. Desktop concurrency Toggle Allow desktop concurrency on to let multiple desktop runs of the automation fire at the same time. The same rules as cloud concurrency apply. Off by default. Desktop runs typically need the screen and a single browser session, so running several in parallel is more likely to clash. Set concurrency for an automation Open the automation and click the Cog icon in the toolbar on the left.Open the Concurrency section.Toggle Allow cloud concurrency on or off.Toggle Allow desktop concurrency on or off. Need more concurrency Each plan ships with a default concurrency limit. To raise it, email support@axiom.ai for a custom package.",{"id":1512,"title":1513,"titles":1514,"content":1515,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fheadless","Run headless",[],"Run an automation in headless mode so it executes in the background without opening a visible browser window. Headless mode runs an automation in the background, without opening a visible browser window. Useful for desktop runs you want out of the way, or when running on a remote machine without a display. Warning: Some sites detect headless browsers and block them. If a site behaves differently in headless mode, run it with the visible browser instead. Enable headless mode Open the automation and click the Cog icon in the toolbar on the left.Open the Run headless section.Toggle Run headless on.",{"id":1517,"title":1518,"titles":1519,"content":1520,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options","Run options",[],"Configure how an automation runs, including scheduling, proxies, timezone, max runtime, headless mode, notifications, and stored cookies. Run options let you fine-tune how an automation runs. From scheduling and proxies to headless mode and stored cookies, this section covers every option in the Run options panel of the Builder settings. Available run options Need help? Contact support or ask a question in our Reddit community.",{"id":1522,"title":1523,"titles":1524,"content":1525,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fmax-runtime","Set maximum runtime",[],"Set a maximum runtime so an automation stops automatically if it runs longer than expected. The maximum runtime option stops an automation if it has been running longer than the limit you set. This protects against runaway runs (loops that never exit, slow-loading pages, and so on) burning through your runtime allowance. The default is set by your subscription plan. Note: This setting only affects cloud runs. Set the maximum runtime Open the automation and click the Cog icon in the toolbar on the left.Open the Set maximum runtime section.Set Maximum runtime to the duration you want as the cap.",{"id":1527,"title":1528,"titles":1529,"content":1530,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fnotifications","Set up notifications",[],"Receive email or webhook notifications when an automation fails, finishes with warnings, or completes successfully. Notifications let you know when an automation has finished, so you don't have to keep checking the dashboard. Choose the conditions that should trigger a notification, and pick whether to receive it by email or webhook. You can be notified when a run: FailsFinishes with warningsSucceeds Set up notifications Open the automation and click the Cog icon in the toolbar on the left.Open the Set up notifications section under Run options.Toggle the conditions you want notifications for: Notify when run fails, Notify when run has warnings, Notify when run succeeds.Choose Notify by email or Notify by webhook. Notify by email Enter one or more email addresses, one per line. The email body includes any errors and metadata. To include extra metadata, add an Add error metadata step to your automation. Notify by webhook Enter the URL to send a POST request to. axiom.ai sends a JSON payload with this structure. Errors and metadata are included in log: {\n    \"status\": \"Run Status\",\n    \"log\": \"Axiom Run completed successfully\"\n} Send notifications to Slack To get run notifications in Slack, enable Notify by webhook and point it at a Slack Workflow that accepts the JSON payload above. For setup details, see \"Triggering a Slack workflow with an axiom.ai automation\" in the Slack guide. The Slack Workflow needs to be modified to parse the payload format shown above. html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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);}",{"id":1532,"title":1533,"titles":1534,"content":1535,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fproxy","Use a proxy",[],"Route automation traffic through a proxy to bypass bot blocks or geo-restricted content, with guidance on parsing a proxy URL into the right fields. The proxy option routes an automation's traffic through a proxy server. Useful for working around sites that block automated traffic, or for reaching content that's restricted to a specific region. Note: axiom.ai doesn't offer proxy services. Use a third-party proxy provider, or a self-hosted proxy server. Parse your proxy URL Most proxy providers give you a single URL containing every detail you need. The form in axiom.ai splits that URL across separate fields, so before configuring a proxy you'll need to break the URL into its parts. A proxy URL has this shape: \u003Cprotocol>:\u002F\u002F\u003Cusername>:\u003Cpassword>@\u003Chost>:\u003Cport> For example, a proxy from a typical provider might look like this: http:\u002F\u002F4bd1c98f3a72de01:xQRtwNZUBsa19YFm@res.proxy-seller.com:10000 Mapped onto axiom.ai's fields: Protocol is HTTP (the part before :\u002F\u002F).Username is 4bd1c98f3a72de01 (the part before the colon, before the @).Password is xQRtwNZUBsa19YFm (the part after the colon, before the @).IP address is res.proxy-seller.com (the part after the @, before the colon). This is a hostname rather than a numeric IP, but the field accepts both.Port is 10000 (the part after the final colon). Note: The example above is an HTTP proxy with credentials. Username and password authentication typically only works with HTTP proxies; SOCKS proxies usually authenticate by IP allowlisting at the provider instead. See Configure a proxy below for details. Note: The example credentials above are not real. Use the credentials your provider gave you. Configure a proxy Open the automation and click the Cog icon in the toolbar on the left.Open the Proxy section.Set Protocol to your proxy's protocol (typically HTTP, HTTPS, SOCKS4, or SOCKS5).Set IP address to your proxy's hostname or IP.Set Port to your proxy's port.If your proxy needs authentication, set Username and Password to the credentials your provider gave you. Note: Username and password authentication typically only works with HTTP proxies. SOCKS proxies usually authenticate by IP allowlisting on the provider's dashboard rather than by credentials in the connection. If you've set the protocol to SOCKS4 or SOCKS5 and the proxy still rejects the connection, check your provider's dashboard for an IP allowlist instead. Troubleshooting The proxy connection times out Confirm the proxy URL works outside axiom.ai before debugging the automation. A quick test from the terminal: curl -x http:\u002F\u002F\u003Cusername>:\u003Cpassword>@\u003Chost>:\u003Cport> https:\u002F\u002Fwww.google.com If curl can't reach the proxy either, the issue is with the proxy itself, not with axiom.ai. Contact your proxy provider. Pages load but the wrong region appears Some proxy providers route traffic through different regions automatically. Check whether your provider offers a region-specific endpoint or sticky session, and use that hostname instead of the rotating one. Authentication errors If you see a 407 Proxy Authentication Required error in run logs, double-check that Username and Password exactly match the credentials your provider issued. Pay particular attention to leading and trailing whitespace, which can sneak in when copying from a provider's dashboard. SOCKS proxy with credentials isn't working Username and password authentication typically only works with HTTP proxies. If your provider gave you a URL with embedded credentials but the protocol is SOCKS4 or SOCKS5, the credentials usually aren't used by the proxy connection itself. Instead, sign in to your provider's dashboard and add the IP address of the machine running the automation to their allowlist. After the IP is allowlisted, the proxy will accept connections from that machine without any credentials in axiom.ai. html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .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);}",{"id":1537,"title":1538,"titles":1539,"content":1540,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Frecord-runs","Record and monitor runs",[],"Record your axiom.ai cloud runs to replay the last minute of a run, view console output, and pinpoint exactly when an error occurred. Run recording captures the last minute of a cloud run along with the full console and interaction logs. When something fails, you can replay what the browser was doing in the seconds before it broke and pinpoint the step that caused the issue, instead of guessing from a stack trace. Note: Run recording is only available for cloud runs. Enabling this has no effect on desktop runs. Enable run recording Open the automation and click the Cog icon in the toolbar on the left.Open the Record \u002F monitor runs section under Run options.Toggle Record runs on. The next time the automation runs in the cloud, axiom.ai stores the recording and logs against that run. View a recording Open the run in the dashboard.The recording sits alongside the run report. Use the timeline to scrub to the moment the error occurred.The console and interaction logs sit next to the video so you can match each browser action to its corresponding log line. What gets captured The last minute of browser activity, as a replayable video.Console output, including warnings, errors, and any console.log calls from custom code steps.Interaction logs showing every click, type, navigation, and scrape the bot performed.",{"id":1542,"title":1296,"titles":1543,"content":1544,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fschedule",[],"Run an automation on a recurring schedule by setting a start date, time, and frequency, with optional JavaScript conditions for advanced patterns. The schedule option runs an automation automatically on a date, time, and frequency you set. Use it for recurring tasks like daily scrapes, weekly reports, or end-of-month rollups. Configure the schedule Open the automation, click the Cog icon, and open the Schedule section. Then configure each field. Set the date Set the date the automation should first run. Click Set the date and pick a date. The start date must be in the future. Set the time Set the time of day the automation should run. Click Change time and pick a time. This is the time of the first run. Set the frequency Set how often the automation repeats. The available frequencies depend on your subscription plan. For example, with the time set to 16:00:00 and frequency set to Daily, the automation runs at 16:00:00 every day. Run on this computer By default, scheduled runs happen in the cloud. Toggle Run on this computer on to run them on your local machine instead. The computer needs to be on and the browser open at the scheduled time. Advanced schedules with JavaScript The standard scheduler covers most cases, but you can extend it with a JavaScript condition for patterns it doesn't support directly (weekdays only, end of month, and so on). To set up a JavaScript schedule: Set the standard schedule to run at least once on each candidate day. For \"weekdays only\", schedule it daily.Add a Continue only if a condition is met step at the start of the automation.Set Condition to check to JS == true.Paste one of the snippets below into the JavaScript field. Run only on weekdays return date => date.getDay() % 6 !== 0; Run only on weekends return date => date.getDay() % 6 === 0; Run only on the last day of the month const today = new Date();\nconst nextMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1);\nnextMonth.setDate(nextMonth.getDate() - 1);\nreturn today.getDate() === nextMonth.getDate(); html pre.shiki code .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .sTDnQ, html code.shiki .sTDnQ{--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sbjLL, html code.shiki .sbjLL{--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}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);}",{"id":1546,"title":1547,"titles":1548,"content":1549,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Fstore-cookies","Store cookies",[],"Share browser cookies and local storage with cloud runs so logged-in sessions are reused, with optional auto-detection of URLs from your automation. The store cookies option shares browser cookies and local storage with cloud runs, so an automation that depends on a logged-in session can reuse that session in the cloud. All stored cookies and local storage are encrypted and have an expiry, so you'll need to resync periodically. By default, cloud runs use the cookies stored locally with the extension. Set this option to Stored cookies are used to copy cookies into axiom.ai for cloud runs. Tip: When stored cookies are enabled, also turn on run notifications so you get notified if a run fails because a stored cookie or local storage session has expired. Configure stored cookies This setting is configured per automation. Add a URL Enter a URL in Cookies and click + Add to register it. To auto-detect URLs from steps in the automation, click Populate from Axiom. Every URL referenced in a Go to page step is added to the list. URLs that aren't picked up automatically can be added manually. Note: Some sites use a separate subdomain for sign-in (for example login.example.com). If the sign-in subdomain isn't auto-detected, add it manually. Resync cookies Click Resync cookies to copy cookies from your local browser into the stored set for this automation. Globally resync cookies Click Globally resync cookies to copy cookies from your local browser into the stored set for this automation, plus every other automation that uses the same URLs. URL settings For each stored URL: URL. The URL the cookies are stored against. Confirm this matches the URL the automation actually loads.Cookies shared. On by default. Lets cloud runs reuse the stored cookies for this URL.Local storage shared. Off by default. Lets cloud runs reuse stored local storage for this URL. Only enable when cookies alone aren't enough; enabling it can slow page loads.Delete. Remove the stored cookies and local storage for this URL.",{"id":1551,"title":1552,"titles":1553,"content":1554,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsettings\u002Frun-options\u002Ftimezone","Configure timezone",[],"Set the timezone used by scheduled cloud automations, instead of the default UTC. By default, scheduled automations run in the cloud on UTC. Use the timezone option to run them on your local timezone instead. Configure the timezone Open the automation and click the Cog icon in the toolbar on the left.Open the Configure timezone section.Pick the timezone the schedule should use. Note: This setting only affects cloud runs. Desktop runs always use the local timezone of the computer they're running on.",{"id":1556,"title":1557,"titles":1558,"content":1559,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fadd-error-metadata","Add error metadata step",[],"Insert debug or error messages. Use to test data output and check step results during automation runs. What to use the Add error metadata step for This step's output is included in error messages from subsequent steps, aiding in debugging and testing data output. You can use this step to: Test data output in stepsWorking out causes of errors in stepsEnhance error messages How to configure the Add error metadata step Add this step to the start of your Axiom. Message Build your custom error message here. Use 'Insert Data' to select tokens to display data you wish to check from steps in your Axiom. Additional information You may want to try our 'Try catch' step to aid debugging.",{"id":1561,"title":1562,"titles":1563,"content":1564,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fadd-row-numbers","Add row numbers",[],"Add row numbers to your data so you can track, organise, and manipulate each row during your automation. What to use the Add row numbers step for Insert row numbers into your data set. This step adds a column to the start of your data so you can track each row. It is useful when you want to write data back to specific rows in your data source. You can use this step to add row numbers to: Data imported from Google Sheets, Excel, or AirtableData imported via a webhook. How to configure the Add row numbers step DATA Select the data to append the row numbers to. Offset Set an number to start the row numbering at.",{"id":1566,"title":1567,"titles":1568,"content":1569,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fappend-or-merge-data","Append or Merge data step",[],"Join data from separate steps. Use to combine scraped data with data from a Google Sheet. Join single columns or entire datasets. What to use the Append or Merge data step for This step merges data by appending one set to another, either horizontally to merge rows or vertically to add columns from the second set to the end of the first. It's commonly used to append a webpage's URL to 'scraped data.'\nYou can use this step to: Combine Google Sheet data with scraped dataMerge scraped data to a CSVJoin two sets of scraped data If you are looking to join different data sources based on matching columns try this step. How to configure the Append or Merge data step If you need to combine more than two sets of data, use multiple Append data steps. Data A Select the Data to be appended to (For example, data from a Google Sheet. When selecting data, click on the token to see a preview. Click 'Save and close' to select all or click 'Clear All' to choose columns individually. Data B Select the Data to be appended (For example, data from the Get data step. When selecting data, click on the token to see a preview. Click 'Save and close' to select all or click 'Clear All' to choose columns individually. Append mode Choose to append the data horizontally or vertically. axiom.ai's data is formatted in a 2D array, so we commonly use the horizontal method which adds a column to the end of the array. Output A preview of the appended data, so you can decide how you want to add it.",{"id":1571,"title":1572,"titles":1573,"content":1574,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fback","Back step",[],"Go back to the previous tab. Return to an earlier page during an automation run. Purpose of the Back step The Back step is a simple action that navigates back to the previous page, similar to clicking the 'Back' button in a browser. You can use this step to: Navigate to the previous page in your browser workflow This step requires no configuration.",{"id":1576,"title":1577,"titles":1578,"content":1579,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclear-cookies","Clear cookies step",[],"Clear cookies during a run. Use to log out or fix login issues caused by corrupted cookies. What to use the Clear cookies step for This step, 'Clear cookies,' is useful for switching between accounts in the same web application and requires no configuration. You can use this step to: Remove session dataWhen logging in with multiple accountsFor additional security How to configure the Clear cookies step No configuration is required. Add the step when needed.",{"id":1581,"title":1582,"titles":1583,"content":1584,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclear-data-from-a-google-sheet","Clear data from a Google Sheet step",[],"Clear data from your Google Sheet. Use to remove rows, columns, or entire ranges before writing new data. What to use the Clear data from a Google Sheet step for This step clears the contents of the selected cell range while preserving formatting in a Google sheet. Use this step to clear data stored in a Google Sheet rather than deleting rows.\nYou can use this step to: Clear values from a Google Sheet How to configure the Clear data from a Google Sheet step Spreadsheet Select a Google Sheet to clear, or paste its URL here . You can also use 'Insert Data' to pass spreadsheet URLs into this step. Sheet name Leave blank to use the first sheet or select a sheet name. First cell Enter a column and row number if you wish to start your clear operation from a particular cell in your Google Sheet. For example, 'B10' will\nmean your bot will start clear data from the second column on the 10th row. Last Cell Enter a column and row number combination if you wish to end the clear operation at a particular cell in your Google Sheet. For example, 'B100' will mean your bot will end clearing data at the 100th row in the second column.",{"id":1586,"title":1587,"titles":1588,"content":1589,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclick-element","Click element step",[],"Replicate page clicks on links or buttons with the Click element step. Point and click to select the action you want to automate. What to use the click element step for The \"Click element\" step automates clicks in web automation, essential for actions like liking content or submitting forms. Learn about optional clicks and using element text for button selection. You can use this step to: Click submit on a formClose a pop-up window by clicking 'X'Like an Instagram post - Click on a select list - Tick a boxSend an email - Click to generate reportsClick to discover even more uses for the Click element step. Configuration Select Click 'Select' to choose the button click you wish to automate. The display will transform into the single selector tool, then point and click. The single selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources like a Google Sheet Watch these guides to learn more about the selector tool. Left click | Right click Toggle off to perform a left click; toggle on to perform a right click. Optional click (Can be very handy) By default, if the selected element is missing, Axiom will throw an error and stop the run. However, in some cases, you may want to click on an element that is not always present. If you check this box, the error will be ignored and the run will complete.",{"id":1591,"title":1592,"titles":1593,"content":1594,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclick-multiple-elements","Click multiple elements step",[],"Replicate multiple clicks on links or buttons with the Click element step. Point and click to select each action to automate. Use our 'Click multiple elements' step to automate many button clicks on any webpage without code. What to use the Click multiple elements step for Instruct the bot to click multiple buttons, links, or other elements with a common structure, ideal for listing and feed pages. You can use this step to: Click buttons on listing pagesInteract with buttons in feeds How to configure the Click multiple elements step Select Click 'Select' to choose the button click you wish to automate. The display will transform into the Single selector tool, then point and click. Watch these guides to learn more about the selector tool. Left click | Right click Toggle off to perform a left click; toggle on to perform a right click. Maximum clicks The maximum number of clicks to perform.",{"id":1596,"title":1597,"titles":1598,"content":1599,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclick-social-media-buttons","Click social media buttons step",[],"Automate actions on social media such as like and follow. Set a value to ensure clicks do not unfollow or unlike. What to use the Click social media buttons step for Click on a social button such as like, follow, etc. but only if it has not already been clicked. Create web automations for any social media platform with this handy step and others. Why not try this Instagram template.\nYou can use this step to: Click like on Instagram- Heart tweets on Twitter- Thumbs up on Facebook How to configure the Click social media buttons step Select Click 'Select' to choose the button click you wish to automate. The display will transform into the Single selector tool, then point and click. The single selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources like a Google Sheet Watch these guides to learn more about the selector tool. Set value to check The bot will check these values. If one is present on the link or in the button code, it will not perform the click. We have set some default values to check for in the HTML. You may need to use the Chrome Inspector tool to work out new values to check for.",{"id":1601,"title":1602,"titles":1603,"content":1604,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclipboard","Get clipboard contents step",[],"Read the browser's clipboard during a bot run and use it in later steps — useful when a page copies its output to the clipboard instead of the page. What to use the Get clipboard contents step for Use this step to read whatever is currently on the browser's clipboard and make it available to the steps that follow. It's useful for pages that respond to a \"copy\" button by putting the result on the clipboard rather than rendering it into the page, so there's nothing to scrape from the DOM. Capture the clipboard value, then pass it into a later step — for example, write it to a 'Google Sheet', or use it to 'enter text' elsewhere on the page. How to configure the Get clipboard contents step This step takes no configuration. When it runs it reads the current clipboard contents and returns them as data you can reference in subsequent steps.",{"id":1606,"title":1607,"titles":1608,"content":1609,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fclose-tab","Close browser tab step",[],"Close tabs during runtime. Use to manage open pages and keep the automation focused on active tasks. What to use the Close browser tab step for This step closes a tab, necessary when new pages open during bot runs to return to the previous tab. The bot operates in only one tab at a time and cannot switch tabs automatically. Errors like 'click not found' occur if the bot is active in the wrong tab. Combine this step with the 'Switch tab' step for multi-tab automation. You can use this step to: Close new tabs that open in pop up windowsReturn to previous tab How to configure the Close browser tab step Select Tab Set the position of the tab to switch to. 1 chooses the tab on the farthest left, 2 the second left etc.",{"id":1611,"title":1612,"titles":1613,"content":1614,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fconditionall-jump-step","Conditionally jump to another step",[],"Jump to a different step based on logic set. Use strings, numbers, or JavaScript to define your argument. What to use the Conditionally Jump step for This logic step enables a bot to either jump to a new step or continue with its run based on the evaluation of a specific condition. For instance, it can be effectively paired with a Scraper step. In this scenario, once the Scraper extracts certain data, the logic step then assesses this data for a particular value. If the value is found, the bot is programmed to jump to a new step. If the value is not found the bot will continue. You can use this step to: Check for a value in Google sheet to bypass stepsCheck against a value on a webpage by scraping it firstConfirm a form or post has been submittedControl the bot flow depending on a value found in a Google Sheet When combining the Conditionally jump to another step step and the Loop through data step, we recommend only using this step to jump to a later step in the loop, or to jump out of the loop to a later step in your automation. We do not recommend using this step to jump to an earlier step in the loop and this can not be used to jump to a previous iteration within the loop - doing so may cause issues with the data within the loop step. How to configure the Conditionally jump Data to check Enter the data to check for values. Condition to check Check data for either a list of words, a number or if a javascript expression is true. Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row or a number. Select if the condition should pass when either any of the supplied words are present in the data, or all of them are. Or select the condition to apply when Numbers is selected. Check this to match only when the complete word appears in the data. Only the characters a-z A-Z 0-9 and _ are considered to be part of a word, all other characters are considered as being part of a word boundary. Jump to step Enter the number of the step to jump to if the value is found. Maximum cycles The number of times the step should jump. Reverse condition Jump if the specified words or number NOT found. Addional information Use the loop step to loop your steps.",{"id":1616,"title":1617,"titles":1618,"content":1619,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fcontinue-if-condition-met","Continue only if a condition is met step",[],"Control bot runs with logic. Decide to continue or end based on argument constructed. Use data passed by other steps. Build argument with strings, numbers, or JavaScript. What to use the Continue only if a condition is met step for This logic step checks a value and continues the bot run if true. For instance, it can verify if content is updated by searching for 'New.' Pair it with the 'scrape data' step to fetch the value. You can use this step to: Query if there's any data left in a Google Sheet, then stop bot run if emptyCheck against a value on a webpage by 'scraping' it firstConfirm a form or post has been submittedControl if a bot runs depending on a value found in a Google Sheet How to configure the Continue only if a condition is met step Data to check Select the variable containing the data you wish to check against. That variable could be from any step, for example, a webhook or scraper Condition to check Check data for either a list of words, a number or if a javascript expression is true. Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row. Leave blank to match anything. Or select the condition to apply when Numbers is selected. Check this to match only when the complete word appears in the data. Only the characters a-z A-Z 0-9 and _ are considered to be part of a word, all other characters are considered as being part of a word boundary. Fail if condition not met Tick this box to end the run with the 'Failed' status if the condition is not met. If this is left unchecked, the run will end in 'Success' instead. Reverse condition Continue if the condition is NOT met.",{"id":1621,"title":1622,"titles":1623,"content":1624,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fcount-rows","Count rows step",[],"Count number of rows in a Google Sheet. Returns a variable for use in steps like Read data from Google Sheet to control how many rows to loop through or how many steps to jump. What to use the Count rows step for Use this step to count the number of rows in the selected data. Useful if you want to get the number of rows to control the number of loops you do with a Jump step. Use with the 'Read data from a Google Sheet' step. You can use this step to: Control the number of times a Jump step jumps. Use this steps token in the 'Maximum cycles' field.Create a token for a row count to use in the 'Javascript step' How to configure the Count rows step Data Select the data to count.",{"id":1626,"title":1627,"titles":1628,"content":1629,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fcreate-a-new-google-sheet","Create a new Google Sheet step",[],"Create new Google Sheet on the fly during a bot run. Step returns the sheet value for use in other steps. What to use the Create a new Google Sheet step for Use this step to create new Google Sheets for your Axioms when automating the browser. If you need to write data to a Google Sheet use this step. Use this step to: Creating new Google Sheets for you web automations How to configure the Create a new Google Sheet step Sheet name Enter a name for the new Google Sheet.",{"id":1631,"title":1632,"titles":1633,"content":1634,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fcurrent-url","Get current bot URL step",[],"Fetch URL from the active tab during a bot run. Return it for use in your automation. What to use the Get current bot URL step for Use this step to Grab the URL that bot is currently on and store it as data for later use. This step is helpful because not all links can be scraped from the source. Using this step in combination with others like 'Click element', you can make a bot to click links and open pages, so you can grab the URL and write it to a 'Google Sheet.'\nYou can use this step to: Get the URL from current pageWhen a link cannot be scraped use a 'Click element' step then 'Get current bot URL' step How to configure the Get current bot URL step Get current bot URL No configuration is required. This Step will return a token containing the URL of the current page.",{"id":1636,"title":1637,"titles":1638,"content":1639,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fcustom-data","Enter custom data step",[],"Insert custom data returned for use in your automation. Used to store small amounts of data for use in your automations. What to use the Enter custom data step for The Enter custom data step is a simple field for storing small amounts of data that can be made accessible to other steps via axiom.ai's 'Insert Data' tokens feature found inside step fields. For example we use this step to store a list of CSS classes that we want to loop through in a Click element step. You can use this step to: Create a token with a number valueMake a token with a text valueStore data such as CSS classes How to configure the Enter custom data step Enter custom data Enter a list of items to store as data; each line will be stored as a new row. Output Preview of data",{"id":1641,"title":1642,"titles":1643,"content":1644,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdate-picker","Date picker step",[],"A step designed to automate date pickers, commonly found in web forms. Select day, month, and year. Purpose of the Date picker step The Date picker step is used to automate interactions with specific types of date pickers, such as the Trainline date picker shown above. This step works on date pickers that feature the current month and date, along with left and right buttons to change the month, and a calendar to select the day. You can use the Date picker step to: Automate entering a date when purchasing ticketsInput a date when generating a reportSubmit a date when filling out web forms How to Configure the Date picker step Select month Select the text of the month displayed on the date picker. Select month change button Choose the \"Previous\" or \"Next\" button, depending on whether you want to navigate to a future or past month. Change month to Enter the exact text of the month you want to change to. Note: The text must match exactly as it appears on the date picker for this to work. Change day of the month to Enter the day of the month you'd like to select. Keen to learn more? Learn how to automate the date pickerExplore how to automate date pickers without code",{"id":1646,"title":1647,"titles":1648,"content":1649,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdate-time","Date and time step",[],"Use this step to return a date and time value as a token in your web automation. What to use this step for Use this step to return a date and time value as a token in your web automation. There are various formats to select from to produce the correct values for your location. Users often insert the token provided by the Date and time step into the 'Enter text' in their web automation. So they can automate web actions like setting a date. You can use the date and time step to: Pass dates into file namesPopulate From and To dates in web formsAutomate report downloads when a date range is neededFiltering dates on listing pagesTagging scraped content by date, use the 'Append step.'\nIf we are missing a value or format, let us know we can add it. How to configure the Date and time step Select date Current - get the current date in your location. Custom - select from preset dates: Last day of previous monthsFirst day of this monthN* days in the pastN* days in the future Select format Select a date or time, even both. Then choose a format to suit your Zone. If using the date in a file path, use hyphens.",{"id":1651,"title":1652,"titles":1653,"content":1654,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdelete-files-from-google-drive","Delete from Google Drive step",[],"Delete a file or folder from your Google Drive. Use this step to clean up files while running bots in the cloud. What to use the Delete from Google Drive step for Use this step to delete a file or folder from your Google Drive. It works in Axiom Cloud, so you can manage Drive files as part of an automation without the desktop application — for example, removing a file once it has been processed, or clearing out a working folder between runs. We have separate steps to upload, download and read files on Google Drive. How to configure the Delete from Google Drive step Google Drive file or folder URL Enter the URL of the file or folder in Google Drive to delete. Click 'Insert data' if you wish to pass URLs from a data source like a Google Sheet into this step.",{"id":1656,"title":1657,"titles":1658,"content":1659,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdelete-rows-from-a-google-sheet","Delete rows from a Google Sheet step",[],"Delete rows from a Google Sheet. Use with Find rows in Google Sheet to locate and remove specific cells or rows. What to use the Delete rows from a Google Sheet step for This step does what it says on the step: it deletes rows from a Google Sheet. But why would you want to do this? We use it as part of a technique called batching. This involves looping through steps using a jump step. For example, we start by reading a single row from a Google Sheet; we execute automation using that row's data. Then, we delete the row before moving on to read a new row. To learn more about batching click here.\nWe also have templates you can try. How to configure the Delete rows from a Google Sheet step Spreadsheet Url Search in the box for a Google Sheet or just cut and paste a URL into the field. First row to delete Enter the number of the first row to delete. Last row to delete Enter the number of the last row to delete. Everything between the first and last rows will also be deleted. Sheet name Axiom fetches sheet names for you to select or type in a valid sheet name into the input field. If you liked this step you may also wish to checkout our read and write Google Sheet steps.",{"id":1661,"title":1662,"titles":1663,"content":1664,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdisplay-a-message","Display a message step",[],"Use Display message to open a dialog window in the browser. Pass data from other steps by inserting their tokens. Useful for debugging. What to use the Display a message step for The Display a message step is mainly utilised for debugging Axioms. It is similar to a 'Console Log' in programming, but is shown on the screen during runtime. This step is helpful in outputting data from previous steps to better comprehend the current situation. Additionally, it can be utilised to verify if any conditional logic is functioning as anticipated. For instance, when using the Conditional Jump Step, you can trigger a message when the conditions are either true or false. You can use this step to: Display data output by stepsCheck conditional logic is working as expectedFlag the step your automation is on Configuration Message Type in the message you would like to display. You can also display data from other steps by clicking 'Insert Data.' You can add multiple tokens.",{"id":1666,"title":1667,"titles":1668,"content":1669,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdownload-file-from-url","Download file from URL step",[],"Use this step to automatically download a file from a specified URL to your computer. What to use the Download file from URL step for Use this step to automatically download a file from a specified URL to your computer. You can use this in conjunction with other steps to create a web automation that retrieves URLs from various sources such as Google Sheet, and downloads the corresponding files. You can also download files locally from a webpage to make your web automation. You can use this step to download files from URLs: Kept in a SpreadsheetScraped from a websiteStored in a CSV file If you would like to know how to download files from a website, please follow this link for instructions. How to configure the Download file from URL step Enter URL Enter the URL of a file to download. You can also plugin data from other steps. Click 'Insert data' to choose the source of you URLs. Folder Set a folder to download into, copy and paste a path to the folder or use the 'select' button to find the folder. Click 'Insert data' if you wish to pass folder paths from a data source into this step. Filename Renaming files is simple. You can type a value or pass a token into the field. A Token could be data from a Google Sheet by clicking 'Insert data'.",{"id":1671,"title":1672,"titles":1673,"content":1674,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdownload-file-step","Download file step",[],"Download a file via the desktop app to the local drive where the app is installed. What to use the Download file step for Use the Download File step to download images from Instagram and even grab files from legacy systems with no API. This step is a ubiquitous step designed to work with file download links. If you would like to know how to download files from a website, please follow this link for instructions. Currently, the Upload and Download steps only work with the axiom.ai Desktop Application. However, you can install the app by clicking here.\nWe now have Google drive steps that allow you to upload and download files in the cloud. You can use this step to download files from: Amazon Seller Central.Social media platforms like Instagram or Youtube.Digital Asset management sites.Government websites.E-commerce stores. How to configure the download file step Select Select the file link. You do this with the selector tool, click 'Select'. The display will transform to the selector tool. Next, click on the link you wish to download your file from and confirm your choice. The single selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors.'Use element text' allows you to click buttons based on the button text i.e. 'Submit'.Pass CSS selectors in from data sources like a Google Sheet. Watch these guides to learn more about the selector tool. Folder Set a folder to download into, copy and paste a path to the folder or use the 'Click to select' button to find the folder. Click 'Insert data' if you wish to pass file path from a data source into this step. Filename Renaming files is simple. You can type a value or pass a token into the field. A Token could be data from a Google Sheet.",{"id":1676,"title":1677,"titles":1678,"content":1679,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdownload-files","Download files step",[],"Download files via the desktop app to the local drive where the app is installed. What to use the Download files step for Use this step to automate the download of multiple files from a webpage. This step is most useful when downloading files from listing pages, like the ones found on Government websites. Currently, the Upload and Download steps only works with the Axiom Desktop Application. However, you can install the app by clicking here.\nWe now have Google Drive steps that allow you to upload and download files in the cloud. You can use this step to download files from: Amazon Seller CentralSocial media platforms like Instagram or YoutubeDigital Asset management sitesGovernment websitesE-commerce storesLegal documentsProperty records If you would like to know how to download files from a website, please follow this link for instructions. How to configure the Download files step Select Select the files. You do this with the selector tool, click 'Select'. The display will transform to the selector tool. Next, click on the links you wish to download your files. The Single selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources like a Google Sheet Watch these guides to learn more about the selector tool. Folder Set a folder to download into, copy and paste a path to the folder or use the 'Click to select' button to find the folder. Click 'Insert data' if you wish to pass file paths from a data source into this step. Filename Renaming files is simple. You can type a value or pass a token into the field. A Token could be data from a Google Sheet by clicking 'Insert data'.",{"id":1681,"title":1682,"titles":1683,"content":1684,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fdownload-files-to-google-drive","Download a file to Google Drive step",[],"Download files from a web page directly to your Google Drive. Use this step to download files when running bots in the cloud. What to use the Download a file to Google Drive step for Use this step to directly download files to your Google Drive from any web app. This step works in Axiom Cloud. Previously, files had to be downloaded to the desktop application. If you would like to know how to download files from a website, please follow this link for instructions.\nYou can use this step to download files from: Amazon Seller CentralSocial media platforms like Instagram or YoutubeDigital Asset management sitesGovernment websitesE-commerce stores We have separate steps to upload and download files on the desktop. Note: the \"Download files to Google Drive\" step supports files up to 250MB. How to configure the Download a file to Google Drive step Select Click 'Select' to choose the file to download. The Single selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources like a Google Sheet Watch these guides to learn more about the selector tool. Google Drive folder URL Enter the URL of the folder in Google Drive to download to. Click 'Insert data' if you wish to pass file paths from a data source into this step. File name Enter a name for the file on Google Drive. Leave blank to keep the existing filename. File names can be passed from data sources like a Google Sheet using 'Insert Data'.",{"id":1686,"title":1687,"titles":1688,"content":1689,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fedit-row","Edit Row step",[],"This step combines Find row and Write to Google Sheet. Use to locate a row and overwrite its data. Purpose of the Edit Row step The Edit Row step is a combination of two steps: \"Find Row\" and \"Write to Google Sheet\". This combination allows you to locate a row based on a specific value and then overwrite its data. Both steps need to be configured correctly to function. You can use the Edit Row step to update spreadsheet data, such as: Adjusting stock levels in a spreadsheetUpdating cryptocurrency valuesModifying report data How to Configure the 'Find Row' Step Spreadsheet Select a Google Sheet to search, or paste its URL. Sheet Name Optionally, specify the name of the sheet to search. Values (comma-separated) Enter a list of values, separated by commas, or provide data containing values in separate rows. These values will be used to locate the specific row in the sheet. The remaining settings are optional and can be used as needed. Select Click 'Select' to choose the item you want to interact with. How to Configure the 'Write to Google Sheet' Step Spreadsheet Select a Google Sheet to search, or paste its URL. Sheet Name Optionally, specify the name of the sheet to write to. Data Select the data that you want to write to the sheet. Write Options If no value is set, the data will be written to column 'A' of the row found by the Find Row step. If you need to modify column, adjust the 'A' value as needed.",{"id":1691,"title":1692,"titles":1693,"content":1694,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fend-loop","End loop",[],"Learn how to use the End loop step in your Axiom What to use the End loop step for The \"End loop\" step allows you to prematurely end a loop that has been initiated with the \"Loop through data\" step. This allows you to end the loop and continue onto the next step within your automation. When combined with a control flow step, you can use logic to determine when to finish your loop, this can be useful for: Ending the loop when a condition is metEnding a loop when an issue occurs, using the Try\u002FCatch step. Things to note: This step requires no configuration.This step can only be used inside of a \"Loop through data\" step - placing it outside of this step will cause the step to be ignored.Using this step and then jumping back into the \"Loop through data\" step will cause the loop to restart from the first iteration, not where the \"End step\" was called.",{"id":1696,"title":1697,"titles":1698,"content":1699,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fend-run","End run",[],"Use this step to end a run. Stops all remaining steps in the automation. What to use the End run step for This step allows you to end your Axiom run without an error. You can use this in conjunction with conditional steps such as the If step to end your automation when a certain condition is met. You can use this step to: End run as part of a If conditionStop a run with Try catch The step requires no configuration. If you want to learn more, here are some web automation tips.",{"id":1701,"title":1702,"titles":1703,"content":1704,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fenter-text","Enter text step",[],"Use this step to enter text into text fields found in web forms. Pass data from other steps into the Enter text step to automate data entry. What to use the Enter text step for The 'Enter text' step enables the user to select an input element and pass data from another step, without writing any code. This step is useful for web automation tasks such as data entry and UI testing. You can use this step to: Enter data into any CRMInput date ranges to download reportsLogin to applicationsSend a DM on Instagram or any social media appCreate a mass mailer in Gmail or OutlookUploading posts to web apps To learn about data and looping, read this page. You may also want to look at this data entry template. Configure the Enter text step Select text field Click 'Select' to choose the text field that the Axiom should enter text into. The display will transform into the single selector tool, then point and click. The single selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources like a Google Sheet Watch these guides to learn more about the selector tool. If you do not select a field, the bot will type into whatever is selected by default, this works well in tandem with the Press key(s) step. Text Input the text to enter. Use 'Insert Data' to pass data from sources such as a Google Sheet or WebHook. Delay Adds a delay between each key press in milliseconds. Append to existing Toggle on to skip clearing the text before entering. The value will be appended to whatever is already in the box. Custom line break Record a sequence of characters to use instead of enter for line breaks. For example, record shift and enter for Instagram DMs. Optional text If checked & the selected field is not present on the page the automation will continue without an error. Learn more about automating data entry by clicking here.",{"id":1706,"title":1707,"titles":1708,"content":1709,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fexport-csv-file","Export to CSV step",[],"Export any data from Axiom in the form of a CSV. Use to download structured results for use outside the automation. What to use the Export to CSV step for This step exports data from any step in your Axiom into a CSV file on your local machine. A helpful step when scraping leads to upload into your CRM or when you need to merge a series of CSVs into a single file. Please note that the CSV will not download if triggered if you are running your automation in the Cloud. You can use this step to: Export scraped data into a CSVUse with 'Import CSV' step to merge CSVs into a single fileTurn a Google Sheet into a CSV How to configure the Export to CSV step DATA Select the data to convert into a CSV file by clicking 'Insert data' inside the step. Folder Set a folder to export the file to, copy and paste a path to the folder or use the 'Click to select' button to find the folder. Click 'Insert data' if you wish to pass file path from a data source into this step. File name Enter a name to save the file as. If the file already exists it will be renamed by the export process unless the overwrite option is used. You can also 'Insert data' and pass file name from a Google Sheet. Overwrite existing file Toggle on to overwrite existing file rather than renaming the new file.",{"id":1711,"title":1712,"titles":1713,"content":1714,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Ffind-row","Find Row step",[],"Purpose of the Find Row step The Find Row step allows you to locate a specific row in a Google Sheet by searching for a value. Once the row is found, the row number is returned as a token, which can be used as data in your automation. You can use the Find Row step to locate rows for tasks such as: Updating stock levelsEditing scraped dataGenerating reports How to Configure the Find Row step Spreadsheet Select a Google Sheet to search, or paste its URL. Sheet Name Optionally, specify the sheet name where you want to perform the search. Values (comma-separated) Enter a list of values, separated by commas, or provide data with one value per row. These values will be used to find the specific row in the sheet. The remaining settings are optional and should be used when necessary.",{"id":1716,"title":1717,"titles":1718,"content":1719,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fgenerate-random-password","Generate random password step",[],"Generate random password. Use in automations that require secure input like account creation or form filling. What to use the Generate random password step for Auto-generate a password. You can configure the types of characters that are included and the length of the password. This step can be used with the 'Enter text' step to input the passwords into a web form. You can use this step to: Test account login pagesCreate new user accounts How to configure the Generate random password Step Password length Add a numeric value to set the length of password. Include non-alphanumeric characters Tick the box to include non-alphanumeric (punctuation etc.) characters.",{"id":1721,"title":1722,"titles":1723,"content":1724,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fget-a-list-of-links-to-pages","Get a list of links from a page step",[],"Scrape links from a webpage. Return results via a token for use in your automation. What to use the Get a list of links to pages step for Use this step to scrape links from the page the bot is currently on. Then pass the links into a 'Get data from a webpage' step to scrape data. Alternatively, write the links to a  'Google sheet' and create a batch scraper for large-scale scraping. We call this design pattern 'Batch scraping' Learn more about 'batching here' or try this template. You can also find a 'Link scraper template here.' You can use this step to scrape: Amazon product page links, like Amazon Book pagesSocial media linksLinkedIn profile links from Sales Navigator- Links from any website How to configure the Get a list of links to pages step Select Click 'Select' to choose the links you wish to scrape. The display will transform into the selector tool, and it will guide you by showing you how to select links from the webpage. The Multi-selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources Watch these guides to learn more about the selector tool. Find pager (optional) Select the 'Next' button for the pager, if there is one. If the button features text such as 'Next,' why not try the 'Use element text' method? Click 'Custom' on the selector toolbar, then click 'Use element text'. Max results We set the max results to 20 to speed up the testing of your bots as you make them. It's best to do short runs while testing your bot. Wait time between scrolls (ms) Adjust the wait time between scrolls to increase or decrease the loading time of content. This feature is particularly useful when scrolling down listing pages with slow-loading content. However, insufficient waiting time could mean that content is not loaded. Therefore, experiment with caution. No. of retry attempts when results not found To speed up your runs, reduce the retry runs. But keep in mind content could be missed. Make sure to do some test runs. Minimum wait before scraping (ms) To speed up your runs, reduce your wait time. However, keep in mind that some content may not have finished loading yet, which is why we wait. Page number to start scraping on For paginated pages, you can specify a starting page. However, not all pages support this. Specify exact number of pixels to scroll Instead of auto-scrolling set a pixel height to scroll. Force a re-scrape after each page change Use if you are only getting the first page of results. Output A preview of the scraped data.",{"id":1726,"title":1727,"titles":1728,"content":1729,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fget-a-list-of-links-url","Get a list of links from a URL step",[],"Scrape links from a URL. Return results via a token for use in your automation. What to use the Get a list of links to pages step for Use this step to scrape links from listing-style pages. Then pass the links into a 'Get data from a webpage' step to scrape data. Alternatively, write the links to a  'Google sheet' and create a batch scraper for large-scale scraping. We call this design pattern 'Batch scraping' Learn more about 'batching here' or try this template. You can also find a 'Link scraper template here.'\nYou can use this step to scrape: Amazon product page links, like Amazon Book pagesSocial media linksLinkedIn profile links from Sales Navigator- Links from any website How to configure the Get a list of links to pages step URL Enter a URL or multiple URLs, each on their own line. You can also plugin data from other steps to provide URLs Select Click 'Select' to choose the links you wish to scrape. The display will transform into the selector tool, and it will guide you by showing you how to select links from the webpage. The Multi-selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources Watch these guides to learn more about the selector tool. Find pager (optional) Select the 'Next' button for the pager, if there is one. If the button features text such as 'Next,' why not try the 'Use element text' method? Click 'Custom' on the selector toolbar, then click 'Use element text'. Max results We set the max results to 20 to speed up the testing of your bots as you make them. It's best to do short runs while testing your bot. Wait time between scrolls (ms) Adjust the wait time between scrolls to increase or decrease the loading time of content. This feature is particularly useful when scrolling down listing pages with slow-loading content. However, insufficient waiting time could mean that content is not loaded. Therefore, experiment with caution. No. of retry attempts when results not found To speed up your runs, reduce the retry runs. But keep in mind content could be missed. Make sure to do some test runs. Minimum wait before scraping (ms) To speed up your runs, reduce your wait time. However, keep in mind that some content may not have finished loading yet, which is why we wait. Page number to start scraping on For paginated pages, you can specify a starting page. However, not all pages support this. Specify exact number of pixels to scroll Instead of auto-scrolling set a pixel height to scroll. Force a re-scrape after each page change Use if you are only getting the first page of results. Output A preview of the scraped data.",{"id":1731,"title":1732,"titles":1733,"content":1734,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fget-data-from-url","Get data from a URL",[],"Scrape data from a URL including images, HTML, and text. Point and click to select the data you wish to extract. What to use the Get data from a URL step for The 'Get data from a URL' step in axiom.ai is a versatile web scraping tool that can extract data from tables, pages, and listing pages on almost any website or web application. It supports pagination and infinite scroll. The tool includes a point-and-click selector for easy content selection without coding. It's suitable for scraping data for simple reports or extensive databases. If you are looking to create a large scale scraper we recommend a design pattern called 'batch scraping'. You will also find a batch scraping template here. If you just want to scrape links use this 'scraper'.\nYou can use this step to scrape: Amazon product page links, like Amazon Book pagesSocial media linksLinkedIn profile links from Sales Navigator- Links from any website How to configure the Get data from a URL step URL Enter a URL or multiple URLs, each on their own line. You can also plugin data from other steps to provide URLs Select Click 'Select' to choose the data you wish to scrape. The display will transform into the selector tool, and it will guide you by showing you how to select data from the webpage. The Multi-selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources Watch these guides to learn more about the selector tool. Find pager (optional) Select the 'Next' button for the pager, if there is one. If the button features text such as 'Next,' why not try the 'Use element text' method? Click 'Custom' on the selector toolbar, then click 'Use element text'. Max results We set the max results to 20 to speed up the testing of your bots as you make them. It's best to do short runs while testing your bot. Wait time between scrolls (ms) Adjust the wait time between scrolls to increase or decrease the loading time of content. This feature is particularly useful when scrolling down listing pages with slow-loading content. However, insufficient waiting time could mean that content is not loaded. Therefore, experiment with caution. No. of retry attempts when results not found To speed up your runs, reduce the retry runs. But keep in mind content could be missed. Make sure to do some test runs. Minimum wait before scraping (ms) To speed up your runs, reduce your wait time. However, keep in mind that some content may not have finished loading yet, which is why we wait. Page number to start scraping on For paginated pages, you can specify a starting page. However, not all pages support this. Specify exact number of pixels to scroll Instead of auto-scrolling set a pixel height to scroll. Force a re-scrape after each page change Use if you are only getting the first page of results. Output A preview of the scraped data.",{"id":1736,"title":1737,"titles":1738,"content":1739,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fget-data-from-website","Get data from a webpage",[],"Scrape data from a webpage including images, HTML, and text. Point and click to select the data you wish to extract. What to use the Get data from a bot's current page step for The 'Get data from a bot's current page' step in axiom.ai is a versatile web scraping tool that can extract data from tables, pages, and listing pages the bot is currently on. It supports pagination and infinite scroll. The tool includes a point-and-click selector for easy content selection without coding. It's suitable for scraping data for simple reports or extensive databases. If you are looking to create a large scale scraper we recommend a design pattern called 'batch scraping'.  You will also find a batch scraping template here. If you just want to scrape links use this 'scraper'.\nYou can use this step to scrape: Amazon product page links, like Amazon Book pagesSocial media linksLinkedIn profiles links from Sales Navigator- Links from any website How to configure the Get data from a bot's current page step Select Click 'Select' to choose the data you wish to scrape. The display will transform into the selector tool, and it will guide you by showing you how to select data from the webpage. The Multi-selector tool comes with several valuable features accessed by clicking custom: Ability to use custom CSS selectors'Use element text' allows you to click buttons based on the button text i.e. 'Submit'Pass CSS selectors in from data sources Watch these guides to learn more about the selector tool. Find pager (optional) Select the 'Next' button for the pager, if there is one. If the button features text such as 'Next,' why not try the 'Use element text' method? Click 'Custom' on the selector toolbar, then click 'Use element text'. Max results We set the max results to 1 to speed up the testing of your bots as you make them. It's best to do short runs while testing your bot. Wait time between scrolls (ms) Adjust the wait time between scrolls to increase or decrease the loading time of content. This feature is particularly useful when scrolling down listing pages with slow-loading content. However, insufficient waiting time could mean that content is not loaded. Therefore, experiment with caution. No. of retry attempts when results not found To speed up your runs, reduce the retry runs. But keep in mind content could be missed. Make sure to do some test runs. Minimum wait before scraping (ms) To speed up your runs, reduce your wait time. However, keep in mind that some content may not have finished loading yet, which is why we wait. Page number to start scraping on For paginated pages, you can specify a starting page. However, not all pages support this. Specify exact number of pixels to scroll Instead of auto-scrolling set a pixel height to scroll. Force a re-scrape after each page change Use if you are only getting the first page of results. Output A preview of the scraped data.",{"id":1741,"title":1742,"titles":1743,"content":1744,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fgo-to-page","Go to page",[],"Load a web page. Pass tokens into this step to retrieve URLs from data sources like spreadsheets. What to use the Go to page step The 'Go to page' step loads a web page for automating web actions or scraping data. You can use this step to: Load a page inside a nested Loop stepOpen a web page to scrape data How to configure Go to page Enter URL Enter a URL or click 'Insert data' to pass URLs from a data source.",{"id":1746,"title":1747,"titles":1748,"content":1749,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fif-condtion","If a condition is true, run steps",[],"Execute a set of steps depending on an If condition. Pass data into this step to use when constructing your argument. IF Conditions can use text, numbers, or custom JavaScript. What to use the If condition step for This logic step can execute a set of sub-steps depending on whether the condition returns true or false. For instance, you could use this step with the scraper step. If the scraper extracts some data, this step can check that data for a particular value. If the value is not found, the bot will skip the sub-steps contained within the condition. You can use this step to: Execute steps based on a value found on a webpage by scraping it firstEntering data into a form depending on a conditionTriggering another Axiom run, depending on a value found in a Google Sheet How to configure If condition step Data to check Select the data to check for values. Condition to check Check data for either a list of words, a number or if a javascript expression is true. Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row. Leave blank to match anything. Or select the condition to apply when Numbers is selected. Apply rule when match, Any word or All words or any condition when Numbers selected. Check - Match only the complete word if it appears in the data. Only the characters a-z A-Z 0-9 and _ are considered to be part of a word, all other characters are considered as being part of a word boundary. Reverse condition Tick the box, to invert the condition to execute and execute the sub-steps if the condition fails. Add step Add the sub-steps you wish to excute as part of the condition. Addional information You can nest this step in loops or other IF conditions.",{"id":1751,"title":1752,"titles":1753,"content":1754,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fif-else-condition","If Else condition step",[],"Execute a set of steps depending on an If Else condition. Pass data into this step to use when constructing your argument. IF Conditions can use text, numbers, or custom JavaScript. Purpose of the If Else condition step The If Else Condition step allows you to execute different sets of actions based on whether a specified condition evaluates to true or false. In the condition, you can 'Insert Data' to check values from Google Sheets or other steps like 'Get Data from Current Page'. You can compare strings, numeric values, or even create custom conditions using JavaScript. You can use this step to compare values and execute different actions, such as: Checking if scraped data matches a specific valueVerifying if the page URL contains 'login' and executing login stepsDetecting if a button is present and clicking it How to Configure the If Else condition Step Data to Check Select the data you want to evaluate. Condition to Check You can check the data for words, a number or test if a JavaScript expression evaluates to true. Enter a list of words or numbers separated by commas, or provide data containing a list of values, one per row. Leave the field blank to match any value. You can apply the rule to match Any Word or All Words. Or any condition when Numbers selected. Enable the option to Match complete word only. This ensures only alphanumeric characters (a-z, A-Z, 0-9, and _) are considered part of a word, while other characters are treated as word boundaries. Reverse Condition Check this box to invert the condition and execute sub-steps if the condition is false. Add Sub-Steps Insert the steps you want to execute when the condition is met. Else - Add Sub-Steps Insert the steps you want to execute when the condition is not met.",{"id":1756,"title":1757,"titles":1758,"content":1759,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fimport-csv-file","Import CSV File step",[],"Import data from a CSV. Pass to other steps via a token for use in your automation. What to use the Import CSV File step for This step imports data from a CSV into your Axiom. You can then use the data in other automation steps, such as web actions like 'Enter text' step. For example, import data from a CSV to upload via a web form. You can use this step to: Import data for data entryUpload multiple CSVs to merge into single CSV for export- Import CSV data to upload into a CRMImport data to filter and clean How to configure the Import CSV File Step Import CSV Select the CSV file to upload. Manually enter the file path or use 'Click to select.' You can also use 'Insert data' to pass a file name or path from another step as a variable. Combine a string and variable to create a file path if required. If you see corrupted characters, please ensure the file is encoded in UTF-8 format. Fist cell Use the first and last cell settings to specify the data range you wish to import. Will use A1 if no value provided. Last cell Will use ZZ if no value provided Output You will see a preview of the imported CSV data.",{"id":1761,"title":1762,"titles":1763,"content":1764,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps","Step index",[],"Every step available in axiom.ai's no-code browser automation builder, grouped by what it does. Every step you can use in the Builder, grouped by what it does. Jump to scrape, navigate, interact, read and write data, files, loop, control flow, debug, webhook and API, AI, manipulate data, email, or other. Scrape Pull data out of a webpage - tables, lists, product grids, links, or metadata. Navigate Move a bot between pages and tabs - go to a URL, open a new tab, switch tabs, or restart the browser. Interact Drive the page like a user would - click, type, press keys, hover, drag, upload files, and select from dropdowns. Read and write data Move data in and out of Google Sheets, CSV files, local files, and Google Drive. Files Download files from a page or URL, save screenshots, or save a page's HTML. Loop Repeat a set of steps for every row of data, or break out of a loop when a condition is met. Control flow Branch a bot based on data, jump to another step, try and catch errors, or end a run early. Debug Inspect what's happening mid-run - display messages, capture the current URL, or add context to errors. Webhook and API Trigger a bot from another app, send data out to any webhook URL, or hit an API directly from a run. AI Extract structured fields from unstructured text or generate new content with Claude, ChatGPT, or another LLM. Manipulate data Transform data between steps - split, merge, replace text, strip HTML, remove duplicates, or filter rows. Email Send an email to one or more recipients when a run finishes or hits a key step. Other Utility steps that don't fit elsewhere - wait, solve CAPTCHAs, generate passwords, get the current date, or run another bot. Can't find the step you're looking for? Drop us a comment - we'd love to hear from you.",{"id":1766,"title":865,"titles":1767,"content":1768,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fintegrate-ai",[],"Interact with LLMs to extract data, generate text or make decisions. Supports either ChatGPT, Claude and others, requires an API key. What to use the Integrate AI step for Add AI into your automation using this step to extract data, generate text, and make decisions as part of your workflow. You can connect to providers like ChatGPT, Claude, Gemini and Sonar using your own API keys, allowing you to handle unstructured data and add flexible, intelligent logic without writing code. You can use this step to: Scrape unstructured data from html with AIExtract details from LinkedIn profile dataCustomise DM messagesUse as part of a larger Axiom that scrapes and responds to commentsExtract data from an API If you have an idea for a different AI feature? let us know we can add it. How to configure the  Integrate AI step Function Select extract data or generate data to set the step AI function. LLM Select the model of LLM you wish to use. API key Enter your API key here. Prompt Enter your prompt this can be combined with data from other steps by clicking \"insert data\".",{"id":1770,"title":1771,"titles":1772,"content":1773,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Finteract-with-a-pages-interface","Interact step",[],"This step is now defunct. Replaced by the Loop step. What to use the Interact step This step is now defunct. Replaced by the Loop step. The 'Interact with a page's interface' step has sub-steps that automate web actions like clicking on elements or 'Entering text'. However, from Axiom 4.0, this step is no longer used, it is replaced by new methods for looping and new nesting features. Although this step will still function, all Axioms created with it will continue to work. You can use this step to combine steps: To automate 'data entry'To scrape multiple 'pages'Social media automation like this 'template'To automate any website actions such as clicks in ChromeTo automate file downloads. How to configure the Interact step Loop through data Repeat for each item in another step's data. Click 'Insert Data' and select the data you wish to loop through. Loop through all Toggle ON this to loop through all rows of data, this function can be disabled to use first row only. Add a sub step Add sub steps required to build your web automation.",{"id":1775,"title":1776,"titles":1777,"content":1778,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fjoin-different-data-sources","Join different data sources based on matching columns step",[],"Merge data from multiple sources into a single dataset by matching columns. Used to combine data from large, database-style sets. What to use the Join different data sources based on matching columns step for Use this to join data gathered from different sources together. A shared column is used to combine the two. For example, use this to join product info from different e-commerce sites or to merge a Google Sheet with a CSV. You can use this step to: Merge a CSV with a spreadsheet- Join data from separate ecommerce storeMerge scraped data sets How to configure the Join different data sources based on matching columns step Base data Enter the base data to join with another. Base data column Column of data to use as the basis of the join. For example, if you want to join based on company name, enter the column number or letter which contains the company name here. Join data Enter the data you want to join with the base data. Column Specify a particular column of the base data to always match against. Leave this blank to match with any column. Fuzzyness of the match Specify a particular column of the base data to always match against. Leave this blank to match with any column. Output A preview results returned by this step.",{"id":1780,"title":1781,"titles":1782,"content":1783,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fjump-step","Jump to another step",[],"Automations run steps in sequence. Use this step to break that sequence and jump to a step outside the order. What to use the Jump to another step step for The jump step is used to create simple loops or to skip steps that you do not want to execute. It works well in conjunction with the Conditional jump step.\nWe use the jump step as part of a technique called batching. This involves looping through steps using a jump step. For example, we start by reading a single row from a Google Sheet; we execute automation using that row's data. Then, we delete the row before moving on to read a new row. When combining the Jump to another step step and the Loop through data step, we recommend only using this step to jump to a later step in the loop, or to jump out of the loop to a later step in your automation. We do not recommend using this step to jump to an earlier step in the loop and this can not be used to jump to a previous iteration within the loop - doing so may cause issues with the data within the loop step. How to configure the Jump to another step Jump to step Enter the number of the step to jump to if the value is found. You can jump up or jump down. Maximum cycles The number of times the step should jump.",{"id":1785,"title":1786,"titles":1787,"content":1788,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Floop","Loop step",[],"Loop through sub-steps inside a loop. Set data to loop through, such as URLs in a Google Sheet. Pass data into sub-steps using tokens. What to use the Loop step for The Loop step iterates through any sub-steps contained within it. Loop step can also be nested. Use it to loop through data, such as rows from a Google Sheet. Click to follow a tutorial on looping. You can use this step to: Loop through data in a Google Sheet to create Social Posts- Enter data into Web forms- Create ChatGPT Web scrapers How to use the Loop step Loop through data Repeat for each item in another step's data. Click 'Insert Data' and select the data you wish to loop through. Loop through all Toggle ON this to loop through all rows of data, this function can be disabled to use first row only. Add step Add the sub-steps you wish to execute in the loop. Addional information You can nest loops up to four levels.",{"id":1790,"title":1791,"titles":1792,"content":1793,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fmouse-click-and-drag","Mouse click and drag",[],"Replicate dragging objects with a mouse by recording coordinates. Use to automate drag-and-drop actions on a page. What to use the Mouse click and drag step for Instruct the bot to move the mouse to the start coordinates then click and drag to the end coordinates. Use the step for web automation in particular dragging sliders into position. You can use this step to: Drag Sliders How to configure the Mouse click and drag step Keywords Enter a list of keywords to search on, each separated by a comma. Email address Enter the email address of the Gmail account to be searched, leave blank to use the default Gmail address. You must be logged into a Gmail account in order to search it, if you are not logged into the specified account then the default Gmail account will be searched instead. Folder Set a folder to download into (please note currently only one new folder can be created at a time) Max results Set a maximum number of emails to retrieve. Output A preview of the Gmail data gathered.",{"id":1795,"title":1796,"titles":1797,"content":1798,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fmove-a-google-sheet","Move a Google Sheet to a new folder in Google Drive",[],"Used to move a Google Sheet within your Google Drive account. Introduction The \"Move a Google Sheet to a new folder in Google Drive\" step can be used to move a Google Sheet within your Google Drive account. This can be used in combination with the Create a new Google Sheet step to create sheets and then move them based on actions within your automation. Configuration This step has two configuration options that are required. Sheet to move Select the spreadsheet or paste in a URL of the sheet that you wish the step to move. Folder URL Enter the URL of the destination folder for the spreadsheet. This must be created before the step is run and the folder must continue to exist for the duration of the automation runs.",{"id":1800,"title":1801,"titles":1802,"content":1803,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fopen-tab","Open a new tab step",[],"Open a new browser tab and navigate it to a URL during a bot run. What to use the Open a new tab step for Use this step to open a new tab in your browser and navigate it to a URL while an automation is running. It's useful when you need to start work on a different page without leaving the current one — for example, opening a record, a search result, or an external tool in a separate tab. The bot operates in one tab at a time, so pair this with the 'Switch tab' step to move the bot to the new tab, and the 'Close browser tab' step to tidy up when you're done. How to configure the Open a new tab step URL Enter the URL to open in the new tab. Click 'Insert data' if you want to pass URLs from a data source like a Google Sheet into this step.",{"id":1805,"title":1806,"titles":1807,"content":1808,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fpress-key","Press keys(s) step",[],"Record keyboard input. Include actions like pressing Return to submit a form or Tab to move between fields. Used to replay typed input as part of an automation. What to use the Press key(s) step for Press key(s) is one of the most useful steps in axiom.ai's stepbox. This feature lets you record keystrokes and replay them later, which is especially useful for web automation. To learn more about how useful the Press key(s) step is read our docs.\nYou can use this step to: Record Tabs to move between form elementsClick a button with a ReturnEnter a date into a form inputUp and down arrows can scroll pagesInteract with pop-ups This step works well in tandem with the Enter text step when automating data entry. Learn to observe where the cursor is loaded on a web page by default. If you're sending DMs on Instagram the cursor is loaded into the message box so you can enter text and record a \"Return\" keypress to send the message. How to configure the Press key(s) step Key Click record, then press the keys you want the bot to press. You can record a sequence of keys. Please note key combinations or special clicks can vary for Mac, Windows and Linux (The cloud runs on Linux). Data Input keystrokes directly from data sources such as WebHooks and Google Sheets. However, each keystroke must be separated by a delimiter, or Axiom will interpret them as a single keystroke. Delimiter Customise your delimiter, use this character to separate individual key presses. Make sure this is present between each desired key press in the given data, or this step will not work properly. Delay Set a delay between each key press (in milliseconds). If you want to learn more, here are some web automation tips.",{"id":1810,"title":1811,"titles":1812,"content":1813,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fread-data-from-a-google-sheet-step","Read data from a Google Sheet step",[],"Fetch data from a Google Sheet to use in your automation. Pass it into steps using tokens. What to use the Read data from a Google Sheet step for The read from a Google sheet step is most commonly used to loop through a list of URLs for scraping content and passing data to web forms. It's a common starting point for most bots made with Axiom. When used in combination with the 'Loop' step, data can be passed without code from the sheet to any website or web application. If you are looking to create a process with thousands of rows, we recommend a design pattern called 'batch scraping'. 😊 You will also find a batch template here. If you just want to scrape links, use this 'scraper'. You can use this step to: Combine with the 'Get data from a URL' step to loop through links and scrape pagesImport data to output as a CSVRead data to input in a form via the 'Interact' and ['Enter text'](\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fenter-text\u002F steps. If you have an Excel sheet, don't worry. They can be imported into Google Sheets and converted with a couple of clicks. How to configure the Read data from a Google Sheet step Spreadsheet Search in the box for a Google Sheet or just cut and paste a URL into the field. Sheet name Optionally specify a sheet name to read from. Sheets are different tabs visible at the bottom of your Google doc; enter the name that appears on the tab to specify the sheet. Leaving this blank will use the first sheet in the document. First cell Enter a column and row number if you wish to start your read operation from a particular cell in your Google Sheet. For example, 'B10' will\nmean your bot will start reading data from the second column on the 10th row. Last Cell Enter a column and row number combination if you wish to stop the read operation at a particular cell in your Google Sheet. For example, 'B100' will\nmean your bot will stop reading data at the 100th row in the second column. Continue when empty If this is turned on, the automation will proceed even if the input sheet is empty otherwise will throw an error.",{"id":1815,"title":1816,"titles":1817,"content":1818,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fread-data-from-airtable","Read data from Airtable",[],"Import data from Airtable into your automations. What to use the Read data from Airtable step for The read data from airtable step is used to loop through rows of data, such as lists of URLs, so you can scrape content or send data to web forms. It is often the starting point for many bots built with Axiom. When combined with the loop step, it allows you to pass data from a table to a website or web app without writing code. If you need to process thousands of rows, use a pattern called batch scraping. This helps you run tasks in smaller chunks. You can also use a batch template for this. If your goal is only to scrape links, use the scraper template instead. You can use this step to: Combine with the 'Get data from a URL' step to loop through links and scrape pagesImport data to output as a CSVRead data to input in a form via the 'Interact' and 'Enter text' steps. If you have an Excel sheet, use the excel step. How to configure the Read data from Airtable step Base ID Input your airtable base ID. Table ID or name Input the table ID or name.",{"id":1820,"title":1821,"titles":1822,"content":1823,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fread-data-from-excel","Read data from Excel sheet step",[],"What to use the Read data from an Excel sheet step for Use this step to read data from an Excel spreadsheet, useful for loading data into your automations. You can use this step for: Importing data to loop through.Reading in authentication credentials to log into websites.Reading in data to input into forms. How to configure the Read data from an Excel sheet step Spreadsheet Enter a URL for the sheet that you wish to read from, or enter the name in the search box. Sheet name The name of the sheet within the workspace to read data from. First cell The first column and row that you wish to start your read operation. This should be formatted as \"column:row\", for example, \"B10\". The column must be capitalised. Last cell The last column and row that you wish to finish your read operation on. This should be formatted as \"column:row\", for example, \"B10\". The column must be capitalised. Continue when empty If enabled, the automation will proceed even if the sheet is empty, otherwise, this will cause an error.",{"id":1825,"title":1826,"titles":1827,"content":1828,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fread-file-from-google-drive","Read file from Google Drive step",[],"Read file from Google Drive The \"Read file from Google Drive\" step can be used to read files from your local computer. This step allows for reading in of text files, such as: .txt, .html, .json, .csvPDFMicrosoft Word (.docx) This step will output the content of your file as a single piece of unformatted data. Configuration Learn how to configure the \"Read file from Google Drive\" step. Google Drive file URL The URL for the file from your Google Drive. This URL should include the ID of your file and often ends with \"\u002Fview\" followed by some parameters. Local folder If you are using axiom.ai locally using the desktop application, this option should be enabled to use a local folder as an intermediary step for the file download.",{"id":1830,"title":1831,"titles":1832,"content":1833,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fread-local-file","Read local file step",[],"Read local file The \"Read local file\" step can be used to read files from your local computer. This step allows for reading in of text files, such as: .txt, .html, .json, .csvPDFMicrosoft Word (.docx) Configuration Learn how to configure the \"Read local file\" step. File path The path to the local file on your computer, this should be the full file path to the file.",{"id":1835,"title":1836,"titles":1837,"content":1838,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Freceive-data-from-another-app","Receive data from another app",[],"Use the 'receive data from another app' step to trigger your automation via our API and webhooks, an integration or a third-party service such as Postman, Power Automate, Google Apps Scripts and much more. Please note: there may be design changes between the video and current design. Introduction The receive data from another app step allows you to receive data sent through our API, an integration, or a third-party service such as Postman, Power Automate, Google Apps Script and much more. This can trigger automations and allows data from your request to be used within your automation. You can use this step to: Trigger an automation via an API.Pass data to automations via a POST request. This feature is limited to certain subscription levels, see pricing for more details. Configuration The options below allow you to configure this step to your workflows specific needs. API credentials Click on an item to copy it to your clipboard. This provides essential information for your API requests. JSON payload example An example payload that the automation is expecting when triggered from an external service. To perform a POST request, you'll need information from the API credentials section. See our API documentation for more details on triggering your automation via webhook\u002FAPI. Test data To test your automation manually, or before your external trigger has been set up, use the test data option. Once enabled, this can be used to add mock data to your automation. [[\"A1\", \"B1\", \"C1\"], [\"A2\", \"B2\", \"C2\"]] When you click run on your automation, this data will be used in place of data received via the API. Further reading Documentation: API.Guides: Postman, Google Apps Script, Zapier, Power Automate - all guides",{"id":1840,"title":1841,"titles":1842,"content":1843,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fremove-duplicates","Remove duplicates step",[],"Check and remove duplicate data from sources such as Google Sheets or CSV files. Use to clean and prepare data before use. What to use the Remove duplicates step for Use this step to remove duplicates from the specified data. This can be limited to particular columns. This step can be used when importing data from Google Sheets or CSV files as well as scraping data. You can use this step to: Filter scraped data for duplicatesClean up data stored in CSV filesRemove duplicates from Google Sheet How to configure the Remove Duplicates step Data Select the data to deduplicate. Columns to check Specify a list of column numbers, each separated with a comma. Only these columns will be checked for duplicates. For example, entering 'A,B' here will check for duplicates in columns A and B only. Output The step outputs a preview of the deduplicated data.",{"id":1845,"title":1846,"titles":1847,"content":1848,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fremove-html-code","Remove HTML code step",[],"Strip HTML from a data source, including data returned by Get data steps. Use to clean text before using it in your automation. What to use the Remove HTML code step for Use this step to strip all the HTML from a set of data. Useful when 'Scraping HTML' and wish to extract data from the HTML. You can use this step to: Remove HTML from scraped contentStrip HTML from Google Sheet data How to configure the SRemove HTML code step Data Click 'Insert Data' to select the data you wish to remove HTML from.",{"id":1850,"title":1851,"titles":1852,"content":1853,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fremove-results-that-contain-certain-words","Remove results that contain certain words step",[],"Filter data by words they contain. Works with multiple sources including Google Sheets and Get data steps. What to use the Remove results that contain certain words step for Use this step to filter out rows from your data that contain particular words. Helpful if you wish to filter scraped data or import data from a Google sheet. You can use this step to: Remove rows from a Google SheetClean data from a CSV- Filter scraped data How to configure the Remove results that contain certain words step Data Select the data you wish to remove rows from. Words (comma separated) Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row. Any row that does not contain the given word will be removed. Word matching mode Select Any or All words. Match on word boundary Check this to match only when the complete word appears in the data. Only the characters a-z A-Z 0-9 and _ are considered to be part of a word, all other characters are considered as being part of a word boundary. Columns (optional) Specify a list of column numbers, each separated with a comma. Only rows that have matches within these columns will be removed. For example, entering '1,2' here will check in columns 1 and 2 only. Output A preview results returned by this step.",{"id":1855,"title":1856,"titles":1857,"content":1858,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fremove-results-which-do-not-contain-certain-words","Remove results which do not contain certain words step",[],"Filter data by words they do not contain. Works with multiple sources including Google Sheets and Get data steps. What to use the Remove results which do not contain certain words step for Use this step to filter out rows from your data that do not contain particular words. Helpful if you wish to filter scraped data or import data from a Google sheet. You can use this step to: Remove rows from a Google SheetClean data from a CSVFilter scraped data How to configure the Remove results which do not contain certain words step Data Select the data you wish to remove rows from. Words (comma separated) Enter either a list of any number of words to check for, separated by commas, or data containing a list of words, one in each row. Any row that does not contain the given word will be removed. Word matching mode Select Any or All words. Match on word boundary Check this to match only when the complete word appears in the data. Only the characters a-z A-Z 0-9 and _ are considered to be part of a word, all other characters are considered as being part of a word boundary. Columns (optional) Specify a list of column numbers, each separated with a comma. Only rows that have matches within these columns will be removed. For example, entering '1,2' here will check in columns 1 and 2 only. Output A preview results returned by this step.",{"id":1860,"title":1861,"titles":1862,"content":1863,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Freplace-text-step","Replace text step",[],"Replace text from any of your data sources by inserting their token in this step. Leave blank to delete, or add text to replace with. What to use the Replace text step for Use this step to replace a text in your data. For example, when generating reports, let's say you have scraped data that reads 'Red Shoes' and the value 40. You could change the text to 'Stock level of Red Shoes is.' Here's a helpful tip, if you just want to remove text, simply leave the 'Replace field' blank. You can use this step to: Overwrite scraped data- Manipulate data from a Google SheetChange data in a CSV How to configure the Replace text step Data to replace words Select the data you want to replace the text. It can be from any step in Axiom. For example, you can pass the output from 'Read from a Google Sheet' or 'Webhook' as a variable into this step. Text to replace Enter the text you wish to change. It has to be found in the variable passed via 'Data to replace words'. Replace with Enter what you want to replace the text with Output No action required it is a preivew of the data output by this step. So you will see your change here.",{"id":1865,"title":875,"titles":1866,"content":1867,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Frestart-browser",[],"Learn how to use the Restart browser step in your Axiom What to use the Restart browser step for Use this step to restart your browser on long or resource heavy automations to prevent the browser from running into memory issues. This behaves similar to pressing F5 to refresh the page during your run. We recommend only using this if you are encountering memory issues within the browser as improper use can lead to your automation taking longer, or causing additional errors in your run. There may be instances where page state, such as the page you are currently viewing in a list, may be stored in JavaScript - in these instances, this state will not be maintained. Page start stored as a URL component will be maintained, for example: \"example.com\u002Flist?page=2\". How to configure this step This step does not have any configuration options.",{"id":1869,"title":1870,"titles":1871,"content":1872,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Frollover-element","Rollover element step",[],"Replicate hovering over HTML elements. Use when you need to reveal hidden data before scraping. What to use the Rollover element step for Use this step to instruct your bot to hover or rollover an HTML element, for example, on a drop-down menu. This step is helpful for web automation when trying to automate data entry or reveal hidden content to scrape into a Google Sheet. The 'Select list' step can also be useful for automating drop-downs. You can use this step to: To reveal hidden content when scraping dataWhen you need to automate a dropdown menuTrigger a hover event How to configure the Rollover Element step Select Click 'Select' to choose the item you want to hover over.",{"id":1874,"title":1875,"titles":1876,"content":1877,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Frun-another-axiom","Run another Axiom step",[],"Run other Axioms from inside a single Axiom with this step. Use to chain automations or reuse existing bots. What to use the Run another Axiom step for This step loads one Axiom into another. You can use this step to create a 'Controller' Axiom that can run multiple sub Axioms. This is a great design pattern if you find yourself creating Axioms with more than 20 steps. However, it's important to note that embedded Axioms cannot share data directly only indirectly through a step like a Read data from a Google Sheet.\nYou can use this step to: Combine Axioms inside a 'Controller' AxiomBreakdown long Axioms into smaller Axioms Configuration Selected Axiom Select the Axiom to run from the drop-down list.",{"id":1879,"title":1880,"titles":1881,"content":1882,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsave-page-as-html","Save page HTML step",[],"Save snapshots of a page’s HTML to your Google Drive. Use to archive content or review page structure later. What to use the Save page HTML step for Use this step to Download the HTML of the current page the bot has open. This can be useful for automated testing of user interfaces. You can use this step to: Testing web pagesSave HTML of web page to desktop How to configure the Save page HTML step Folder Set a folder to save to (please note currently only one new folder can be created at a time) File name Enter a name to save the HTML page as. If a file with this name already exists it will be appended with a number e.g. 'page' would become 'page1.html', 'page2.html' and so on unless the overwrite existing file option is used. Only use 'Insert data' if you wish to pass a file name from another step like 'Read data from a Google Sheet'. Overwrite existing file Toggle to overwrite existing file.",{"id":1884,"title":1885,"titles":1886,"content":1887,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsave-screenshot-locally","Save screenshot locally step",[],"Save screenshots to your local Drive. Use to archive content or review page structure later. What to use the Save screenshot locally step for Use this step to save a webpage screenshot to your local machine. This is a handy step when making Axiom bots to test websites or do data entry, and you want visual confirmation of the result. If you're going to run your bot in the cloud, taking screenshots try this 'step.'\nYou can use this step to: Capture the results of UI testsConfirm a web form has been submittedGrab a screenshot of dataHelp monitor status of a web page How to configure the Save screenshot locally step Folder Set a folder to save to (please note currently only one new folder can be created at a time) File name Enter a name to save the screenshot as. If a file with this name already exists it will be appended with a number e.g. 'screenshot' would become 'screenshot1.jpeg', 'screenshot2.jpeg' and so on unless the overwrite existing file option is used. File type File type to save the screenshot as a JPEG or PNG.",{"id":1889,"title":1890,"titles":1891,"content":1892,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsave-screenshot-to-google-drive","Save screenshot to Google Drive step",[],"Save screenshots to your gogole Drive. Use to archive content or review page structure later. What to use the Save screenshot to Google Drive step for Use this step to save a screenshot of a webpage to a Google Drive folder. This is a handy step when making Axiom bots to test websites or for data entry, and you want visual confirmation of the result. If you're going to run your bot on the desktop, try this step.\nYou can use this step to: Capture the results of UI testsConfirm a web form has been submittedGrab a screenshot of dataHelp monitor status of a web pageTest checkout pages How to configure the Save screenshot to Google Drive step Google Drive folder URL Enter the URL of the folder in Google Drive to save the screenshot to. File name Enter a name to save the screenshot as. Leave blank to use the default Google Drive filename. Only use 'Insert data' if you wish to pass a file name from another step like 'Read data from a Google Sheet'. File type File type to save the screenshot as a JPEG or PNG.",{"id":1894,"title":1895,"titles":1896,"content":1897,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fscrape-metadata","Scrape metadata step",[],"Scrape metadata The \"Scrape metadata\" step can be used to extract metadata from a website. This metadata contains information about the page and is set by the author of the page. This includes social media tags, and general tags such as the page title, description or keywords. You can then use the data, or export this to an external service such as Google Sheets or Microsoft Excel. Step configuration Learn how to configure the step. Metadata Select the options that you want to extract from the dropdown. Selected options will be highlighted. Use the \"Select all\" or \"Deselect all\" to select or deselect whole categories.",{"id":1899,"title":1900,"titles":1901,"content":1902,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fselect-list","Select list step",[],"Automate interactions with select lists and dropdowns. Pass data into the step to dynamically select options. What to use the Select list step for This step automates the select list (or dropdown) web action. Select the dropdown you wish to automate and the value you wish to select. Use this step with other web action steps like 'Enter text' and 'Click element' to automate tasks like data entry. You can use this step to: Automate Select lists when entering data into webformsInteracting with web page to change search filtersConfiguring web based softwareData entry into a CRMWhen uploading files How to configure the Select list Step Select Click 'Select' to choose the select list, then use our 'Selector tool' to highlight the select list you wish to automate. Text Input the option the bot should select or click 'Insert data' to pass a value from another step, such as 'Read data from a Google Sheet.'",{"id":1904,"title":1905,"titles":1906,"content":1907,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fselect-random-rows","Select random rows step",[],"Randomly select a row from a Google Sheet. Use this step to pick a single entry for actions like testing, sampling, or random output. What to use the Select random rows step for Select random rows from a given data set, and create a new data set containing them. This could be used to vary content used in a direct message or to enter a random number. You can use this step to: Enter random numbers stored in a Google Sheet randomlyEnter text stored in a 'Google sheet' randomly How to configure the Select random rows step Rows Enter the number of rows to select from. Data Click 'Insert Data' to select the data to get rows from. Output A preview of random results returned by this step.",{"id":1909,"title":1910,"titles":1911,"content":1912,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsend-an-email","Send an email step",[],"Send an email. Use to share scraped data, distribute downloaded files, or confirm that an Axiom has completed. What to use the Send an email step for Use this step to send an email to one or more email addresses. Very useful for confirming an Axiom has run or sharing data scraped from a reporting page with colleagues. Please respect this step and not use it to spam others. You can use this step to: Send confirmations an Axiom has completedEmail colleagues data you have scrapedDistribute files you have downloaded How to configure the Send an email step Email addresses Enter a list of email addresses to send to, one email address per line. All emails are sent from a no-reply axiom.ai email address and you will not receive a reply to any message sent. Messages are rate limited to one per 30 seconds. Please do not use this step to send unsolicited email to third parties! Email subject Add your email subject line in this field. Email body Add your email body in this field. Use 'Insert Data' to pass data from any step into your email body.",{"id":1914,"title":1915,"titles":1916,"content":1917,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsolve-captcha","Solve Captcha step",[],"Use a third party to solve captchas encountered during your bot run. What to use the Solve Captcha step for Use the 2Captcha external service to solve a captcha when your web automation encounters it. You will need to sign up and get your own API key, you can also learn more about solving Captcha in our docs.\nYou can use this step to: Solve reCAPTCHA V2Solve reCAPTCHA V3Solve invisible reCAPTCHA How to configure the Solve Captcha step 2Captcha API key Enter your 2Captcha API key here to use this key as the default on all steps that require a 2Captcha API key. Your API key can be found on your 2Captcha account page. Override default API key Enter a 2Captcha API key here to be used only on this widget.",{"id":1919,"title":1920,"titles":1921,"content":1922,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsplit-a-name-into-columns","Split a name into columns step",[],"Extract first names, middle names, and surnames from scraped data. Pass in a token from your selected data source to use. What to use the Split a name into columns step for This step takes any full name and splits it into its parts - title, first name, last name, and additional name. Useful when scraping LinkedIn Sales Navigator, and you want to send personalised messages. See this LinkedIn template.\nYou can use this step to: To extract first names to create personalised messagesExtract names for CRM dataExtract first and last name from LinkedInExtract first names from data in a Google Sheet or CSV- Extract names to personalise email campaigns How to configure the Split a name into columns step Data Select the data containing the names. Column Enter the column in the data where the names can be found. You can enter either a number (starting from 1) or a capital letter (starting from A). Please ensure you only enter one value as only the first column provided will be used. Fields Select the fields to split the name into. Output The step outputs a preview of the split names.",{"id":1924,"title":1925,"titles":1926,"content":1927,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fsplit-by-character","Split by character step",[],"Extract data from large volumes of scraped text using the Split by character step. Use multiple steps if needed to remove text before the start and after the end. What to use the Split by character step for Use this step to extract specific data from a larger data block like HTML. For example, you may be trying to scrape an image URL, but it's not a standard link. Using the  'Get data from a URL', scrape the HTML, then use this step to extract the URL. You can also extract text with this step. Finally, you may need to use multiple Split steps, one to strip the data before and one step to strip the data after. You can use this step to: Extract links from scraped HTMLGet Image URLs from scraped HTMLGet specific text from scraped data How to configure the Split by character text step Character Enter a character or word to split the data on. Data Select the variable containing the data you wish to split. Using multiple split steps If you wish to extract data that has data in front and after, you will need to use multiple Split steps. You can easily share data between these steps by clicking 'Insert Data' and selecting the correct token.",{"id":1929,"title":1930,"titles":1931,"content":1932,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fswap-rows-and-columns","Swap rows and columns step",[],"What to use the Swap rows and columns step for Swap (transpose) the rows and columns in your data. Rows become columns and columns become rows. This can be useful when looking to manipulate data from a Google Sheet. You can use this step to: Transpose scraped data- Manipulate data from a Google SheetFlip data from a CSV How to configure the Swap rows and columns step Transposable data Select the step you whish to transpose data from.",{"id":1934,"title":1935,"titles":1936,"content":1937,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fswitch-browser-tab","Switch browser tab step",[],"Use this step to switch active browser tabs during a run. Helps control which page the automation interacts with. What to use the Switch browser tab step for This step is essential when Axiom opens a new browser tab or window during operation. Since the bot operates in only one tab at a time and cannot switch tabs automatically, you must manually direct it to the new tab. Failing to do so may result in errors like 'click element not found' because the bot remains active in the original tab. For multi-tab tasks, combine this step with the 'Close tab' step for seamless automation. You can use this step to: Switch form one tab to a pop up that is a new tabJump between new tabs opened during a bot run How to configure the Switch browser tab step Select Tab Set the position of the tab to switch to. 1 chooses the tab on the farthest left, 2 the second left etc. Additional information Some websites add '_blank' to their links, forcing a page to open a new tab, so keep an eye out for new tabs opening when testing your bot.",{"id":1939,"title":1940,"titles":1941,"content":1942,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Ftrigger-webhook","Trigger webhook step",[],"Post data to other web apps via webhook. What to Use the Trigger webhook step for The Trigger webhook step sends a POST request containing data from your automation to an endpoint. The data is output in a 2D array. You can use this step to: Send data to Zapier or Make.Post data to any web app or API. How to configure the Trigger webhook step Payload Enter the payload for the request as JSON. To send data from a step, click 'Insert Data', select the token of the step you wish to post data from, and the payload will be set up automatically. The data will be posted in a 2D array. You can also construct your own payload using JSON and a combination of the tokens available for selection. See the example below: {\n  \"request\": \"[google-sheet-data?all&1]\",\n  \"customer\": {\n    \"first_name\": \"[google-sheet-data?all&2]\",\n    \"last_name\": \"[google-sheet-data?all&3]\",\n    \"email\": \"[google-sheet-data?all&4]\",\n    \"phone\": \"[google-sheet-data?all&5]\",\n    \"company\": {\n      \"name\": \"[google-sheet-data?all&6]\",\n      \"job_title\": \"[google-sheet-data?all&7]\",\n      \"industry\": \"[google-sheet-data?all&8]\"\n    },\n  }\n} Endpoint Insert the URL of the 'Endpoint' you wish to post to. API Key You can access your API key here, which is only available for Pro subscribers and higher. Keen to Learn More? Post data from Zapier.Read about our API.",{"id":1944,"title":1945,"titles":1946,"content":1947,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Ftry-catch","Try catch",[],"Execute a different set of steps if an error is encountered during runtime. Use to handle errors. What to use the Try catch step for The Try catch step executes sub-steps within the 'Try' block. If these steps trigger an error, it is intercepted by the 'Catch' block. This block not only catches the error but also returns it as a token for debugging purposes. Additionally, it can execute a separate set of sub-steps tailored for error handling. You can use this step to: Debug Axiom runs How to configure the Try catch step Try Add the sub-steps you wish to execute as part of the 'Try' condition. Catch Add the sub-steps you wish to execute as part of the 'Catch' condition. Addional information You can nest this step in loops or the IF condition step.",{"id":1949,"title":1950,"titles":1951,"content":1952,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fupload-file","Upload a file step",[],"Using the desktop app, upload files locally from the computer where the app is installed. What to use the Upload a file step for Use the Upload File step to attach files to an email and even automate uploading images to social media. This step is a ubiquitous step designed to work with file upload fields. You can use this step to upload files to: CMS pagesSocial media platforms like TwitterDigital Asset management sitesGovernment websitesE-commerce storesNFT websites Currently, the Upload and Download steps only work in conjunction with the Axiom Desktop Application, you can install the app by clicking here. We also now have Google Drive steps that allow you to upload and download files in the cloud. Configuration How to configure the upload a file step First up, select the file input field you wish to upload your file to. You do this with the selector tool click 'File Input Field'. The display will transform into the selector tool. Next, click on the input you wish to upload to and confirm your choice. A custom selector option is available. We only recommend using this if the selector tool fails to find the element. Folder Set a folder you wish to upload from, copy and paste a path to the folder or use the 'Click to select' button to find the file.",{"id":1954,"title":1955,"titles":1956,"content":1957,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fupload-file-google-drive","Upload a file from Google Drive step",[],"Upload files directly to a folder in your Google Drive. What to use the Upload load a file to Google Drive step for Use this step to directly upload files from your Google Drive into any web app. This step works in Axiom Cloud. Previously, files had to be uploaded from the desktop application. You can use this step to upload files to: CMS pagesSocial media platforms like TwitterDigital Asset management sitesGovernment websitesE-commerce storesNFT websites We have separate steps to upload and download files on the desktop. Configuration File Input Field Click 'Select' to choose form element to upload the file to. Note that this is only guaranteed to work on standard HTML file upload fields - some customised file upload implementations may not function. Sorry! Google Drive file URL Enter the URL of the file in Google Drive to upload.",{"id":1959,"title":1960,"titles":1961,"content":1962,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fwait","Wait step",[],"Pause your automation to manually interact or wait for an event to conclude before continuing. What to use the wait step for This step allows you to add a wait to pause your bot run. You can do this to interact with the page and manually enter a password. But the most common use is to slow the bot by a fraction of a second to allow HTML elements, such as a button, to load. A top tip when testing your Axiom: if you notice actions out of sync or misfiring clicks, try adding a wait. It's most likely the click fired before the button loaded. You can use this step to: Pause your bot and interact with the page only on Desktop or VPSWait to allow data to loadSlow the bot to allow buttons and new elements to loadAllow long file uploads How to configure the Wait step Set a time in milliseconds One second it 1000 milliseconds, for waits between click elements try 500. If you want to learn more, here are some web automation tips.",{"id":1964,"title":1965,"titles":1966,"content":1967,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fwrite-data-to-a-google-sheet-step","Write data to a Google Sheet step",[],"Output data from your automation to a Google Sheet. What to use this step for Use this step to output data generated by your Axioms into a Google Sheet. You will also find steps to read and delete data from Google Sheets. You can use this step to: Write scraped data to a Google SheetTransfer data stored in CSVs into a Google SheetOutput repporting data into This step features in many of our bot templates. How to configure the Write data to a Google Sheet step Spreadsheet Search in the box for a Google Sheet or just cut and paste a URL into the field. Sheet name Axiom fetches sheet names for you to select or type in a valid sheet name into the input field. Data Select the data you wish to write to the Google Sheet Write options - Clear data before writing | Add to existing data Select 'Add to existing data' to write the new data to the sheet without first deleting existing data; select 'Clear data before writing' to delete all data before writing any new data. Starting cell To start writing to a particular cell in a Google Sheet, enter the column and row information, for example, 'D7'. You will also need to set 'Add to existing data' for this option to work. Write method If you want to write formulas to the Google Sheet set this option to 'User entered'.",{"id":1969,"title":1970,"titles":1971,"content":1972,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fwrite-data-to-airtable","Write data to Airtable",[],"Export data to Airtable from your automations. What to use the Write data to Airtable step for Write data to Airtable from your Axiom steps to store, organise, and use your automation results in a structured table. You can use this step to: Export scraped data into AirtableSend form submissions directly to AirtableStore automation results in Airtable for later use How to configure the Write data to Airtable step Base ID Input your airtable base ID. Table ID or name Input the table ID or name. Data Select the data to write.",{"id":1974,"title":1975,"titles":1976,"content":1977,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fwrite-data-to-an-excel-sheet","Write data to a Excel sheet step",[],"What to use the Write data to an Excel sheet step for Use this step to output data generated by your automations into an Excel sheet. You can use this step to: Write scraped data to an Excel sheet.Transfer data stored in CSVs into an Excel sheet.Output reporting data into an Excel sheet. How to configure this step Spreadsheet Enter a URL for the sheet that you wish to write to, or enter the name in the search box. Sheet name The name of the sheet within the workspace to write data to. Data The data token that contains the data that you wish to write to the Excel sheet. Write options Add to existing data: write data to the next available row within your sheet. Clear data before writing: clear the spreadsheet, and then write the data into the newly cleared spreadsheet. Starting cell The cell that you wish to start writing on. Note: failure to change this will cause the cell to be re-written during subsequent runs. Write method To write formulas, set this option to \"User entered\".",{"id":1979,"title":1980,"titles":1981,"content":1982,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Freference\u002Fsteps\u002Fwrite-javascript","Write javascript step",[],"Use JavaScript and Puppeteer in your no-code automation to extend functionality. Puppeteer library is already loaded, no need to include it. What to use the Write javascript step for Are you a coder? Write custom javascript for any operation inside your Axiom, from posting to an API to formatting data from steps. You can also use data from other steps as variables in your custom JS. Please note Axiom data model is a 2D array, so when returning data as a token, remember to return an array (or it will not work). You can return values as an array of arrays from this step - they will be appended to the current row. To learn more about what you can do, click here. Are you using this step to create a required feature? Please do let us know we may create a new step for you. You can use this step to: Create custom logicFormat data from other stepsUse Puppeteer's APIUse the node filesystem APIClick buttonsScrape contentRun JS in the browser or the App Some useful JS snippets. How to configure the Write javascript step Script Write your JS into our JS editor field. If tokens are available from other steps, you will see an 'Insert Data' button. Data is only available for steps added before your Javascript step. Run in app Toggle on, then Check to run the javascript in the context of the Axiom app, rather than in the browser window. This allows you to javascript APIs available in the axiom desktop app - such as Puppeteer, FS, and Chat GPT - which are not available in the browser. It is also a better method of sending API requests manually, because sending such requests from the browser often cause CORS errors.",{"id":1984,"title":1985,"titles":1986,"content":1987,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-10-0","New Make integration, better loops, smarter scraping, and fixes",[],"New features Integromat \u002F Make app integration added. Look out for the axiom app appearing on their platform soon!New “unconditional jump” step - allows you to create more complex loops without having to provide a condition that always passesAdded a visual indication when data has been selected in scrapers and other interact stepsImprovements to step renamingWhen your login expires, you can now re-enter your details right there rather than being sent back to the main login pageVisual indication of result grouping added, extended scraper tool tutorial to encompass itStep number now available in error messages to help with debuggingAdded the run time for each bot run to the Reports page Bug fixes Google Sheet previews no longer default to a maximum of 52 columnsImproved template setup flow by adding a confirmation when the setup is completeScraper now better supports pages which load content in via AJAXFixes to scrolling behaviour during scraping that should work better on some sites, such like LinkedinFixed several issues with writing to Google Sheets when there were a very large (1000+) number of columnsSelect list behaviour is now smarter and is able to find elements in a larger variety of cases",{"id":1989,"title":1990,"titles":1991,"content":1992,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-11-0","Dashboard redesign, better conditionals, stop remote bots, and more",[],"New features All remote running bots (scheduled or via Zapier, API etc.) now show up as running in the main axiom.ai dashboard and can be stopped from there.Conditional steps now have a “not” toggle, allowing jumping or continuing on error when a condition does not match.New, cleaner dashboard design with integrated documentation.“Continue on error” now prevents sub-steps within loops from being skipped when there’s an error.Speed improvements on select list and when clicking by text.Suggest a template banner and link added to step finder. Bug fixes Fixes to data replacement within javascript widgets for some data types.Alerts now always automatically confirm, and correctly confirm in newly open tabs.Improvements to preview result display.Duplicate axioms now automatically renamed.Download link to desktop app now available under run button.",{"id":1994,"title":1995,"titles":1996,"content":1997,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-12-0","Solve captchas, press keys smarter, fix iframe hangs, and more",[],"New features Fixes to issues that caused pages to hang when certain types of iframe were presentIntegrated CAPTCHA solve step using a third party serviceAdded new extension open \u002F close togglePress Key(s) step now can be set to automatically delay between key pressesUpdated design for error reporting and displayed messages Bug fixes Faster and less error-prone algorithm when writing huge volumes of data to Google SheetsAdded all missing Puppeteer page functions to code box, including page.screenshotFixes to click events on some sitesLocal storage loading now optional",{"id":1999,"title":2000,"titles":2001,"content":2002,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-13-0","Optional steps, screenshot tool, scraper upgrades",[],"Changes to Steps Optional click We have added the ability to set clicks as optional. Instead of throwing an error, axiom will click the element if present, and continue if not. Improved 'Split Name' step Improved support for foreign and unicode characters in the split name step. Improved CAPTCHA step Improved the CAPTCHA solver consistency and the number of CAPTCHAs supported. New step: 'Save a Screenshot' We have added a new step to save a screenshot of the current page. Scheduling Users can now schedule Axioms on the Desktop Runner application instead of on the Cloud Runner. Chrome Extension UI Axiom builder can now be minimised and docked to the side of the browser. Web scraper We've made numerous scraper improvements to increase the number of pages we support and to improve general consistency and speed. Most notably, Axiom will no longer scroll all the way to the bottom of the page before scraping, which allows us to scrape all data from pages that unload content when the screen\nscrolls below a certain point. Successfully scraped data is now also highlighted orange, so you can see what's being grabbed as you go. Minor bug fixes Remove words step now correctly removes no results when no words are given, instead of removing allImproved error messaging when attempting to access bad URLsFixed issues where the UI would get stuck if the network connection to the backend was lost during savingAdded rename operation to the javascript API",{"id":2004,"title":2005,"titles":2006,"content":2007,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-14-0","Selector overhaul, drag to reorder steps, new templates, and more",[],"New custom selector interface This one has been in the works for quite some time, but we're pleased to anounce the new custom selector interface is here. Let us know if you have any feedback! The new interface hugely improves the experience of adding and editing custom selectors, allowing the following features: Custom selectors can be set per column in scrapesEasily mix custom selectors with ones that have been automatically selectedSet selectors from previous data without having to manually edit JSONSee live previews of your custom selectorsSelect by textGet helpful suggestions for refining a selector which can help with automation accuracy To learn more about the new custom selector tool click here. Select, copy and move steps This feature has been in demand for a while, and we're pleased to announce it has now been released in axiom 3.14. By clicking on the step number of a step, or selecting \"Select\" from the step menu, you can now select one or more steps. Once selected, these can either be copied or moved to a new place, making fixing your bots much easier! Expanded file download system For new bots, a new file download system has been created that prefers direct downloads from the Axiom application directly. This should significantly improve speed and consistency for many use cases, and the system still falls back to the previous browser-based method when the file cannot be located in this way. Additionally we have provided a proxy to force downloads that are otherwise not possible to determine automatically. Old bots will still use the previous method, so anything working should remain as it was. Overhauled template system We're delighted to announce that we have replaced our recipe system, which was getting a little long in the tooth. We have now added a set of fresh new templates with much improved user experience and design, and we hope to continue adding more in the upcoming releases. Expanded iframe support Iframe support in Axiom was limited and had some issues. These issues have now been fixed; all interact steps should now be compatible with iframes. Error messages now point to the step that caused the error In long or complex bots, it can be difficult to work out where an error is being generated from. To help with this, whenever a runtime error is generated we now highlight the step that caused the error in red, and additionally scroll the builder down to focus on it. UI design cleanup We've been working to improve the design language across the board in the axiom builder, with our focus being on consistency. We hope you like it! This general work is ongoing and will continue over the next few releases. Dropdowns, tables and buttons were all covered in this release. Minor fixes Improved select list accuracy when whitespace was present in the option textFixes to infinite hanging issues in the scraper on one websiteRemoved desktop only warning for Captcha; you can now use it in the cloud without any issuesSimplified handling of unicode charactersRemoved misleading output warning from gmail steps",{"id":2009,"title":2010,"titles":2011,"content":2012,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-15-0","Custom scraper settings, new templates, and payment upgrade",[],"Expanded parameters for the scraper We have exposed several new parameters in the scraper which were previously being automagically managed. This was a nice idea in theory, but the reality is that the world of websites is too varied and contradictory for a single solution to ever be optimal. This resulted in Axiom often running slower than it needed to in order to accommodate relatively rare website features, or in order to maximise its reliability in all cases. The new scraper parameters, in addition to the existing options, allow you to control the scroll speed and behaviour, and gives you more control over axiom's way of checking for new results. Playing with these new options will allow you to get much better performance for your specific use case. Existing scrapers should not be affected. Revamped payment system We have migrated to a fully Stripe-hosted payment system, which should be much more reliable. It also gives us the option to support a broader range of payment systems, including alternate payment methods such as Apple pay, Google pay or Paypal. In addition, customers now have access to a customer portal, available from the \"Account\" page, which lets you view invoices and change your payment card details without having to contact support. New templates to teach common design patterns As part of an ongoing effort to make learning axiom easier, and to make sure new users understand the best practices for building automations, we have released a number of new templates focused on teaching fundamental design patterns for building in axiom. The new templates are general and can be used for a wide variety of automations. Further work is being done to more intelligently suggest these design patterns when they are applicable. Stay tuned! See the templates on our website here. New documentation on javascript snippets We have added a number of new javascript snippets to the documentation. These are frequently useful in building automations; hopefully you find them so! The new page can be found here. Zapier integration within axiom.ai We have implemented Zapier's new embed feature to allow you to access your axiom.ai zaps from within the axiom.ai application. Minor fixes Validation messages no longer thrown when steps have been disabled.Users now cannot get stuck if their session is expired immediately after registration.Improvements to download error handling.Implemented Net Promoter Score survey to take user feedback in-app.Improved error message when a bot hits its single run limit.Significantly improved speed when an axiom.ai is initially saved.Added more information about steps that require data to be generated in order to work.",{"id":2014,"title":2015,"titles":2016,"content":2017,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-16-0","Upload to drive, undo mistakes, upgrade steps, and more",[],"We're excited to present axiom version 3.16. This is a bumper release containing a huge number of improvements, and we've additionally been working on updates to our debugger and onboarding which we're excited to bring to you soon. Read on to find out what's new in 3.16. Google Drive integration for file operations in the cloud Previously, file uploads and downloads were only possible using the desktop application. New in this release is an integration with Google Drive that allows you to upload files in our cloud runner. You can now upload files directly from Google Drive to a website, and download files from a website directly to Google Drive, all without needing the desktop application. Your remote drive folder acts as a 1-1 replacement for your own local filesystem. This feature allows file operations to be directly integrated with tools like Zapier and with our cloud scheduler. Have fun! Undo \u002F redo Undo and Redo is now available. Anything can be un\u002Fre-done in the builder, from text entry to adding new steps, up to a maximum of 50 interactions. Both buttons and handy keyboard shortcuts (ctrl+z and ctrl+y) are available. Javascript evaluation in conditional steps Now, in addition to checking whether particular data is present or not, you can write a javascript expression in order to determine whether to trigger a conditional step. This feature is available for both \"Continue only if a condtion is met\" and \"Conditional jump\" steps and will allow you to more precisely control flow within your automations. New data variable options Data variables can now be entered into the First Cell and Last Cell parameters of all Google Sheet widgets, allowing you to dynamically specify these values. In addition, the \"Replace text\" step now allows data variables to be used for both of its parameters, making it more flexible and useful. Improvements to date step The existing \"Current Date and Time\" step has been overhauled, allowing you to specify custom dates - previously, javascript had to be used for this. In addition to using the current date and time, you can also generate a date for either the last day of the previous month, first day of the month, or a number of days in the past of future. In addition, formatting options have been expanded for times, primarily to make them more compatible with file names. Upgrade your axiom steps We often release updated versions of steps in our releases. By default, your existing axioms keep you on the previous version of a step to maintain backwards compatibility, and in order to upgrade and take advantage of new features you were required to delete and re-add the step - rather a pain. Now we've provided a button which automatically upgrades your old step to the new format, and automatically remaps your existing data, which should make taking advantage of new features in your older automations much more convenient. Edit token selections Now you can click on a token in order to edit your selection, rather than having to remove and re-add the token. Handy! Delete multiple steps at once The move and copy selection steps have been updated to include a \"Delete all\" function, so now you can clear out multiple steps with a few clicks. New templates Several more templates have been added to get you started quicker with your automations: How to automate downloading filesHow to automate taking screenshotsHow to automate Apollo.io listsHow to automate data from LinkedIn to ClickUpHow to scrape Album data from Spotify New API endpoint to retrieve google sheet data We've added a new API endpoint that lets you see the current running status of a bot and automatically extracts any google sheet data that was written, returning it back to you. This should come in handy for those who want to integrate axiom into other automation systems and would prefer not to manually check google sheets. ... and many other improvements Extra caching has been added to axiom which will significantly improve performance over a sessionTrial time is no longer counted towards your monthly total after you subscribeSubscriptions now roll over at the date you subscribed rather than the beginning of the monthMore error message improvements to the \"Press Key(s)\" and \"Webhook\" stepsScheduler now notifies you by email when your runtime has run outHTML scraper now can return outer HTML if inner HTML returns no resultsInteraction points are now more clear when in template setup modeNew subscriber email updated with some tips and tricksThese release notes now appear in the Chrome extension ;)You can now delete your account from within axiomIt's now possible to retrieve your API key without regenerating itMultiple updates to the documentationIn fields where commas are inappropriate, like in filenames, the data variable system will no longer place commas when appending multiple valuesThe Test Data parameter in the \"Receive data from another app\" step now consistently generates a previewImprovements to batching and retrying code, increasing the reliability of axioms that handle large amounts of dataFixes and improvements to the Webhook step in handling JSON and returning useful error messagesCaptcha solver now works in iframesStopped axiom cloud from hanging when it's sent axioms with hundreds of stepsFixed issues with custom token replacement inside sub-axioms",{"id":2019,"title":2020,"titles":2021,"content":2022,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-17-0","Better notifications, custom errors, iframe tools, and more",[],"Iframe support is back Those with good memories may recall that this feature was added a while ago, but then had to be rolled back as it caused unintended problems. Now it has returned! This time, you will need to turn on iframe support from the settings section of your axiom.ai; each axiom.ai can have iframe support on or off as required. The default is for iframe support to be turned off. Once iframe support is turned on, axiom.ai will be able to interact with most elements within iframes, and scrape data in them too. As a nice bonus, automation performance on sites that make heavy use of iframes (usually for things like ads or tracking) will now be much better out of the box. Improved notifications We have enanced the notification system to be more flexible and useful, particularly for those who are using axiom.ai as part of a larger automation stack. Now you can: Turn on notifications for success, failure or both.Specify an email address to send notifications to (previously, these always went to the email associated with your account).Send a webhook as a success or failure notification. Custom error logging A new step has been added, \"Add error metadata\", which lets you augment error messages with custom data. This should be help bots that run on schedules or remotely to more accurately debug issues, or to simply give better information on what failed and why. This feature works well in conjunction with the notification enhancements. Customised line breaks in the Enter Text step Many modern messaging apps, such as Instagram, use the \"Enter\" key as a way of sending a message rather than entering a line break. This means it is quite awkward to construct a single message with many paragraphs using axiom.ai. Now we've added a custom line break feature to help with this. When turned on, it will let you record a custom keypress value to use instead of the enter key when a new line is encountered in your input. Better tab handling Two features related to handling tabs have been introduced in 3.17. Firstly, the goto step now has a checkbox that allows you to specify that the page should be opened in a new tab. The change means axiom.ai will automatically switch the context to the new tab when you do this. Secondly, a new step has been added that allows tabs to be closed. Context in that case switches to the last open tab. Download page HTML step A new step has been added which allows you to download the entire HTML of a page and save it locally. The page is downloaded after rendering is complete, which means that all javascript has run. Minor fixes Enter text steps now do not click into the box if a passed token value is empty.UI tweaked on conditional logic steps to clarify what the default state does.Fixes to cases where automations would get stuck \"In Progress\" when stopped.After a certain number of steps have passed, axiom.ai will now restart chrome, to try and stop websites that have memory leaks from breaking long automations.Custom selectors containing double quotation marks no longer fail.New video guides added for steps.New retry logic added for external requests to reduce the chance that temporary network problems or outages will stop your automation from completing.",{"id":2024,"title":2025,"titles":2026,"content":2027,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-18-0","Structured scraping with chatgpt, new schedule view, filters, and fixes",[],"Extract data with ChatGPT A new step has been added that allows you to use ChatGPT to get structured data from raw text. Think extracting prices, email addresses, phone, numbers, names etc. from any kind of unstructured data - a blog post, product page, document etc. This is something that is very hard to do with traditional browser automation technology. We're excited to have a path to overcoming this limitation! All you need is a ChatGPT API key, which can be grabbed for free from OpenAI. This is a beta feature, so it currently has some limitations (for example, it will not work when using the cloud scheduler, only the local scheduler). If you have any feedback, please let us know! This is the first step in a wider roadmap for ChatGPT integration in Axiom; a potential game-changer for browser automation. For more info, check out this blog post:  AI Automation - building bots with ChatGPT. More to come in upcoming releases, stay tuned... New Schedule page For subscribers at the pro tier or above who can schedule axiom runs, there's now a new Schedules page. Here you can see a timeline of your upcoming schedules and when they last ran, with a link to edit the axiom to which the schedule is attached. In addition, if you are running local schedules, you can now turn these off on the current computer. This is very useful when you are signed into Axiom on multiple PCs and have local schedules; switching local schedules off on all except 1 PC will allow only that PC to run your axioms, preventing duplication. Report filtering The \"Reporting\" section has been overhauled to include new filters. Now you can search for axiom runs by name, by status, and also select a data to filter by. The main goal here is to help those of you who do a lot of remote triggering or scheduling find and debug failed runs. This is part of our roadmap on making debugging easier and more convient - more to come. \"Continue if empty\" on Google Sheets With automations that read from Google Sheets, we often need to check if the sheet is empty before continuing. As this is a common operation, a checkbox has been added to the \"Read Google Sheet\" step. If the sheet contains no data and this box is ticked, the automation will end immediately. Go back when automating Sometimes it's useful to go back to the previous page during an automation run. This was handled with a javascript snippet before, but we've now added a step to make this more convenient. Minor fixes Updated the icon design across the extensionFixed a rare hanging issue when a data variable contained double quotation marksBetter file name validationYou can no longer save an automation with no nameImport template link is now directly accessible from the start screen on the builderPeople who used a different email to subscribe than they did to sign up can now see both emails on the account page. It is also auto-filled when accessing the customer portal.Only one run viewer can now be open at a time when running cloud automations; this should fix a number of issues with run viewer connections being interruptedThe \"multiple click\" step now has a \"Maximum clicks\" settingOptional click will now ignore the error thrown when the selector happens to find an unclickable elementFix for hanging issue on empty code stepsFix to result grouping in scraping that would sometimes cause results to be associated with irrelevant dataNew Helium10 template See here",{"id":2029,"title":2030,"titles":2031,"content":2032,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-19-0","New debugger, generate text with chatgpt, save to drive, and more",[],"Debugger improvements We've added a new sidebar to allow you to view and filter errors more easily. You can also now view multiple warnings or errors simultaneously, and disable or re-enable \"continue on error\" without having to go via the settings page. We plan to expand this feature in the coming months with breakpoints, inline data viewing and more - stay tuned! ChatGPT text generation A new step has been added which allows you to generate text using ChatGPT. This uses the ChatGPT API so will be much faster than the equivalent step of visiting the ChatGPT website and entering the text manually. Give it a try! This step requires an OpenAI API key to use, and will not currently run on a schedule in cloud. Minimum interval lowered to one minute for local scheduling Quite a few people have asked us in the past how they can trigger the desktop application from Zapier. While this isn't directly possible, it is possible to have Zapier write to a google sheet, and then process that sheet on a schedule with Axiom. However, the minimum frequencies for scheduling (1 day for Pro, down to 15 mins for Ultimate) are really too slow for this use case. So now we've removed those limits - everyone with access to the scheduler (Pro or above) can now trigger local schedules every minute. Remember to keep an eye on your runtime if you are doing this! The previous limits still apply to cloud schedule runs. Clear a range from a Google Sheet As a companion to the \"Delete rows from a Google Sheet\" step, you can now clear rows from a Google Sheet too. Instead of deleting the row, this simply wipes an area of the sheet. This is good for cases where you want to keep formatting or formulas intact! Save a screenshot to Google Drive Along with saving a screenshot to your desktop, you can now save a screenshot to Google Drive too. New button to reboot VPS For those on the ultimate tier who have access to a VPS, we have now provided a button to let you reboot your own server in case you run into issues. Minor fixes You can now pass a data variable into \"Max Cycles\" when jumpingCustom file name field now available on the \"Export CSV\" stepDownload to Google Drive now returns a token for filenameDesktop app \"busy\" check no longer triggers if the desktop app is not runningFix to incorrect display on the upcoming schedules page if a start date for a schedule wasn't setBig reduction on email send speed to nerf spam use casesJump steps will now reset the result count once they've finished, which will let sub-loops work much betterSmall fixes to data output consistency across the boardWhen supplying multiple columns for words to filter on, now all columns are used instead of just the firstFixed an issue with duplicated file extensions when \"Force file download\" was checkedWhen the Iframe box is ticked, iframes are now processed in reverse order to reduce the chance of selector collisionsFixed an issue where the trial time would appear to still be subtracted from a user's runtime on the first day after subscriptionYou can now use the node filesystem library (fs) in javascript steps (only when running in app)Improved template loading from \u002Fguides\u002F",{"id":2034,"title":2035,"titles":2036,"content":2037,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-20-0","Affiliates, smarter queues, overwrite files, and a 4.0 teaser",[],"Introducing axiom.ai affiliates We are pleased to announce our new affiliate system! Now you can sign up as an axiom affiliate at axiom.ai\u002Faffiliates and get a 15% referral fee for anyone you get to sign up to Axiom. Make templates, share them with your friends, and make some money while doing so! Queueing system added For those of you who use Axiom as part of wider workflows with Zapier, Make or via API, we've now introduced a queueing system to reduce errors. Whenever the Axiom server is busy or you run over your concurrency limit, the system will now automatically queue up and retry the runs that could not start. Run Axiom in Incognito Mode You can now run Axiom in incognito mode. By default, incognito mode does not copy any session data, so it's useful for testing automations that are intended to run as scheduled or via API on our cloud servers. Use ChatGPT directly from within the \"Write Javascript\" step You can now utilise our ChatGPT helper function to quickly access OpenAI's ChatGPT API and automatically ouput the response in an Axiom-compatible data format. Find out more here Docs integrated with phind AI search Thanks to our friends at phind, we have integrated a search using ChatGPT into our documentation that will provide text-based answers to your questions. The option is always available at the bottom of any search query you make on our docs site. Overwrite files instead of renaming When downloading files, the default behaviour of axiom is to rename files that are duplicated. In some cases this is great, but in others it eats up your disk space and makes determining which file you want to use more difficult. To solve those problems, we've introduced a new option to overwrite files instead of renaming them. This will reduce the number of files on your system and make it very easy to use that file in automations, as the filename will remain static. Coming soon - Axiom 4.0 We've been hard at work on our next generation of the builder interface, which overhauls the UI and brings new abilities for nesting and combining steps that should streamline the logic of more complex axioms. More info coming soon.... Minor fixes Increased maximum size for uploading files to Google Drive (now 250MB)Fixing issues where the click confirmation would show even though it didn't workFixing an issue caused by undoing all the way back to 0 stepsStopping an axiom should now always work, even if the connection to the server has been lostUpdate to the Google Sheet writing logic to prevent rare errors when accessing the Sheets APILine breaks now work in emailsAuto-update will no longer restart the axiom desktop app if an automation is running, and will wait until it can proceed safely",{"id":2039,"title":2040,"titles":2041,"content":2042,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-21-0","Sneak peek at 4.0, open linked axioms, new steps, and more",[],"Coming soon - Axiom 4.0 We've been hard at work on our next generation of the builder interface, which overhauls the UI and brings new abilities for nesting and combining steps that should streamline the logic of more complex axioms. We want to achieve this without increasing the complexity of the interface for new users. This feature has been taking up most of our product development work time, but it's almost done! See below for a sneak peek... We'd love to hear your feedback, so please get in touch if you have any queries. We're also looking for early access testers to get an advance copy of this feature and let us know what we should change. Please email us at support@axiom.ai if you'd like to be part of this group! Open linked axioms from \"Run another axiom\" step Now when you use the \"Run another axiom\" step, a link is available that will let you go directly to that axiom and edit it, rather than having to go back to the main axiom listing and find it from there. Disable page change monitoring On some (rare) sites, animated elements can cause Axiom to hang indefinitely. Previously we have fixed this as issues were reported, but now there's a new option available in the \"Settings\" page that will disable all page monitoring. This skips the code that waits for a page to stop changing, which will fix indefinite hanging issues and may work to speed up some slow sites. Please note that disabling this will likely require more manual waits to be added! New pricing options in the Ultimate tier Two new tiers have been added above Ultimate to capture use cases which need a lot of runtime each month. Previously, one would have to sign up to multiple accounts or request a custom package, which was inconvenient. You can now select from the Ultimate 500 and Ultimate 750 tier, which offer 500 and 750 hours of runtime respectively. Monthly option in Scheduler You can now set schedules to trigger once a month. New step: \"Count rows\" As its name suggests, this new step will return the number of rows in a piece of data. Minor fixes Fixed a permission issue that affected Google Sheets within Team WorkspacesUpdated branding on desktop app splash screen to reflect current visual design languageStep finder now updates if the desktop app is started while it's open, removing the \"download desktop app\" errorsPrevented registration from anonymous email providers to protect against spammers abusing the free tierA payment reminder is now shown in the extension for lapsed paymentsFixed minor bug in conditional widgetFixed an issue where reading out of range of a google sheet was treated differently to reading an empty cellNew helper article on running multiple bots, linked for users with concurrencyFixed display issues in some error messages caused by attempting to render the HTML of the element we tried to clickClearer error message when files not foundChanges to runtime calculation to improve performance and fix some exploits that could extra runtimeThe auto-convert option in Google Drive if a file is uploaded by axiom",{"id":2044,"title":2045,"titles":2046,"content":2047,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-22-0","Last stop before 4.0, Scrape images, reorder columns, and more",[],"Axiom 4.0 - early access is ready We've been hard at work on our next generation of the builder interface, which overhauls the UI and brings new abilities for nesting and combining steps that should streamline the logic of more complex axioms. We want to achieve this without increasing the complexity of the interface for new users. This feature has been taking up most of our product development work time, but will finally be here in the next axiom release. We're also looking for early access testers to get an advance copy of this feature and let us know what we should change. We'll be in touch with those of you who have already expressed an interest - thank you! Please email us at support@axiom.ai if you'd like to be part of this group. Image type added to selector tool A new \"Image\" type has been added to the selector tool. When scraping, this will return the URL for the selected image, so no more scraping the HTML and using splits to get at them. Google Drive steps now usable on desktop Previously, the upload from Google Drive and download to Google Drive features were available only for cloud runs. Now, they are available when running on the desktop application too. Columns in the multi-select tool can now be re-ordered If you want to change the order of columns in a scrape, you can now use the provided arrows to move the column rather than having to delete and re-select. New notification option added for warnings In previous verisons of axiom, notification options allowed you to either send notifcations on success or failure (or on both). We've now added a third option that allows notifications to only be sent on warnings, which should be particularly useful when \"Continue on error\" is used but you still want to know if an error was encountered. Minor fixes Improved handling of errors when using the Chat GPT features of axiomYou can no longer run a search on the dashboard before axioms have loaded and get incorrect resultsRetry logic improved when connection issues occur, which should eliminate almost all axiom run failures with 502 or 504 error codesNew 30 min option for schedulingYou can now pass variables to specify the first and last rows in Google Sheet stepsSearch added to \"Run another axiom\" step interfaceFixed a rare issue where the scraper would skip to the next page before it had fully scraped the current oneAdded better error handling when all browser tabs are closed during an automationCtrl + S shortcut added for saving an axiomAxioms can now be deleted from the builder, instead of just from the dashboardImproved recursion detection in \"Run another axiom\" to reduce false positive errorsIcon and tier added to dashboard when subscribed",{"id":2049,"title":2050,"titles":2051,"content":2052,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-5-0","Live data previews, easier navigation, new onboarding tools",[],"New features Categories added to the step list in builder to aid navigation.Inline previews now update in real time rather than on opening a step.Now when a field is toggled off it uses the default value instead of the entered value.New design for install sucess page, now with an introduction video.Split by character filter now allows you to enter a line break.Fixes to the synchronisation of selected columns with the page highlights in the selector tool.New onboarding system to allow us to provide contextual “getting started” help to new signups.New design for login page. Bug fixes You can now back out of adding a recipe or template without going all the way back to the dashboard.Minor improvements to showing the run times in the cloud run viewer.Improved several error messages during run.",{"id":2054,"title":2055,"titles":2056,"content":2057,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-6-0","Better sheets integration, loop controls, and fixes",[],"New features New interface to select Google Sheets directly from your drive account - you no longer have to copy and paste the URLs (unless you want to of course - the old way is still supported).New interface to explicitly present the concept of looping, and to allow it to be toggled on and off. Previously the implementation of loops happened automatically, with a hidden mechanism that could be confusing if you didn’t know the trick.Max Wait parameter removed from scrapers; it was a trap for new users.Improved error messages for some Google Sheets problems.We now warn you if no output step has been added (and therefore the automation won’t do anything). You are prompted to either add an output step or to run anyway, in which case the automation engine will automatically display any scraped results.Link to documentation added to the Custom Selector interface. Bug fixes More contextual information added to tokens to help aid in understanding.Runs that are terminated for running over their maximum allowed runtime send a more helpful error message.Improvements to how tokens created within loops work to prevent common errors.",{"id":2059,"title":2060,"titles":2061,"content":2062,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-7-0","Better builder errors, webhook stability, test default data, and more",[],"New features “Receive data from another app” step now allows you to add default data to make testing easier.Data tokens can now be passed in custom selectors.Improvements to selector tool behaviour when no content of the selected type is found.Clarifying error messages and step instruction text across the board.Paid-only features now much more clearly marked. Bug fixes Improvements to validation and error reporting when triggering axiom.ai via webhook or API.Better handling on connections being dropped during long running  axiom.ai cloud sessions, when logging out or entering sleep mode etc.Minor brand update for consistency with new website design.Fixing an issue with result formatting if an error occurs during a looping bot run.Sending a webhook from  axiom.ai now works as you would expect.Updated help videos to latest versions.",{"id":2064,"title":2065,"titles":2066,"content":49,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-8-0","Axiom academy is live, smarter scraping, improved validation",[],{"id":2068,"title":2069,"titles":2070,"content":2071,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-8-0#new-features","New features",[],"Improvements to scraper tool which should lead to fewer missing data errors, as well as better speed in many cases.New axiom.ai academy site, replacing old docs.Improvements to error messages and validation across the board.Added a “report error” button into the scraper.“Space” is now supported when providing key presses via data.Some puppeteer functions are now usable in javascript steps. Bug fixes If your runs are blocked by the concurrency limit, you can now stop all of your running bots in case something is stuck.Removed confusing column selection when adding a loop token.Several fixes to scraper preview behaviour.Fixed a bug in the multiple file downloader that meant only one file would be downloaded when a page change occurred.Fixed bug in “Login” step where the username was not entered under some conditions.Fixes for several cases where passing data into a custom selector did not work as expected.Fixed conditional widgets when criteria were provided by data from another step.",{"id":2073,"title":2074,"titles":2075,"content":2076,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-3-9-0","Step-by-step templates, improved scraping, click multiple, and more",[],"New features New scraper design and tutorial flow.New guided step-by step flow for configuring a template.The scheduler returns! You can now schedule axioms to run automatically on the pro tier or above.Fixing issues in the scraper with innacurate scrolling and results counting in some cases.New step to append two data variables together into one.New step to click multiple similar elements in one go rather than having to loop.You can now shorten the default waiting time for scrapers that have no results. Bug fixes Fixing issues where sometimes the connection to Axiom Cloud would be lost.More improvements to error messages and linking to a docs section on commonly encountered errors.Now when an error is encountered within an automation that loads another axiom, the error message will indicate in which axiom the error was encountered in.Bad filenames are now validated properly when downloading files.",{"id":2078,"title":2079,"titles":2080,"content":2081,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-0-0","Build smarter with nesting, chatgpt 4, and cloud sessions",[],"Axiom 4.0 is here After many months of development, we are proud to release Axiom 4.0! This overhaul of the UI and underlying engine lays the groundwork for the 4.x version updates, which will focus on simplifying the onboarding and increasing the power of the features available in the builder. We've also refreshed the design of the builder, with the main focus being reducing visual noise and making everything more compact and consistent. Introducing nested steps Axiom previously used a flat structure in the builder. This works fine for simple axioms, but for more complex use cases builds can become confusing due to the use of multiple \"Jump\" steps. Looping functionality was also limited to \"Interact\" steps like clicking, which made some more complex builds difficult or even impossible to pull off. With axiom 4.0 you can now nest steps within other steps in a more generalised way. Loop through data Similar to the old \"Interact with a page's interface\" step, but much more flexible. You can now place any step inisde a loop (including another loop). If statement When the condition in the If statement is true, all nested steps are run. If the condition is false, all steps are skipped. Try \u002F Catch Enhance error handling with this step for advanced builders. First, the steps in the \"try\" section are run. Then, if an error is hit, execution switches to the \"catch\" section, running those steps. This opens the door to flexible and powerful error handling, well beyond what can be done with the existing notifications system. New snippets to get started faster You can now get into building in a single click by using the new beginner snippets, which cover common design patterns in axiom. Click to add and then fill in the details as you need. Store cookies for use in the cloud You can now optionally store local session cookies remotely. This will allow you to use your local session to connect to websites using the cloud system, which allows the use of the cloud scheduler and API calls. Cookies are stored encrypted and the feature is opt-in and fully configurable - no cookies are saved except the ones you specify. Enhanced select, move and copy commands We have cleared up and improved the move and copy commands to work with the new interface. The toolbar has also been enhanced with new features, including adding the ability to loop all the selected steps. Improved step finder The step finder has been improved with a more compact design and significantly enhanced keyboard controls. You can now move up and down the list with the cursor keys after searching, press enter to add a step, and even add multiple steps by using the \"*x\" suffix. For example, \"Enter Text*4\" will add 4 of the \"Enter Text\" step to your axiom. This will always add the highlighted step, so you can still move the cursor to another step and keep the multiplier. Support for Chat GPT 4.0 Chat GPT 4.0 can now be selected for the AI steps, if you have an account with this enabled. You can still use 3.5 as the default. Internal docs page Documentation is now available from within the sidebar while you're working on an axiom. You no longer have to switch to a separate tab to get advice on your issue. Set your own run limits You can now set a maximum time your axiom can run to manually cut off slow or hanging bot runs. You cannot set this higher than the maximum enforced by your account level, of course! Improved iframe support in the selector tool You can now more clearly see whether an element you want to select is inside an iframe or not, and you can enable iframe support from right within the selector tool. Control scraper scroll distance In very rare cases, the smart scrolling in axiom is not able to find the next item you want. In these cases we now provide the option to manually set the scroll distance that the scraper should use, bypassing the automated system and allowing those cases to work properly. Minor fixes Remote and local runs are now more clearly differentiated in run reportsMinor improvements to error messages for Google Sheet stepsStep names automatically assigned for more step typesYou can now update your own email address from within the extensionFixed an issue where some downloads did not overwrite existing files correctly",{"id":2083,"title":2084,"titles":2085,"content":2086,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-1-0","Guided templates, step help, datepickers, partial screenshots, and more",[],"New guided template system Templates have been overhauled with a new UI and inline instructions to help guide you through the process of setting up botss - whether for the first time, or when you just need to get set up quickly. Further improvements are being prepared to templates to make them more user friendly, so watch this space! Inline step help improved New help and help videos are available on all steps when added to the builder. Sync all stored cookies In 4.0, cloud storage of cookies was introduced. Cookies are stored seprately for each bot, which makes re-syncing them quite awkward if you have many bots that share the same cookies. In 4.1, a new button has been added to globally re-sync all cookies of a particular type, which should save some time! Search for and edit a particular row in a Google Sheet A new step has been added allowing you to get the row number of a row in Google Sheets that contains some specified text. This step returns the row number so that you can use it in subsequent write operations, allowing you to edit particular parts of the sheet. A pre-set snippet has also been added to cover this functionality. New datepicker step Datepickers have long been annoying to deal with in browser automation, due to the number of different implementations that exist. In 4.1, we've added a new step that lets axiom.ai better understand the structure of these datepickers, making many examples much easier to automate. Settings page redesign The settings page has been getting crowded, so has been redesigned to group information hierarchically and save on screen space. Go back to previous bot When editing an bot linked to a parent, the back button now allows you to return to the parent instead of just to the dashboard. Configure download wait time The time that axiom.ai will wait for a file download is now customisable, to cover cases where the download takes a long time to start. This is particularly helpful in cases where large reports are being generated by a website on demand. Use your local timezone in Cloud runs Previously, axiom runs would occur in the UTC timezone when running remotely. In rare cases this can cause discrepancies between the time of a run according to the server, and the time of the run locally. To resolve these issues, there's now an option to use your local timezone for cloud runs, under Settings. Desktop runs continue to use local timezone information as usual. Take partial screenshots The screenshot step can now be used to screenshot a particular element instead of only the whole page; simply select the element you want to snapshot and axiom.ai will output an image of that section. Minor fixes Token replacement fixed in conditional check steps. Old bots continue to work as in previous versions.axiom.ai can now recommend content for new users based on their activity.Body selector can now be used in the selector tool, improving the ease of scraping with ChatGPT or other LLMs.Wait and random wait steps combined.Customisable message added into extension to report on any ongoing issues more transparently.Invoices are now kept accessible to users who have previously unsubscribed.Fixed issue with xlsx files being interpreted as zip files when uploading to Google Drive.Schedules can no longer be set to start in the past, as this was causing confusion in some cases.Load times improved for large bots by only rendering steps that have been scrolled down to.First sheet now auto-selected in Google Sheet steps instead of having an implicit default behaviour only.Delay setting now works if no element was selected on the \"Enter Text\" step.Updated design of approval screen for Google authentication.Fixes to a few issues with the \"Test Data\" parameter on the \"Receive data from webhook\" step.Fixing issues with punctuation breaking the remove words steps.",{"id":2088,"title":2089,"titles":2090,"content":2091,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-2-0","Proxy auth, conditional logic, flexible scheduling, and more",[],"Run axiom with a proxy Quickly scaffold a bot by answering a few questions about what you are trying to do, building towards a natural language AI interface for bot building. Give it a try! Reformat date and time Quick action sidebar We have introduced a new user interface element - a contextual sidebar with quick actions. This is another area for expansion, with more detailed run reports and other options coming soon. In addition, visuals have been altered to give more room to the debugger and documentation elements, and provide a more comfortable experience. If \u002F Else step Basic authentication available for proxies Compare numbers in conditions More flexible scheduling Onboarding slides for new users added going over the basics of axiom automations. You can view them from the menu in the top right of the dashboard! Copy steps to another axiom Saving as duplicate is the current way to copy and slightly modify an existing axiom, but we have now added a new method to copy only a small set of steps to another of your axioms. This should save some time where axioms need to have similar functionality! Add steps without closing the step finder You can now add new steps without closing the step finder by using shift+click or shift+enter to select the step, allowing multiple steps to be added more quickly. Minor fixes Fixes to the run viewer step tracker, making it more reliable with large automationsIndicate which axiom caused a runtime notification so that re-activating disabled schedules is easierMore inuitive data variable naming on loopsFixing text formatting issues when adding a data variable into a URLFixed an issue with Create Google Sheet preview creating new sheets when it shouldn'tFixed visual issue with empty data variable previews not togglingCorrected broken link to API documentation\"Use Element Text\" in the selector tool now works properly in conjunction with data variablesFixed display bugs when re-selecting a data variable that's already been set",{"id":2093,"title":2094,"titles":2095,"content":2096,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-3-0","Quick builder, new sidebar, better onboarding, and more",[],"Quick builder Quickly scaffold a bot by answering a few questions about what you are trying to do, building towards a natural language AI interface for bot building. Give it a try! Quick action sidebar We have introduced a new user interface element - a contextual sidebar with quick actions. This is another area for expansion, with more detailed run reports and other options coming soon. In addition, visuals have been altered to give more room to the debugger and documentation elements, and provide a more comfortable experience. Basic authentication available for proxies Continuing from the proxy support released in 4.2, we now have enabled basic auth support, as well as IP auth. Look out for proxy rotations coming soon, as we continue to develop this aspect of the tool. New onboarding flow Onboarding slides for new users added going over the basics of axiom automations. You can view them from the menu in the top right of the dashboard! General improvements to error messaging Error messages across much of the application have been streamlined to be more intuitive and helpful. As well as this, error reporting in loops have been tuned to remove redundant information and to bring them more in line with how other errors are reported. Further work is planned to push this farther, so stay tuned. Minor fixes Fixes to the run viewer step tracker, making it more reliable with large automations.Indicate which axiom caused a runtime notification so that re-activating disabled schedules is easier.More inuitive data variable naming on loops.Fixing text formatting issues when adding a data variable into a URL.Fixed an issue with Create Google Sheet preview creating new sheets when it shouldn't.Fixed visual issue with empty data variable previews not toggling.Corrected broken link to API documentation.\"Use Element Text\" in the selector tool now works properly in conjunction with data variables.Fixed display bugs when re-selecting a data variable that's already been set.",{"id":2098,"title":2099,"titles":2100,"content":2101,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-4-0","Live run status, step recommendations, keyboard shortcuts, and more",[],"New run status overlay For users with multiple running bots, or those that run via API or schedule, it can be difficult to keep track of what is running and what isn't. To help with this, we have introduced a new sidebar button that shows a summary of all running bots, as well as the status of the last three completed runs. This is available in the builder and on the dashboard. Enhanced step recommendations Previously, Beginner Snippets were available to give a quick entry point for some common actions, but these always showed no matter the current status of the axiom. We've altered this section so that it will now show 'Recommended' steps depending on the context of your automation. This should mean less time searching the step list! New keyboard shortcuts Two new shortcuts have been added: When using the scraper, Ctrl-n will add a new columnWhen in the builder, '+' will open the step finder Live system status available in sidebar The current live system status is now displayed in the extension on the sidebar. Green: all is wellOrange: degraded performanceRed: system is down Inline JSON validation added For steps that allow JSON input (currently \"Trigger Webhook\"), live JSON validation has been added. Now if there's a syntax error in your JSON, you can see the issue before running your axiom, which should speed debugging. Refresh preview button added Previews automatically refresh on certain events in the builder, but in some cases (for example, if data is manually altered in a Google Sheet) the preview would not refresh. To cover these cases, a manual refresh button has been added to the preview header. Enjoy! Local storage now available to save in cloud Most of the time, sessions are possible to recreate using only a session cookie. However, a few sites also require a local storage value in order for a login session to be properly recreated. This option has now been added. If cookie storage alone is not sufficient to recreate your session, you can try turning this on and see if it helps. Minor fixes Notifications on run ending now accept multiple email addressesFixed a bug caused by inner text selectors being too long and causing a hangSchedules no longer have to be re-enabled if runtime expires; they will automatically start working once the account is updatedBugfix on the number option in conditional check, which only evaluated 1 digit numbers correctlyAdded explicit Copy \u002F Move item into step kebab menu to make the option more clear to usersImproved description of the \"First Cell\" option in the \"Write to a Google Sheet\" stepWhen writing to a Google Sheet the default option is now to append data instead of clear itRe-allowed changing the run time of a schedule if the schedule date is in the past",{"id":2103,"title":2104,"titles":2105,"content":2106,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-5-0","Scrape faster, set keys once, skip steps, end runs early, and more",[],"Quick select options added to the scraper You can now use a shortcut button to select either all page HTML, or all page text with a single click. This is helpful when combined with ChatGPT data extraction, and also lets multiple different layouts of pages be scraped more easily. New API key management interface For OpenAI and 2Captcha keys, there is now a dedicated place these keys are stored globally so that you do not have to re-enter the same key in multiple automations. You can still override the default key with a different value, if you'd like. Update status now displayed on desktop application Previously, the desktop application would automatically update in the background with limited messaging. Now, the desktop splash screen will display a message about what state it's in and what it's doing. Improved \"Receive data from another app\" step With new API guides, improved documentation and a much cleaner design, we hope this step now should be a lot easier to understand and use for those triggering an automation from other systems. Optional enter text step Just as with clicks, you can now set enter text steps to be optional. Useful if you have fields that don't always appear in a form, and you don't want them to raise an error. Open axiom.ai with the keyboard As part of the ongoing push to incorporate more keyboard shortcuts, the axiom.ai [builder](\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fbuilder can now be opened using a Chrome shortcut. By default, this is set to Alt + Shift + X on Windows and Linux, and Option + Shift + X on OSX. This is a default, and can be configured as you please. New \"End Run\" step Adding this step will end the run immediately - use it inside an if statement to save on runtime! Minor fixes Messaging for Google Docs \u002F Sheets auth flow improved when authentication failsError message made more obvious when axiom.ai login failedFixed issues where hanging automation would ignore the user's runtime limit settingImproved error message when trying to run in cloud with bot blocking onRemoved dependency on Google Drive API in the spreadsheet picker interfaceImproved authentication handling between Google Drive and Google SheetsFixed an issue where the CSV download and Display Message steps did not trigger during locally scheduled runsNew write CSV step that works much more like the Download File step. The old step is deprecated but will still work on existing automations.Fixed the selector tool vanishing on some pagesImproved reliability of run state tracking in the extensionProxies can now be used when bot detection bypassing is switched onMade it more clear that local schedules can run every minute, on all tiersFixed some inconsistencies in the naming of Google Sheet steps",{"id":2108,"title":2109,"titles":2110,"content":2111,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-6-0","Excel steps, folder sorting, GPT-4o smarts, end loop control, quick filters, and more",[],"Excel read and write steps We've expanded our integrations by introducing Excel read and write steps. Similar to our existing Google Sheets steps, these new Excel steps allow you to automate data extraction and input within Excel spreadsheets. This feature brings greater flexibility for those of you who prefer to work with Microsoft Excel files instead of Google Sheets. Axiom listings - sort with folders Axiom listings now support sorting your automations by adding them to a folder, allowing you to better organize and manage your automation workflows. This enhancement should make it easier to find and access the automations you need. End Loop step A new \"End Loop\" step has been added, providing better control over loop execution. This step allows you to explicitly terminate a loop under specific conditions, preventing unnecessary iterations and improving automation performance. Integration of GPT-4o and GPT-4o mini models We've upgraded our AI capabilities by integrating OpenAI's latest GPT-4o and GPT-4o Mini models. These models provide faster and more accurate text processing for AI-driven automation steps, enhancing data extraction, content generation, and decision-making workflows. New \"+ Filter\" button for data preview To enhance data management, we've added a \"+ Filter\" button to the data preview interface. This acts as a quick shortcut to add data filtering steps to your automations, hopefully speeding up the building process. Predicted runtime usage warning We've introduced a new feature that predicts runtime usage for automations and warns you if you will run out of runtime in the next week, before your runtime is topped up. This should help you avoid situations where your runtime expires and your automations start failing! Minor fixes Improved in-app messaging and support for Google Sheets token expiryAdded a link to a dedicated troubleshooting page for the \"failed to start\" errorAdded the ability to close in-extension documentationImproved text clarity for Google Sheets grant permission and required stepMore than 10 URLs can now be displayed on the stored cookies tabFixed an issue where the add new step shortcut interrupted the javascript input boxEnsured new scrape page data buttons only appear on scrapers and not on unrelated UI elementsReworked instructions for the \"Solve Captcha\" step for better clarityFixed an issue where the \"Extract data with ChatGPT\" input box was too smallCorrected an incorrect link in bot detection bypass settingsChanging the column type in the selector tool now also switches columnFixed an issue where clearing token text boxes occasionally left behind a \u003Cbr> tagFixed an error that prevented automation imports when they contained a \"Remove Duplicates\" stepResolved display issues with step titles and token displays when nested inside loops Known issues When updating the desktop application, there may be instances where you receive an error. If you experience an error while the application is updating, quit the application and reopen it and the update should complete as expected - we have already fixed this issue for later releases.",{"id":2113,"title":2114,"titles":2115,"content":2116,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-7-0","Proxy rotation, AI updates, new run options and more",[],"Run dropdown A new dropdown has been added to the run button to surface some of the more useful runtime settings - cookie storage, scheduling, bot detection bypass and notifications. Proxy rotation You can now specify a list of proxies to use; axiom will rotate through them randomly during runs. New AI step and new providers We have revamped the AI step to both simplify the UI and to integrate new providers, with model options now provided from Claude.ai, Deepseek and Perplexity. You will need an API key for each of these providers to use these new models. Option to automatically re-sync a cookie during axiom runs You can now optionally turn on the ability to automatically re-sync cookies if they change while axiom is running. In some cases this should cut down significantly on the number of manual re-syncs you need to do to keep an automation running. New API routes We've added some new utility routes to our API: Get remaining runtime, get list of automations, and get last n run reports. Optionally block resources A new setting has been added to allow you to specify resource blocking rules for images, files etc. This can be used on heavy pages to speed up runs and reduce memory usage. Restart Chromium step On some sites, Chrome can run out of memory during long automations. We've added a step which restarts the tab when triggered, clearing any memory buildup on such sites. General performance improvements We've made a number of changes to improve the performance of axiom in certain edge cases. This involves reducing the memory usage of the app during long automations, preventing issues with Chrome crashes when a large number of sites are used in one automations, and significantly improving the performance of the auto-wait functionality on long or complex pages. Re-sync cookies from the \"Go to page\" step We've added a new button so you can re-sync any cloud cookie storage directly from the \"Go to page\" step, rather than needing to go via the settings. Minor fixes Cleaned up some request spam when authenticating a Google accountMade sure step finder does not open in collapsed state when it shouldn'tFixed a bug where the infinite loader on the axiom listing would stop working in some casesAdded ability to search the run report page by error messageRemoved invisible reCaptchaV3 from list of captchas solved by the captcha solving stepFixed an issue with reading from sheets with colons or exclamation marks in their namesDelete modal now displays the automation name to reduce the chance of deleting the wrong thingHourly intervals in the scheduler now preserve the starting minute, preventing schedules from drifting from their chosen start timeDowngrading from pro to started now properly disables local schedulesFixed an issue where token replacement for javascript if statements inside loops did not replace properly",{"id":2118,"title":2119,"titles":2120,"content":2121,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-8-0","Axiom.ai v4.8",[],"Unlimited Desktop concurrency The desktop application now supports unlimited concurrency, allowing for any number of automations to run simultaneously on your local machine, limited only by your computer's resources. Furthermore, users can now individually enable or disable concurrency for specific axioms, for both desktop and cloud runs, giving finer control over resource usage and task execution logic. Airtable integration We have now integrated axiom with Airtable, providing dedicated steps for both reading and writing data to Airtable bases. This simplifies data exchange with one of the leading no-code database platforms. Users can now seamlessly pull data from Airtable into an axiom or push collected data directly into an Airtable base. File read capabilities Axiom.ai can now read a local file (on Desktop) or from Google Drive (on Cloud or Desktop). This new step allows users to read the contents of a specified file (such as a CSV, TXT, or JSON file) directly within an automation. The data read from the file can then be passed to subsequent steps in the bot, such as filters, AI, javascript or anything else you can think of! Runtime usage email warnings To help users manage their resources proactively, Axiom will now automatically send email warnings when your runtime usage reaches certain thresholds. You'll receive alerts at 80%, 90%, and 100% of your allocated runtime. These notifications are designed to prevent unexpected interruptions to your automation runs. Users have the flexibility to disable these warnings in the application's options settings if they prefer. New step: Metadata scraping A dedicated step has been added for scraping metadata from any web page. This feature provides a targeted way to extract valuable information typically found in the \u003Chead> section of a webpage's HTML, such as the page title, description, keywords, or Open Graph tags. The step is configurable, allowing you to specify which metadata attributes you want to collect. Cloud Bot Bypass enabled Cloud bots are now able to bypass certain bot detection mechanisms, as on Desktop. This new feature provides an option to run automations in the cloud with configurations that are more resilient to anti-bot measures, potentially allowing for more reliable and successful runs on websites with sophisticated bot protection. Minor Fixes Tasks now no longer incorrectly remain stuck \"In Progress\" if they have failed but could not update the server with the failure statePrevented axiom application from crashing if internet disconnects during a runFixed rare cases of filename collisions when two axioms are running concurrently in the same environmentFixed issue where switching filters on run reports while loading caused incorrect resultsFixed occasional issue where previous selector entries would be incorrectly cleared when opening the selector toolFixed issue where changing folders during task loading on the dashboard resulted in incorrect dataAdded Gemini as an AI providerFixed issues where screenshots would occasionally fire before the canvas had completed renderingFixed an issue where when removing a step, the preview was not entirely deletedFixed clicking '+Filter' in the output preview occasionally failed to open the Step FinderFixed issue with HTML passed to the Integrate AI step causing the axiom to stopFixed rare issue where a duplicate schedule could be created, resulting in double axiom runsWildcards improved when blocking resourcesFixed issue where current date and time widget was ignoring the \"use local timezone\" settingMIME type can be optionally forced for file downloads to work around issues where the correct file extension is not present in a download URLImproved API key display",{"id":2123,"title":2124,"titles":2125,"content":2126,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Faxiom-version-4-9-0","Axiom.ai v4.9",[],"Team requests for Ultimate tier Ultimate tier users can now request team access, allowing runtimes to be shared across selected accounts for improved collaboration, billing and resource management. Code editor improvements The code editor has been significantly improved with support for templated snippets, a full-screen editing mode, and multiple quality-of-life enhancements to improve usability. Improvements to support flows Added an improved support pane into the builder, with better instructions, shortcuts and the ability to export the currently active browser tab as an HTML file to share in case the site is behind a login. Double click option for Click step The Click step now supports a double-click option, expanding interaction capabilities for sites that require more advanced UI actions. New Row Numbers step Introduced a new data step that allows row numbers to be automatically added to datasets, making it easier to reference, debug, and post-process extracted data. Minor Fixes Fixed issue in Go To step where IP addresses were incorrectly prevented from loadingFixed empty error message when “Upload a file from Google Drive” element is not foundAdded refresh button to run reportsAdded ability to choose fixed columns for the Append Data step when input data has variable lengthsOperating system is now shown in task reports for desktop runsFixed issue where inserting data into the Integrate AI token field cleared all textFixed issue where upgrading a step did not set the default value correctly, resulting in issues with the optional field togglesFixed resource blocking not working when “open in new tab” is usedFixed override of website iframe classes breaking builderAdded data refresh button to data previewFixed unhandled exceptions hanging the desktop app and requiring a restartFixed “Do not share local storage” option being ignored on Go To Page stepFixed UI issue on Proxy page when protocol is entered twiceFixed YouTube video embedding in the extensionFixed inaccuracy in the 1-minute runtime interval on the desktop scheduler",{"id":2128,"title":2129,"titles":2130,"content":2131,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes","Release notes",[],"See what's new in the latest axiom.ai release, plus the full archive of previous releases covering features, fixes, and improvements. The latest release is shown below. For older releases, scroll to the Previous releases section. Latest release Previous releases Need help? Contact support or ask a question in our Reddit community.",{"id":2133,"title":2134,"titles":2135,"content":2136,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Frelease-notes\u002Flatest","Axiom.ai v4.10",[],"Run recording and improved error logging You can now optionally turn on run recording for unattended axiom runs (such as those run from a schedule or an API call) in order to review cases where the bot may have failed to complete. In addition, much more comprehensive browser and axiom logs are provided in run reports when this is turned on, helping with debugging. This feature is available for Ultimate users only. Delete file from Google Drive step You can now delete files from Google Drive from within an axiom, useful for cases where you need to clean up temporary files or ensure certain states for the rest of your run. Minor Fixes Fixed issue with clicking folder after coming back from the builderIncreased maximum file size for Google Drive uploadsFixed a bug with using a custom profile that would cause the profile to be deleted in some casesOpen in new tab now also uses the incognito window if this is setCan now use a token as the local folder path in the \"Read File from Google Drive\" stepFixed an issue with bot blocking bypass not being attached to new tabs sometimesPrevented the validator from incorrectly blocking a run when a partial token is used in a file pathFixed a misleading message when there are no sheets in a Google account on the sheet picker, and some other cases",{"id":2138,"title":2139,"titles":2140,"content":2141,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fai-assistant","AI Assistant",[],"Use the in-Builder AI Assistant to debug failing automations, get suggested fixes, extend your automation with new steps, and resolve common configuration issues from a chat conversation. The AI Assistant's main job is to help you build and debug an automation. It is an assistant, and still requires a human to be in the driving seat. It can help you debug errors, suggest fixes and guide you through documentation with natural language. It can also extend an automation by adding, looping, or modifying steps from a natural-language description. Start a troubleshooting conversation Type \u002Fhelp and the assistant asks whether you want to Debug my automation or Extend my automation. If you choose Debug, the assistant offers a list of common problems and takes you to the right place: Incorrect data or element selectedWrong page loadingNo data outputLogin or session failingInteracting with an element failingWrong data mapping to a fieldWrong order of stepsExtra stepsNot loopingNeed to add a new stepA specific error message If you choose Extend, the assistant helps you change your automation by chat — adding, looping, or editing steps as described below. Extend your automation You can ask the assistant to change the automation in plain English. It proposes the change, shows a preview, and asks before applying it. Add steps. \"Add a click step after step 6\", \"write to a Google Sheet at the end\". The assistant proposes the step(s) and the position.Loop steps. \"Loop steps 3 to 6\" wraps a range of steps in a loop.Fill a form. Ask the assistant to fill a form and it walks you through the Enter text \u002F Select list \u002F Click pattern.Read and write Google Sheets. Ask and it inserts the read-sheet \u002F find-row \u002F write-sheet trio.Upload or download files. Ask and it inserts the right file-transfer steps for local files or Google Drive.Receive or trigger a webhook. Ask and it sets up an incoming webhook (with a sample payload to test) or an outgoing webhook (you can paste a curl command for it to parse). What the assistant can help with The assistant covers a lot of ground. The list below is a quick tour of the things you can ask it for. You can usually start any of them by typing what you want; the most common ones are also a click away in the \u002Fhelp menu. Debugging an error Error help. When something goes wrong, the assistant looks at the error and suggests fixes. Opens automatically when a run fails, or type \"error in step 3\".Autofix. Lets the AI try to fix the error for you by editing the automation. You'll see an Autofix button on supported errors, and the assistant might ask a quick clarifying question before making the change.Skip non-critical errors. Helps you tell the automation to keep going if a step fails, when that failure isn't important. Say \"ignore this error\" or pick it from the suggested fixes.Click not working. When a Click step isn't hitting the right thing, the assistant offers to reselect the element, click by its text, use a custom selector, or get support. Pick \"Interacting with element failing\" or type \"click not working\".Selector issues. When a selector isn't finding the right element — iframes, hidden elements, attribute selectors and so on — the assistant walks you through the options. Pick \"Incorrect data or element selected\" or type \"selector not working\".Page won't load. Helps with URL, network, VPN, and blocker issues. Offers autofix, a URL check, a login check, a network check, or support. Opens on page-load errors, or pick \"Wrong page loading\".Empty Google Sheet. Steps in when a Get data from Google Sheet step reads an empty sheet. Offers to open the sheet for you or set the step to continue when it's empty.Cloudflare blocks. Spots when a page is being blocked by Cloudflare and offers to turn on the bot-detection bypass. If it's already on, the assistant points you to support.Run-in-app required. Pops up when a Write javascript step needs the desktop app's \"Run in app\" mode, and offers to switch it on.Mac \"Chromium not supported\". When the desktop app shows this macOS error, the assistant walks you through gathering the system details support will need. Editing your automation by chat Add steps. Describe what you want and the assistant adds it. Type \"add a step\", pick \"Need to add a new step\", or accept an autofix suggestion.Loop steps. Wraps a range of steps in a loop. Try \"loop steps 3 to 6\", or pick \"Not looping\".Fill a form. Sets up the usual Enter text \u002F Select list \u002F Click pattern for filling forms. Type \"fill a form\" or pick it from the \u002Fhelp menu.Read and write Google Sheets. Adds the read-sheet, find-row, and write-sheet steps in one go. Type \"write to a Google Sheet\".Working with files. Adds upload or download steps for local files or Google Drive. Type \"upload a file\".Incoming webhook. Sets up an endpoint so other tools — Zapier, your own service, anything that can make a request — can kick off your automation. You'll see the URL and a sample payload, and you can do a test run before saving. Type \"trigger from Zapier\" or \"webhook\".Send to a webhook. Adds a step that calls an external endpoint. Paste a curl command and the assistant works out the rest. Type \"send to an API\" or \"call a webhook\". Settings and scheduling Schedule a run. Sets up a schedule — date, frequency, local or cloud — or turns an existing one off. Type \"schedule\", \"run daily\", and so on.Schedule running at the wrong time. Helps with timezone, daylight saving, and UTC mix-ups. Type \"schedule running at the wrong time\".Notifications. Sets up or changes email or webhook notifications for run results — failure, warning, or success. Type \"notify me\" or \"email on failure\".Proxy settings. Walks you through proxy setup — SOCKS5 or HTTP, host, port, auth. Type \"proxy\".Stay logged in. Captures and re-syncs your login cookies so cloud runs stay signed in. Type \"sync cookies\" or \"stay logged in\".Block resources. Speeds up runs by blocking images, fonts, media, stylesheets, and other things the page doesn't strictly need. Type \"block images\", or pick it from the Slow automation help. Speed and reliability Slow automation. Help when runs are slow or Chrome crashes (\"Oh Snap\"). The assistant suggests blocking resources, or pointing you to support. Type \"slow\" or \"Oh Snap\".Slow scraper. Spots Get data steps that are slow because of retry attempts, and offers to dial them down. Type \"scrape is slow\".Stuck automation. Helps when a run looks like it's hanging. The assistant can stop it for you, and set a max runtime so future runs cut themselves off. Type \"stuck\" or \"running forever\".Runtime limit hit. Shows up when a run goes over the maximum runtime on your plan. Offers tips to make the run shorter, or an upgrade.Upgrade your plan. Appears when you hit a plan limit. Shows the right plan to switch to, with a checkout button. Other Troubleshooting menu. The top-level \u002Fhelp menu that leads to everything above. Type \u002Fhelp, \"troubleshoot\", or \"help\".Contact support. Hands you off to human support, with the issue details and error already attached. Type \"contact support\", or click any Contact support button you see in the chat.Backing out. If you change your mind partway through — \"cancel\", \"never mind\" — the assistant tidies up the pending step and lets you start fresh.",{"id":2143,"title":2144,"titles":2145,"content":2146,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fbuilder","The no-code Builder",[],"Learn how to add, duplicate, move, and configure steps in the axiom.ai Builder, plus useful keyboard shortcuts. The Builder is the visual editor where you create browser automations by combining steps. This guide covers the essentials: adding, duplicating, and moving steps, plus useful keyboard shortcuts. To open the Builder, click New automation on the Dashboard. Name your automation Give your automation a memorable title so you can find it later. We recommend including meta information in the title (such as version or status, for example In progress) to help you keep track of work in flight. Click the title New automation in the top left corner.Delete the default text and type your own title. Save your automation To save changes to your automation, click Save in the top right corner. We recommend saving periodically as you build. Tip: Your automation saves automatically when you click Run. For a quick save, press Ctrl + S with your mouse pointer inside the extension. Return to the dashboard To return to the Dashboard, click the back button in the top left corner of the Builder. You will be prompted to save any unsaved changes before leaving. Duplicate your automation To duplicate your automation, use the kebab menu in the top right corner of the Builder. Click the kebab menu icon in the top right corner.Select Save as duplicate from the dropdown.The Builder switches to editing the duplicate. Start your automation When you open the Builder, you are offered several starting points. For more on starting points for beginners, see your first automation. Quick builder (Beta) Let axiom.ai build an automation for you based on a description of what you want it to do. Add first step To start from scratch, click Add first step. The step finder opens so you can choose your first step. Import automation To import a previously shared or downloaded template: Click Import automation.Click Select file and upload the template.Click Confirm to finish. Start from template To use a pre-built template: Click Start from template.Choose what you want to automate.Click the template you want to use.Click Start setup and follow the guide. Using the step finder The step finder is where you search for and add steps to your automation. Open the step finder In an empty automation, click Add first step or press Shift + +.To add a step at the bottom of the automation, click Add step or press Shift + +.To add a sub-step, click Add sub-step or click between existing sub-steps.To add a step above or below an existing step, click between the step borders. Close the step finder To close the step finder, click outside its borders or select a step. Search for steps Type a familiar term into the search bar, for example Google Sheet, Click, or Scrape, to find the step you want. Snippets Snippets are pre-built combinations of steps for common automation patterns. They appear at the top of the step finder and are a good way to start a new automation. There are four beginner snippets: Scrape data from a page to a Google Sheet.Scrape links from a website and scrape each page.Scrape pages from a list of links in a Google Sheet.Fill in a form. See all steps To see every available step, click Expand all at the bottom of the step finder. To learn more, see browser action steps or the full steps reference. Step finder shortcuts You can interact with the step finder using these keyboard shortcuts: Shift + +: open the step finder.Return: add the selected step and close the finder.Shift + Return or Shift + click: add the selected step and keep the finder open.Esc: close the step finder.Add multiple steps at once: type the step name followed by an asterisk and a number, for example enter*8 adds eight Enter text steps. Disable, move, duplicate, delete, and loop steps You can move, duplicate, or delete any step using the Move toolbar. To open the Move toolbar, click the checkbox to the left of any step title.To close the Move toolbar, click Deselect. Move steps Tick the checkbox to the left of each step you want to move.Click above, below, or between steps, then click Move here. Duplicate steps Tick the checkbox to the left of each step you want to copy.Click above, below, or between steps, then click Copy selection here. Delete steps Tick the checkbox to the left of each step you want to delete.In the Move toolbar, click Delete. Move steps into a loop Tick the checkbox to the left of each step you want to loop.In the Move toolbar, click Loop.Select Loop through data. Disable or enable steps Tick the checkbox to the left of each step you want to disable or enable.In the Move toolbar, click Disable or Enable. Working with steps Every step in axiom.ai needs configuring once it's added. The configuration is usually self-explanatory; for detail on a specific step, see the steps reference. Step number The step number shows the step's position in the automation. Edit a step title Edit a step's title to keep track of what it does or to add meta information. Expand or collapse a step To expand or collapse a step, click the blank space between the step title and the kebab menu. Disable a step Click the kebab menu and select Disable step, or use the Move toolbar. Delete a step Click the kebab menu and select Delete, or use the Move toolbar. Select a step to move or copy Tick the checkbox to the left of the step number, then use the Move toolbar. You can also choose Select or Copy \u002F Move from the kebab menu on the right of the step. Step output token Some steps generate tokens that let other steps access their data. A preview of the data appears in the step's footer. To refresh the preview, click the refresh icon in its header. Run your automation To run your automation, click Run and choose between cloud and desktop. We recommend testing on desktop. For the trade-offs between the two, see running your automation. Tip: Run frequently as you build. Catching issues early is much easier than debugging a long automation at the end. Settings Each automation has its own settings. Most beginners can ignore them. For details, see the settings reference. To open the settings panel: In the Builder, look at the vertical sidebar on the far left.Click the gear icon. Run options ProxyScheduleConfigure timezoneSet up notificationsStore cookiesSet maximum runtimeRun headless Import and export Import or download Error handling Continue on errorInteract with iframesDisable page monitoring Chrome Bot blockingSet executable pathSet profileLoad another extensionRun in incognito mode Undo and redo The undo and redo options let you step back and forth through your changes, up to 50 actions deep. To undo or redo a change, click the three dots in the top right next to Save, then select Undo or Redo. You can also use keyboard shortcuts: Ctrl + Z undoes the last action.Ctrl + Y redoes the last undone action.",{"id":2148,"title":2149,"titles":2150,"content":2151,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fdashboard","The dashboard",[],"A tour of the axiom.ai dashboard, where you create new automations, check run reports, and find your scheduled automations. New to the dashboard? This guide walks through the features you'll use most: creating automations, checking run reports, and finding video guides. Dashboard overview The dashboard is split into three areas, plus a vertical icon toolbar on the far left. Icon toolbar (far left). The burger menu opens account settings. Other icons cover home, run status, embedded docs, and video guides. Desktop and extension version numbers sit at the bottom.Header (top). Shows your runtime, subscription plan, and the New automation button.Left column. Menu links to recommended content, run reports, scheduled automations, Google Sheets, API keys, and your subscription plan.Main column (right). A searchable list of your automations. Vertical icon toolbar The icon toolbar gives you quick access to your account, the home dashboard, run status, and embedded help. My account From My account you can edit your email and password, manage your subscription plan, and delete your account. Click the burger icon at the top left.Click My account. Home The home icon returns you to the default dashboard view, where your automations are listed. Run status The play icon shows the status of any currently running automations. To see your run status, click the play icon. Embedded documentation You can read the axiom.ai documentation inside the extension without leaving the app. Video guides Video guides cover use cases ranging from web scraping to social media automation, all accessible from the dashboard. Vertical menu The vertical menu, to the right of the icon toolbar, changes the content shown in the main dashboard area. Dashboard The default view, showing a list of your automations. Run reports To check the status of all your runs, click Run reports. Reports load into the main dashboard area. Scheduled automations To view your scheduled automations, click Scheduled axioms. Google Sheets and API key To connect or disconnect your Google Sheets account, or fetch your API key, click Google Sheets and API key. Change my plan Out of runtime? Click Change plan to upgrade for more. Main column The main column lists your automations and is shown by default. From here you can search, edit, run, and delete automations. Search for an automation Use the search field to find an automation by name. Edit an automation Click an automation in the list to open it in the Builder. Run an automation Click the Run button next to any automation to start a run. Delete an automation Click the bin icon to delete an automation. Warning: Deleted automations cannot be recovered. Dashboard header The header sits across the top of the dashboard and contains the New automation button along with your runtime and subscription details. Create a new automation The dashboard is the starting point for every automation. Click New automation in the top right corner to begin. Runtime and subscription Your subscription plan and runtime usage are shown in the top right corner. Runtime resets monthly and unused runtime does not carry over. Hover over the percentage to see a detailed breakdown.",{"id":2153,"title":1227,"titles":2154,"content":2155,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder",[],"Get started with the axiom.ai No-Code Tool. Install the Chrome extension, create an account, and build your first browser automation. The No-Code Tool is a visual Builder inside the axiom.ai Chrome extension. Drag and drop steps to record clicks, scrape data, fill forms, and connect to Google Sheets, no code required. This section covers everything you need to go from installation to running your first automation. Get set up Install the Chrome extension and get familiar with the dashboard before you build your first automation. Every new account gets 120 minutes of free runtime so you can build and test without committing to a plan. Use the Builder The Builder is where automations come together. Add steps from the step finder, configure each one, and pass data between them with tokens. The selector tool helps you point steps at the exact elements on a page you want them to interact with. Share Export an automation as a JSON file to share it with a teammate or back it up. Imported files replace the current automation, so import into a fresh automation if you don't want to overwrite an existing one. Need help? Contact support or ask a question in our Reddit community.",{"id":2157,"title":2158,"titles":2159,"content":2160,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Finstall","Installation",[],"Install the axiom.ai Chrome extension and optional desktop application to build and run browser automations. The axiom.ai Chrome extension lets you build automations and run them on cloud infrastructure. Optionally, install the desktop application to run automations locally. The extension is required either way. Install the Chrome extension To install the extension, open the axiom.ai listing on the Chrome Web Store and click Add to Chrome. Set up the extension Click Add to Chrome to install the extension.Click the jigsaw icon in the Chrome toolbar, then click the pin icon to keep axiom.ai visible.Click the axiom.ai icon to open the extension. Permissions The axiom.ai Chrome extension requests permission to read and change all sites you visit. This is required to display the extension window inside web pages and to run your automations. axiom.ai does not collect data from the sites you visit. You can restrict this permission to specific sites in Chrome's extension settings, but axiom.ai may not work as expected. Install the desktop application The desktop application is an optional companion to the Chrome extension. It lets your automations run locally and use local files. The extension is still required to build and run automations. To install it, head to the downloads page and follow the instructions for your operating system. The application needs to be active to run automations, but it doesn't need to be open in a window. Note: Automations run locally count towards your overall runtime.",{"id":2162,"title":2163,"titles":2164,"content":2165,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fpass","Pass data between steps",[],"Learn how data variables work in axiom.ai and how to pass data from one step to another in your automation. Data imported or generated by one step can be passed to another step in the same automation. Steps expose their output as data variables, which you plug into later steps to transform, filter, or write that data elsewhere. To learn how to import data first, see the data tutorials. Pass data from one step to another To pass data into a step, look for the Insert data button on any field that accepts it. Clicking it shows a list of variables produced by earlier steps. Like variables in code, a data variable is only available to steps added after the step that produced it. Steps that output data Many steps in axiom.ai output data. You can spot them by the orange plug icon in their header. Each variable has a unique name that identifies the step it came from, for example google-sheet-data, custom-data, or scrape-data. Steps that accept data Fields that accept data show an Insert data dropdown. Selecting a variable from the dropdown passes that data into the current step. These are some of the steps you can pass data into: Go to pageEnter textExtract data with ChatGPTGenerate text with ChatGPTExport CSVWrite to a Google SheetWrite JavaScriptJoin dataAppend data Select what data to pass When passing data, you can pass everything or select a subset. For variables that support this, a column-picker window appears when you add the data. To pass specific columns, click Clear all then click each column header you want to include. At runtime, the variable is replaced with the output from its associated step, exactly as if you had typed the data into the field manually. Steps that require data input Some steps need data passed in to function. If you add one of these steps before a step that outputs data, you'll see this warning: Warning: This step requires data input to function. You should add a step that outputs data before this one to use it. Data formats between steps Almost all step output is formatted as a two-dimensional array of rows and columns, the same as a spreadsheet. Steps that handle data accept this format and behave accordingly. Data in axiom.ai is immutable: once a step outputs data, no other step modifies it in place. When a step processes data, it reads the input variable and produces a new variable with the modified result. The original is left unchanged. This is how steps remove duplicates, filter rows, replace text, and so on. Data variable types Data variables store information for use during a run. axiom.ai has three variable types, each with a different appearance and behaviour. Global variable A global variable is accessible anywhere in the automation, and you always have direct access to all the data it holds. It is overwritten each time it's regenerated, so loops do not accumulate data into a global variable. To accumulate, use an accumulator variable instead. Loop variable A loop variable is the input to a loop. axiom.ai automatically selects the current row for each iteration. You can still pick a specific column from the row. Accumulator variable An accumulator is a special global variable that collects the output of every sub-step inside a loop. Data is appended in step order, and the accumulator persists across multiple loops.",{"id":2167,"title":2168,"titles":2169,"content":2170,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fselector-tool\u002Fcustom-css-selectors","Use custom CSS selectors",[],"Set custom CSS selectors in the Single Selector and Multi Selector tools to target elements that the default picker can't reach. The Single Selector and Multi Selector tools pick elements on a webpage for your automation to interact with. When the default picker doesn't get a unique match, you can supply your own CSS selector instead. For background on CSS selectors, see Additional resources. Add a custom CSS selector You can use custom CSS selectors in both the Single Selector and Multi Selector tools. Single Selector Open the Selector Tool by clicking Select in an interact step.Click Custom and enter your selector in the text box. Multi Selector Open the Selector Tool by clicking Select in an interact step.In the data column you want to target, click the arrow and choose Custom selector.Enter your selector in the text box. To set the custom selector dynamically from a data variable, click Set selector from data and pick the token that contains the selector. This is useful when you want to loop through several different selectors at runtime. Loop through custom selectors Use the Loop through data step to run an interaction against multiple custom selectors in turn. Common use cases: Click through multiple buttons on a page.Tick a series of checkboxes.Walk a list of items, perform actions on each, then move to the next.Scrape data from inconsistent layouts where each row needs a different selector. To set this up: Read. Add a Read data from a Google Sheet step to load your list of CSS selectors.Loop. Add a Loop through data step using the output of the Read data step.Interact. Inside the loop, add your interact step (for example Click element) and configure it using a custom CSS selector. Follow the instructions in Add a custom CSS selector.Run. Run the automation and check that each selector matches the right element. Tip: Use the Edit a row in a Google Sheet step to write scraped data back to the same row as the selector that produced it. Choose a good selector A good selector is unique to the element you want, and stable enough to keep working when the page changes. Some sites make this deliberately hard to deter automation. The examples below introduce the main selector types in the context of axiom.ai. For deeper tutorials, see Additional resources. To inspect the underlying HTML, right-click anywhere on the page and choose Inspect. Class-based selectors HTML: \u003Ch1 class=\"main-heading\">Interest rates cut for first time in over four years\u003C\u002Fh1> axiom.ai selector: .main-heading ID-based selectors HTML: \u003Ch1 id=\"main-heading\">Interest rates cut for first time in over four years\u003C\u002Fh1> axiom.ai selector: #main-heading Attribute-based selectors HTML: \u003Cinput aria-activedescendant=\"\" aria-controls=\"suggestions\" aria-expanded=\"false\" aria-haspopup=\"listbox\" id=\"searchInput\" placeholder=\"Search the BBC\" role=\"combobox\"> axiom.ai selectors (either works): [aria-controls=\"suggestions\"]\n[placeholder=\"Search the BBC\"] Grouped selectors When a single selector isn't unique, combine two or more to narrow the match. Try different combinations until the selector picks only the element you want. Group by class and element: header .consent-banner-text a Group by attribute and element: input[aria-controls=\"suggestions\"] Group by ID and element: #main-heading a Advanced selectors For more specific cases, CSS pseudo-classes give you finer control: :not() excludes elements that match a sub-selector. See :not() on MDN.:has() matches elements that contain a descendant matching a sub-selector. See :has() on MDN. For example, to select list items that don't also have the link class: p.list-item:not(.list-item.link) To target an anchor whose href contains checkout-: a:has([href*=\"checkout-\"]) Use nth-child() to target elements by position nth-child() selects an element by its position within a parent. This is useful for picking out one specific item from a list, or for looping through every item in a series. To loop through a series of elements, list each nth-child() selector as a row in a Google Sheet: Selectorbutton.download:nth-child(1)button.download:nth-child(2)button.download:nth-child(3) Then use a Loop through data step to set the custom selector on your interact step to each row in turn. Additional resources Selectors on MDNType, class, and ID selectors on MDNChrome DevTools CSS reference html pre.shiki code .s4rv2, html code.shiki .s4rv2{--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sjgCt, html code.shiki .sjgCt{--shiki-default:#116329;--shiki-dark:#7EE787}html pre.shiki code .sHrmB, html code.shiki .sHrmB{--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sSVrQ, html code.shiki .sSVrQ{--shiki-default:#0A3069;--shiki-dark:#A5D6FF}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 .sjeE4, html code.shiki .sjeE4{--shiki-default:#CF222E;--shiki-dark:#FF7B72}",{"id":2172,"title":2173,"titles":2174,"content":2175,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fselector-tool","The selector tool",[],"Use the no-code selector tool to pick elements to interact with, extract data from a page, and pass custom CSS selectors into your automations. The selector tool is how you tell axiom.ai which elements on a page to interact with or scrape. Use the Single Selector to target one element at a time, or the Multi Selector to extract data from a list. Both support custom CSS selectors and can accept selectors passed in from a data source. Tutorials for the selector tool Walk through each tool below. The Single Selector is the right starting point for most steps. Move on to the Multi Selector when you're working with lists or tables, and to custom CSS selectors when the visual selector picks an element that doesn't generalise across pages. Need help? Contact support or ask a question in our Reddit community. For a deeper look at building selectors, see our blog post on CSS attribute selectors.",{"id":2177,"title":2178,"titles":2179,"content":2180,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fselector-tool\u002Fmulti","Use the Multi Selector tool",[],"Point and click to select text, images, links, and HTML for extraction, group repeating content into rows, and apply custom CSS selectors. The Multi Selector tool is built into the web scraping steps, such as Get data from current page. It lets you point and click to choose what to extract from a webpage, set the data type for each column (text, image, link, or HTML), and group repeating content into rows. Advanced users can switch to custom CSS selectors when the visual picker isn't enough. Use the Multi Selector tool To start, use the step finder to search for scraper and add the scrape step you want. Click Select to start choosing the data to extract. The features below cover everything from a simple point-and-click selection to the grouping algorithm that powers row-by-row scraping. Select content The simplest way to choose data is to point and click. After you click Select, an orange highlight shows the selected element. Click an element again to unselect it. Set the data type (text, image, link, or HTML) to match what you want to extract. Use columns Columns arrange the data you extract into a table. Each column has its own selector, data type, and optional custom CSS selector. To add a column, click Add column or press Shift + N. Set the data type axiom.ai supports four data types: text, image, link, and HTML. Set the type per column based on what you want to extract. Click the dropdown menu at the top right of the column.Choose the data type. Group repeating content into rows axiom.ai detects patterns when you select two similar elements, then groups every matching element on the page into rows. This is how you scrape lists like profiles, search results, or product cards. For example, to scrape a list of profiles with names, job titles, and profile links: Select the first name at the top of the list.Scroll down and select another name further down. axiom.ai detects the pattern and selects every name in the list.Add a new column, change the data type to link, and select the same name again to capture its link. axiom.ai aligns the columns into rows automatically, so each profile's name, title, and link end up on the same row. Advanced features Custom CSS selectors For sites where the visual picker can't get a clean match, switch to a custom CSS selector. Any valid CSS selector works. For background and examples, see custom CSS selectors. To use a custom selector: Click the dropdown menu at the top right of the column.Choose Custom selector and enter your CSS selector. Pass a selector from a data source You can pass selectors into the Multi Selector from another data source, for example a Google Sheet. This lets you change which elements to scrape at runtime without editing the automation. Click the dropdown menu at the top right of the column.Choose Custom selector and tick Set selector from data.Click Insert data and choose your data source.",{"id":2182,"title":2183,"titles":2184,"content":2185,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fselector-tool\u002Fsingle","Use the Single Selector",[],"Use the no-code Single Selector to point and click an element on a page, type a text label to match it, paste a custom CSS selector, or pass selectors in from a data source. The Single Selector captures the location of an HTML element you want to interact with, like a button or input field, without writing any code. The most direct way to use it is point and click, but you can also match by text, paste a custom CSS selector, or pass selectors in from a data source. The Single Selector appears in the Click element, Enter text, Click multiple elements, Select list, and file upload and download steps. Use the Single Selector Open the step finder, search for a step that uses the tool (for example, Click element), and add it to your automation. Inside the step, click Select to start picking the element. Point and click The simplest way to pick an element is point and click. After clicking Select, hover over the page and click the element you want. The selected element is highlighted in orange. To deselect, click the element again. Advanced features Use a custom CSS selector Use the custom selector field to type or paste any valid CSS selector. This is useful when the point-and-click mode picks an element whose generated selector doesn't generalise to other pages, or when you already know the selector you need. For details on writing CSS selectors, see custom CSS selectors. Match by element text To pick an element by the text it contains, type the text into the selector. For example, type share to match a button labelled Share. This is useful when an element doesn't have a stable class or ID, but its visible label stays the same across pages. Pass selectors from a data source Selectors can be passed in from a data source, such as a Google Sheet. The automation loops through the selectors in the data source and runs the step against each one. This pattern is useful for repeating UIs like calendars, where each cell needs a different selector but the action against each is the same.",{"id":2187,"title":2188,"titles":2189,"content":2190,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Fthe-builder\u002Fsharing","Share an automation",[],"Download your axiom.ai automation as a template file so you can share it with our support team or with other users. Every axiom.ai user can download an automation as a template file and share it. Use this to send a copy to our support team if you need help, or to share working automations with other users. Download an automation to share Downloading takes a few seconds. Once you have the file, you can share it however you choose. To start, open the automation you want to share in the Builder. Click the gear icon in the vertical sidebar on the left of the Builder. Or click the kebab menu in the top right and choose Settings.In Settings, click Import or download.Under Share automation, click Download.",{"id":2192,"title":2193,"titles":2194,"content":2195,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferror-handling","Handle errors in an automation",[],"Catch errors with Try \u002F Catch, ignore them with Continue on error, handle empty loops gracefully, and get notified when runs fail. axiom.ai gives you a few ways to deal with errors that come up during a run. Use Try \u002F Catch to recover and continue along a different path, or continue on error to ignore failures entirely. Catch errors with Try \u002F Catch Wrap risky steps in a Try \u002F Catch step to handle errors without stopping the whole automation. The steps inside the Try branch run as normal. If any of them throw an error, the automation jumps to the Catch branch and runs those steps instead. For example, put a Get data from current page step in the Try branch and recovery actions in the Catch branch. If the data isn't found on the page, the automation runs the recovery actions instead of failing the whole run. Without Try \u002F Catch, the automation would stop at the failing step. Ignore errors with Continue on error By default, axiom.ai stops on the first error to prevent unexpected side effects. Toggle continue on error on to override that behaviour and let the automation push through errors. Note: With Continue on error enabled, every run reports as successful at the end regardless of how many errors occurred. Errors appear as warnings in run reports. First-iteration loop errors If a loop hits an error on its first row, axiom.ai treats it as a warning instead of an error. This means an empty data source or an unexpectedly bad first row doesn't stop the whole automation; subsequent iterations still run. Get notified on run status Set up notifications so you find out as soon as a run fails or finishes with warnings, instead of having to check the dashboard. Notifications can be sent by email or webhook and can fire on any combination of these events: A run fails.A run succeeds.A run succeeds with warnings.",{"id":2197,"title":2198,"titles":2199,"content":2200,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fdesktop-app","Desktop app errors",[],"Errors that can occur with the axiom.ai desktop application, including port conflicts that prevent the app from starting. The errors on this page can occur when running or debugging automations through the axiom.ai desktop application. Port 3333 in use Error: Port 3333 in use. Problem: The desktop app uses port 3333 to communicate with the Chrome extension. If another application is already bound to that port, or if a second instance of the desktop app is running, the app can't start. Common causes: Another desktop application is using port 3333.A second instance of the axiom.ai desktop app is already running.A previous axiom.ai process didn't shut down cleanly and is still holding the port.A firewall, antivirus, or system-level process is blocking the port. Fix: Work through these in order: Quit and reopen the axiom.ai desktop app.Check whether a second instance of the desktop app is running and quit it.If the issue persists, restart your computer to release any hung processes. If the error continues after a restart, contact support with details of any other applications you suspect may be using port 3333. Browser could not be started Error: Browser could not be started. This may be an incompatibility between the axiom.ai desktop application and your operating system. Please contact support@axiom.ai and let us know about the issue. This error can also occur on Mac if you have tried to load a missing or broken extension. Problem: This error has several possible causes: An incompatibility between the desktop app and your operating system.A Set executable path setting pointing at the wrong Chrome executable.A Load another extension setting pointing at a missing or broken extension.A hanging axiom.ai process on your machine. Fix: Work through these in order: Make sure your operating system is up to date. Older OS versions may not be compatible.Verify the Chrome path. See set executable path.Verify any loaded extension is installed and the path is correct. See load another extension.Restart your computer to clear any hanging processes.",{"id":2202,"title":2203,"titles":2204,"content":2205,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fgeneral","General errors",[],"Errors that can occur during automation runs, including server errors, version mismatches, concurrency limits, and browser launch failures. The errors on this page are general issues that can occur during automation runs or when starting the desktop application. Internal server error Error: Internal server error. Problem: If you see this in the extension or when running an automation in the cloud, axiom.ai may be experiencing a service issue. If you see this on a page that isn't part of axiom.ai, contact the owner of that page. Fix: The team is likely already working on a resolution. If the error persists, contact support. This step does not exist in your version of the axiom.ai desktop application Error: This step does not exist in your version of the axiom.ai desktop application. Problem: A version mismatch between the installed desktop application and the automation you're running. The automation contains a step that was added in a newer version. Fix: Update the desktop application by opening it. If the Builder shows update prompts, follow them to update individual steps to the latest version. Concurrency limit reached Error: All of your concurrency allocations are currently in use. Click below to stop them, or wait for them to finish. Problem: Your account has hit its concurrency limit. See the pricing page for the limits on each plan. Fix: Wait for in-flight runs to finish, or upgrade your plan for more concurrency. Cloud servers busy Error: Oh no, all our cloud servers are busy right now. Problem: Very rare. axiom.ai's cloud capacity is fully in use. Fix: Try again in a few minutes, or run the automation locally in the desktop app.",{"id":2207,"title":2208,"titles":2209,"content":2210,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors","Common errors",[],"Browse common errors by category to find the cause and recommended fix for issues with installation, runs, and the desktop application. This section lists the errors most commonly seen in axiom.ai. Pick a category below and search for the message you're seeing for a description of the cause and the steps to fix it. If you can't find the error you're experiencing, free users can ask in the Reddit community, and subscribers can contact customer support. Error categories The categories below group errors by where they originate. General covers errors that span the platform. Installation and Desktop app cover errors specific to those parts of the product. Steps and Integrations cover errors thrown by specific automation components. Runtime covers errors that surface during a run, regardless of which step caused them. Need help? Contact support or ask a question in our Reddit community.",{"id":2212,"title":2213,"titles":2214,"content":2215,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Finstallation","Installation and uninstallation errors",[],"Errors that can appear when installing or uninstalling the axiom.ai Chrome extension or desktop application, and how to resolve them. The errors on this page are related to installing or uninstalling the axiom.ai Chrome extension and desktop application. A JavaScript error occurred in the main process Error: A JavaScript error occurred in the main process. Problem: A long-standing Windows issue when uninstalling Electron applications: the uninstaller occasionally leaves files behind on disk. Fix: Remove the leftover files manually. axiom.ai stores few files on your machine, so this is a quick clean-up. Delete both of these folders, where \u003CUSER> is your Windows username: C:\\Users\\\u003CUSER>\\AppData\\Roaming\\axiom-desktopC:\\Users\\\u003CUSER>\\AppData\\Local\\Programs\\axiom-desktop A search for axiom-desktop from File Explorer also shows both folders. If axiom.ai was installed on a drive other than C:, adjust the path accordingly. Note: This issue is specific to Windows. If you see it on macOS or Linux, contact support.",{"id":2217,"title":2218,"titles":2219,"content":2220,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fintegrations\u002F2captcha","2Captcha errors",[],"Errors that can occur when using the Solve Captcha step with 2Captcha, mostly related to missing or invalid API keys. The errors on this page can occur when using the Solve Captcha step. For background on the integration, see the 2Captcha integration page. For errors returned directly by the 2Captcha API, see the 2Captcha API documentation. Invalid API key Error: 2captcha error: ERROR_WRONG_USER_KEY. Problem: The API key set on the Solve Captcha step doesn't match a valid 2Captcha account. Fix: Find your API key on the 2Captcha settings page, copy it in full, and paste it into API key on the step. Missing API key Error: 2Captcha API key: API key is required. Problem: The Solve Captcha step doesn't have an API key set. Fix: Sign up for a 2Captcha account if you don't already have one, then paste your API key into API key on the step. Note: 2Captcha charges a small fee per successfully solved captcha. See 2Captcha's pricing for current rates.",{"id":2222,"title":2223,"titles":2224,"content":2225,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fintegrations\u002Fai","AI integration errors",[],"Errors that can occur when using AI steps with OpenAI, Google Gemini, Anthropic Claude, or Perplexity Sonar, mostly related to missing or invalid API keys. The errors on this page can occur when using AI steps in an automation. axiom.ai's AI steps connect to several providers: OpenAI (ChatGPT and GPT models)Google (Gemini)Anthropic (Claude)Perplexity AI (Sonar) For background on the AI steps, see the ChatGPT integration page. API key not provided Error: You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. Problem: No API key was set on the AI step (for example a generate-text or LLM-prompt step). Fix: Set API key on the step. Get a key from the relevant provider's dashboard: OpenAI API keysGoogle AI Studio (Gemini)Anthropic Console (Claude)Perplexity API settings (Sonar) API key invalid Error: Incorrect API key provided. Problem: The API key on the step is invalid, expired, or doesn't match the provider expected by the step. Fix: Open the relevant provider's dashboard and check that: The key is still active.The key matches the provider the step is configured for.The key has no leading or trailing whitespace and was copied in full. If the key looks correct and the error persists, regenerate it in the provider's dashboard and paste the new key into the step.",{"id":2227,"title":2228,"titles":2229,"content":2230,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fintegrations\u002Fgoogle-sheets","Google Sheets errors",[],"Errors that can occur when reading from or writing to Google Sheets, including expired tokens, missing data, permission issues, and invalid ranges. The errors on this page are specific to the Google Sheets integration. For general background on the integration, see Google Sheets. Google access token has expired Error: Your Google access token is invalid or has expired. Please connect your Google account to continue. Problem: Google has revoked the token axiom.ai uses to act on your behalf, usually as a security precaution. This is controlled by Google, not axiom.ai. Fix: Reconnect your Google account and re-run the automation. No data in Google Sheet Error: No data read from spreadsheet, aborting run. Turn on Continue when empty in this step if you want the run to proceed. Problem: The automation couldn't find any data in the Google Sheet referenced by the step. Most often this is because the sheet itself is empty, but it can also happen if the sheet name or cell range points at an empty area. Fix: Confirm there's data in the sheet. If you genuinely want the automation to continue when the sheet is empty, enable Continue when empty on the Read data from a Google Sheet step. No editor permission for Google Sheet Error: You do not have editor permissions for this Google Sheet with the Google account connected to your axiom.ai account. You will not be able to write to it. Problem: The Google account connected to axiom.ai has read-only access to the sheet, so write operations fail. Fix: Check the share settings on the Google Sheet. If you don't have editor access, ask the sheet owner to grant it. Sheet not found Error: The sheet cannot be found. Please verify the URL and the name are valid. The error can also appear as Requested entity not found. Problem: The Google Sheet URL or sheet tab name set in the step doesn't match a sheet your connected Google account can see. Fix: Check the spreadsheet URL and the sheet name set in the step. Confirm the sheet exists, hasn't been deleted, and is shared with the Google account connected to axiom.ai. First cell is not correctly formatted Error: First cell value is not in the correct format. It should be capital letters followed by optional numbers. For example, B10 starts from column B and row 10. Problem: The value in First cell doesn't match Google Sheets' cell-reference format. This field appears in every spreadsheet step. Fix: Set First cell to a valid cell reference, for example A2 or B10. Invalid range Error: Invalid range set in step. Please adjust the value in Add to existing data to a valid range. Problem: The range entered under Add to existing data in the Write data to a Google Sheet step isn't a valid Google Sheets range. Fix: Set the range to a valid value such as A2:B10 or a single cell like A2. Values must be strings Error: Values must be strings. Found value undefined of type undefined on row 1. Problem: axiom.ai writes string values to Google Sheets. A row in the data being written contains a value that isn't a string (often undefined from an upstream step that didn't produce data). Fix: Trace the data variable feeding the write step back to its source. Confirm every cell contains a string. If some rows can be empty, use a Replace text step or a Write javascript step to substitute an empty string for any undefined values before writing. Cannot delete all rows Error: You can't delete all the rows on a Google Sheet. Please make sure your sheet contains either empty rows, or rows with data. Problem: Google Sheets requires at least one row in every sheet, so deleting them all isn't allowed. Fix: Adjust the Delete rows from a Google Sheet step so at least one row remains. Either lower Last row to delete, or leave the header row in place. Google Sheets unavailable Error: Unable to fetch data from the Google Sheet. Please try again shortly. If the issue persists, contact customer support. Problem: axiom.ai couldn't reach Google Sheets. This is usually a temporary network issue or a Google Sheets outage. Fix: Wait a few minutes and try again. If the error persists, contact support.",{"id":2232,"title":2233,"titles":2234,"content":2235,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fintegrations","Integration errors",[],"Browse errors specific to axiom.ai integrations including Google Sheets, AI providers, and 2Captcha, with the cause and recommended fix for each. This section lists the errors most commonly seen with axiom.ai integrations. Pick a category below and search for the message you're seeing for a description of the cause and the steps to fix it. If you can't find the error you're experiencing, free users can ask in the Reddit community, and subscribers can contact customer support. Integration error categories Need help? Contact support or ask a question in our Reddit community.",{"id":2237,"title":2238,"titles":2239,"content":2240,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fruntime","Runtime errors",[],"Errors that occur while an automation is running, including missing elements, browser navigation issues, and runtime limits on long jobs. The errors on this page occur during an automation run. Selectors found no content Error: Your chosen selectors have failed to find any content on the page. The error can also appear as Could not find the requested element, Error in all rows of loop, or Error in all rows of loop, your chosen selectors have failed to find any content on the page. Problem: The element your step is configured to interact with isn't on the page. Common causes: The selector is inconsistent across pages.The automation is on the wrong page when the step runs.The page hasn't finished loading.The site is blocking the automation. Fix: Confirm the element is on the page when you load it manually, and that the automation is on the correct page when the step runs. To handle slow-loading pages, increase the minimum wait time in the step's configure scraper options. If the site is blocking the automation, try the desktop app or bypass bot detection. If none of these resolve the issue, contact support. Browser closed Problem: The browser was closed while the automation was still running. Fix: Don't close the browser during a run. If the browser closes on its own, contact support. Execution context was destroyed, most likely because of a navigation Error: Execution context was destroyed, most likely because of a navigation. Problem: The browser navigated away from the page or tab the automation was working on. Fix: Don't switch tabs while a run is in progress. If the automation needs to follow a link that opens in a new tab, handle the switch with the Switch browser tab step. Runtime errors on long automations Problem: Larger automations can hit single-run runtime limits or concurrency limits. Fix: Break large jobs into smaller batches. For example, split a 10,000-record scrape into ten runs of 1,000 records each. This reduces the chance of a single error costing you the whole job and makes restarts much faster. For runtime and concurrency limits per plan, see the pricing page.",{"id":2242,"title":2243,"titles":2244,"content":2245,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Fcontrol-flow","Control flow step errors",[],"Errors that can occur with control flow steps including Jump to another step and Continue only if a condition is met. The errors on this page can occur with control flow steps such as Jump to another step and Continue only if a condition is met. Jump target step does not exist Error: Jump to another step: Step number given does not exist in this axiom. The error can also appear as Step number given does not exist in this axiom. Problem: The step number set in Jump to step on a Jump to another step step doesn't match an actual step in the automation. This often happens after deleting or reordering steps. Fix: Open the Jump to another step step and update Jump to step to a step that exists. After moving steps around in an automation, check every jump step still points where you intended. Continue condition did not pass Error: Continue condition check did not pass. Problem: A Continue only if a condition is met step's condition evaluated to false (or to true if Reverse condition was on), so the automation stopped at that point. Fix: Watch the run to see what value Data to check actually contained when the step fired, then adjust Condition to check to match the data you're seeing. If the failed condition should be a clean stop rather than an error, leave Fail if condition not met off; the automation will end without an error.",{"id":2247,"title":2248,"titles":2249,"content":2250,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Ffiles","File step errors",[],"Errors that can occur with file steps including Upload a file and Download file, with the cause and recommended fix for each. The errors on this page can occur with file upload and download steps. File to upload not found Error: Could not find the file to upload. Please double check that a file exists at the given path. Problem: The path set on an Upload a file step doesn't point at a file that exists when the automation runs. Fix: Open the Upload a file step and click Click to select to browse for the file. Confirm the file is at that path on the machine running the automation. For desktop runs that's your local machine; for cloud runs you'll need a path the cloud runner can reach (typically a Google Drive file via the Upload a file from Google Drive step instead). File download did not start Error: File download did not start. Problem: axiom.ai triggered the download but no file started downloading. The most common cause is a network issue or the site blocking the download. Fix: Try the download manually in your browser to confirm it works at all. If it does, run the automation in the desktop app so the local browser handles the download instead of the cloud runner. Could not create folder Error: Couldn't create folder. Try a different location or change write permissions. Problem: A Download file step couldn't create the destination folder. Either the parent folder doesn't exist, or the user running axiom.ai doesn't have write permission for the location. Fix: Check that the parent folder exists. axiom.ai can only create one folder at a time, so a path like \u002FDownloads\u002Fscrapes\u002F2025\u002Fjanuary fails if 2025 doesn't already exist. Confirm your user account has write permission for the destination.",{"id":2252,"title":2253,"titles":2254,"content":2255,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps","Step errors",[],"Browse errors specific to axiom.ai steps by category, including interact, scrape, navigate, loop, files, control flow, JavaScript, and webhooks. This section lists errors specific to individual step categories. Pick a category below and search for the message you're seeing for a description of the cause and the steps to fix it. If you can't find the error you're experiencing, free users can ask in the Reddit community, and subscribers can contact customer support. Step error categories Need help? Contact support or ask a question in our Reddit community.",{"id":2257,"title":2258,"titles":2259,"content":2260,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Finteract","Interact step errors",[],"Errors that can occur with interact steps including click, enter text, and press key, with the cause and recommended fix for each. The errors on this page can occur with interact steps such as Click element, Enter text, and Press key(s). Element not found on page Error: Your chosen selectors have failed to find any content on page. The error can also appear as Could not find the requested element, Error in all rows of loop, your chosen selectors have failed to find any content on page, or Node is either not clickable or not an HTMLElement on row 1. Problem: The element selected in the step wasn't on the page when the automation ran. Common causes: The page didn't finish loading before the step fired.The page changed since the automation was set up, and the selector no longer matches.The automation is on a different page from the one the selector was built against. Fix: Re-select the element using the selector tool inside the failing step. If the page is slow to load, increase the minimum wait time in the step's configure scraper options. Text is not iterable Error: Text is not iterable. Problem: An Enter text or Press key(s) step has an empty Text field. Fix: Set Text on the step to a value, or pass data in via Insert data. Character not recognised Error: (Something) is not a character. Problem: The text contains a character axiom.ai doesn't recognise as a single character. This often happens with copy-pasted content that includes hidden formatting or zero-width characters. Fix: Look at the text in the failing step and replace any unusual characters. If the text was copy-pasted, retype it manually to strip any invisible metadata. Browser closed Error: Browser closed. The error can also appear as Automation could not continue as all open browser tabs were closed. Problem: The browser or all of its tabs were closed during the run. Fix: Keep the browser open while the automation runs. To run unattended without this risk, run the automation in the cloud instead of on the desktop.",{"id":2262,"title":2263,"titles":2264,"content":2265,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Floop","Loop step errors",[],"Errors that can occur with loop steps, including how to debug a loop where every iteration fails. The errors on this page relate to the Loop through data step. Most loop errors are caused by a step inside the loop failing on every iteration, not by the loop itself. Error in all rows of loop Error: Error in all rows of loop. The error appears with the underlying message appended, for example Error in all rows of loop, your chosen selectors have failed to find any content on page. Problem: A step inside the Loop through data step failed on every iteration. The text after the comma is the actual error from the failing inner step. The wrapping \"Error in all rows of loop\" prefix tells you the failure is consistent rather than intermittent. Fix: Look up the underlying error in its specific section: Could not find the requested elementYour chosen selectors have failed to find any content on pageProtocol error (Page.navigate)Evaluation failed",{"id":2267,"title":2268,"titles":2269,"content":2270,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Fmisc","Other step errors",[],"Errors that don't fit other step categories, including JavaScript runtime errors from the Write javascript step. The errors on this page don't fit the other step categories. JavaScript runtime error Error: [javascript error message]. Please check your code. Problem: A Write javascript step threw an error when it ran. The actual JavaScript error appears in place of [javascript error message] in the displayed message. Fix: Read the JavaScript error in the message itself; it tells you what went wrong (a syntax error, an undefined variable, a failed network call, and so on). For tips on debugging JavaScript steps, see Debug an automation.",{"id":2272,"title":2273,"titles":2274,"content":2275,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Fnavigate","Navigate step errors",[],"Errors that can occur with navigate steps including Go to page and Switch browser tab, with the cause and recommended fix for each. The errors on this page can occur with navigate steps such as Go to page and Switch browser tab. Cannot navigate to blank URL Error: Cannot navigate to blank URL. Problem: A Go to page step has an empty URL field. Fix: Set URL on the step to a valid URL, or disable the step if it isn't needed. Cannot open this URL Error: Could not open this URL. Problem: The URL set in the Go to page step isn't valid or isn't reachable from axiom.ai's runner. Fix: Open the URL manually in your browser to confirm it loads. Check for typos, expired links, or sites that block traffic from cloud runners. Tab does not exist Error: Switch browser tab: You are attempting to switch to browser tab {tab_number} but only {open_count} browser tabs are open. Problem: A Switch browser tab step is set to a tab number that doesn't exist when the step runs. For example, the step is set to switch to tab 3 but only 2 tabs are open. Fix: Watch the automation run to see how many tabs are open at the moment the Switch browser tab step fires, then update Tab position on the step to match. If the tab count varies between runs, set the position to Last opened tab instead of a fixed number.",{"id":2277,"title":2278,"titles":2279,"content":2280,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Fscrape","Scrape step errors",[],"Errors that can occur with scrape steps including Get data from a URL and Get data from current page, with the cause and recommended fix. The errors on this page can occur with scrape steps such as Get data from a URL and Get data from bot's current page. Element not found on page Error: Your chosen selectors have failed to find any content on page. The error can also appear as Could not find the requested element or Error in all rows of loop, your chosen selectors have failed to find any content on page. Problem: The element selected in the step wasn't on the page when the automation ran. Common causes: The page didn't finish loading before the scrape fired.The page changed since the automation was set up, and the selector no longer matches.The automation is on a different page from the one the selector was built against. Fix: Re-select the element using the selector tool inside the failing step. If the page is slow to load, increase the minimum wait time in the step's configure scraper options.",{"id":2282,"title":2283,"titles":2284,"content":2285,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Ferrors\u002Fsteps\u002Fwebhooks-api","Webhook and API step errors",[],"Errors that can occur when using the Trigger webhook and Receive data from another app steps, including JSON validation issues and missing test data. The errors on this page can occur with steps that send or receive data over webhooks. For errors returned by the axiom.ai API itself, see API errors. Text must be valid JSON Error: Text must be a valid JSON string. The error can also appear as (Something) is not valid JSON. Problem: The payload set on a Trigger webhook step isn't valid JSON. Fix: Check the payload for syntax issues such as missing quotes, trailing commas, or unescaped characters. Paste it into an online JSON validator if you're unsure. Webhook returned an error Error: Webhook server returned an error. Please check your JSON for errors. Problem: axiom.ai sent the payload, but the receiving server responded with an error. The cause is on the receiving end, not in axiom.ai. Fix: Check what the receiving service expects. Common causes include payload structure mismatches, missing authentication headers, or a service outage on the receiving end. No data received from webhook Error: No data has been received from an external service and no test data entered for this step. Problem: A Receive data from another app step ran without any data flowing in from the trigger, and no test data is set on the step. Fix: When testing the automation manually, toggle Test data on and set a sample 2D array so the step has something to work with. When triggering from a webhook, check the upstream service is actually sending data in the format axiom.ai expects.",{"id":2287,"title":2288,"titles":2289,"content":2290,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting\u002Fhow-to-debug","Debug an automation",[],"Use the in-builder error messages, debugger, run reports, and steps like Display a message and Add error metadata to find the cause of a failing automation. There are several ways to debug an automation in axiom.ai. The fastest path is to read the error message, follow its recommended action, and use the in-builder debugger. When that's not enough, the Display a message and Add error metadata steps let you inspect data during a run. For background on specific errors, see common errors. Read the in-builder error messages When an automation hits an issue, errors and warnings appear inline in the Builder. The message describes what went wrong and often suggests how to fix it. Read these first; most issues can be resolved straight from the message. Use the debugger Every error message includes a Debug button. Clicking it opens the debugger, which highlights the steps with issues and suggests an action to fix each one. Check run reports If you missed the in-builder message (for example, on a scheduled or cloud run), check Run reports in the dashboard. Every run is logged there with the same error and warning detail. Watch the run Watching the automation run is one of the most useful debugging techniques. Screen-record it if you can, then play it back to see exactly where things go wrong. While watching, look for: Elements missing from the page.The order of elements changing.Loading issues.Captchas being triggered. Use the Display a message step The Display a message step opens a pop-up showing the data you pass into it. Use it like a print statement to confirm what's flowing between steps. To inspect data partway through a run, open the step finder and add a Display a message step. Click Insert data and pick the variable you want to see. For example, drop a [scrape-data] token into the message after a Get data from current page step to confirm the right rows are being scraped. Tip: Disable your Display a message steps before shipping the automation. They add pop-ups to every run and aren't needed in production. Use the Add error metadata step The Add error metadata step attaches extra context to errors. Place it before a step that might fail, and the metadata is included in the error if that step throws. For example, if you're passing a variable into an Enter text step and the step sometimes fails on bad input, add an Add error metadata step beforehand that includes the variable's contents. The error message then tells you exactly what value caused the failure. Use Chrome DevTools Chrome DevTools is built into Chrome. The Console tab shows warnings and errors from the page itself, plus anything you log from the Write javascript step. To open DevTools, right-click the page and choose Inspect, then switch to the Console tab. If you're debugging a Write javascript step, use console.log() inside the script to see values during the run. This can also help diagnose issues with the page itself rather than the automation. For more on DevTools, see the Chrome DevTools documentation. Note: DevTools is only available for desktop runs. Cloud runs close the browser when they finish, so you may need to add a Wait step at the end of the automation to keep the window open long enough to inspect the console.",{"id":2292,"title":2293,"titles":2294,"content":2295,"level":56},"\u002Fdocs\u002Fno-code-tool\u002Ftroubleshooting","Troubleshooting",[],"Tools and patterns for debugging an axiom.ai automation, handling errors gracefully, and finding the cause when a run fails. When an automation fails or behaves unexpectedly, the pages in this section help you find out why. Use the debugger and Display a message step to inspect what's happening during a run, and the error handling guide to keep an automation running through expected failures. Troubleshooting guides Start with the debugger when you need to see what's happening during a run. Move on to error handling once you understand the failure and want the automation to react to it gracefully. The common errors reference covers specific error messages, what they mean, and how to fix each one. Need help? Contact support or ask a question in our Reddit community.",{"id":2297,"title":2298,"titles":2299,"content":2300,"level":56},"\u002Fdocs\u002Fsupport","Get support",[],"Reach out for help with an axiom.ai automation through the customer support form, the Reddit community, or a dedicated Slack channel. Subscribers can contact us through the customer support form or the Reddit community. Ultimate and Pro-max subscribers receive priority support, we aim to respond the same working day. For all other subscribers, we aim to reply within two working days, often sooner. Our operating hours are Monday to Friday, 9am to 5pm GMT, excluding public holidays. Support for subscribers Subscribers can contact us through the customer support form or the Reddit community. Response times depend on your plan: PlanResponse targetUltimate, Pro-maxSame working dayAll other paid plansWithin two working days, often sooner To get the fastest possible turnaround on any plan, send us as much detail as you can up front. Missing context slows the back-and-forth. We recommend including: A screen recording of the automation run.The automation experiencing the issue. See sharing your automation for how to export it.The target webpage exported as HTML, so we can reproduce the run against the same page snapshot.A walk-through of what the automation is meant to do and where it's going wrong.Any Google Sheets used in the automation, shared with support@axiom.ai with editor permission.Notes on what you're seeing during the run versus what you expect to see. Tip: the Chrome extension can export the automation and the target webpage from the same place. When editing an automation, click the Customer support icon in the left sidebar. A drawer opens with buttons to download both, ready to attach to your support request. Reddit support Our Reddit community is growing, and we'd love you to be part of it. We post news and documentation updates there and encourage every user to share questions, ideas, and issues. Team members are active in the community, and other users often weigh in with their own experience. For feedback, post in the feedback megathread. If you're looking for someone to build an automation for you, post in the community with the Seeking Bot Builder flair. Read the auto-response on those posts for important guidance before posting. Slack support Higher-tier subscriptions include a dedicated Slack channel between your organisation and ours. Slack works best for quick how-to questions and simple issues. For complex problems, the customer support form is still the better channel, you'll get the same priority either way. The Slack channel is for asynchronous conversation and is monitored during our operating hours. There's no need to @-mention team members. We'll get back to you as soon as we can. When you sign up for a plan that includes Slack support, you'll receive an email with the setup details. If you don't receive that email, contact us through the customer support form. When asking for help in Slack, include: Your question or a description of the issue.Notes on what you're seeing during the run versus what you expect to see.Any Google Sheets used in the automation, shared with support@axiom.ai with editor permission. Note: Slack support is only available on select plans. See pricing for details. Support for non-subscribers Non-subscribers can reach out through the customer support form or post in the Reddit community. The community is a one-stop shop for support, automation building tips, and product news. Everyone's welcome, including users who are just thinking about getting started with axiom.ai.",{"id":2302,"title":2303,"titles":2304,"content":2305,"level":56},"\u002Fextension-uninstalled","Extension uninstalled",[],"Sorry to see you go. Tell us why you uninstalled axiom.ai — your feedback shapes what we build next.",{"id":2307,"title":2308,"titles":2309,"content":2310,"level":56},"\u002F","browser automation for humans and AI",[],"Build bots with no-code, code them, or describe them to Claude. axiom runs on our cloud or your machine.",{"id":2312,"title":707,"titles":2313,"content":2314,"level":56},"\u002Finfrastructure\u002F_api",[],"Three layered APIs with one key. Chrome API for low-level browser control, Step API for high-level browser actions, and Orchestrate API to trigger any automation — code or no-code.",{"id":2316,"title":2317,"titles":2318,"content":595,"level":56},"\u002Finfrastructure\u002F_privacy","Build with Claude",[],{"id":2320,"title":2321,"titles":2322,"content":2323,"level":56},"\u002Finfrastructure\u002Fcloud","Cloud Browser Infrastructure",[],"Run managed Chromium in the cloud or locally, isolated per run. Trigger from the No-Code Tool, API, MCP, or CDP, with built-in concurrency and queuing.",{"id":2325,"title":2326,"titles":2327,"content":2328,"level":56},"\u002Finfrastructure\u002Fdesktop","Local Browser Automation on Desktop",[],"Run unlimited browser bots on your own machine. Local scheduling, no data leaves your computer, built for privacy-sensitive and regulated teams.",{"id":2330,"title":2331,"titles":2332,"content":2333,"level":56},"\u002Finfrastructure","Private Browser Infrastructure",[],"Browser infrastructure for code, no-code, and AI bots. The same Chromium runtime runs every automation, in the cloud or locally on your own machine.",{"id":2335,"title":2336,"titles":2337,"content":2338,"level":56},"\u002Finstall-desktop-app","Install the desktop runner for axiom.ai's browser automation extension",[],"Install the axiom.ai desktop app on Linux, Windows or Mac to automate your browser with no code. Build bots to scrape data, fill forms and more using your local machine.",{"id":2340,"title":2341,"titles":2342,"content":2343,"level":56},"\u002Fno-code-tool","No-code tool for making browser automations in Chrome",[],"The axiom.ai Builder features a range of no-code steps to automate browser tasks—from web scraping and AI data extraction to form filling—without writing a single line of code.",{"id":2345,"title":2346,"titles":2347,"content":2348,"level":56},"\u002Fpricing","Pricing",[],"Browser automation plans starting free with 2 hours of runtime, no card required. Pro adds scheduling; Pro Max adds parallel runs; Ultimate unlocks everything.",{"id":2350,"title":2351,"titles":2352,"content":2353,"level":56},"\u002Fprivacy-policy","Privacy Policy",[],"We don't store, share, or train AI on your data. Bots process data in your browser, then it's gone. Read the full privacy policy. axiom.ai is built for privacy\n  axiom.ai bots process data. We do not store, share or train AI's with your data. Once processed, any data used is deleted.\n  \n    Privacy policy\n    \n      We only store customer account information and configuration settings\n      No data is used to training AI's\n      We do not share or sell customer data to third parties.\n      All data processsed during runtime is encrypted\n    \n  Our data policyThe intent of this policy is to inform the user of the axiom.ai software about the data we collect and use or otherwise process during the use of the software, and to detail our responsibilities under legislation such as GDPR. For the purposes of this information, axiom.ai AI is classified as a data processor.What data is processed and why?For use of the software, login details connected to an email address are stored. This is required for account authentication.For operation of the product, certain data will be stored by axiom.ai, in order for the system to access resources required for its operation. Data collected takes the following form:API details for particular services, in the form of API keysThe individual steps of automations created, along with configuration parametersPersonal account detailsWhere possible axiom.ai uses its own internal credentials to perform its functionality, but be aware that some functionality of the axiom.ai software requires this data to be stored to operate. These features can be used at your discretion and will be clearly communicated.axiom.ai is able to make use of your existing session data in order to allow automations to work consistently. This data consists of cookies and local storage values set in the browser that is running the Chrome extension. Only required cookies and storage values are used. When using the desktop application, this session data is shared locally with the application, and does not leave your machine. When using the cloud service, this data is sent to our cloud run servers in order for your automation to run successfully. Any such data is not stored and is permanently deleted immediately after usage. The cloud service is provided for user convenience only; the desktop application is always available for download if this behaviour is not desired.axiom.ai may collect and monitor usage statistics for the purposes of improving the software, including use in learning algorithms. This data is anonymised and not associated with any particular personally identifiable information.axiom.ai may use these details for system-level communications, such as notifications of completed automation runs, or problems in running a particular job. These notifications are opt-in and not required for the system's operation; all such data is available on demand when logged into the software.axiom.ai does not use stored user data to train AI or machine learning models. We also do not use any data we process as part of runs to train AI or machine learning models. This includes data from all external sources, for example Google Sheets and Google Drive.Finally, stored data may be used from time to time in marketing operations conducted by the company. This usage is subject to explicit consent.Google dataGoogle data is processed on an opt-in basis using APIs provided by Google. Granting consent to the axiom.ai application allows us to perform the following actions:Read, write, update and delete any Google Sheet in the granted accountRead, write and delete any Google Drive file in the granted accountAccess to such data is given only to allow you to use these features in automations built or configured by you, the user, when adding one or more of the following functions to an automation you are building:Read data from a specified Google SheetWrite data to a specified Google SheetDelete a specified Google SheetCreate a new Google Sheet in your Google Sheets accountUpload a specified file from Google Drive to a websiteDownload a file from a website to your Google Drive accountThe use of any of these features is optional and is not required to use the axiom.ai software.Any data we access in your Google Sheets or Drive account is not stored on our infrastructure, and is accessed by us only in transit. Such data is encrypted by SSL during this process. Your data is not used by axiom.ai in any way, including for the training of machine learning or AI models, for marketing, or for any other purpose outside of those explicitly stated above.No data from your Google account is transferred to or shared with any third party. During transit, the data is processed using infrastructure provided by Amazon Web Services (AWS). This data is processed in transit only, is not stored on any short or long-term storage system, and is encrypted end-to-end.If at any time you wish to revoke axiom's access to your Google data, you can do so within the axiom.ai user interface at any time. All Google access tokens will be immediately revoked.Data SecurityLogin data for the axiom.ai product itself is encrypted with a salted hash and stored in a secured database.Personal data is also stored in a database. It is not accessible to other users of the product and access to this is behind an SSL-encrypted security layer.axiom.ai continually monitors and will update this security policy according to developments in best practice or other domains.Data StorageData is stored only for as long as required for operation of the service. At any time this data may be voluntarily withdrawn, at which point all personal data related to a particular user or organisation will be immediately and permanently removed from the system. Withdrawing the data in this way will terminate operation of the software immediately.Any anonymous data collected during the operation of the software will remain in the system; we are unable to remove this data because it is not associated with any identifiable account details.User Rightsaxiom.ai guarantees the following user rights for all personal data stored, in accordance with GDPR regulations.The right to be informedThis document aims to lay out how data is stored by axiom.ai and for what reason.Queries can be directed to at privacy@axiom.pm if any further information is required, or if you have any concerns that need addressing with this policy.The right of accessUsers have the right to access their personal information at any time.As much information as is feasibly possible will be exposed through accessible user interface elements.The right to rectificationUsers have the right to alter or correct any personal information stored in the system at any time.This functionality is available directly through the Axiom application, or can be altered by direct request.The right to erasurePersonal information can be erased on request at any time. Please see the 'Data Storage' section for further information.The right to restrict processingUsers have the right to restrict processing at any time. This means we can continue to store the data, but not use it for any purpose.Please note that exercising this right will cease operation of the axiom.ai software.The right to data portabilityAny personal information supplied to axiom.ai is guaranteed to be accessible and portable to other services.We will not hide or otherwise store personal information without providing equivalent methods to access and retrieve this data.The right to objectUsers have the right to object to the use of personal data, for example in marketing communications or other uses of their data.Users have an absolute right to object to the use of their data in regards to marketing.Note that in other cases, if there are legitimate reasons for the use of this data, objections will not necessarily result in removal or a change of behaviour.",{"id":2355,"title":2356,"titles":2357,"content":2358,"level":56},"\u002Fsteps","No-code steps for browser automation",[],"The axiom.ai no-code builder features a range of no-code steps to automate browser tasks—from web scraping and AI data extraction to form filling—without writing a single line of code. Get data Point and click web scraperAI Extract data or generate text with LLMsWeb actions Click buttons, interact with UILooping and logic Click buttons, interact with UIFilters Proxies and IP rotationFiles Upload and download filesWebhooks Send and receive datadebugging Upload and download filesIntergrations Get past turnstile Use the selector tool in the get data from webpage steps to point and click on data you wish to scrape from virtually any website. Combine it with our ChatGPT step to extract unstructured data. For an example of what's possible with our no-code steps, check out this guide. Can't find a step that meets your needs? We're building this tool for you, so if there's a step you'd like to see added, reach out and share your idea. If it's within scope, we'll do our best to include it in a future release. Simply contact customer support. In the meantime if you are keen to learn more check out these guides and tutorials listed below.",{"id":2360,"title":2361,"titles":2362,"content":2363,"level":56},"\u002Fsuccess","You're all set",[],"Your axiom.ai account is ready. Start building automations in the Chrome extension, write a code script in the Code Dashboard, or use the Claude skill to build with AI.",{"id":2365,"title":2366,"titles":2367,"content":2368,"level":56},"\u002Fterms-of-use","Terms of use",[],"Read the axiom.ai terms of use, including acceptable use, license terms, account responsibilities, and support contact. Terms of Use\n  Contact us using support@axiom.ai for any queries or concerns you may have regarding terms of use or any aspect of the Services provided.\n  \n    Acceptable Use\n    \n      Only use axiom.ai for purposes that are legal in your region or operation.\n      Do not use any measures to bypass any license restriction applied by axiom.ai.\n      You will not use our Services for the purposes of spamming or distributing malware.\n      You will back up or otherwise secure any data or sensitive material that will be used in relation to the operation of any of the Services.\n    \n  Definitions\"axiom.ai\" \"Axiom\" \"we\" \"us\" \"our\" refers to Axiom Ai Limited, a limited company registered in the United Kingdom (company number 11171985).\"Services\" or \"Products\" means axiom.ai's websites, applications and browser extensions, including any online services, products, software applications, improvements, updates, patches and enhancements, together with the associated documentation (excluding any publicity or marketing materials) and any other content of axiom.ai such as videos or blog posts. In addition:\"Extension\" refers specifically to the Axiom AI Chrome Extension, either obtained from the Chrome web store at https:\u002F\u002Fchrome.google.com\u002Fwebstore\u002Fdetail\u002Faxiom-automations\u002Fcpgamigjcbffkaiciiepndmonbfdimbb or by any other means.\"Builder\" refers specifically to the Axiom AI Builder tool that is included with the Chrome Extension\"Application\" refers specifically to the desktop application that is installed in order to run Axiom automations on the user's own computer\"you\" means any individual or a company or organization that has, accesses or directs the use of, an account with us, or is testing or using the Services; \"your users\" means your affiliates and employees or equivalent contractors.\"Content\"\"Automations\" means anything developed for use with the functionality provided by the Services, for any purpose whatsoever.GeneralTo use the Services, you must be at least 16-years old or have full capacity to contract according to your country of residence. You might use the Services for yourself or your employer\u002Fsimilar contractor (which we call here the \"Entity\") and if you sign on for axiom.ai's Services on behalf of your Entity (for instance, by using your business email at registration), axiom.ai assumes you have the relevant power and capacity to do so and references to \"you\" will include both you as individual and the Entity.Although we will take reasonable steps to notify you of material changes to the Terms of Use, axiom.ai reserves the right to change the Services and the Terms of Use from time to time without prior notice. If you continue to use the Services after any change, axiom.ai will assume that you have agreed with said change to the Services and the Terms of Use. Your only remedy for your dissatisfaction with the Services, the Terms of Use or any updates, is to stop using the Services.You may not assign or otherwise transfer these Terms of Use or your rights and obligations under the Terms of Use, in whole or in part, without axiom.ai's written consent and any such attempt will be void. axiom.ai may transfer its rights under these Terms of Use to a third party, in which case these Terms of Use will be updated and made available on the axiom.ai website.If you're a legal entity, you hereby grant axiom.ai a transferable, sub-licensable, royalty-free, non-exclusive, worldwide, valid for the entire duration of the rights, license to copy, host, store, assess, test, distribute, modify, publicly perform, display, prepare derivative works of, incorporate into other works and otherwise use your trademarks, service marks and logos in our marketing materials, for the purpose of promoting our Services and marketing your participation.You may contact us using support@axiom.ai for any queries or concerns you may have regarding this document or any aspect of the Services provided.Licenseaxiom.ai hereby agrees to provide you the right to use the Services, under a limited, non-exclusive, non-transferable, non-sublicensable and revocable license.You hereby give axiom.ai an unlimited, perpetual, transferable, sub-licensable, non-exclusive, worldwide and royalty free license to use, host, store, copy, distribute, assess, test, modify, publicly perform, display, create derivative works of, incorporate into other works, and otherwise use, any of your automations, content, suggestions, ideas and other feedback, without any restriction or compensation to you, for the purpose of providing our Services and managing our platforms. axiom.ai may independently acquire, license, or develop, any intellectual property rights and technology performing similar functions as the software\u002Fworkflows developed by, or for, you.Contentaxiom.ai is not liable, nor has any responsibility for, any Content developed using the Services, except in cases where axiom.ai has developed that Content. This includes, but is not necessarily limited to, the following cases:a. Content developed by you\nb. Content developed by a third party for you, where that third party is not axiom.ai\nc. Any flaw or problem caused by Content falling under this clause is entirely and completely the responsibility of the user, i.e. you. axiom.ai will take reasonable efforts to safeguard your account from malicious usage, but any damage or distress caused by the app under operation from Content not created by axiom.ai is not supported and cannot be guaranteed to function.Privacy and Securityaxiom.ai is GDPR compliant as a Processor of data. Your data will be used by our system solely in order to operate the Services, and any data that is used to provide said Services will be deleted immediately after usage.axiom.ai collects analytics data as part of its functionality. This data includes, but is not necessarily limited to, the following:Data relating to UI activity within the Extension, including tracking of clicks and page viewsData relating to activity within the Application, including details on the running of the extension (data from the output is not stored)Data relating to account activity within the services, such as logging in and out, session data, and times that you are active on the Servicesaxiom.ai is not liable in any way for privacy and security issues brought about by Content provided either by you or by a third party who is not axiom.ai itself. You, the user, takes full responsibility for any operation of third-party Content, and agrees to abide by all applicable Privacy and Security agreements that may be applicable to your use of the Services.Axiom does not store the results of any automation. However, any data entered into an automation using the Builder is stored in our databases and is accessible to developers and employees of axiom.ai. As such, it is not recommended to enter sensitive or secret data into Axiom steps. If sensitive or secret data is required for an Axiom to function, it should be connected from a source under your control.General session data (such as cookies for the sites you are using in an automation) is synced between the Application and the browser running the Builder. In the case of automations that are running on our cloud Service, rather than using the Application, session data is synced to the server on a temporary basis, as this is required for the Service to function. It is deleted immediately after use. By using the cloud functionality of Axiom you assent to this; the Application is available if this behaviour is not desired.Any information we have on you or your operations, confidential or otherwise, may be disclosed by us to any official or law-making body as required for our legal purposes or to protect any legal interest of axiom.ai.Fees, Subscriptions and RefundsThe Services are provided on a subscription basis (“Subscription”).Subscriptions are billed in advance on a recurring basis (for example, monthly or annually), depending on the plan selected. Your Subscription will automatically renew at the end of each billing cycle unless you cancel it prior to the renewal date.You may cancel your Subscription at any time through the features provided within the Services or by contacting us at support@axiom.ai. Cancellation will take effect at the end of the current billing period, and you will retain access to the paid features until that time.Non-payment of fees within a 30 day period will result in the termination of the relevant Service.axiom.ai reserves the right to change Subscription fees at any time. Any price changes will take effect at the start of the next billing cycle following notice to you. Continued use of the Services after such changes come into effect constitutes your agreement to the updated fees.For annual Subscriptions, fees are prepaid and non-refundable. No refunds or credits will be provided for partial use, unused periods, or downgrades, except where required by applicable law.Nothing in these Terms affects your statutory rights. Where you are a consumer, you may have a legal right to cancel within a cooling-off period, unless you have expressly requested access to the Services during that period and acknowledged that your right to cancel will be lost.WarrantyNo warranties: All Services are provided on an as-is and as-available basis. Neither axiom.ai nor any of its direct affiliates provides any kind of warranty (express, implied, statutory or otherwise) in relation to the Services, including but not necessarily limited to availability, uptime. fitness for a particular purpose, merchantability or interoperability with any other service. axiom.ai does not warrant that any Content developed by axiom.ai, its affiliates, you or any third party will run uninterrupted without error or defect. Responsibility of maintenance for Content being run by the user is the responsibility of the user of said Content. axiom.ai is not responsible for any harm or damages caused by any third party provider or content due to the operation of any of the Services. The customer bears all the risk of using any part of the Services.As regards to any Service or Content released by axiom.ai in beta, early access, released as a demo or otherwise still being developed, the following points additionally apply to them:They may not be ready for production and therefore have defects in privacy, security or any other wayThere may be defects in functionality that require patches or further updates to fixThey may not be fault-tolerant and data loss may be possible; responsibility for backing up important data rests with you the userYou will not use them for any commercial purpose or in any production situation or environmentYou represent and warrant at all times that:You have all necessary right and title to enter into the Terms of Use and to perform your obligations hereunderYou and your users will use the Services in strict accordance with the Terms of Use and with all applicable legislationYou have obtained all rights, permissions and\u002For consents necessary for the lawful use of your data and the operation of the ServicesNo part of your data used within the Services infringes or otherwise conflicts with any third-party rights. You expressly agree that the use of the Services and Content is at your sole risk.LiabilityTo the maximum extent permitted by applicable law, in no event will axiom.ai Parties be liable for any SPECIAL, INDIRECT, MORAL, CONSEQUENTIAL, INCIDENTAL, PUNITIVE OR EXEMPLARY DAMAGES, THE USE OR INABILITY TO USE THE PRODUCTS, COMPUTER MALFUNCTION OR FAILURE, SERVER DOWN TIME, FAILURE OF THE PRODUCTS TO OPERATE WITH ANY OTHER PROGRAMS, LOSS OF PROFITS, REPUTATION, USE OR REVENUE, LOSS OR CORRUPTION OF DATA, OR INTERRUPTION OF BUSINESS, regardless if the axiom.ai Party was aware of the likelihood of such damages occurring, and whether such liability is based on contract, tort, negligence, strict liability, products liability or otherwise. For the avoidance of any doubt, under no circumstances may any axiom.ai Party be liable for any claims of any kind and nature that may be asserted, granted or imposed against, directly or indirectly, arising from, or in connection with, your Content, your failure to comply with the Terms of Use or use of your account.Your exclusive remedy against any axiom.ai Party, for each and all claims, actions, proceedings and damages (individually and together), including direct damages, arising out of, or in connection with, the Terms of Use, and including where the warranty exclusions above are not valid or permitted under the applicable law, is limited up the higher of (i) one hundred (100) USD or (ii) the value of the consideration you paid for the month during in which the loss or breach occurred. These limitations and exclusions apply even if this remedy doesn't fully compensate you for any losses and even if axiom.ai knew or should have known about the possibility of the damages or the likelihood of their occurrence.You will indemnify any axiom.ai Party, defend and hold them harmless against any losses, damages, fines and expenses (including attorneys' fees and costs) arising out of, or relating to any claims based on, (i). your, and your users use or attempted use of the Services in violation of the Terms of Use; (ii). your violation of the applicable law or rights of any third party; or (iii). your Content, including without limitation any claim of infringement or misappropriation of intellectual property or other proprietary rights.Acceptable UseYou will only use axiom.ai for purposes that are legal in your region of operation of the Services.You will not assume that violation of the terms of service of any third party application or service by your operation of the Services or any Content developed by any party (including axiom.ai for the purposes of demonstration) will be assignable to axiom.ai or any of its affiliates.You will take responsibility for the operation of any Services or the use of any Content operated on your account in regards to the licenses or terms of use you have signed with other third party applications or organisations.You will back up or otherwise secure any data or sensitive material that will be used in relation to the operation of any of the Services.You will not use any measures to bypass any license restriction applied by axiom.ai to you or your accounts.Only a single account may be owned by a you at any time, unless we have provided authorisation in writing. Additional accounts created by you are subject to our approval and may be removed at our discretion.You may take backups or other copies of Services granted to you for the purposes of disaster recovery.You may not reverse engineer, analyse or otherwise attempt to make use of code distributed with our Services, except where a specific distribution license permits it.You may not distribute, sell or otherwise re-assign in any way the rights and responsibilities given to you as part of these Terms of Use to any other third party.You will not rely on axiom.ai providing any backup or recovery service for any damage or loss associated with your operation of the Services. All liability for such damages or losses lies with you.You will allow axiom.ai to provide automatic updates and fixes to Services installed on your property for the purposes of fixing bugs, upgrading security and improving the functionality of the Services.You will not attempt to gain access to or otherwise access any account, network, Service, Content or any other item by any means except the provision of a license to do so by axiom.ai.You will not use the Services for the purposes of spamming, distributing malware, misleading other users, harassment, bullying, discrimination, destructive activities or any other purpose deemed individually unacceptable by us, regardless of local laws relating to these matters.You are permitted to develop Content for other third party users, and to charge as you see fit for any service rendered. If those third party users utilise accounts provided by you, all responsibility for the terms of use remains with you and does not transfer to those third party users, unless they explicitly sign this agreement and create an account directly with us.You will keep any passwords, login information and access to your infrastructure secure so that it cannot be co-opted by any unauthorised third party. Any loss associated with such an event is your sole responsibility.If you suspect malicious activity on your account, or that an unauthorised user is using your account or your access to Content or Services to perform any action in violation of these Terms of Use, you undertake to contact as at any of the given contact addresses to inform us of this information so we may take appropriate action.ComplianceYou may only allow other users to access the Services for your direct business benifit, and hereby guarantee that any sub-user given access to Content or Services by you complies with the Terms of Use and all applicable policies. Upon request you will provide details of any third party who may have access to your accounts.If you are a business, company, or organization, axiom.ai may, at its expense, verify that your use, access, installation, or deployment of the Services comply with these Terms of Use. Upon request, you will provide axiom.ai with details and use reports of all your users.If you suspect any abuse or a breach of any clause of these Terms of Use, you can let us know by contacting us at ai@axiom.ai. Please disclose any and all information you feel is necessary for the resolution of this issue, including but not necessarily limited to:A description of the breachInformation on the person who has performed the breachInformation at which we can contact youA statement declaring that this information, under penalty of perjury, is accurate to the best of your knowledge and ability to verify, and that the identified party is the owner of the infringing ContentTerminationYou may stop using any Services or Content at any point you wish, without notice. Please let us know you are terminating the services using either the contact address indicated above or by using the features available within the Services provided for such a purpose. Your account will be terminated within three working days and any fees or payments cancelled.axiom.ai reserves the right to terminate your account, Services and remove access to any Content that is running through any of our Services, for any of the following reasons:a. A breach, or attempted breach, of any of these Terms of Use is reasonably attributable to your account\nb. Failure to pay for services after a 30-day grace period has expired\nc. Provision of Services is taken to breach any special local law or condition that may apply to you\nd. If a particular Service is discontinued or no longer being supported by us\ne. A period of inactivity not less than six monthsIf any termination of your accounts, Services or access to Content is to take place, we will make best efforts to notify you by your supplied contact details before this takes place and give you the option of response. Please note that the option of response does not imply that we will either reverse or suspend the decision to terminate or otherwise restrict access to any part of our Services or Content.Once an account has been Terminated, all Content, Data and Services associated with or stored on this account will no longer be recoverable.",[],[],1781777666220]