[{"data":1,"prerenderedAt":2116},["ShallowReactive",2],{"navigation":3,"page:\u002Fguides\u002Fjson-and-network-locators":1019,"surround:\u002Fguides\u002Fjson-and-network-locators":2107},[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":98,"body":1021,"breaking":2097,"date":2098,"description":2099,"extension":2100,"generated":2097,"meta":2101,"navigation":2102,"path":2103,"seo":2104,"stem":2105,"version":2098,"__hash__":2106},"docs\u002F3.guides\u002F04.json-and-network-locators.md",{"type":1022,"value":1023,"toc":2084},"minimark",[1024,1028,1033,1078,1081,1088,1106,1200,1210,1216,1231,1282,1306,1312,1366,1380,1421,1438,1444,1449,1516,1523,1527,1536,1546,1580,1583,1587,1594,1870,1880,1894,1914,1945,1949,2004,2007,2080],[1025,1026,1027],"p",{},"Many pages are drawn from JSON: a server-rendered page embeds it in a script tag, a single-page app\nfetches it from an API after loading. Reading that JSON directly is more precise than reading the\nHTML made from it, survives redesigns, and can let a job run at the cheaper http tier without a\nbrowser.",[1029,1030,1032],"h2",{"id":1031},"when-to-use-it","When to use it",[1034,1035,1036,1060,1072],"ul",{},[1037,1038,1039,1043,1044,1048,1049,1052,1053,1056,1057,1059],"li",{},[1040,1041,1042],"strong",{},"The data is in the page source as JSON"," (",[1045,1046,1047],"code",{},"__NEXT_DATA__",", ",[1045,1050,1051],{},"window.__INITIAL_STATE__",",\n",[1045,1054,1055],{},"application\u002Fld+json","): use a ",[1045,1058,680],{}," locator. It works at every tier.",[1037,1061,1062,1065,1066,1068,1069,1071],{},[1040,1063,1064],{},"The page fetches the data from an API while it loads",": use a ",[1045,1067,626],{}," locator, or a\n",[1045,1070,571],{}," step when you need the response in a variable for later steps.",[1037,1073,1074,1077],{},[1040,1075,1076],{},"You do not know where the data comes from",": run the program at the browser tier with ordinary\nCSS locators, and let API discovery propose the JSON locators for you.",[1025,1079,1080],{},"Stay with CSS locators when the values only exist in the rendered page (a price computed in the\nbrowser, text assembled from several responses), or when the API needs a token the page negotiates\nin a way you cannot reproduce.",[1029,1082,1084,1085,1087],{"id":1083},"embedded-json-the-json-locator","Embedded JSON: the ",[1045,1086,680],{}," locator",[1025,1089,1090,1091,1093,1094,1048,1097,1048,1099,1101,1102,1105],{},"A ",[1045,1092,680],{}," field evaluates a JSONPath over the JSON embedded in the page. Kaabist looks at\n",[1045,1095,1096],{},"\u003Cscript id=\"__NEXT_DATA__\">",[1045,1098,1051],{},[1045,1100,1055],{}," and\n",[1045,1103,1104],{},"application\u002Fjson"," script tags, in document order, and the first non-empty result wins:",[1107,1108,1112],"pre",{"className":1109,"code":1110,"language":680,"meta":1111,"style":1111},"language-json shiki shiki-themes kaab-code kaab-code kaab-code","\"extract\": {\n  \"stock\": { \"json\": \"$.props.pageProps.product.stock\", \"type\": \"integer\" },\n  \"list_price\": { \"json\": \"$.props.pageProps.product.price\", \"type\": \"number\" }\n}\n","",[1045,1113,1114,1127,1165,1194],{"__ignoreMap":1111},[1115,1116,1119,1123],"span",{"class":1117,"line":1118},"line",1,[1115,1120,1122],{"class":1121},"suOy4","\"extract\"",[1115,1124,1126],{"class":1125},"sTzsn",": {\n",[1115,1128,1130,1134,1138,1141,1144,1146,1149,1152,1155,1157,1160,1163],{"class":1117,"line":1129},2,[1115,1131,1133],{"class":1132},"sqn18","  \"stock\"",[1115,1135,1137],{"class":1136},"sQm2-",":",[1115,1139,1140],{"class":1125}," { ",[1115,1142,1143],{"class":1132},"\"json\"",[1115,1145,1137],{"class":1136},[1115,1147,1148],{"class":1121}," \"$.props.pageProps.product.stock\"",[1115,1150,1151],{"class":1136},",",[1115,1153,1154],{"class":1132}," \"type\"",[1115,1156,1137],{"class":1136},[1115,1158,1159],{"class":1121}," \"integer\"",[1115,1161,1162],{"class":1125}," }",[1115,1164,1052],{"class":1136},[1115,1166,1168,1171,1173,1175,1177,1179,1182,1184,1186,1188,1191],{"class":1117,"line":1167},3,[1115,1169,1170],{"class":1132},"  \"list_price\"",[1115,1172,1137],{"class":1136},[1115,1174,1140],{"class":1125},[1115,1176,1143],{"class":1132},[1115,1178,1137],{"class":1136},[1115,1180,1181],{"class":1121}," \"$.props.pageProps.product.price\"",[1115,1183,1151],{"class":1136},[1115,1185,1154],{"class":1132},[1115,1187,1137],{"class":1136},[1115,1189,1190],{"class":1121}," \"number\"",[1115,1192,1193],{"class":1125}," }\n",[1115,1195,1197],{"class":1117,"line":1196},4,[1115,1198,1199],{"class":1125},"}\n",[1025,1201,1202,1203,1206,1207,1209],{},"A product page such as ",[1045,1204,1205],{},"https:\u002F\u002Fshop.example.com\u002Fp\u002F1"," that embeds its product in ",[1045,1208,1047],{},"\nlets this extract read the stock and the list price there at the http tier, while other fields of the same extract read the\nHTML.",[1029,1211,1213,1214,1087],{"id":1212},"api-responses-the-network-locator","API responses: the ",[1045,1215,626],{},[1025,1217,1090,1218,1220,1221,1223,1224,1227,1228,1230],{},[1045,1219,626],{}," field reads a JSON response the page received: ",[1045,1222,610],{}," is a glob matched against the full\nURL, ",[1045,1225,1226],{},"method"," is optional, and ",[1045,1229,680],{}," is the JSONPath into the body.",[1107,1232,1234],{"className":1109,"code":1233,"language":680,"meta":1111,"style":1111},"\"offers\": { \"network\": { \"url\": \"**\u002Fapi\u002Foffers*\", \"json\": \"$.items[*].price\" }, \"type\": \"list\" }\n",[1045,1235,1236],{"__ignoreMap":1111},[1115,1237,1238,1241,1244,1247,1249,1251,1254,1256,1259,1261,1264,1266,1269,1271,1273,1275,1277,1280],{"class":1117,"line":1118},[1115,1239,1240],{"class":1121},"\"offers\"",[1115,1242,1243],{"class":1125},": { ",[1115,1245,1246],{"class":1132},"\"network\"",[1115,1248,1137],{"class":1136},[1115,1250,1140],{"class":1125},[1115,1252,1253],{"class":1132},"\"url\"",[1115,1255,1137],{"class":1136},[1115,1257,1258],{"class":1121}," \"**\u002Fapi\u002Foffers*\"",[1115,1260,1151],{"class":1136},[1115,1262,1263],{"class":1132}," \"json\"",[1115,1265,1137],{"class":1136},[1115,1267,1268],{"class":1121}," \"$.items[*].price\"",[1115,1270,1162],{"class":1125},[1115,1272,1151],{"class":1136},[1115,1274,1154],{"class":1132},[1115,1276,1137],{"class":1136},[1115,1278,1279],{"class":1121}," \"list\"",[1115,1281,1193],{"class":1125},[1025,1283,1284,1285,1288,1289,1291,1292,1295,1296,1298,1299,1301,1302,1305],{},"Give a path that returns several values ",[1045,1286,1287],{},"\"type\": \"list\"",". A list of objects works too: put the\n",[1045,1290,626],{}," locator on a ",[1045,1293,1294],{},"many: true"," field with ",[1045,1297,642],{},", and each subfield's ",[1045,1300,680],{}," path is then\nevaluated against its own item (",[1045,1303,1304],{},"$.price","), the way a CSS subfield is located inside its own card.",[1025,1307,1308,1309,1311],{},"To be sure the response has arrived before you read it, make the navigation wait for it with a\n",[1045,1310,626],{}," condition:",[1107,1313,1315],{"className":1109,"code":1314,"language":680,"meta":1111,"style":1111},"{ \"goto\": \"https:\u002F\u002Fapp.example.com\u002F\", \"expect\": { \"network\": { \"url\": \"**\u002Fapi\u002F**\", \"status\": 200 } } }\n",[1045,1316,1317],{"__ignoreMap":1111},[1115,1318,1319,1322,1325,1327,1330,1332,1335,1337,1339,1341,1343,1345,1347,1349,1352,1354,1357,1359,1363],{"class":1117,"line":1118},[1115,1320,1321],{"class":1125},"{ ",[1115,1323,1324],{"class":1132},"\"goto\"",[1115,1326,1137],{"class":1136},[1115,1328,1329],{"class":1121}," \"https:\u002F\u002Fapp.example.com\u002F\"",[1115,1331,1151],{"class":1136},[1115,1333,1334],{"class":1132}," \"expect\"",[1115,1336,1137],{"class":1136},[1115,1338,1140],{"class":1125},[1115,1340,1246],{"class":1132},[1115,1342,1137],{"class":1136},[1115,1344,1140],{"class":1125},[1115,1346,1253],{"class":1132},[1115,1348,1137],{"class":1136},[1115,1350,1351],{"class":1121}," \"**\u002Fapi\u002F**\"",[1115,1353,1151],{"class":1136},[1115,1355,1356],{"class":1132}," \"status\"",[1115,1358,1137],{"class":1136},[1115,1360,1362],{"class":1361},"sHJIl"," 200",[1115,1364,1365],{"class":1125}," } } }\n",[1025,1367,1368,1369,1372,1373,1376,1377,1379],{},"At the ",[1040,1370,1371],{},"browser tier"," the responses are the ones the page fetched. At the ",[1040,1374,1375],{},"http tier"," no script\nruns, so Kaabist fetches the endpoints your ",[1045,1378,626],{}," locators name itself, alongside the document.\nIt can only do that for a glob that names one endpoint:",[1034,1381,1382,1397,1408],{},[1037,1383,1384,1385,1388,1389,1392,1393,1396],{},"a leading ",[1045,1386,1387],{},"**\u002F"," is resolved against the page's own origin, so ",[1045,1390,1391],{},"**\u002Fapi\u002Fproducts"," fetches\n",[1045,1394,1395],{},"\u002Fapi\u002Fproducts"," on the site you navigated to;",[1037,1398,1399,1400,1403,1404,1407],{},"a trailing ",[1045,1401,1402],{},"*"," after the path (",[1045,1405,1406],{},"**\u002Fapi\u002Foffers*",") is dropped, which asks the endpoint for its\ndefaults;",[1037,1409,1410,1411,1413,1414,1048,1417,1420],{},"a ",[1045,1412,1402],{}," anywhere inside the path (",[1045,1415,1416],{},"**\u002Fapi\u002F**",[1045,1418,1419],{},"**\u002Fproducts\u002F*",") cannot be fetched, and that\nlocator finds nothing at the http tier.",[1025,1422,1423,1424,1427,1428,1431,1432,1434,1435,1437],{},"At most three endpoints are fetched per page, all at once, each within 5 seconds and up to 512 KB.\nOnly ",[1045,1425,1426],{},"GET"," and ",[1045,1429,1430],{},"HEAD"," endpoints are fetched: a ",[1045,1433,626],{}," locator naming another ",[1045,1436,1226],{}," finds\nnothing at the http tier, and the job reads it in a browser. Each endpoint is fetched once per job,\nhowever many pages ask for it. An answer of 400 or above is not recorded, and one over 512 KB is\nlisted as truncated, with no body.",[1029,1439,1441,1442],{"id":1440},"capturing-a-response-capture_response","Capturing a response: ",[1045,1443,571],{},[1025,1445,1446,1448],{},[1045,1447,571],{}," waits for a matching response that arrives while the step runs and stores it,\nor the part of it a JSONPath selects, in a variable:",[1107,1450,1452],{"className":1109,"code":1451,"language":680,"meta":1111,"style":1111},"{ \"capture_response\": { \"url\": \"**\u002Fapi\u002Fmore*\", \"method\": \"GET\", \"json\": \"$.items[*].label\",\n  \"into\": \"vars.labels\", \"timeout_ms\": 15000 } }\n",[1045,1453,1454,1493],{"__ignoreMap":1111},[1115,1455,1456,1458,1461,1463,1465,1467,1469,1472,1474,1477,1479,1482,1484,1486,1488,1491],{"class":1117,"line":1118},[1115,1457,1321],{"class":1125},[1115,1459,1460],{"class":1132},"\"capture_response\"",[1115,1462,1137],{"class":1136},[1115,1464,1140],{"class":1125},[1115,1466,1253],{"class":1132},[1115,1468,1137],{"class":1136},[1115,1470,1471],{"class":1121}," \"**\u002Fapi\u002Fmore*\"",[1115,1473,1151],{"class":1136},[1115,1475,1476],{"class":1132}," \"method\"",[1115,1478,1137],{"class":1136},[1115,1480,1481],{"class":1121}," \"GET\"",[1115,1483,1151],{"class":1136},[1115,1485,1263],{"class":1132},[1115,1487,1137],{"class":1136},[1115,1489,1490],{"class":1121}," \"$.items[*].label\"",[1115,1492,1052],{"class":1136},[1115,1494,1495,1498,1500,1503,1505,1508,1510,1513],{"class":1117,"line":1129},[1115,1496,1497],{"class":1132},"  \"into\"",[1115,1499,1137],{"class":1136},[1115,1501,1502],{"class":1121}," \"vars.labels\"",[1115,1504,1151],{"class":1136},[1115,1506,1507],{"class":1132}," \"timeout_ms\"",[1115,1509,1137],{"class":1136},[1115,1511,1512],{"class":1361}," 15000",[1115,1514,1515],{"class":1125}," } }\n",[1025,1517,1518,1519,1522],{},"Later steps read it as ",[1045,1520,1521],{},"{{vars.labels}}",". Use it for something the page fetches in reaction to an\naction (a \"load more\", a filter) or for a value you need in a URL or a condition rather than in the\nresult. The response body may be at most 2 MB.",[1029,1524,1526],{"id":1525},"api-discovery","API discovery",[1025,1528,1529,1530,1532,1533,1535],{},"After a successful browser-tier run, Kaabist compares the values the job extracted with the JSON\nresponses the page fetched. When one endpoint explains the extracted data (most top-level fields\nand every list field found in it), it builds a ",[1045,1531,626],{}," locator for each field, or a ",[1045,1534,680],{},"\nlocator if the same JSON is embedded in the document. It then checks them by re-running the\nextract with only the new locators against the same page, and discards them unless the result is\nidentical. Discovery runs at most once a day per program version.",[1025,1537,1538,1539,1541,1542,1545],{},"What survives becomes a ",[1040,1540,498],{}," of kind ",[1045,1543,1544],{},"api_discovery"," on your program, waiting in the review\nqueue. Nothing changes until you approve it. Approving it:",[1034,1547,1548,1554,1565],{},[1037,1549,1550,1551,1553],{},"puts the discovered locators first in each field's ",[1045,1552,655],{},", keeping your previous locators\nafter them as fallbacks;",[1037,1555,1556,1557,1560,1561,1564],{},"when ",[1040,1558,1559],{},"every"," top-level field then reads JSON, sets ",[1045,1562,1563],{},"options.prefer_tier: \"http\"",", so the next\njob starts without a browser;",[1037,1566,1567,1568,1571,1572,1575,1576,1579],{},"with ",[1045,1569,1570],{},"promote: true",", publishes the result as a new version and moves the ",[1045,1573,1574],{},"latest"," alias (never\n",[1045,1577,1578],{},"production",", which you move yourself).",[1025,1581,1582],{},"The program now reads the endpoint instead of the DOM, and runs at the http tier: the same data,\nfor the price of an http fetch.",[1029,1584,1586],{"id":1585},"worked-example","Worked example",[1025,1588,1589,1590,1593],{},"Take a single-page app at ",[1045,1591,1592],{},"https:\u002F\u002Fapp.example.com"," that is an empty shell: its script fetches the\nproducts from a JSON API half a second after loading, then draws the cards. This program waits for that API call and reads the\nproduct names and prices straight out of its body:",[1595,1596,1597],"code-group",{},[1107,1598,1603],{"className":1599,"code":1600,"filename":1601,"language":1602,"meta":1111,"style":1111},"language-ts shiki shiki-themes kaab-code kaab-code kaab-code","const definition = {\n  kaab: \"1\",\n  name,\n  options: { max_tier: \"browser\" }, \u002F\u002F the API call is made by the page's JavaScript\n  steps: [\n    \u002F\u002F Wait until the page's API call has answered…\n    { goto: `${site}\u002F`, expect: { network: { url: \"**\u002Fapi\u002F**\", status: 200 } } },\n    {\n      extract: {\n        \u002F\u002F …then read fields straight out of its JSON body.\n        names: { network: { url: \"**\u002Fapi\u002F**\", json: \"$..items[*].name\" }, type: \"list\" },\n        prices: { network: { url: \"**\u002Fapi\u002F**\", json: \"$..items[*].price\" }, type: \"list\" },\n      },\n    },\n  ],\n};\n","TypeScript","ts",[1045,1604,1605,1619,1631,1638,1661,1672,1678,1734,1740,1750,1756,1799,1840,1848,1856,1864],{"__ignoreMap":1111},[1115,1606,1607,1610,1613,1616],{"class":1117,"line":1118},[1115,1608,1609],{"class":1132},"const",[1115,1611,1612],{"class":1361}," definition",[1115,1614,1615],{"class":1132}," =",[1115,1617,1618],{"class":1125}," {\n",[1115,1620,1621,1624,1626,1629],{"class":1117,"line":1129},[1115,1622,1623],{"class":1125},"  kaab",[1115,1625,1137],{"class":1132},[1115,1627,1628],{"class":1121}," \"1\"",[1115,1630,1052],{"class":1136},[1115,1632,1633,1636],{"class":1117,"line":1167},[1115,1634,1635],{"class":1125},"  name",[1115,1637,1052],{"class":1136},[1115,1639,1640,1643,1645,1648,1650,1653,1655,1657],{"class":1117,"line":1196},[1115,1641,1642],{"class":1125},"  options",[1115,1644,1137],{"class":1132},[1115,1646,1647],{"class":1125}," { max_tier",[1115,1649,1137],{"class":1132},[1115,1651,1652],{"class":1121}," \"browser\"",[1115,1654,1162],{"class":1125},[1115,1656,1151],{"class":1136},[1115,1658,1660],{"class":1659},"sKog0"," \u002F\u002F the API call is made by the page's JavaScript\n",[1115,1662,1664,1667,1669],{"class":1117,"line":1663},5,[1115,1665,1666],{"class":1125},"  steps",[1115,1668,1137],{"class":1132},[1115,1670,1671],{"class":1125}," [\n",[1115,1673,1675],{"class":1117,"line":1674},6,[1115,1676,1677],{"class":1659},"    \u002F\u002F Wait until the page's API call has answered…\n",[1115,1679,1681,1684,1686,1689,1692,1695,1698,1701,1703,1706,1708,1711,1713,1716,1718,1720,1722,1725,1727,1729,1732],{"class":1117,"line":1680},7,[1115,1682,1683],{"class":1125},"    { goto",[1115,1685,1137],{"class":1132},[1115,1687,1688],{"class":1121}," `",[1115,1690,1691],{"class":1132},"${",[1115,1693,1694],{"class":1125},"site",[1115,1696,1697],{"class":1132},"}",[1115,1699,1700],{"class":1121},"\u002F`",[1115,1702,1151],{"class":1136},[1115,1704,1705],{"class":1125}," expect",[1115,1707,1137],{"class":1132},[1115,1709,1710],{"class":1125}," { network",[1115,1712,1137],{"class":1132},[1115,1714,1715],{"class":1125}," { url",[1115,1717,1137],{"class":1132},[1115,1719,1351],{"class":1121},[1115,1721,1151],{"class":1136},[1115,1723,1724],{"class":1125}," status",[1115,1726,1137],{"class":1132},[1115,1728,1362],{"class":1361},[1115,1730,1731],{"class":1125}," } } }",[1115,1733,1052],{"class":1136},[1115,1735,1737],{"class":1117,"line":1736},8,[1115,1738,1739],{"class":1125},"    {\n",[1115,1741,1743,1746,1748],{"class":1117,"line":1742},9,[1115,1744,1745],{"class":1125},"      extract",[1115,1747,1137],{"class":1132},[1115,1749,1618],{"class":1125},[1115,1751,1753],{"class":1117,"line":1752},10,[1115,1754,1755],{"class":1659},"        \u002F\u002F …then read fields straight out of its JSON body.\n",[1115,1757,1759,1762,1764,1766,1768,1770,1772,1774,1776,1779,1781,1784,1786,1788,1791,1793,1795,1797],{"class":1117,"line":1758},11,[1115,1760,1761],{"class":1125},"        names",[1115,1763,1137],{"class":1132},[1115,1765,1710],{"class":1125},[1115,1767,1137],{"class":1132},[1115,1769,1715],{"class":1125},[1115,1771,1137],{"class":1132},[1115,1773,1351],{"class":1121},[1115,1775,1151],{"class":1136},[1115,1777,1778],{"class":1125}," json",[1115,1780,1137],{"class":1132},[1115,1782,1783],{"class":1121}," \"$..items[*].name\"",[1115,1785,1162],{"class":1125},[1115,1787,1151],{"class":1136},[1115,1789,1790],{"class":1125}," type",[1115,1792,1137],{"class":1132},[1115,1794,1279],{"class":1121},[1115,1796,1162],{"class":1125},[1115,1798,1052],{"class":1136},[1115,1800,1802,1805,1807,1809,1811,1813,1815,1817,1819,1821,1823,1826,1828,1830,1832,1834,1836,1838],{"class":1117,"line":1801},12,[1115,1803,1804],{"class":1125},"        prices",[1115,1806,1137],{"class":1132},[1115,1808,1710],{"class":1125},[1115,1810,1137],{"class":1132},[1115,1812,1715],{"class":1125},[1115,1814,1137],{"class":1132},[1115,1816,1351],{"class":1121},[1115,1818,1151],{"class":1136},[1115,1820,1778],{"class":1125},[1115,1822,1137],{"class":1132},[1115,1824,1825],{"class":1121}," \"$..items[*].price\"",[1115,1827,1162],{"class":1125},[1115,1829,1151],{"class":1136},[1115,1831,1790],{"class":1125},[1115,1833,1137],{"class":1132},[1115,1835,1279],{"class":1121},[1115,1837,1162],{"class":1125},[1115,1839,1052],{"class":1136},[1115,1841,1843,1846],{"class":1117,"line":1842},13,[1115,1844,1845],{"class":1125},"      }",[1115,1847,1052],{"class":1136},[1115,1849,1851,1854],{"class":1117,"line":1850},14,[1115,1852,1853],{"class":1125},"    }",[1115,1855,1052],{"class":1136},[1115,1857,1859,1862],{"class":1117,"line":1858},15,[1115,1860,1861],{"class":1125},"  ]",[1115,1863,1052],{"class":1136},[1115,1865,1867],{"class":1117,"line":1866},16,[1115,1868,1869],{"class":1125},"};\n",[1025,1871,1872,1873,1427,1876,1879],{},"The job succeeds at the browser tier with ",[1045,1874,1875],{},"data.names",[1045,1877,1878],{},"data.prices"," read from the API.",[1881,1882,1883],"note",{},[1025,1884,1090,1885,1887,1888,1890,1891,1893],{},[1045,1886,626],{}," field is the dependable way to read a response today. A ",[1045,1889,571],{}," step does\nnot yet catch a response that arrives while it runs on a page like this one; until that is fixed,\nread the response with a ",[1045,1892,626],{}," locator, as above.",[1025,1895,1896,1897,1900,1901,1048,1904,1427,1907,1910,1911,1137],{},"To see discovery at work, publish a program that reads the same site with CSS locators only\n(",[1045,1898,1899],{},"#products .product-card"," with ",[1045,1902,1903],{},".title",[1045,1905,1906],{},".price",[1045,1908,1909],{},".sku"," subfields) and ",[1045,1912,1913],{},"prefer_tier: \"http\"",[1915,1916,1917,1920,1932,1942],"ol",{},[1037,1918,1919],{},"The first job starts at the http tier, finds an empty shell, and escalates to the browser, where\nit succeeds.",[1037,1921,1922,1923,1925,1926,1928,1929,1931],{},"A pending proposal of kind ",[1045,1924,1544],{}," appears for that program, with ",[1045,1927,626],{}," locators on\nthe site's ",[1045,1930,1395],{}," endpoint.",[1037,1933,1934,1935,1937,1938,1941],{},"Approve it with ",[1045,1936,1570],{},", and remove any ",[1045,1939,1940],{},"expect"," on the navigation that counts cards in\nthe DOM (see the pitfalls).",[1037,1943,1944],{},"The next job reads the endpoint at the http tier and returns the same products.",[1029,1946,1948],{"id":1947},"pitfalls","Pitfalls",[1034,1950,1951,1966,1978,1987,1998],{},[1037,1952,1953,1956,1957,1959,1960,1962,1963,1965],{},[1040,1954,1955],{},"DOM postconditions keep a job on the browser."," Approving a discovery rewrites locators, not\n",[1045,1958,1940],{}," conditions. A ",[1045,1961,590],{}," that still expects product cards in the HTML fails at the http\ntier, because the shell has none, and the job escalates again. Expect a ",[1045,1964,626],{}," response\ninstead, or nothing.",[1037,1967,1968,1971,1972,1974,1975,1977],{},[1040,1969,1970],{},"Wildcards inside the path."," At the http tier an endpoint is only fetched when the glob's path\nis literal. The worked example's ",[1045,1973,1416],{}," is fine in a browser and finds nothing without one;\nwrite ",[1045,1976,1391],{}," (or the full URL) for a program meant to run at the http tier.",[1037,1979,1980,1983,1984,1986],{},[1040,1981,1982],{},"APIs that change shape."," An API is a contract the site never promised you either. Keep the\nCSS locators as later ",[1045,1985,655],{}," (discovery does this for you) so a changed payload falls back\nrather than failing.",[1037,1988,1989,1994,1995,1997],{},[1040,1990,1991,1993],{},[1045,1992,571],{}," only sees responses that arrive while it runs."," A response that came during\nan earlier step is gone; capture it in the step that triggers it, or read it with a ",[1045,1996,626],{},"\nlocator in the extract.",[1037,1999,2000,2003],{},[1040,2001,2002],{},"Analytics beacons."," A page sends its own data to tracking endpoints too. Make the glob specific\nenough to match the data API only.",[1029,2005,155],{"id":2006},"reference",[1034,2008,2009,2028,2042,2056,2066],{},[1037,2010,2011,2012,1048,2018,1052,2023],{},"Fields: ",[2013,2014,2016],"a",{"href":2015},"\u002Freference\u002Fdsl\u002Ffields\u002Fjson",[1045,2017,680],{},[2013,2019,2021],{"href":2020},"\u002Freference\u002Fdsl\u002Ffields\u002Fnetwork",[1045,2022,626],{},[2013,2024,2026],{"href":2025},"\u002Freference\u002Fdsl\u002Ffields\u002Fmany",[1045,2027,684],{},[1037,2029,2030,2035,2036],{},[2013,2031,2033],{"href":2032},"\u002Freference\u002Fdsl\u002Factions\u002Fcapture-response",[1045,2034,571],{}," and the\n",[2013,2037,2039,2041],{"href":2038},"\u002Freference\u002Fdsl\u002Fconditions\u002Fnetwork",[1045,2040,626],{}," condition",[1037,2043,2044,1048,2048,1052,2052],{},[2013,2045,2047],{"href":2046},"\u002Freference\u002Fapi\u002Fproposals\u002Flist-proposals","list proposals",[2013,2049,2051],{"href":2050},"\u002Freference\u002Fapi\u002Fproposals\u002Fapprove-proposal","approve a proposal",[2013,2053,2055],{"href":2054},"\u002Freference\u002Fapi\u002Fschemas\u002Fproposal","proposal schema",[1037,2057,2058,1043,2062,2065],{},[2013,2059,2061],{"href":2060},"\u002Freference\u002Fapi\u002Fsites\u002Fget-site-profile","Site profiles",[1045,2063,2064],{},"api_endpoints_count",")",[1037,2067,2068,2069,1048,2073,1052,2077],{},"Concepts: ",[2013,2070,2072],{"href":2071},"\u002Fconcepts\u002Ftiers-and-escalation","tiers and escalation",[2013,2074,2076],{"href":2075},"\u002Fconcepts\u002Fhttp-tier","the http tier",[2013,2078,63],{"href":2079},"\u002Fconcepts\u002Flocators",[2081,2082,2083],"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 .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .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 pre.shiki code .sKog0, html code.shiki .sKog0{--shiki-light:var(--kaab-code-token-comment);--shiki-default:var(--kaab-code-token-comment);--shiki-dark:var(--kaab-code-token-comment)}",{"title":1111,"searchDepth":1167,"depth":1167,"links":2085},[2086,2087,2089,2091,2093,2094,2095,2096],{"id":1031,"depth":1129,"text":1032},{"id":1083,"depth":1129,"text":2088},"Embedded JSON: the json locator",{"id":1212,"depth":1129,"text":2090},"API responses: the network locator",{"id":1440,"depth":1129,"text":2092},"Capturing a response: capture_response",{"id":1525,"depth":1129,"text":1526},{"id":1585,"depth":1129,"text":1586},{"id":1947,"depth":1129,"text":1948},{"id":2006,"depth":1129,"text":155},false,null,"Read the JSON a page embeds or fetches instead of the HTML drawn from it, capture API responses, and let a discovered API move a job to the http tier.","md",{},true,"\u002Fguides\u002Fjson-and-network-locators",{"title":98,"description":2099},"3.guides\u002F04.json-and-network-locators","n8njL8r18bd4STYpycjdVCBuOAM1eTnvU7KsCTKjv0I",[2108,2112],{"title":95,"path":2109,"stem":2110,"description":2111,"children":-1},"\u002Fguides\u002Flists-and-pagination","3.guides\u002F03.lists-and-pagination","Extract lists of objects, follow \"next\" links across pages, and load infinite lists by scrolling, with bounds lint can check.",{"title":101,"path":2113,"stem":2114,"description":2115,"children":-1},"\u002Fguides\u002Fschedules-and-change-detection","3.guides\u002F05.schedules-and-change-detection","Run a program on a cron in your timezone, compare each result with the last one, and get a webhook only when a watched field changes.",1793593415971]