[{"data":1,"prerenderedAt":1943},["ShallowReactive",2],{"navigation":3,"page:\u002Fconcepts\u002Fbrowser-tier":1019,"surround:\u002Fconcepts\u002Fbrowser-tier":1936},[4,21,82,133,154,1010],[5,6,7,8],"Getting started","\u002Fgetting-started","i-lucide-rocket",[9,12,15,18],[10,6,11,11],"What Kaabist is",0,[13,14,11,11],"API keys and modes","keys-and-modes",[16,17,11,11],"Your first job","first-job",[19,20,11,11],"Understanding the envelope","envelope",[22,23,24,25],"Concepts","\u002Fconcepts","i-lucide-book-open",[26,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79],[27,23,11,11],"Overview",[29,30,11,11],"Programs and versions","programs-and-versions",[32,33,11,11],"Tiers and escalation","tiers-and-escalation",[35,36,11,11],"The http tier","http-tier",[38,39,11,11],"The browser tier","browser-tier",[41,42,11,11],"Sessions","sessions",[44,45,11,11],"Human in the loop","human-in-the-loop",[47,48,11,11],"How healing works","self-healing",[50,51,11,11],"Obstacles and captchas","obstacles",[53,54,11,11],"Validation and warnings","validation-and-warnings",[56,57,11,11],"Credits and billing","credits-and-billing",[59,60,11,11],"Limits","limits",[62,63,11,11],"Locators","locators",[65,66,11,11],"Snapshots","snapshots",[68,69,11,11],"Egress and proxies","egress-and-proxies",[71,72,11,11],"Queueing and fairness","queueing",[74,75,11,11],"Accounts, organisations and roles","accounts-and-roles",[77,78,11,11],"Data retention","data-retention",[80,81,11,11],"Documents and PDFs","documents-and-pdfs",[83,84,85,86],"Guides","\u002Fguides","i-lucide-map",[87,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130],[27,84,11,11],[89,90,11,11],"Authenticated flows","authenticated-flows",[92,93,11,11],"Hosted resolve pages","hosted-resolve",[95,96,11,11],"Lists and pagination","lists-and-pagination",[98,99,11,11],"JSON and network locators","json-and-network-locators",[101,102,11,11],"Schedules and change detection","schedules-and-change-detection",[104,105,11,11],"Webhooks","webhooks",[107,108,11,11],"Bring your own providers","byo-providers",[110,111,11,11],"Testing: replay, dry-run and test mode","testing",[113,114,11,11],"Side-effect safety","side-effect-safety",[116,117,11,11],"Security & data handling","security-and-data",[119,120,11,11],"Migrating from other tools","migrating",[122,123,11,11],"Drift detection and canaries","drift-and-canaries",[125,126,11,11],"SDKs","sdks",[128,129,11,11],"The kaab CLI","cli",[131,132,11,11],"Coding agents (MCP)","mcp",[134,135,136,137],"Panel","\u002Fpanel","i-lucide-layout-dashboard",[138,139,142,145,148,151],[27,135,11,11],[140,141,11,11],"The program builder","builder",[143,144,11,11],"Picking and recording","picking-and-recording",[146,147,11,11],"Taking over a job","takeover",[149,150,11,11],"Getting help","support",[152,153,11,11],"Referrals","referrals",[155,156,157,158],"Reference","\u002Freference","i-lucide-library",[159,160,520,834,837,840,1006,1007],[27,156,11,11],[161,162,11,163],"API","api",[164,166,169,212,222,274,297,316,347,376,389,396,403,410,426,447,454],[27,165,11,11],"\u002Freference\u002Fapi",[167,168,11,11],"Interactive reference","explorer",[170,171,11,172],"Jobs","jobs",[173,176,179,182,185,188,191,194,197,200,203,206,209],[174,175,11,11],"Create job","create-job",[177,178,11,11],"List jobs","list-jobs",[180,181,11,11],"Create job batch","create-job-batch",[183,184,11,11],"Estimate job","estimate-job",[186,187,11,11],"Get job","get-job",[189,190,11,11],"List job steps","list-job-steps",[192,193,11,11],"Get job snapshot","get-job-snapshot",[195,196,11,11],"Get job screenshot","get-job-screenshot",[198,199,11,11],"Get job artifact","get-job-artifact",[201,202,11,11],"Submit job input","submit-job-input",[204,205,11,11],"Resume job","resume-job",[207,208,11,11],"Takeover job","takeover-job",[210,211,11,11],"Cancel job","cancel-job",[213,214,11,215],"Batches","batches",[216,219],[217,218,11,11],"Get batch","get-batch",[220,221,11,11],"List batch jobs","list-batch-jobs",[223,224,11,225],"Programs","programs",[226,229,232,235,238,241,244,247,250,253,256,259,262,265,268,271],[227,228,11,11],"Create program","create-program",[230,231,11,11],"List programs","list-programs",[233,234,11,11],"Lint program","lint-program",[236,237,11,11],"Get program","get-program",[239,240,11,11],"Update program","update-program",[242,243,11,11],"Delete program","delete-program",[245,246,11,11],"List program versions","list-program-versions",[248,249,11,11],"Create program version","create-program-version",[251,252,11,11],"Update program version","update-program-version",[254,255,11,11],"Delete program version","delete-program-version",[257,258,11,11],"Get program version","get-program-version",[260,261,11,11],"Publish program version","publish-program-version",[263,264,11,11],"Diff program version","diff-program-version",[266,267,11,11],"Replay program version","replay-program-version",[269,270,11,11],"Set program alias","set-program-alias",[272,273,11,11],"Delete program alias","delete-program-alias",[41,42,11,275],[276,279,282,285,288,291,294],[277,278,11,11],"Create session","create-session",[280,281,11,11],"List sessions","list-sessions",[283,284,11,11],"Get session","get-session",[286,287,11,11],"Update session","update-session",[289,290,11,11],"Delete session","delete-session",[292,293,11,11],"Verify session","verify-session",[295,296,11,11],"Refresh session","refresh-session",[298,299,11,300],"Proposals","proposals",[301,304,307,310,313],[302,303,11,11],"List proposals","list-proposals",[305,306,11,11],"Get proposal","get-proposal",[308,309,11,11],"Approve proposal","approve-proposal",[311,312,11,11],"Reject proposal","reject-proposal",[314,315,11,11],"Edit proposal","edit-proposal",[317,318,11,319],"Schedules","schedules",[320,323,326,329,332,335,338,341,344],[321,322,11,11],"Create schedule","create-schedule",[324,325,11,11],"List schedules","list-schedules",[327,328,11,11],"Get schedule","get-schedule",[330,331,11,11],"Update schedule","update-schedule",[333,334,11,11],"Delete schedule","delete-schedule",[336,337,11,11],"Pause schedule","pause-schedule",[339,340,11,11],"Resume schedule","resume-schedule",[342,343,11,11],"List schedule runs","list-schedule-runs",[345,346,11,11],"Get schedule run diff","get-schedule-run-diff",[104,105,11,348],[349,352,355,358,361,364,367,370,373],[350,351,11,11],"Create webhook","create-webhook",[353,354,11,11],"List webhooks","list-webhooks",[356,357,11,11],"Get webhook","get-webhook",[359,360,11,11],"Update webhook","update-webhook",[362,363,11,11],"Delete webhook","delete-webhook",[365,366,11,11],"Rotate webhook secret","rotate-webhook-secret",[368,369,11,11],"List webhook deliveries","list-webhook-deliveries",[371,372,11,11],"Resend webhook delivery","resend-webhook-delivery",[374,375,11,11],"Test webhook","test-webhook",[377,378,11,379],"Organisation","org",[380,383,386],[381,382,11,11],"Rotate org webhook secret","rotate-org-webhook-secret",[384,385,11,11],"Get org","get-org",[387,388,11,11],"Request data deletion","request-data-deletion",[390,391,11,392],"Credits","credits",[393],[394,395,11,11],"Get credits","get-credits",[397,398,11,399],"Ledger","ledger",[400],[401,402,11,11],"List ledger entries","list-ledger-entries",[404,405,11,406],"Usage","usage",[407],[408,409,11,11],"Get usage","get-usage",[411,412,11,413],"API keys","api-keys",[414,417,420,423],[415,416,11,11],"List API keys","list-api-keys",[418,419,11,11],"Create API key","create-api-key",[421,422,11,11],"Rotate API key","rotate-api-key",[424,425,11,11],"Revoke API key","revoke-api-key",[427,108,11,428],"BYO providers",[429,432,435,438,441,444],[430,431,11,11],"List BYO providers","list-byo-providers",[433,434,11,11],"Create BYO provider","create-byo-provider",[436,437,11,11],"Get BYO provider","get-byo-provider",[439,440,11,11],"Update BYO provider","update-byo-provider",[442,443,11,11],"Delete BYO provider","delete-byo-provider",[445,446,11,11],"Test BYO provider","test-byo-provider",[448,449,11,450],"Sites","sites",[451],[452,453,11,11],"Get site profile","get-site-profile",[455,456,11,457],"Objects","schemas",[458,460,463,466,469,470,473,476,479,482,485,487,490,493,496,499,502,505,508,511,514,517],[27,459,11,11],"\u002Freference\u002Fapi\u002Fschemas",[461,462,11,11],"ApiKey","api-key",[464,465,11,11],"Batch","batch",[467,468,11,11],"ByoProvider","byo-provider",[390,391,11,11],[471,472,11,11],"ErrorResponse","error-response",[474,475,11,11],"ExtractSchema","extract-schema",[477,478,11,11],"Job","job",[480,481,11,11],"LedgerEntry","ledger-entry",[483,484,11,11],"LintResult","lint-result",[486,378,11,11],"Org",[488,489,11,11],"Program","program",[491,492,11,11],"ProgramDefinition","program-definition",[494,495,11,11],"ProgramVersion","program-version",[497,498,11,11],"Proposal","proposal",[500,501,11,11],"Schedule","schedule",[503,504,11,11],"Session","session",[506,507,11,11],"SiteProfile","site-profile",[509,510,11,11],"StepRecord","step-record",[512,513,11,11],"Webhook","webhook",[515,516,11,11],"WebhookDelivery","webhook-delivery",[518,519,11,11],"WebhookEvent","webhook-event",[521,522,11,523],"DSL","dsl",[524,526,529,532,535,538,603,637,640,751,754,756],[27,525,11,11],"\u002Freference\u002Fdsl",[527,528,11,11],"Inputs","inputs",[530,531,11,11],"Options","options",[533,534,11,11],"Policies","policies",[536,537,11,11],"Steps","steps",[539,540,11,541],"Actions","actions",[542,544,546,548,550,552,554,556,558,560,562,565,568,570,573,575,577,579,582,585,587,589,591,594,596,598,600],[27,543,11,11],"\u002Freference\u002Fdsl\u002Factions",[545,545,11,11],"fill",[547,547,11,11],"click",[549,549,11,11],"press",[551,551,11,11],"hover",[553,553,11,11],"select",[555,555,11,11],"check",[557,557,11,11],"uncheck",[559,559,11,11],"upload",[561,561,11,11],"scroll",[563,564,11,11],"wait_for","wait-for",[566,567,11,11],"set_session","set-session",[569,569,11,11],"extract",[571,572,11,11],"capture_response","capture-response",[574,574,11,11],"evaluate",[576,576,11,11],"paginate",[578,578,11,11],"download",[580,581,11,11],"read_pdf","read-pdf",[583,584,11,11],"set_vars","set-vars",[586,586,11,11],"sleep",[588,588,11,11],"reload",[590,590,11,11],"goto",[592,593,11,11],"await_input","await-input",[595,595,11,11],"checkpoint",[597,597,11,11],"screenshot",[599,599,11,11],"when",[601,602,11,11],"loop_until","loop-until",[604,605,11,606],"Conditions","conditions",[607,609,611,613,615,617,619,621,623,625,627,629,631,633,635],[27,608,11,11],"\u002Freference\u002Fdsl\u002Fconditions",[610,610,11,11],"url",[612,612,11,11],"title",[614,614,11,11],"visible",[616,616,11,11],"hidden",[618,618,11,11],"exists",[620,620,11,11],"absent",[622,622,11,11],"text",[624,624,11,11],"count",[626,626,11,11],"network",[628,628,11,11],"var",[630,630,11,11],"landmark",[632,632,11,11],"all",[634,634,11,11],"any",[636,636,11,11],"not",[638,639,11,11],"Targets","targets",[641,642,11,643],"Fields","fields",[644,646,649,651,654,656,659,661,663,666,668,671,672,674,677,679,681,683,685,687,690,693,695,698,701,703,704,707,709,712,714,716,718,720,722,724,726,728,731,733,734,736,738,740,743,745,747,749],[27,645,11,11],"\u002Freference\u002Fdsl\u002Ffields",[647,648,11,11],"allow_suffix","allow-suffix",[650,650,11,11],"attr",[652,653,11,11],"base_url","base-url",[655,655,11,11],"candidates",[657,658,11,11],"case_insensitive","case-insensitive",[660,660,11,11],"country",[662,662,11,11],"currency",[664,665,11,11],"date_format","date-format",[667,667,11,11],"decimal",[669,670,11,11],"false_values","false-values",[642,642,11,11],[673,673,11,11],"flags",[675,676,11,11],"follow_redirects","follow-redirects",[678,678,11,11],"frame",[680,680,11,11],"json",[682,682,11,11],"locale",[684,684,11,11],"many",[686,686,11,11],"max",[688,689,11,11],"max_items","max-items",[691,692,11,11],"max_length","max-length",[694,694,11,11],"min",[696,697,11,11],"min_items","min-items",[699,700,11,11],"min_length","min-length",[702,702,11,11],"name",[626,626,11,11],[705,706,11,11],"null_markers","null-markers",[708,708,11,11],"nullable",[710,711,11,11],"on_invalid","on-invalid",[713,713,11,11],"pattern",[715,715,11,11],"presence",[717,717,11,11],"regex",[719,719,11,11],"required",[721,721,11,11],"role",[723,723,11,11],"sample",[725,725,11,11],"selector",[727,727,11,11],"source",[729,730,11,11],"strip_fragment","strip-fragment",[732,732,11,11],"testid",[622,622,11,11],[735,735,11,11],"thousands",[737,737,11,11],"timezone",[739,739,11,11],"transforms",[741,742,11,11],"true_values","true-values",[744,744,11,11],"type",[746,746,11,11],"unique",[748,748,11,11],"values",[750,750,11,11],"xpath",[752,753,11,11],"Assertions","assertions",[755,739,11,11],"Transforms",[757,758,11,759],"Lint codes","lint",[760,762,765,768,771,774,777,780,783,786,789,792,795,798,801,804,807,810,813,816,819,822,825,828,831],[27,761,11,11],"\u002Freference\u002Fdsl\u002Flint",[763,764,11,11],"E001","e001",[766,767,11,11],"E002","e002",[769,770,11,11],"E003","e003",[772,773,11,11],"E004","e004",[775,776,11,11],"E005","e005",[778,779,11,11],"E006","e006",[781,782,11,11],"E007","e007",[784,785,11,11],"E008","e008",[787,788,11,11],"E009","e009",[790,791,11,11],"E010","e010",[793,794,11,11],"E011","e011",[796,797,11,11],"E012","e012",[799,800,11,11],"E013","e013",[802,803,11,11],"E014","e014",[805,806,11,11],"W001","w001",[808,809,11,11],"W002","w002",[811,812,11,11],"W003","w003",[814,815,11,11],"W004","w004",[817,818,11,11],"W005","w005",[820,821,11,11],"W006","w006",[823,824,11,11],"W007","w007",[826,827,11,11],"W008","w008",[829,830,11,11],"W009","w009",[832,833,11,11],"W010","w010",[835,836,11,11],"Codes","codes",[838,839,11,11],"Events","events",[841,129,11,842],"CLI",[843,845,847,850,853,856,859,862,865,868,871,874,877,880,883,886,889,892,895,898,901,904,907,910,913,916,919,922,925,928,931,934,937,940,943,946,949,952,955,958,961,964,967,970,973,976,979,982,985,988,991,994,997,1000,1003],[27,844,11,11],"\u002Freference\u002Fcli",[846,846,11,11],"kaab",[848,849,11,11],"kaab auth","kaab-auth",[851,852,11,11],"kaab auth login","kaab-auth-login",[854,855,11,11],"kaab auth logout","kaab-auth-logout",[857,858,11,11],"kaab auth status","kaab-auth-status",[860,861,11,11],"kaab completion","kaab-completion",[863,864,11,11],"kaab completion bash","kaab-completion-bash",[866,867,11,11],"kaab completion fish","kaab-completion-fish",[869,870,11,11],"kaab completion powershell","kaab-completion-powershell",[872,873,11,11],"kaab completion zsh","kaab-completion-zsh",[875,876,11,11],"kaab credits","kaab-credits",[878,879,11,11],"kaab jobs","kaab-jobs",[881,882,11,11],"kaab jobs cancel","kaab-jobs-cancel",[884,885,11,11],"kaab jobs get","kaab-jobs-get",[887,888,11,11],"kaab jobs input","kaab-jobs-input",[890,891,11,11],"kaab jobs list","kaab-jobs-list",[893,894,11,11],"kaab jobs resume","kaab-jobs-resume",[896,897,11,11],"kaab jobs run","kaab-jobs-run",[899,900,11,11],"kaab jobs snapshot","kaab-jobs-snapshot",[902,903,11,11],"kaab jobs steps","kaab-jobs-steps",[905,906,11,11],"kaab jobs takeover","kaab-jobs-takeover",[908,909,11,11],"kaab open","kaab-open",[911,912,11,11],"kaab open job","kaab-open-job",[914,915,11,11],"kaab programs","kaab-programs",[917,918,11,11],"kaab programs alias","kaab-programs-alias",[920,921,11,11],"kaab programs alias set","kaab-programs-alias-set",[923,924,11,11],"kaab programs diff","kaab-programs-diff",[926,927,11,11],"kaab programs lint","kaab-programs-lint",[929,930,11,11],"kaab programs list","kaab-programs-list",[932,933,11,11],"kaab programs pull","kaab-programs-pull",[935,936,11,11],"kaab programs push","kaab-programs-push",[938,939,11,11],"kaab proposals","kaab-proposals",[941,942,11,11],"kaab proposals approve","kaab-proposals-approve",[944,945,11,11],"kaab proposals list","kaab-proposals-list",[947,948,11,11],"kaab proposals reject","kaab-proposals-reject",[950,951,11,11],"kaab proposals show","kaab-proposals-show",[953,954,11,11],"kaab schedules","kaab-schedules",[956,957,11,11],"kaab schedules create","kaab-schedules-create",[959,960,11,11],"kaab schedules list","kaab-schedules-list",[962,963,11,11],"kaab schedules pause","kaab-schedules-pause",[965,966,11,11],"kaab schedules resume","kaab-schedules-resume",[968,969,11,11],"kaab schedules runs","kaab-schedules-runs",[971,972,11,11],"kaab sessions","kaab-sessions",[974,975,11,11],"kaab sessions create","kaab-sessions-create",[977,978,11,11],"kaab sessions delete","kaab-sessions-delete",[980,981,11,11],"kaab sessions list","kaab-sessions-list",[983,984,11,11],"kaab sessions verify","kaab-sessions-verify",[986,987,11,11],"kaab usage","kaab-usage",[989,990,11,11],"kaab version","kaab-version",[992,993,11,11],"kaab webhooks","kaab-webhooks",[995,996,11,11],"kaab webhooks create","kaab-webhooks-create",[998,999,11,11],"kaab webhooks deliveries","kaab-webhooks-deliveries",[1001,1002,11,11],"kaab webhooks list","kaab-webhooks-list",[1004,1005,11,11],"kaab webhooks test","kaab-webhooks-test",[125,126,11,11],[1008,1009,11,11],"Plans and pricing","plans",[1011,1012,1013,1014],"Changelog","\u002Fchangelog","i-lucide-history",[1015,1016],[27,1012,11,11],[1017,1018,11,11],"Deprecations","deprecations",{"id":1020,"title":38,"body":1021,"breaking":1926,"date":1927,"description":1928,"extension":1929,"generated":1926,"meta":1930,"navigation":1931,"path":1932,"seo":1933,"stem":1934,"version":1927,"__hash__":1935},"docs\u002F2.concepts\u002F04.browser-tier.md",{"type":1022,"value":1023,"toc":1914},"minimark",[1024,1034,1039,1055,1070,1097,1101,1112,1116,1123,1170,1176,1195,1199,1213,1225,1245,1249,1267,1273,1277,1287,1294,1298,1304,1394,1405,1409,1416,1660,1690,1717,1723,1753,1784,1788,1833,1836,1910],[1025,1026,1027,1028,1033],"p",{},"When a program has to click, type or wait for JavaScript, its job runs at the browser tier: a real Chromium, one fresh context per job, driven over the DevTools protocol. It costs more than the ",[1029,1030,1032],"a",{"href":1031},"\u002Fconcepts\u002Fhttp-tier","http tier",", so Kaabist blocks what a program never reads and keeps each job isolated from every other.",[1035,1036,1038],"h2",{"id":1037},"when-to-use-it","When to use it",[1025,1040,1041,1042,1045,1046,1050,1051,1054],{},"Kaabist moves a job here by itself when the program needs it (see ",[1029,1043,32],{"href":1044},"\u002Fconcepts\u002Ftiers-and-escalation","). Ask for it with ",[1047,1048,1049],"code",{},"options.prefer_tier: \"browser\""," only when you already know a site renders its content in JavaScript, to skip the failed http attempt. The ",[1047,1052,1053],{},"stealth"," tier is the same browser, hardened and on residential addresses, for sites that refuse ordinary traffic; it needs a paid plan.",[1025,1056,1057,1058,1061,1062,1065,1066,1069],{},"The stealth tier has a second browser for sites that refuse even that one: Camoufox, a Firefox build. A stealth job starts on Chromium. If a site refuses it, the job tries once more on Camoufox, and later jobs on that site start there. Set ",[1047,1059,1060],{},"options.engine"," to ",[1047,1063,1064],{},"\"firefox\""," to start on Camoufox, or to ",[1047,1067,1068],{},"\"chromium\""," to never switch. Three things change on Camoufox:",[1071,1072,1073,1081,1091],"ul",{},[1074,1075,1076,1080],"li",{},[1077,1078,1079],"strong",{},"No live view and no takeover."," A job parked for a person is continued in a Chromium browser of its own.",[1074,1082,1083,1086,1087,1090],{},[1077,1084,1085],{},"Sessions stay on their engine."," A session saved on one engine is refused on the other with ",[1047,1088,1089],{},"session_engine_mismatch",", because a site that ties its sign-in to the browser would refuse it anyway.",[1074,1092,1093,1096],{},[1077,1094,1095],{},"Compute costs the same."," Camoufox is a little slower per page, so a long job can cross the next ten-second boundary sooner.",[1035,1098,1100],{"id":1099},"your-job-gets-its-own-context-and-sometimes-its-own-process","Your job gets its own context, and sometimes its own process",[1025,1102,1103,1104,1107,1108,1111],{},"Every job runs in a fresh browser context: its own cookies, storage and cache, nothing inherited from the job before it and nothing left for the job after. Contexts of different customers share one Chromium process, except when your job carries a ",[1029,1105,504],{"href":1106},"\u002Fconcepts\u002Fsessions"," or an input of ",[1047,1109,1110],{},"type: \"secret\"","; then it runs in a process reserved for your organisation. A context separates data; a process separates what a browser bug could reach.",[1035,1113,1115],{"id":1114},"images-and-trackers-are-not-loaded","Images and trackers are not loaded",[1025,1117,1118,1119,1122],{},"Images, video and fonts are never fetched, and neither is anything from a curated list of analytics, advertising and consent-banner domains. Proxy bandwidth is most of what a browser job costs, and on a typical page those requests are most of the bandwidth. ",[1047,1120,1121],{},"meta.assets"," reports what was refused:",[1124,1125,1129],"pre",{"className":1126,"code":1127,"language":680,"meta":1128,"style":1128},"language-json shiki shiki-themes kaab-code kaab-code kaab-code","\"assets\": { \"blocked_requests\": 34, \"blocked_bytes_estimate\": 1530000 }\n","",[1047,1130,1131],{"__ignoreMap":1128},[1132,1133,1136,1140,1144,1148,1152,1156,1159,1162,1164,1167],"span",{"class":1134,"line":1135},"line",1,[1132,1137,1139],{"class":1138},"suOy4","\"assets\"",[1132,1141,1143],{"class":1142},"sTzsn",": { ",[1132,1145,1147],{"class":1146},"sqn18","\"blocked_requests\"",[1132,1149,1151],{"class":1150},"sQm2-",":",[1132,1153,1155],{"class":1154},"sHJIl"," 34",[1132,1157,1158],{"class":1150},",",[1132,1160,1161],{"class":1146}," \"blocked_bytes_estimate\"",[1132,1163,1151],{"class":1150},[1132,1165,1166],{"class":1154}," 1530000",[1132,1168,1169],{"class":1142}," }\n",[1025,1171,1172,1175],{},[1047,1173,1174],{},"blocked_bytes_estimate"," is an estimate: a refused request has no response to measure, so it is the count per resource type times that type's typical size.",[1025,1177,1178,1179,1182,1183,1186,1187,1190,1191,1194],{},"Nothing a program reads is affected: the document, XHR and ",[1047,1180,1181],{},"fetch"," responses, scripts and stylesheets always load. To block more (a site's own analytics, which the shared list cannot name), list glob patterns in ",[1047,1184,1185],{},"options.block_urls",". To load images, video and fonts, for a screenshot a person will look at or a layout that depends on an image, set ",[1047,1188,1189],{},"options.assets: \"allow\"",". The analytics, advertising and consent-banner domains stay refused either way: they show nothing a program reads, and a page keeps talking to them for seconds after it has loaded. A live takeover or editor refuses them too, and loads the images, since a person is looking. A page that loads its own code at runtime and times out while requests were being refused fails with a hint to set ",[1047,1192,1193],{},"assets: \"allow\"",".",[1035,1196,1198],{"id":1197},"clicks-are-clicks","Clicks are clicks",[1025,1200,1201,1202,1204,1205,1208,1209,1212],{},"A ",[1047,1203,547],{}," is a mouse: the element is scrolled into view, the middle of its box is found, and a pointer moves there, presses and releases. It is not ",[1047,1206,1207],{},"element.click()",", which no ",[1047,1210,1211],{},":hover"," rule believes and which \"clicks\" a button behind a cookie banner.",[1025,1214,1215,1216,1220,1221,1224],{},"Before acting on an element, Kaabist waits for it to be there, visible, enabled and not covered. It asks the page what is painted at the point it is about to press; if the answer is a dialog rather than your button, the ",[1029,1217,1219],{"href":1218},"\u002Fconcepts\u002Fobstacles","obstacle layer"," deals with the dialog, and if it cannot, the step reports ",[1047,1222,1223],{},"covered_target"," and names what was in the way instead of clicking something you did not ask for.",[1025,1226,1227,1229,1230,1233,1234,1237,1238,1241,1242,1194],{},[1047,1228,545],{}," replaces a field's contents in one edit, the way a paste does. A field with an input mask or a per-keystroke validator may need the keys themselves: set ",[1047,1231,1232],{},"options.fill_mode: \"type\"",". A page that opens a link in a popup (",[1047,1235,1236],{},"window.open",", ",[1047,1239,1240],{},"target=_blank",") can be followed in the same tab with ",[1047,1243,1244],{},"options.follow_popups: true",[1035,1246,1248],{"id":1247},"waiting-for-a-code-from-your-phone","Waiting for a code from your phone",[1025,1250,1251,1252,1254,1255,1258,1259,1262,1263,1266],{},"When a program reaches ",[1047,1253,592],{}," (a one-time password, an e-mail code), the job parks and the browser ",[1077,1256,1257],{},"stays open"," on the machine that parked it, for the step's ",[1047,1260,1261],{},"ttl",": five minutes by default, never longer than fifteen. Answer inside that window with ",[1047,1264,1265],{},"POST \u002Fv1\u002Fjobs\u002F{id}\u002Finput"," and the run carries on in the page it was on, still signed in and on the same step.",[1025,1268,1269,1270,1194],{},"Answering later loses nothing. When the window ends, the session is saved to the job's checkpoint and the browser is released; the resume reopens the page and restores the session. It is a few seconds slower. See ",[1029,1271,44],{"href":1272},"\u002Fconcepts\u002Fhuman-in-the-loop",[1035,1274,1276],{"id":1275},"what-the-page-can-see","What the page can see",[1025,1278,1279,1280,1283,1284,1286],{},"A Kaabist job leaves no trace in the page it visits. Locators are resolved in an isolated JavaScript world: your target expressions run against the real DOM, but nothing is written to it, no globals appear in the page's own world, and a ",[1047,1281,1282],{},"MutationObserver"," on the page records nothing from Kaabist finding an element. ",[1047,1285,574],{}," is the exception you opt into: it runs your script in the page's own world.",[1025,1288,1289,1290,1293],{},"The browser presents a consistent identity: the user agent, client hints, viewport, locale and time zone agree with each other and with the proxy the traffic comes from. ",[1047,1291,1292],{},"options.browser_profile: \"mobile\""," swaps the whole set, not only the user-agent string.",[1035,1295,1297],{"id":1296},"what-it-costs-and-what-stops-it","What it costs, and what stops it",[1025,1299,1300,1301,1303],{},"Compute is 5 credits for a browser job (20 at ",[1047,1302,1053],{},"), plus 1 for every started ten seconds beyond the first thirty, and proxy traffic is billed per megabyte. Time a job spends parked is not billed.",[1305,1306,1307,1323],"table",{},[1308,1309,1310],"thead",{},[1311,1312,1313,1317,1320],"tr",{},[1314,1315,1316],"th",{},"Limit",[1314,1318,1319],{},"Default",[1314,1321,1322],{},"Option",[1324,1325,1326,1343,1355,1367,1381],"tbody",{},[1311,1327,1328,1332,1338],{},[1329,1330,1331],"td",{},"Whole job",[1329,1333,1334,1335,1337],{},"300 s (30 min for a program with ",[1047,1336,592],{},"), parked time excluded",[1329,1339,1340],{},[1047,1341,1342],{},"max_duration_ms",[1311,1344,1345,1347,1350],{},[1329,1346,536],{},[1329,1348,1349],{},"200",[1329,1351,1352],{},[1047,1353,1354],{},"max_steps",[1311,1356,1357,1361,1364],{},[1329,1358,1359],{},[1047,1360,574],{},[1329,1362,1363],{},"5 s, 1 MB result",[1329,1365,1366],{},"per step",[1311,1368,1369,1373,1376],{},[1329,1370,1371],{},[1047,1372,578],{},[1329,1374,1375],{},"64 MB",[1329,1377,1378],{},[1047,1379,1380],{},"download.max_bytes",[1311,1382,1383,1386,1389],{},[1329,1384,1385],{},"Viewport",[1329,1387,1388],{},"1280 × 800",[1329,1390,1391],{},[1047,1392,1393],{},"viewport",[1025,1395,1396,1397,1400,1401,1404],{},"A download is the only way a job touches a file. It is streamed and cut off at the cap rather than measured afterwards, and it is stored as one of the job's artifacts. Screenshots are taken on failure by default (",[1047,1398,1399],{},"policies.screenshot: \"on_failure\"","); set ",[1047,1402,1403],{},"always"," to keep one per step.",[1035,1406,1408],{"id":1407},"worked-example","Worked example",[1025,1410,1411,1412,1415],{},"Run the single-page app at ",[1047,1413,1414],{},"https:\u002F\u002Fapp.example.com",", whose script fetches its product list as JSON after the page loads:",[1124,1417,1419],{"className":1126,"code":1418,"language":680,"meta":1128,"style":1128},"{\n  \"kaab\": \"1\",\n  \"name\": \"app-products\",\n  \"options\": { \"prefer_tier\": \"browser\" },\n  \"steps\": [\n    { \"goto\": { \"url\": \"https:\u002F\u002Fapp.example.com\u002F\", \"wait_until\": \"networkidle\" },\n      \"expect\": { \"count\": { \"target\": \"#products .product-card\", \"min\": 1 } } },\n    { \"extract\": { \"products\": { \"selector\": \"#products .product-card\", \"many\": true,\n        \"fields\": { \"title\": \".title\", \"sku\": { \"selector\": \".sku\", \"regex\": \"SKU:\\\\s*([A-Z0-9-]+)\" } } } } }\n  ]\n}\n",[1047,1420,1421,1426,1440,1453,1477,1488,1523,1563,1601,1648,1654],{"__ignoreMap":1128},[1132,1422,1423],{"class":1134,"line":1135},[1132,1424,1425],{"class":1142},"{\n",[1132,1427,1429,1432,1434,1437],{"class":1134,"line":1428},2,[1132,1430,1431],{"class":1146},"  \"kaab\"",[1132,1433,1151],{"class":1150},[1132,1435,1436],{"class":1138}," \"1\"",[1132,1438,1439],{"class":1150},",\n",[1132,1441,1443,1446,1448,1451],{"class":1134,"line":1442},3,[1132,1444,1445],{"class":1146},"  \"name\"",[1132,1447,1151],{"class":1150},[1132,1449,1450],{"class":1138}," \"app-products\"",[1132,1452,1439],{"class":1150},[1132,1454,1456,1459,1461,1464,1467,1469,1472,1475],{"class":1134,"line":1455},4,[1132,1457,1458],{"class":1146},"  \"options\"",[1132,1460,1151],{"class":1150},[1132,1462,1463],{"class":1142}," { ",[1132,1465,1466],{"class":1146},"\"prefer_tier\"",[1132,1468,1151],{"class":1150},[1132,1470,1471],{"class":1138}," \"browser\"",[1132,1473,1474],{"class":1142}," }",[1132,1476,1439],{"class":1150},[1132,1478,1480,1483,1485],{"class":1134,"line":1479},5,[1132,1481,1482],{"class":1146},"  \"steps\"",[1132,1484,1151],{"class":1150},[1132,1486,1487],{"class":1142}," [\n",[1132,1489,1491,1494,1497,1499,1501,1504,1506,1509,1511,1514,1516,1519,1521],{"class":1134,"line":1490},6,[1132,1492,1493],{"class":1142},"    { ",[1132,1495,1496],{"class":1146},"\"goto\"",[1132,1498,1151],{"class":1150},[1132,1500,1463],{"class":1142},[1132,1502,1503],{"class":1146},"\"url\"",[1132,1505,1151],{"class":1150},[1132,1507,1508],{"class":1138}," \"https:\u002F\u002Fapp.example.com\u002F\"",[1132,1510,1158],{"class":1150},[1132,1512,1513],{"class":1146}," \"wait_until\"",[1132,1515,1151],{"class":1150},[1132,1517,1518],{"class":1138}," \"networkidle\"",[1132,1520,1474],{"class":1142},[1132,1522,1439],{"class":1150},[1132,1524,1526,1529,1531,1533,1536,1538,1540,1543,1545,1548,1550,1553,1555,1558,1561],{"class":1134,"line":1525},7,[1132,1527,1528],{"class":1146},"      \"expect\"",[1132,1530,1151],{"class":1150},[1132,1532,1463],{"class":1142},[1132,1534,1535],{"class":1146},"\"count\"",[1132,1537,1151],{"class":1150},[1132,1539,1463],{"class":1142},[1132,1541,1542],{"class":1146},"\"target\"",[1132,1544,1151],{"class":1150},[1132,1546,1547],{"class":1138}," \"#products .product-card\"",[1132,1549,1158],{"class":1150},[1132,1551,1552],{"class":1146}," \"min\"",[1132,1554,1151],{"class":1150},[1132,1556,1557],{"class":1154}," 1",[1132,1559,1560],{"class":1142}," } } }",[1132,1562,1439],{"class":1150},[1132,1564,1566,1568,1571,1573,1575,1578,1580,1582,1585,1587,1589,1591,1594,1596,1599],{"class":1134,"line":1565},8,[1132,1567,1493],{"class":1142},[1132,1569,1570],{"class":1146},"\"extract\"",[1132,1572,1151],{"class":1150},[1132,1574,1463],{"class":1142},[1132,1576,1577],{"class":1146},"\"products\"",[1132,1579,1151],{"class":1150},[1132,1581,1463],{"class":1142},[1132,1583,1584],{"class":1146},"\"selector\"",[1132,1586,1151],{"class":1150},[1132,1588,1547],{"class":1138},[1132,1590,1158],{"class":1150},[1132,1592,1593],{"class":1146}," \"many\"",[1132,1595,1151],{"class":1150},[1132,1597,1598],{"class":1154}," true",[1132,1600,1439],{"class":1150},[1132,1602,1604,1607,1609,1611,1614,1616,1619,1621,1624,1626,1628,1630,1632,1635,1637,1640,1642,1645],{"class":1134,"line":1603},9,[1132,1605,1606],{"class":1146},"        \"fields\"",[1132,1608,1151],{"class":1150},[1132,1610,1463],{"class":1142},[1132,1612,1613],{"class":1146},"\"title\"",[1132,1615,1151],{"class":1150},[1132,1617,1618],{"class":1138}," \".title\"",[1132,1620,1158],{"class":1150},[1132,1622,1623],{"class":1146}," \"sku\"",[1132,1625,1151],{"class":1150},[1132,1627,1463],{"class":1142},[1132,1629,1584],{"class":1146},[1132,1631,1151],{"class":1150},[1132,1633,1634],{"class":1138}," \".sku\"",[1132,1636,1158],{"class":1150},[1132,1638,1639],{"class":1146}," \"regex\"",[1132,1641,1151],{"class":1150},[1132,1643,1644],{"class":1138}," \"SKU:\\\\s*([A-Z0-9-]+)\"",[1132,1646,1647],{"class":1142}," } } } } }\n",[1132,1649,1651],{"class":1134,"line":1650},10,[1132,1652,1653],{"class":1142},"  ]\n",[1132,1655,1657],{"class":1134,"line":1656},11,[1132,1658,1659],{"class":1142},"}\n",[1025,1661,1662,1665,1666,1669,1670,1673,1674,1676,1677,1680,1681,1684,1685,1689],{},[1077,1663,1664],{},"The network log."," The job's snapshot (",[1047,1667,1668],{},"GET \u002Fv1\u002Fjobs\u002F{id}\u002Fsnapshot",") has ",[1047,1671,1672],{},"tier: \"browser\""," and a ",[1047,1675,626],{}," list: the document, the script bundle, the ",[1047,1678,1679],{},"GET"," of the product JSON with its body kept, and the request the page sends to its own ",[1047,1682,1683],{},"\u002Fcollect"," beacon. JSON bodies up to 512 KB are stored; other bodies are not. That stored JSON is what ",[1029,1686,1688],{"href":1687},"\u002Fconcepts\u002Ftiers-and-escalation#when-a-discovered-api-makes-a-job-cheaper","API discovery"," compares the extracted values against.",[1025,1691,1692,1695,1696,1698,1699,1702,1703,1705,1706,1708,1709,1712,1713,1716],{},[1077,1693,1694],{},"What blocking saved."," ",[1047,1697,1121],{}," counts the requests the browser refused and estimates their bytes. Run the job again with ",[1047,1700,1701],{},"\"assets\": \"allow\""," in ",[1047,1704,531],{},": ",[1047,1707,1121],{}," is absent, ",[1047,1710,1711],{},"data"," is identical, and the proxy line of ",[1047,1714,1715],{},"meta.credits.breakdown"," is larger.",[1025,1718,1719,1722],{},[1077,1720,1721],{},"A failed step."," Add a step that clicks something the page does not have:",[1124,1724,1726],{"className":1126,"code":1725,"language":680,"meta":1128,"style":1128},"{ \"click\": \"#not-on-this-page\", \"timeout_ms\": 1000 }\n",[1047,1727,1728],{"__ignoreMap":1128},[1132,1729,1730,1733,1736,1738,1741,1743,1746,1748,1751],{"class":1134,"line":1135},[1132,1731,1732],{"class":1142},"{ ",[1132,1734,1735],{"class":1146},"\"click\"",[1132,1737,1151],{"class":1150},[1132,1739,1740],{"class":1138}," \"#not-on-this-page\"",[1132,1742,1158],{"class":1150},[1132,1744,1745],{"class":1146}," \"timeout_ms\"",[1132,1747,1151],{"class":1150},[1132,1749,1750],{"class":1154}," 1000",[1132,1752,1169],{"class":1142},[1025,1754,1755,1756,1759,1760,1763,1764,1767,1768,1771,1772,1775,1776,1779,1780,1783],{},"The target never appears on the step's own page, so the job parks as ",[1047,1757,1758],{},"needs_attention"," with reason ",[1047,1761,1762],{},"unknown_page",". ",[1047,1765,1766],{},"attention.detail"," names the selector (",[1047,1769,1770],{},"target_missing: #not-on-this-page",", followed by an explanation), ",[1047,1773,1774],{},"attention.screenshot"," links to the page as it was when the step gave up, and ",[1047,1777,1778],{},"attention.snapshot"," to its HTML. ",[1047,1781,1782],{},"GET \u002Fv1\u002Fjobs\u002F{id}\u002Fsteps"," shows the same screenshot on the failed step's row.",[1035,1785,1787],{"id":1786},"pitfalls","Pitfalls",[1071,1789,1790,1799,1807,1823],{},[1074,1791,1792,1695,1795,1798],{},[1077,1793,1794],{},"A browser for a document.",[1047,1796,1797],{},"prefer_tier: \"browser\""," on a server-rendered page multiplies the compute cost by five for the same data.",[1074,1800,1801,1695,1804,1806],{},[1077,1802,1803],{},"Allowing assets for good.",[1047,1805,1193],{}," is for pages that need it; it can multiply proxy traffic.",[1074,1808,1809,1812,1813,1815,1816,1819,1820,1822],{},[1077,1810,1811],{},"Fixed sleeps."," A ",[1047,1814,586],{}," is billed browser time and still races the page. Use ",[1047,1817,1818],{},"expect"," or ",[1047,1821,563],{}," with a condition.",[1074,1824,1825,1830,1831,1194],{},[1077,1826,1827,1829],{},[1047,1828,574],{}," for everything."," It runs in the page's own world, is invisible to the healer and needs a verified payment method; prefer locators and ",[1047,1832,569],{},[1035,1834,155],{"id":1835},"reference",[1071,1837,1838,1863,1890,1904],{},[1074,1839,1840,1844,1845,1237,1848,1237,1851,1237,1854,1237,1857,1237,1860,1862],{},[1029,1841,1843],{"href":1842},"\u002Freference\u002Fdsl\u002Foptions","Program options"," (",[1047,1846,1847],{},"assets",[1047,1849,1850],{},"block_urls",[1047,1852,1853],{},"fill_mode",[1047,1855,1856],{},"follow_popups",[1047,1858,1859],{},"browser_profile",[1047,1861,1393],{},")",[1074,1864,1865,1237,1870,1237,1875,1237,1880,1237,1885],{},[1029,1866,1868],{"href":1867},"\u002Freference\u002Fdsl\u002Factions\u002Fclick",[1047,1869,547],{},[1029,1871,1873],{"href":1872},"\u002Freference\u002Fdsl\u002Factions\u002Ffill",[1047,1874,545],{},[1029,1876,1878],{"href":1877},"\u002Freference\u002Fdsl\u002Factions\u002Fawait-input",[1047,1879,593],{},[1029,1881,1883],{"href":1882},"\u002Freference\u002Fdsl\u002Factions\u002Fdownload",[1047,1884,578],{},[1029,1886,1888],{"href":1887},"\u002Freference\u002Fdsl\u002Factions\u002Fevaluate",[1047,1889,574],{},[1074,1891,1892,1237,1896,1237,1900],{},[1029,1893,1895],{"href":1894},"\u002Freference\u002Fapi\u002Fjobs\u002Flist-job-steps","List a job's steps",[1029,1897,1899],{"href":1898},"\u002Freference\u002Fapi\u002Fjobs\u002Fget-job-screenshot","get its screenshot",[1029,1901,1903],{"href":1902},"\u002Freference\u002Fapi\u002Fjobs\u002Fget-job-snapshot","get its snapshot",[1074,1905,1906],{},[1029,1907,1909],{"href":1908},"\u002Freference\u002Fcodes#diagnose-classes","Diagnose classes",[1911,1912,1913],"style",{},"html pre.shiki code .suOy4, html code.shiki .suOy4{--shiki-light:var(--kaab-code-token-string-expression);--shiki-default:var(--kaab-code-token-string-expression);--shiki-dark:var(--kaab-code-token-string-expression)}html pre.shiki code .sTzsn, html code.shiki .sTzsn{--shiki-light:var(--kaab-code-foreground);--shiki-default:var(--kaab-code-foreground);--shiki-dark:var(--kaab-code-foreground)}html pre.shiki code .sqn18, html code.shiki .sqn18{--shiki-light:var(--kaab-code-token-keyword);--shiki-default:var(--kaab-code-token-keyword);--shiki-dark:var(--kaab-code-token-keyword)}html pre.shiki code .sQm2-, html code.shiki .sQm2-{--shiki-light:var(--kaab-code-token-punctuation);--shiki-default:var(--kaab-code-token-punctuation);--shiki-dark:var(--kaab-code-token-punctuation)}html pre.shiki code .sHJIl, html code.shiki .sHJIl{--shiki-light:var(--kaab-code-token-constant);--shiki-default:var(--kaab-code-token-constant);--shiki-dark:var(--kaab-code-token-constant)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":1128,"searchDepth":1442,"depth":1442,"links":1915},[1916,1917,1918,1919,1920,1921,1922,1923,1924,1925],{"id":1037,"depth":1428,"text":1038},{"id":1099,"depth":1428,"text":1100},{"id":1114,"depth":1428,"text":1115},{"id":1197,"depth":1428,"text":1198},{"id":1247,"depth":1428,"text":1248},{"id":1275,"depth":1428,"text":1276},{"id":1296,"depth":1428,"text":1297},{"id":1407,"depth":1428,"text":1408},{"id":1786,"depth":1428,"text":1787},{"id":1835,"depth":1428,"text":155},false,null,"What Kaabist does with a real browser: isolation, asset blocking, real clicks, waiting for a one-time code, what a page can see, and the limits.","md",{},true,"\u002Fconcepts\u002Fbrowser-tier",{"title":38,"description":1928},"2.concepts\u002F04.browser-tier","P64A_M5Sclinn5F4HN_jZSpQMkwhMK3soRWpwe2_RTg",[1937,1940],{"title":35,"path":1031,"stem":1938,"description":1939,"children":-1},"2.concepts\u002F03.http-tier","The cheapest way to read a page: what Kaabist can do without a browser, what makes a job need one, and how conditions behave on a document.",{"title":41,"path":1106,"stem":1941,"description":1942,"children":-1},"2.concepts\u002F05.sessions","Staying signed in across jobs: what a session stores, how jobs bind and lock it, how Kaabist checks it, what happens when it expires, and refresh programs.",1793593409371]