[{"data":1,"prerenderedAt":2694},["ShallowReactive",2],{"navigation":3,"page:\u002Fconcepts\u002Fsessions":1019,"surround:\u002Fconcepts\u002Fsessions":2686},[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":41,"body":1021,"breaking":2676,"date":2677,"description":2678,"extension":2679,"generated":2676,"meta":2680,"navigation":2681,"path":2682,"seo":2683,"stem":2684,"version":2677,"__hash__":2685},"docs\u002F2.concepts\u002F05.sessions.md",{"type":1022,"value":1023,"toc":2658},"minimark",[1024,1028,1033,1036,1040,1249,1276,1280,1283,1296,1333,1336,1349,1444,1466,1470,1480,1514,1527,1532,1542,1563,1566,1570,1577,1598,1617,1621,1624,1653,1663,1667,1684,1748,1768,1772,1780,1802,1812,1816,1819,1837,1840,1847,1851,1898,1902,1916,1958,1971,1991,1997,2310,2316,2527,2548,2552,2587,2590,2654],[1025,1026,1027],"p",{},"A session is a stored, encrypted browser storage state that lets jobs start already signed in to a site. You create it once, from a first run or by uploading a state, and every job you bind to it skips the login, until the site expires it and a refresh program or a person signs in again.",[1029,1030,1032],"h2",{"id":1031},"when-to-use-it","When to use it",[1025,1034,1035],{},"Use a session for any program that works behind a login and runs more than once: a scheduled export, a report read every hour, a batch of lookups in a portal. Without one, every job signs in, which is slower, costs browser time, and on many sites triggers a one-time code or a \"new device\" warning each time. For a single run, a program that signs in without saving a session is enough.",[1029,1037,1039],{"id":1038},"what-a-session-is","What a session is",[1041,1042,1046],"pre",{"className":1043,"code":1044,"language":680,"meta":1045,"style":1045},"language-json shiki shiki-themes kaab-code kaab-code kaab-code","{\n  \"id\": \"ses_01J…\",\n  \"object\": \"session\",\n  \"name\": \"portal-login\",\n  \"origins\": [\"https:\u002F\u002Fportal.example.com\"],\n  \"status\": \"valid\",\n  \"concurrency\": \"exclusive\",\n  \"refresh\": { \"program\": \"portal-report\", \"has_inputs\": true },\n  \"last_verified_at\": \"2026-09-20T09:00:00Z\",\n  \"last_used_at\": \"2026-09-20T11:42:00Z\",\n  \"locked_by\": null,\n  \"created_at\": \"…\", \"updated_at\": \"…\"\n}\n","",[1047,1048,1049,1058,1076,1089,1102,1121,1134,1147,1183,1196,1209,1222,1243],"code",{"__ignoreMap":1045},[1050,1051,1054],"span",{"class":1052,"line":1053},"line",1,[1050,1055,1057],{"class":1056},"sTzsn","{\n",[1050,1059,1061,1065,1069,1073],{"class":1052,"line":1060},2,[1050,1062,1064],{"class":1063},"sqn18","  \"id\"",[1050,1066,1068],{"class":1067},"sQm2-",":",[1050,1070,1072],{"class":1071},"suOy4"," \"ses_01J…\"",[1050,1074,1075],{"class":1067},",\n",[1050,1077,1079,1082,1084,1087],{"class":1052,"line":1078},3,[1050,1080,1081],{"class":1063},"  \"object\"",[1050,1083,1068],{"class":1067},[1050,1085,1086],{"class":1071}," \"session\"",[1050,1088,1075],{"class":1067},[1050,1090,1092,1095,1097,1100],{"class":1052,"line":1091},4,[1050,1093,1094],{"class":1063},"  \"name\"",[1050,1096,1068],{"class":1067},[1050,1098,1099],{"class":1071}," \"portal-login\"",[1050,1101,1075],{"class":1067},[1050,1103,1105,1108,1110,1113,1116,1119],{"class":1052,"line":1104},5,[1050,1106,1107],{"class":1063},"  \"origins\"",[1050,1109,1068],{"class":1067},[1050,1111,1112],{"class":1056}," [",[1050,1114,1115],{"class":1071},"\"https:\u002F\u002Fportal.example.com\"",[1050,1117,1118],{"class":1056},"]",[1050,1120,1075],{"class":1067},[1050,1122,1124,1127,1129,1132],{"class":1052,"line":1123},6,[1050,1125,1126],{"class":1063},"  \"status\"",[1050,1128,1068],{"class":1067},[1050,1130,1131],{"class":1071}," \"valid\"",[1050,1133,1075],{"class":1067},[1050,1135,1137,1140,1142,1145],{"class":1052,"line":1136},7,[1050,1138,1139],{"class":1063},"  \"concurrency\"",[1050,1141,1068],{"class":1067},[1050,1143,1144],{"class":1071}," \"exclusive\"",[1050,1146,1075],{"class":1067},[1050,1148,1150,1153,1155,1158,1161,1163,1166,1169,1172,1174,1178,1181],{"class":1052,"line":1149},8,[1050,1151,1152],{"class":1063},"  \"refresh\"",[1050,1154,1068],{"class":1067},[1050,1156,1157],{"class":1056}," { ",[1050,1159,1160],{"class":1063},"\"program\"",[1050,1162,1068],{"class":1067},[1050,1164,1165],{"class":1071}," \"portal-report\"",[1050,1167,1168],{"class":1067},",",[1050,1170,1171],{"class":1063}," \"has_inputs\"",[1050,1173,1068],{"class":1067},[1050,1175,1177],{"class":1176},"sHJIl"," true",[1050,1179,1180],{"class":1056}," }",[1050,1182,1075],{"class":1067},[1050,1184,1186,1189,1191,1194],{"class":1052,"line":1185},9,[1050,1187,1188],{"class":1063},"  \"last_verified_at\"",[1050,1190,1068],{"class":1067},[1050,1192,1193],{"class":1071}," \"2026-09-20T09:00:00Z\"",[1050,1195,1075],{"class":1067},[1050,1197,1199,1202,1204,1207],{"class":1052,"line":1198},10,[1050,1200,1201],{"class":1063},"  \"last_used_at\"",[1050,1203,1068],{"class":1067},[1050,1205,1206],{"class":1071}," \"2026-09-20T11:42:00Z\"",[1050,1208,1075],{"class":1067},[1050,1210,1212,1215,1217,1220],{"class":1052,"line":1211},11,[1050,1213,1214],{"class":1063},"  \"locked_by\"",[1050,1216,1068],{"class":1067},[1050,1218,1219],{"class":1176}," null",[1050,1221,1075],{"class":1067},[1050,1223,1225,1228,1230,1233,1235,1238,1240],{"class":1052,"line":1224},12,[1050,1226,1227],{"class":1063},"  \"created_at\"",[1050,1229,1068],{"class":1067},[1050,1231,1232],{"class":1071}," \"…\"",[1050,1234,1168],{"class":1067},[1050,1236,1237],{"class":1063}," \"updated_at\"",[1050,1239,1068],{"class":1067},[1050,1241,1242],{"class":1071}," \"…\"\n",[1050,1244,1246],{"class":1052,"line":1245},13,[1050,1247,1248],{"class":1056},"}\n",[1025,1250,1251,1254,1255,1258,1259,1262,1263,1266,1267,1270,1271,1275],{},[1047,1252,1253],{},"status"," is ",[1047,1256,1257],{},"valid",", ",[1047,1260,1261],{},"expired"," or ",[1047,1264,1265],{},"unknown",". ",[1047,1268,1269],{},"origins"," scopes which sites the session's cookies may be sent to. The storage state itself is ",[1272,1273,1274],"strong",{},"write-only",": the object has no field for it. You can replace it and delete it; nothing (not the API, not the panel, not a support request) reads it back. It is encrypted with your organisation's own data key and exists in the clear only inside the worker running your job, for the length of that job.",[1029,1277,1279],{"id":1278},"creating-a-session","Creating a session",[1025,1281,1282],{},"There are two ways.",[1025,1284,1285,1288,1289,1291,1292,1295],{},[1272,1286,1287],{},"From a job."," A ",[1047,1290,595],{}," step with ",[1047,1293,1294],{},"save_session"," writes the browser's storage state to the named session, creating it if it does not exist and merging into it if it does:",[1041,1297,1299],{"className":1043,"code":1298,"language":680,"meta":1045,"style":1045},"{ \"checkpoint\": { \"name\": \"logged_in\", \"save_session\": \"portal-login\" } }\n",[1047,1300,1301],{"__ignoreMap":1045},[1050,1302,1303,1306,1309,1311,1313,1316,1318,1321,1323,1326,1328,1330],{"class":1052,"line":1053},[1050,1304,1305],{"class":1056},"{ ",[1050,1307,1308],{"class":1063},"\"checkpoint\"",[1050,1310,1068],{"class":1067},[1050,1312,1157],{"class":1056},[1050,1314,1315],{"class":1063},"\"name\"",[1050,1317,1068],{"class":1067},[1050,1319,1320],{"class":1071}," \"logged_in\"",[1050,1322,1168],{"class":1067},[1050,1324,1325],{"class":1063}," \"save_session\"",[1050,1327,1068],{"class":1067},[1050,1329,1099],{"class":1071},[1050,1331,1332],{"class":1056}," } }\n",[1025,1334,1335],{},"This is the usual way: the program signs in once, and the state it ends up with is what later jobs start from.",[1025,1337,1338,1341,1342,1345,1346,1068],{},[1272,1339,1340],{},"From a state you already have."," ",[1047,1343,1344],{},"POST \u002Fv1\u002Fsessions"," with a Playwright ",[1047,1347,1348],{},"storageState",[1041,1350,1352],{"className":1043,"code":1351,"language":680,"meta":1045,"style":1045},"{\n  \"name\": \"portal-login\",\n  \"storage_state\": { \"cookies\": [], \"origins\": [] },\n  \"concurrency\": \"exclusive\",\n  \"refresh\": { \"program\": \"portal-report\", \"inputs\": { \"email\": \"dev@example.com\" } }\n}\n",[1047,1353,1354,1358,1368,1397,1407,1440],{"__ignoreMap":1045},[1050,1355,1356],{"class":1052,"line":1053},[1050,1357,1057],{"class":1056},[1050,1359,1360,1362,1364,1366],{"class":1052,"line":1060},[1050,1361,1094],{"class":1063},[1050,1363,1068],{"class":1067},[1050,1365,1099],{"class":1071},[1050,1367,1075],{"class":1067},[1050,1369,1370,1373,1375,1377,1380,1382,1385,1387,1390,1392,1395],{"class":1052,"line":1078},[1050,1371,1372],{"class":1063},"  \"storage_state\"",[1050,1374,1068],{"class":1067},[1050,1376,1157],{"class":1056},[1050,1378,1379],{"class":1063},"\"cookies\"",[1050,1381,1068],{"class":1067},[1050,1383,1384],{"class":1056}," []",[1050,1386,1168],{"class":1067},[1050,1388,1389],{"class":1063}," \"origins\"",[1050,1391,1068],{"class":1067},[1050,1393,1394],{"class":1056}," [] }",[1050,1396,1075],{"class":1067},[1050,1398,1399,1401,1403,1405],{"class":1052,"line":1091},[1050,1400,1139],{"class":1063},[1050,1402,1068],{"class":1067},[1050,1404,1144],{"class":1071},[1050,1406,1075],{"class":1067},[1050,1408,1409,1411,1413,1415,1417,1419,1421,1423,1426,1428,1430,1433,1435,1438],{"class":1052,"line":1104},[1050,1410,1152],{"class":1063},[1050,1412,1068],{"class":1067},[1050,1414,1157],{"class":1056},[1050,1416,1160],{"class":1063},[1050,1418,1068],{"class":1067},[1050,1420,1165],{"class":1071},[1050,1422,1168],{"class":1067},[1050,1424,1425],{"class":1063}," \"inputs\"",[1050,1427,1068],{"class":1067},[1050,1429,1157],{"class":1056},[1050,1431,1432],{"class":1063},"\"email\"",[1050,1434,1068],{"class":1067},[1050,1436,1437],{"class":1071}," \"dev@example.com\"",[1050,1439,1332],{"class":1056},[1050,1441,1442],{"class":1052,"line":1123},[1050,1443,1248],{"class":1056},[1025,1445,1446,1448,1449,1452,1453,1258,1455,1262,1458,1461,1462,1465],{},[1047,1447,1269],{}," is derived from the state when you do not send it. ",[1047,1450,1451],{},"PATCH \u002Fv1\u002Fsessions\u002F{id}"," changes ",[1047,1454,702],{},[1047,1456,1457],{},"concurrency",[1047,1459,1460],{},"refresh",", or replaces ",[1047,1463,1464],{},"storage_state",".",[1029,1467,1469],{"id":1468},"binding-a-session-to-jobs","Binding a session to jobs",[1025,1471,1472,1473,1475,1476,1479],{},"A job binds a session by name, with ",[1047,1474,504],{}," in the job body or ",[1047,1477,1478],{},"options.session"," in the program:",[1041,1481,1483],{"className":1043,"code":1482,"language":680,"meta":1045,"style":1045},"{ \"options\": { \"session\": \"portal-login\", \"resume_from_session\": true } }\n",[1047,1484,1485],{"__ignoreMap":1045},[1050,1486,1487,1489,1492,1494,1496,1499,1501,1503,1505,1508,1510,1512],{"class":1052,"line":1053},[1050,1488,1305],{"class":1056},[1050,1490,1491],{"class":1063},"\"options\"",[1050,1493,1068],{"class":1067},[1050,1495,1157],{"class":1056},[1050,1497,1498],{"class":1063},"\"session\"",[1050,1500,1068],{"class":1067},[1050,1502,1099],{"class":1071},[1050,1504,1168],{"class":1067},[1050,1506,1507],{"class":1063}," \"resume_from_session\"",[1050,1509,1068],{"class":1067},[1050,1511,1177],{"class":1176},[1050,1513,1332],{"class":1056},[1025,1515,1516,1517,1520,1521,1523,1524,1526],{},"The session is loaded before the first step. With ",[1047,1518,1519],{},"resume_from_session: true",", a job whose session is valid skips straight to the step after the ",[1047,1522,595],{}," that saved it: the login steps run only when they are needed. A schedule binds a session the same way, through the program or the schedule's ",[1047,1525,531],{},", so every fire starts signed in.",[1528,1529,1531],"h3",{"id":1530},"two-halves-of-being-signed-in","Two halves of being signed in",[1025,1533,1534,1535,1341,1538,1541],{},"Being signed in is cookies ",[1272,1536,1537],{},"and",[1047,1539,1540],{},"localStorage",", and the tiers see them differently:",[1543,1544,1545,1553],"ul",{},[1546,1547,1548,1549,1552],"li",{},"the ",[1272,1550,1551],{},"browser"," tiers load and save both, so a session saved by a browser job is complete;",[1546,1554,1548,1555,1558,1559,1562],{},[1272,1556,1557],{},"http"," tier carries the cookies only and never writes a session back. A program that saves a session needs a browser, and its ",[1047,1560,1561],{},"checkpoint … save_session"," gives it one.",[1025,1564,1565],{},"A session saved by a browser job therefore works at the http tier afterwards, but not the other way round.",[1029,1567,1569],{"id":1568},"locking","Locking",[1025,1571,1572,1573,1576],{},"Two jobs signed in as the same person at the same time is how sites decide you are a robot, and on a site that allows one session at a time each job logs the other out. So a job holding a session holds a ",[1272,1574,1575],{},"lease"," on it:",[1543,1578,1579,1592],{},[1546,1580,1581,1584,1585,1588,1589,1465],{},[1047,1582,1583],{},"exclusive"," (the default): one job at a time. Another job bound to the session waits in the queue with ",[1047,1586,1587],{},"meta.blocked_reason: \"session_locked\"",", and a job that still cannot take the lease after a minute fails ",[1047,1590,1591],{},"session_locked_timeout",[1546,1593,1594,1597],{},[1047,1595,1596],{},"shared",": opt in for sites you know tolerate parallel sign-ins.",[1025,1599,1600,1601,1604,1605,1608,1609,1612,1613,1616],{},"A job releases its lease when it ends, whichever way it ends. ",[1047,1602,1603],{},"locked_by"," names the job holding it, and ",[1047,1606,1607],{},"DELETE \u002Fv1\u002Fsessions\u002F{id}"," answers ",[1047,1610,1611],{},"409 session_locked"," (with ",[1047,1614,1615],{},"details.job_id",") while one does.",[1029,1618,1620],{"id":1619},"checking-that-a-session-works","Checking that a session works",[1025,1622,1623],{},"Sites expire sessions on their own schedule and never say so. Kaabist finds out in two places:",[1625,1626,1627,1643],"ol",{},[1546,1628,1629,1632,1633,1635,1636,1638,1639,1642],{},[1272,1630,1631],{},"Before the job."," If nobody has checked the session in the last hour, a probe loads the root of the session's first origin with it, at the http tier, and reads the answer: a recognised sign-in page means ",[1047,1634,1261],{},"; a page that cannot be judged means ",[1047,1637,1265],{},", and the job runs and finds out. A session already known to be expired is not probed. A site whose signed-in page only appears after its JavaScript runs should set ",[1047,1640,1641],{},"options.session_probe: \"browser\""," on the program, which probes with a browser page load instead.",[1546,1644,1645,1648,1649,1652],{},[1272,1646,1647],{},"During the job."," A step that lands on a sign-in page (the program's ",[1047,1650,1651],{},"login_page"," landmark, or a recognised login form) is classified as an expired session rather than a broken program.",[1025,1654,1655,1658,1659,1662],{},[1047,1656,1657],{},"POST \u002Fv1\u002Fsessions\u002F{id}\u002Fverify"," runs the probe now and answers ",[1047,1660,1661],{},"{ \"status\", \"checked_at\" }",". It costs 1 credit, or 5 where a browser probes.",[1029,1664,1666],{"id":1665},"expiry","Expiry",[1025,1668,1669,1670,1672,1673,1675,1676,1679,1680,1683],{},"When a session is found expired, its ",[1047,1671,1253],{}," becomes ",[1047,1674,1261],{},", a ",[1047,1677,1678],{},"session.expired"," event is sent once, and the job does what the program's ",[1047,1681,1682],{},"policies.on_session_expired"," says:",[1685,1686,1687,1702],"table",{},[1688,1689,1690],"thead",{},[1691,1692,1693,1699],"tr",{},[1694,1695,1696],"th",{},[1047,1697,1698],{},"on_session_expired",[1694,1700,1701],{},"What the job does",[1703,1704,1705,1719,1736],"tbody",{},[1691,1706,1707,1713],{},[1708,1709,1710,1712],"td",{},[1047,1711,1460],{}," (default)",[1708,1714,1715,1716],{},"runs the session's refresh program and carries on; with no refresh program, or one that cannot finish, parks as ",[1047,1717,1718],{},"session_expired",[1691,1720,1721,1726],{},[1708,1722,1723],{},[1047,1724,1725],{},"park",[1708,1727,1728,1729,1732,1733,1735],{},"parks as ",[1047,1730,1731],{},"needs_attention"," with reason ",[1047,1734,1718],{},", for a person to sign in",[1691,1737,1738,1743],{},[1708,1739,1740],{},[1047,1741,1742],{},"fail",[1708,1744,1745,1746],{},"fails with ",[1047,1747,1718],{},[1025,1749,1750,1751,1753,1754,1759,1760,1764,1765,1465],{},"A parked ",[1047,1752,1718],{}," job is resolved like any other park: a person ",[1755,1756,1758],"a",{"href":1757},"\u002Fpanel\u002Ftakeover","takes over"," and signs in, or you share a ",[1755,1761,1763],{"href":1762},"\u002Fguides\u002Fhosted-resolve","hosted resolve page"," with whoever holds the account. See ",[1755,1766,44],{"href":1767},"\u002Fconcepts\u002Fhuman-in-the-loop",[1029,1769,1771],{"id":1770},"refresh-programs","Refresh programs",[1025,1773,1774,1775,1777,1778,1465],{},"A refresh program is an ordinary program that knows how to sign in and ends with a ",[1047,1776,595],{}," that saves the session. Name it in the session's ",[1047,1779,1460],{},[1025,1781,1782,1783,1786,1787,1790,1791,1794,1795,1798,1799,1801],{},"When a session expires mid-job, Kaabist runs the refresh program ",[1272,1784,1785],{},"inside that job, in the same browser",", so the page your program was on is the page that ends up signed in, and then retries the step that failed. Its steps appear in the job's timeline under ",[1047,1788,1789],{},"session_refresh\u002F",". If the site asks for a one-time code, the refresh stops and ",[1272,1792,1793],{},"your job parks"," for it as ",[1047,1796,1797],{},"awaiting_input",", exactly as an ",[1047,1800,592],{}," step in your own program would; answering it resumes the refresh, not the whole program.",[1025,1803,1804,1807,1808,1811],{},[1047,1805,1806],{},"POST \u002Fv1\u002Fsessions\u002F{id}\u002Frefresh"," runs the refresh program on demand as an ordinary job and answers ",[1047,1809,1810],{},"202"," with it.",[1528,1813,1815],{"id":1814},"credentials","Credentials",[1025,1817,1818],{},"Storing a password is optional, discouraged, and off unless you turn it on. Kaabist keeps a refresh program's input only when all three are true:",[1625,1820,1821,1824,1831],{},[1546,1822,1823],{},"your organisation has enabled secret storage in its settings;",[1546,1825,1826,1827,1830],{},"the refresh program declares the input as ",[1047,1828,1829],{},"{ \"type\": \"secret\", \"store\": true }",";",[1546,1832,1833,1834,1465],{},"you supplied it in the session's ",[1047,1835,1836],{},"refresh.inputs",[1025,1838,1839],{},"Setting a session's refresh inputs is recorded in your organisation's audit log.",[1025,1841,1842,1843,1846],{},"Offering a secret that cannot be stored is refused with ",[1047,1844,1845],{},"422 secret_storage_disabled"," rather than dropped, so you are never told a password was saved when it was not. A session with no stored credentials cannot refresh unattended: it parks and a person signs in, which is the mode we recommend.",[1029,1848,1850],{"id":1849},"what-is-kept-and-where","What is kept, and where",[1685,1852,1853,1861],{},[1688,1854,1855],{},[1691,1856,1857,1859],{},[1694,1858],{},[1694,1860],{},[1703,1862,1863,1871,1882,1890],{},[1691,1864,1865,1868],{},[1708,1866,1867],{},"Storage state",[1708,1869,1870],{},"encrypted with your organisation's data key; write-only",[1691,1872,1873,1876],{},[1708,1874,1875],{},"Stored refresh inputs",[1708,1877,1878,1879],{},"the same, and only inputs marked ",[1047,1880,1881],{},"store: true",[1691,1883,1884,1887],{},[1708,1885,1886],{},"Logs, snapshots, screenshots, webhooks",[1708,1888,1889],{},"cookie names at most, never values",[1691,1891,1892,1895],{},[1708,1893,1894],{},"Deleting a session",[1708,1896,1897],{},"removes the row and its state; an organisation data deletion removes every session",[1029,1899,1901],{"id":1900},"worked-example","Worked example",[1025,1903,1904,1905,1908,1909,1912,1913,1915],{},"The site at ",[1047,1906,1907],{},"https:\u002F\u002Fportal.example.com"," signs in with an e-mail and password, asks for a six-digit code, and sets a ",[1047,1910,1911],{},"sid"," cookie. A program for it fills the form, parks on ",[1047,1914,592],{}," for the code, then saves the session:",[1041,1917,1919],{"className":1043,"code":1918,"language":680,"meta":1045,"style":1045},"{ \"id\": \"save\", \"checkpoint\": { \"name\": \"logged_in\", \"save_session\": \"portal-login\" } }\n",[1047,1920,1921],{"__ignoreMap":1045},[1050,1922,1923,1925,1928,1930,1933,1935,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956],{"class":1052,"line":1053},[1050,1924,1305],{"class":1056},[1050,1926,1927],{"class":1063},"\"id\"",[1050,1929,1068],{"class":1067},[1050,1931,1932],{"class":1071}," \"save\"",[1050,1934,1168],{"class":1067},[1050,1936,1937],{"class":1063}," \"checkpoint\"",[1050,1939,1068],{"class":1067},[1050,1941,1157],{"class":1056},[1050,1943,1315],{"class":1063},[1050,1945,1068],{"class":1067},[1050,1947,1320],{"class":1071},[1050,1949,1168],{"class":1067},[1050,1951,1325],{"class":1063},[1050,1953,1068],{"class":1067},[1050,1955,1099],{"class":1071},[1050,1957,1332],{"class":1056},[1025,1959,1960,1961,1964,1965,1967,1968,1465],{},"It binds ",[1047,1962,1963],{},"options.session: \"portal-login\""," with ",[1047,1966,1519],{},", and sets ",[1047,1969,1970],{},"policies.on_session_expired: \"refresh\"",[1025,1972,1973,1976,1977,1980,1981,1984,1985,1254,1988,1465],{},[1272,1974,1975],{},"First run."," No session exists yet, so the job runs every step: it signs in, parks for the code, takes your answer, and at the ",[1047,1978,1979],{},"save"," checkpoint creates ",[1047,1982,1983],{},"portal-login",". The envelope's ",[1047,1986,1987],{},"meta.session",[1047,1989,1990],{},"{ \"id\": \"ses_…\", \"name\": \"portal-login\", \"saved\": true }",[1025,1992,1993,1996],{},[1272,1994,1995],{},"Uploading instead."," If you already hold a signed-in state, create the session directly and run the program against it:",[1998,1999,2000],"code-group",{},[1041,2001,2006],{"className":2002,"code":2003,"filename":2004,"language":2005,"meta":1045,"style":1045},"language-ts shiki shiki-themes kaab-code kaab-code kaab-code","\u002F\u002F Storage state is write-only: Kaabist encrypts it and never returns it.\nconst session = await kaab.sessions.create({\n  name,\n  storage_state: {\n    cookies: [\n      {\n        name: \"sid\",\n        value: \"example-session-cookie\",\n        domain: new URL(site).hostname,\n        path: \"\u002F\",\n        expires: -1,\n        httpOnly: true,\n        secure: false,\n        sameSite: \"Lax\",\n      },\n    ],\n    origins: [],\n  },\n  origins: [new URL(site).origin],\n  concurrency: \"exclusive\", \u002F\u002F one job at a time inside it\n});\nconsole.log(`${session.id}: ${session.name} is ${session.status}`);\n","TypeScript","ts",[1047,2007,2008,2014,2042,2049,2059,2069,2074,2086,2098,2116,2128,2143,2154,2166,2179,2187,2195,2207,2215,2235,2250,2256],{"__ignoreMap":1045},[1050,2009,2010],{"class":1052,"line":1053},[1050,2011,2013],{"class":2012},"sKog0","\u002F\u002F Storage state is write-only: Kaabist encrypts it and never returns it.\n",[1050,2015,2016,2019,2022,2025,2028,2031,2034,2036,2039],{"class":1052,"line":1060},[1050,2017,2018],{"class":1063},"const",[1050,2020,2021],{"class":1176}," session",[1050,2023,2024],{"class":1063}," =",[1050,2026,2027],{"class":1063}," await",[1050,2029,2030],{"class":1176}," kaab",[1050,2032,1465],{"class":2033},"sJugJ",[1050,2035,42],{"class":1176},[1050,2037,2038],{"class":2033},".create",[1050,2040,2041],{"class":1056},"({\n",[1050,2043,2044,2047],{"class":1052,"line":1078},[1050,2045,2046],{"class":1056},"  name",[1050,2048,1075],{"class":1067},[1050,2050,2051,2054,2056],{"class":1052,"line":1091},[1050,2052,2053],{"class":1056},"  storage_state",[1050,2055,1068],{"class":1063},[1050,2057,2058],{"class":1056}," {\n",[1050,2060,2061,2064,2066],{"class":1052,"line":1104},[1050,2062,2063],{"class":1056},"    cookies",[1050,2065,1068],{"class":1063},[1050,2067,2068],{"class":1056}," [\n",[1050,2070,2071],{"class":1052,"line":1123},[1050,2072,2073],{"class":1056},"      {\n",[1050,2075,2076,2079,2081,2084],{"class":1052,"line":1136},[1050,2077,2078],{"class":1056},"        name",[1050,2080,1068],{"class":1063},[1050,2082,2083],{"class":1071}," \"sid\"",[1050,2085,1075],{"class":1067},[1050,2087,2088,2091,2093,2096],{"class":1052,"line":1149},[1050,2089,2090],{"class":1056},"        value",[1050,2092,1068],{"class":1063},[1050,2094,2095],{"class":1071}," \"example-session-cookie\"",[1050,2097,1075],{"class":1067},[1050,2099,2100,2103,2105,2108,2111,2114],{"class":1052,"line":1185},[1050,2101,2102],{"class":1056},"        domain",[1050,2104,1068],{"class":1063},[1050,2106,2107],{"class":1063}," new",[1050,2109,2110],{"class":2033}," URL",[1050,2112,2113],{"class":1056},"(site).hostname",[1050,2115,1075],{"class":1067},[1050,2117,2118,2121,2123,2126],{"class":1052,"line":1198},[1050,2119,2120],{"class":1056},"        path",[1050,2122,1068],{"class":1063},[1050,2124,2125],{"class":1071}," \"\u002F\"",[1050,2127,1075],{"class":1067},[1050,2129,2130,2133,2135,2138,2141],{"class":1052,"line":1211},[1050,2131,2132],{"class":1056},"        expires",[1050,2134,1068],{"class":1063},[1050,2136,2137],{"class":1063}," -",[1050,2139,2140],{"class":1176},"1",[1050,2142,1075],{"class":1067},[1050,2144,2145,2148,2150,2152],{"class":1052,"line":1224},[1050,2146,2147],{"class":1056},"        httpOnly",[1050,2149,1068],{"class":1063},[1050,2151,1177],{"class":1176},[1050,2153,1075],{"class":1067},[1050,2155,2156,2159,2161,2164],{"class":1052,"line":1245},[1050,2157,2158],{"class":1056},"        secure",[1050,2160,1068],{"class":1063},[1050,2162,2163],{"class":1176}," false",[1050,2165,1075],{"class":1067},[1050,2167,2169,2172,2174,2177],{"class":1052,"line":2168},14,[1050,2170,2171],{"class":1056},"        sameSite",[1050,2173,1068],{"class":1063},[1050,2175,2176],{"class":1071}," \"Lax\"",[1050,2178,1075],{"class":1067},[1050,2180,2182,2185],{"class":1052,"line":2181},15,[1050,2183,2184],{"class":1056},"      }",[1050,2186,1075],{"class":1067},[1050,2188,2190,2193],{"class":1052,"line":2189},16,[1050,2191,2192],{"class":1056},"    ]",[1050,2194,1075],{"class":1067},[1050,2196,2198,2201,2203,2205],{"class":1052,"line":2197},17,[1050,2199,2200],{"class":1056},"    origins",[1050,2202,1068],{"class":1063},[1050,2204,1384],{"class":1056},[1050,2206,1075],{"class":1067},[1050,2208,2210,2213],{"class":1052,"line":2209},18,[1050,2211,2212],{"class":1056},"  }",[1050,2214,1075],{"class":1067},[1050,2216,2218,2221,2223,2225,2228,2230,2233],{"class":1052,"line":2217},19,[1050,2219,2220],{"class":1056},"  origins",[1050,2222,1068],{"class":1063},[1050,2224,1112],{"class":1056},[1050,2226,2227],{"class":1063},"new",[1050,2229,2110],{"class":2033},[1050,2231,2232],{"class":1056},"(site).origin]",[1050,2234,1075],{"class":1067},[1050,2236,2238,2241,2243,2245,2247],{"class":1052,"line":2237},20,[1050,2239,2240],{"class":1056},"  concurrency",[1050,2242,1068],{"class":1063},[1050,2244,1144],{"class":1071},[1050,2246,1168],{"class":1067},[1050,2248,2249],{"class":2012}," \u002F\u002F one job at a time inside it\n",[1050,2251,2253],{"class":1052,"line":2252},21,[1050,2254,2255],{"class":1056},"});\n",[1050,2257,2259,2262,2265,2268,2271,2274,2276,2279,2282,2285,2287,2289,2292,2294,2296,2298,2300,2303,2305,2307],{"class":1052,"line":2258},22,[1050,2260,2261],{"class":1176},"console",[1050,2263,2264],{"class":2033},".log",[1050,2266,2267],{"class":1056},"(",[1050,2269,2270],{"class":1071},"`",[1050,2272,2273],{"class":1063},"${",[1050,2275,504],{"class":1176},[1050,2277,2278],{"class":1056},".id",[1050,2280,2281],{"class":1063},"}",[1050,2283,2284],{"class":1071},": ",[1050,2286,2273],{"class":1063},[1050,2288,504],{"class":1176},[1050,2290,2291],{"class":1056},".name",[1050,2293,2281],{"class":1063},[1050,2295,1254],{"class":1071},[1050,2297,2273],{"class":1063},[1050,2299,504],{"class":1176},[1050,2301,2302],{"class":1056},".status",[1050,2304,2281],{"class":1063},[1050,2306,2270],{"class":1071},[1050,2308,2309],{"class":1056},");\n",[1025,2311,2312,2315],{},[1272,2313,2314],{},"Later runs."," The session is valid, so the job jumps past the login to the report and never parks. Bind the same program to a schedule and every fire starts at the report:",[1998,2317,2318],{},[1041,2319,2321],{"className":2002,"code":2320,"filename":2004,"language":2005,"meta":1045,"style":1045},"const job = await kaab.jobs.create({\n  url: `${site}\u002Fapi\u002Fecho`,\n  extract: { sid: { network: { url: \"**\u002Fapi\u002Fecho\", json: \"$.cookies.sid\" } } },\n  session: name, \u002F\u002F the job starts with the session's cookies and storage\n  options: { prefer_tier: \"browser\" }, \u002F\u002F a browser, as a signed-in person would use\n  wait: 30,\n});\nconsole.log(`${job.id} ran in ${job.meta.session?.name}: sid=${JSON.stringify(job.data?.sid)}`);\n",[1047,2322,2323,2344,2366,2406,2421,2443,2455,2459],{"__ignoreMap":1045},[1050,2324,2325,2327,2330,2332,2334,2336,2338,2340,2342],{"class":1052,"line":1053},[1050,2326,2018],{"class":1063},[1050,2328,2329],{"class":1176}," job",[1050,2331,2024],{"class":1063},[1050,2333,2027],{"class":1063},[1050,2335,2030],{"class":1176},[1050,2337,1465],{"class":2033},[1050,2339,171],{"class":1176},[1050,2341,2038],{"class":2033},[1050,2343,2041],{"class":1056},[1050,2345,2346,2349,2351,2354,2356,2359,2361,2364],{"class":1052,"line":1060},[1050,2347,2348],{"class":1056},"  url",[1050,2350,1068],{"class":1063},[1050,2352,2353],{"class":1071}," `",[1050,2355,2273],{"class":1063},[1050,2357,2358],{"class":1056},"site",[1050,2360,2281],{"class":1063},[1050,2362,2363],{"class":1071},"\u002Fapi\u002Fecho`",[1050,2365,1075],{"class":1067},[1050,2367,2368,2371,2373,2376,2378,2381,2383,2386,2388,2391,2393,2396,2398,2401,2404],{"class":1052,"line":1078},[1050,2369,2370],{"class":1056},"  extract",[1050,2372,1068],{"class":1063},[1050,2374,2375],{"class":1056}," { sid",[1050,2377,1068],{"class":1063},[1050,2379,2380],{"class":1056}," { network",[1050,2382,1068],{"class":1063},[1050,2384,2385],{"class":1056}," { url",[1050,2387,1068],{"class":1063},[1050,2389,2390],{"class":1071}," \"**\u002Fapi\u002Fecho\"",[1050,2392,1168],{"class":1067},[1050,2394,2395],{"class":1056}," json",[1050,2397,1068],{"class":1063},[1050,2399,2400],{"class":1071}," \"$.cookies.sid\"",[1050,2402,2403],{"class":1056}," } } }",[1050,2405,1075],{"class":1067},[1050,2407,2408,2411,2413,2416,2418],{"class":1052,"line":1091},[1050,2409,2410],{"class":1056},"  session",[1050,2412,1068],{"class":1063},[1050,2414,2415],{"class":1056}," name",[1050,2417,1168],{"class":1067},[1050,2419,2420],{"class":2012}," \u002F\u002F the job starts with the session's cookies and storage\n",[1050,2422,2423,2426,2428,2431,2433,2436,2438,2440],{"class":1052,"line":1104},[1050,2424,2425],{"class":1056},"  options",[1050,2427,1068],{"class":1063},[1050,2429,2430],{"class":1056}," { prefer_tier",[1050,2432,1068],{"class":1063},[1050,2434,2435],{"class":1071}," \"browser\"",[1050,2437,1180],{"class":1056},[1050,2439,1168],{"class":1067},[1050,2441,2442],{"class":2012}," \u002F\u002F a browser, as a signed-in person would use\n",[1050,2444,2445,2448,2450,2453],{"class":1052,"line":1123},[1050,2446,2447],{"class":1056},"  wait",[1050,2449,1068],{"class":1063},[1050,2451,2452],{"class":1176}," 30",[1050,2454,1075],{"class":1067},[1050,2456,2457],{"class":1052,"line":1136},[1050,2458,2255],{"class":1056},[1050,2460,2461,2463,2465,2467,2469,2471,2473,2475,2477,2480,2482,2484,2486,2489,2491,2493,2496,2498,2501,2503,2506,2509,2511,2513,2515,2518,2521,2523,2525],{"class":1052,"line":1149},[1050,2462,2261],{"class":1176},[1050,2464,2264],{"class":2033},[1050,2466,2267],{"class":1056},[1050,2468,2270],{"class":1071},[1050,2470,2273],{"class":1063},[1050,2472,478],{"class":1176},[1050,2474,2278],{"class":1056},[1050,2476,2281],{"class":1063},[1050,2478,2479],{"class":1071}," ran in ",[1050,2481,2273],{"class":1063},[1050,2483,478],{"class":1176},[1050,2485,1465],{"class":1056},[1050,2487,2488],{"class":1176},"meta",[1050,2490,1465],{"class":1056},[1050,2492,504],{"class":1176},[1050,2494,2495],{"class":1056},"?.name",[1050,2497,2281],{"class":1063},[1050,2499,2500],{"class":1071},": sid=",[1050,2502,2273],{"class":1063},[1050,2504,2505],{"class":1176},"JSON",[1050,2507,2508],{"class":2033},".stringify",[1050,2510,2267],{"class":1056},[1050,2512,478],{"class":1176},[1050,2514,1465],{"class":1056},[1050,2516,2517],{"class":1176},"data",[1050,2519,2520],{"class":1056},"?.sid)",[1050,2522,2281],{"class":1063},[1050,2524,2270],{"class":1071},[1050,2526,2309],{"class":1056},[1025,2528,2529,2532,2533,1672,2535,1258,2537,2539,2540,2543,2544,2547],{},[1272,2530,2531],{},"Expiry."," When the site expires the cookie, the next job's report page redirects to the sign-in form. The step is classified as an expired session, ",[1047,2534,1983],{},[1047,2536,1261],{},[1047,2538,1678],{}," is sent, and the refresh program signs in again inside the job, parking for a new code if the site asks for one. With ",[1047,2541,2542],{},"on_session_expired: \"park\""," instead, the job parks as ",[1047,2545,2546],{},"needs_attention: session_expired"," for a person.",[1029,2549,2551],{"id":2550},"pitfalls","Pitfalls",[1543,2553,2554,2566,2572,2581],{},[1546,2555,2556,2562,2563,2565],{},[1272,2557,2558,2559,2561],{},"Two jobs, one account, ",[1047,2560,1596],{}," concurrency."," On a site that allows one sign-in at a time, each job logs the other out. Keep ",[1047,2564,1583],{}," unless you know the site tolerates it.",[1546,2567,2568,2571],{},[1272,2569,2570],{},"A session for an http-only program."," The http tier never saves a session; a program that only reads with cookies needs the session created by a browser job or uploaded.",[1546,2573,2574,2577,2578,2580],{},[1272,2575,2576],{},"Storing passwords by default."," Prefer ",[1047,2579,1725],{}," or a refresh program without stored secrets, and let a person sign in when the session expires.",[1546,2582,2583,2586],{},[1272,2584,2585],{},"Expecting to read the state back."," You cannot. Keep your own copy if you need one, or create the session again from a job.",[1029,2588,155],{"id":2589},"reference",[1543,2591,2592,2609,2615,2634,2647],{},[1546,2593,2594,1258,2598,1258,2602,1258,2606],{},[1755,2595,2597],{"href":2596},"\u002Freference\u002Fapi\u002Fsessions\u002Fcreate-session","Create a session",[1755,2599,2601],{"href":2600},"\u002Freference\u002Fapi\u002Fsessions\u002Fupdate-session","update",[1755,2603,2605],{"href":2604},"\u002Freference\u002Fapi\u002Fsessions\u002Fverify-session","verify",[1755,2607,1460],{"href":2608},"\u002Freference\u002Fapi\u002Fsessions\u002Frefresh-session",[1546,2610,2611],{},[1755,2612,2614],{"href":2613},"\u002Freference\u002Fapi\u002Fschemas\u002Fsession","The session object",[1546,2616,2617,1258,2622,1258,2627,1258,2631],{},[1755,2618,2620],{"href":2619},"\u002Freference\u002Fdsl\u002Factions\u002Fcheckpoint",[1047,2621,595],{},[1755,2623,2625],{"href":2624},"\u002Freference\u002Fdsl\u002Factions\u002Fset-session",[1047,2626,567],{},[1755,2628,2630],{"href":2629},"\u002Freference\u002Fdsl\u002Foptions","program options",[1755,2632,534],{"href":2633},"\u002Freference\u002Fdsl\u002Fpolicies",[1546,2635,2636,2639,2640,2642,2643],{},[1755,2637,838],{"href":2638},"\u002Freference\u002Fevents"," (",[1047,2641,1678],{},") and ",[1755,2644,2646],{"href":2645},"\u002Freference\u002Fcodes#errors","error codes",[1546,2648,2649],{},[1755,2650,2652],{"href":2651},"\u002Freference\u002Fcli\u002Fkaab-sessions-create",[1047,2653,974],{},[2655,2656,2657],"style",{},"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 .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 .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);}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)}html pre.shiki code .sJugJ, html code.shiki .sJugJ{--shiki-light:var(--kaab-code-token-function);--shiki-default:var(--kaab-code-token-function);--shiki-dark:var(--kaab-code-token-function)}",{"title":1045,"searchDepth":1078,"depth":1078,"links":2659},[2660,2661,2662,2663,2666,2667,2668,2669,2672,2673,2674,2675],{"id":1031,"depth":1060,"text":1032},{"id":1038,"depth":1060,"text":1039},{"id":1278,"depth":1060,"text":1279},{"id":1468,"depth":1060,"text":1469,"children":2664},[2665],{"id":1530,"depth":1078,"text":1531},{"id":1568,"depth":1060,"text":1569},{"id":1619,"depth":1060,"text":1620},{"id":1665,"depth":1060,"text":1666},{"id":1770,"depth":1060,"text":1771,"children":2670},[2671],{"id":1814,"depth":1078,"text":1815},{"id":1849,"depth":1060,"text":1850},{"id":1900,"depth":1060,"text":1901},{"id":2550,"depth":1060,"text":2551},{"id":2589,"depth":1060,"text":155},false,null,"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.","md",{},true,"\u002Fconcepts\u002Fsessions",{"title":41,"description":2678},"2.concepts\u002F05.sessions","Ve8gLl5HvyuzCqBZ5aIIkUVS3YV2VqEKyfZQJDOWvMA",[2687,2691],{"title":38,"path":2688,"stem":2689,"description":2690,"children":-1},"\u002Fconcepts\u002Fbrowser-tier","2.concepts\u002F04.browser-tier","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.",{"title":44,"path":1767,"stem":2692,"description":2693,"children":-1},"2.concepts\u002F06.human-in-the-loop","How a job parks for a person (awaiting_input and needs_attention) and the ways to answer it: inputs, the five resume actions, hosted pages and takeover.",1793593409375]