[{"data":1,"prerenderedAt":4680},["ShallowReactive",2],{"navigation":3,"page:\u002Fguides\u002Fschedules-and-change-detection":1019,"surround:\u002Fguides\u002Fschedules-and-change-detection":4672},[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":101,"body":1021,"breaking":4663,"date":4664,"description":4665,"extension":4666,"generated":4663,"meta":4667,"navigation":4009,"path":4668,"seo":4669,"stem":4670,"version":4664,"__hash__":4671},"docs\u002F3.guides\u002F05.schedules-and-change-detection.md",{"type":1022,"value":1023,"toc":4649},"minimark",[1024,1028,1033,1036,1039,1071,1075,1263,1375,2094,2099,2132,2136,2151,2162,2281,2291,2295,2305,2339,2352,2393,2408,2412,2430,2434,2465,3084,3088,3095,3290,4336,4339,4343,4413,4416,4607,4645],[1025,1026,1027],"p",{},"A schedule is a stored job request plus a cron: every time it fires, Kaabist creates an ordinary job\nfrom it, with the same envelope, the same credits and the same webhooks. With change detection on,\nKaabist also compares the result with the previous run's and tells you exactly what moved, so you\nhear about a competitor's new price instead of reading the same page every hour.",[1029,1030,1032],"h2",{"id":1031},"when-to-use-it","When to use it",[1025,1034,1035],{},"Use a schedule when the same program should run on a clock: a price watch, a daily report export, a\nstock check. Turn on change detection when you care about differences rather than every result.",[1025,1037,1038],{},"Use something else when:",[1040,1041,1042,1051,1058],"ul",{},[1043,1044,1045,1046,1050],"li",{},"the run depends on an event in your own system (an order, a sign-up): create the job from that\nevent with ",[1047,1048,1049],"code",{},"POST \u002Fv1\u002Fjobs",";",[1043,1052,1053,1054,1057],{},"you need many inputs at once: create a batch (",[1047,1055,1056],{},"POST \u002Fv1\u002Fjobs\u002Fbatch","), from your own scheduler if\nit must recur;",[1043,1059,1060,1061,1064,1065,1070],{},"you want to know that the ",[1062,1063,489],"strong",{}," broke, not that the data changed: that is drift detection\nand canaries, which Kaabist runs for you (see ",[1066,1067,1069],"a",{"href":1068},"\u002Fguides\u002Fdrift-and-canaries","drift and canaries",").",[1029,1072,1074],{"id":1073},"creating-a-schedule","Creating a schedule",[1076,1077,1081],"pre",{"className":1078,"code":1079,"language":680,"meta":1080,"style":1080},"language-json shiki shiki-themes kaab-code kaab-code kaab-code","{\n  \"program\": \"competitor-price@production\",\n  \"inputs\": { \"product_id\": \"1\" },\n  \"cron\": \"0 * * * *\",\n  \"timezone\": \"Europe\u002FIstanbul\",\n  \"change_detection\": { \"enabled\": true, \"fields\": [\"price\"] },\n  \"webhook_url\": \"https:\u002F\u002Fhooks.example.com\u002Fkaab\",\n  \"options\": { \"max_tier\": \"http\" },\n  \"overlap_policy\": \"skip\",\n  \"catch_up\": false\n}\n","",[1047,1082,1083,1092,1110,1134,1147,1160,1198,1211,1233,1246,1257],{"__ignoreMap":1080},[1084,1085,1088],"span",{"class":1086,"line":1087},"line",1,[1084,1089,1091],{"class":1090},"sTzsn","{\n",[1084,1093,1095,1099,1103,1107],{"class":1086,"line":1094},2,[1084,1096,1098],{"class":1097},"sqn18","  \"program\"",[1084,1100,1102],{"class":1101},"sQm2-",":",[1084,1104,1106],{"class":1105},"suOy4"," \"competitor-price@production\"",[1084,1108,1109],{"class":1101},",\n",[1084,1111,1113,1116,1118,1121,1124,1126,1129,1132],{"class":1086,"line":1112},3,[1084,1114,1115],{"class":1097},"  \"inputs\"",[1084,1117,1102],{"class":1101},[1084,1119,1120],{"class":1090}," { ",[1084,1122,1123],{"class":1097},"\"product_id\"",[1084,1125,1102],{"class":1101},[1084,1127,1128],{"class":1105}," \"1\"",[1084,1130,1131],{"class":1090}," }",[1084,1133,1109],{"class":1101},[1084,1135,1137,1140,1142,1145],{"class":1086,"line":1136},4,[1084,1138,1139],{"class":1097},"  \"cron\"",[1084,1141,1102],{"class":1101},[1084,1143,1144],{"class":1105}," \"0 * * * *\"",[1084,1146,1109],{"class":1101},[1084,1148,1150,1153,1155,1158],{"class":1086,"line":1149},5,[1084,1151,1152],{"class":1097},"  \"timezone\"",[1084,1154,1102],{"class":1101},[1084,1156,1157],{"class":1105}," \"Europe\u002FIstanbul\"",[1084,1159,1109],{"class":1101},[1084,1161,1163,1166,1168,1170,1173,1175,1179,1182,1185,1187,1190,1193,1196],{"class":1086,"line":1162},6,[1084,1164,1165],{"class":1097},"  \"change_detection\"",[1084,1167,1102],{"class":1101},[1084,1169,1120],{"class":1090},[1084,1171,1172],{"class":1097},"\"enabled\"",[1084,1174,1102],{"class":1101},[1084,1176,1178],{"class":1177},"sHJIl"," true",[1084,1180,1181],{"class":1101},",",[1084,1183,1184],{"class":1097}," \"fields\"",[1084,1186,1102],{"class":1101},[1084,1188,1189],{"class":1090}," [",[1084,1191,1192],{"class":1105},"\"price\"",[1084,1194,1195],{"class":1090},"] }",[1084,1197,1109],{"class":1101},[1084,1199,1201,1204,1206,1209],{"class":1086,"line":1200},7,[1084,1202,1203],{"class":1097},"  \"webhook_url\"",[1084,1205,1102],{"class":1101},[1084,1207,1208],{"class":1105}," \"https:\u002F\u002Fhooks.example.com\u002Fkaab\"",[1084,1210,1109],{"class":1101},[1084,1212,1214,1217,1219,1221,1224,1226,1229,1231],{"class":1086,"line":1213},8,[1084,1215,1216],{"class":1097},"  \"options\"",[1084,1218,1102],{"class":1101},[1084,1220,1120],{"class":1090},[1084,1222,1223],{"class":1097},"\"max_tier\"",[1084,1225,1102],{"class":1101},[1084,1227,1228],{"class":1105}," \"http\"",[1084,1230,1131],{"class":1090},[1084,1232,1109],{"class":1101},[1084,1234,1236,1239,1241,1244],{"class":1086,"line":1235},9,[1084,1237,1238],{"class":1097},"  \"overlap_policy\"",[1084,1240,1102],{"class":1101},[1084,1242,1243],{"class":1105}," \"skip\"",[1084,1245,1109],{"class":1101},[1084,1247,1249,1252,1254],{"class":1086,"line":1248},10,[1084,1250,1251],{"class":1097},"  \"catch_up\"",[1084,1253,1102],{"class":1101},[1084,1255,1256],{"class":1177}," false\n",[1084,1258,1260],{"class":1086,"line":1259},11,[1084,1261,1262],{"class":1090},"}\n",[1040,1264,1265,1292,1303,1319,1342,1349,1368],{},[1043,1266,1267,1271,1272,1274,1275,1274,1278,1274,1281,1274,1284,1287,1288,1291],{},[1062,1268,1269],{},[1047,1270,489],{}," is any program reference (",[1047,1273,702],{},", ",[1047,1276,1277],{},"name@3",[1047,1279,1280],{},"name@alias",[1047,1282,1283],{},"prg_…",[1047,1285,1286],{},"pv_…","). It must\nresolve now, and it is resolved again at every run, so a schedule on ",[1047,1289,1290],{},"@production"," follows the\nalias when you move it.",[1043,1293,1294,1298,1299,1302],{},[1062,1295,1296],{},[1047,1297,528],{}," are checked against the program's inputs as a job's would be and stored encrypted.\n",[1047,1300,1301],{},"secret"," inputs are never returned.",[1043,1304,1305,1310,1311,1315,1316,1070],{},[1062,1306,1307],{},[1047,1308,1309],{},"cron"," has five fields and is read in ",[1062,1312,1313],{},[1047,1314,737],{}," (an IANA zone, default ",[1047,1317,1318],{},"UTC",[1043,1320,1321,1326,1327,1109,1330,1333,1334,1337,1338,1341],{},[1062,1322,1323],{},[1047,1324,1325],{},"change_detection.fields"," are field paths of the program's extract (",[1047,1328,1329],{},"price",[1047,1331,1332],{},"products[].price","). Without them the whole of ",[1047,1335,1336],{},"data"," is compared. An unknown path is refused\nwith ",[1047,1339,1340],{},"422 validation_failed",".",[1043,1343,1344,1348],{},[1062,1345,1346],{},[1047,1347,531],{}," are laid over the program's options for every run.",[1043,1350,1351,1356,1357,1359,1360,1363,1364,1341],{},[1062,1352,1353],{},[1047,1354,1355],{},"webhook_url"," receives each run's job events, as on ",[1047,1358,1049],{},". Schedule events\n(",[1047,1361,1362],{},"schedule.changed"," and the rest) go to your registered ",[1066,1365,1367],{"href":1366},"\u002Fguides\u002Fwebhooks","webhook endpoints",[1043,1369,1370,1371,1374],{},"A schedule created with an ",[1047,1372,1373],{},"sk_test_"," key runs test jobs.",[1376,1377,1378,1586,1776],"code-group",{},[1076,1379,1384],{"className":1380,"code":1381,"filename":1382,"language":1383,"meta":1080,"style":1080},"language-ts shiki shiki-themes kaab-code kaab-code kaab-code","const schedule = await kaab.schedules.create({\n  program: `${name}@latest`, \u002F\u002F follows the alias: publishing a fix changes what runs\n  inputs,\n  cron: \"0 * * * *\",\n  timezone: \"Europe\u002FIstanbul\",\n  change_detection: { enabled: true, fields: [\"price\"] },\n  overlap_policy: \"skip\",\n});\nconsole.log(\n  `${schedule.id}: \"${schedule.cron}\" ${schedule.timezone}, next run ${schedule.next_run_at}`,\n);\n","TypeScript","ts",[1047,1385,1386,1414,1441,1448,1459,1470,1499,1510,1515,1526,1581],{"__ignoreMap":1080},[1084,1387,1388,1391,1394,1397,1400,1403,1406,1408,1411],{"class":1086,"line":1087},[1084,1389,1390],{"class":1097},"const",[1084,1392,1393],{"class":1177}," schedule",[1084,1395,1396],{"class":1097}," =",[1084,1398,1399],{"class":1097}," await",[1084,1401,1402],{"class":1177}," kaab",[1084,1404,1341],{"class":1405},"sJugJ",[1084,1407,318],{"class":1177},[1084,1409,1410],{"class":1405},".create",[1084,1412,1413],{"class":1090},"({\n",[1084,1415,1416,1419,1421,1424,1427,1429,1432,1435,1437],{"class":1086,"line":1094},[1084,1417,1418],{"class":1090},"  program",[1084,1420,1102],{"class":1097},[1084,1422,1423],{"class":1105}," `",[1084,1425,1426],{"class":1097},"${",[1084,1428,702],{"class":1090},[1084,1430,1431],{"class":1097},"}",[1084,1433,1434],{"class":1105},"@latest`",[1084,1436,1181],{"class":1101},[1084,1438,1440],{"class":1439},"sKog0"," \u002F\u002F follows the alias: publishing a fix changes what runs\n",[1084,1442,1443,1446],{"class":1086,"line":1112},[1084,1444,1445],{"class":1090},"  inputs",[1084,1447,1109],{"class":1101},[1084,1449,1450,1453,1455,1457],{"class":1086,"line":1136},[1084,1451,1452],{"class":1090},"  cron",[1084,1454,1102],{"class":1097},[1084,1456,1144],{"class":1105},[1084,1458,1109],{"class":1101},[1084,1460,1461,1464,1466,1468],{"class":1086,"line":1149},[1084,1462,1463],{"class":1090},"  timezone",[1084,1465,1102],{"class":1097},[1084,1467,1157],{"class":1105},[1084,1469,1109],{"class":1101},[1084,1471,1472,1475,1477,1480,1482,1484,1486,1489,1491,1493,1495,1497],{"class":1086,"line":1162},[1084,1473,1474],{"class":1090},"  change_detection",[1084,1476,1102],{"class":1097},[1084,1478,1479],{"class":1090}," { enabled",[1084,1481,1102],{"class":1097},[1084,1483,1178],{"class":1177},[1084,1485,1181],{"class":1101},[1084,1487,1488],{"class":1090}," fields",[1084,1490,1102],{"class":1097},[1084,1492,1189],{"class":1090},[1084,1494,1192],{"class":1105},[1084,1496,1195],{"class":1090},[1084,1498,1109],{"class":1101},[1084,1500,1501,1504,1506,1508],{"class":1086,"line":1200},[1084,1502,1503],{"class":1090},"  overlap_policy",[1084,1505,1102],{"class":1097},[1084,1507,1243],{"class":1105},[1084,1509,1109],{"class":1101},[1084,1511,1512],{"class":1086,"line":1213},[1084,1513,1514],{"class":1090},"});\n",[1084,1516,1517,1520,1523],{"class":1086,"line":1235},[1084,1518,1519],{"class":1177},"console",[1084,1521,1522],{"class":1405},".log",[1084,1524,1525],{"class":1090},"(\n",[1084,1527,1528,1531,1533,1535,1538,1540,1543,1545,1547,1550,1552,1555,1557,1559,1562,1564,1567,1569,1571,1574,1576,1579],{"class":1086,"line":1248},[1084,1529,1530],{"class":1105},"  `",[1084,1532,1426],{"class":1097},[1084,1534,501],{"class":1177},[1084,1536,1537],{"class":1090},".id",[1084,1539,1431],{"class":1097},[1084,1541,1542],{"class":1105},": \"",[1084,1544,1426],{"class":1097},[1084,1546,501],{"class":1177},[1084,1548,1549],{"class":1090},".cron",[1084,1551,1431],{"class":1097},[1084,1553,1554],{"class":1105},"\" ",[1084,1556,1426],{"class":1097},[1084,1558,501],{"class":1177},[1084,1560,1561],{"class":1090},".timezone",[1084,1563,1431],{"class":1097},[1084,1565,1566],{"class":1105},", next run ",[1084,1568,1426],{"class":1097},[1084,1570,501],{"class":1177},[1084,1572,1573],{"class":1090},".next_run_at",[1084,1575,1431],{"class":1097},[1084,1577,1578],{"class":1105},"`",[1084,1580,1109],{"class":1101},[1084,1582,1583],{"class":1086,"line":1259},[1084,1584,1585],{"class":1090},");\n",[1076,1587,1592],{"className":1588,"code":1589,"filename":1590,"language":1591,"meta":1080,"style":1080},"language-python shiki shiki-themes kaab-code kaab-code kaab-code","schedule = kaab.schedules.create(\n    program=f\"{name}@latest\",  # follows the alias: publishing a fix changes what runs\n    inputs=inputs,\n    cron=\"0 * * * *\",\n    timezone=\"Europe\u002FIstanbul\",\n    change_detection={\"enabled\": True, \"fields\": [\"price\"]},\n    overlap_policy=\"skip\",\n)\nprint(f'{schedule.id}: \"{schedule.cron}\" {schedule.timezone}, next run {schedule.next_run_at}')\n","Python","python",[1047,1593,1594,1615,1644,1654,1666,1678,1708,1720,1725],{"__ignoreMap":1080},[1084,1595,1596,1599,1602,1604,1606,1608,1610,1613],{"class":1086,"line":1087},[1084,1597,1598],{"class":1090},"schedule ",[1084,1600,1601],{"class":1097},"=",[1084,1603,1402],{"class":1090},[1084,1605,1341],{"class":1101},[1084,1607,318],{"class":1090},[1084,1609,1341],{"class":1101},[1084,1611,1612],{"class":1405},"create",[1084,1614,1525],{"class":1101},[1084,1616,1617,1620,1622,1625,1628,1631,1633,1635,1638,1641],{"class":1086,"line":1094},[1084,1618,1619],{"class":1101},"    program",[1084,1621,1601],{"class":1097},[1084,1623,1624],{"class":1097},"f",[1084,1626,1627],{"class":1105},"\"",[1084,1629,1630],{"class":1177},"{",[1084,1632,702],{"class":1101},[1084,1634,1431],{"class":1177},[1084,1636,1637],{"class":1105},"@latest\"",[1084,1639,1640],{"class":1101},",  ",[1084,1642,1643],{"class":1439},"# follows the alias: publishing a fix changes what runs\n",[1084,1645,1646,1649,1651],{"class":1086,"line":1112},[1084,1647,1648],{"class":1101},"    inputs",[1084,1650,1601],{"class":1097},[1084,1652,1653],{"class":1101},"inputs,\n",[1084,1655,1656,1659,1661,1664],{"class":1086,"line":1136},[1084,1657,1658],{"class":1101},"    cron",[1084,1660,1601],{"class":1097},[1084,1662,1663],{"class":1105},"\"0 * * * *\"",[1084,1665,1109],{"class":1101},[1084,1667,1668,1671,1673,1676],{"class":1086,"line":1149},[1084,1669,1670],{"class":1101},"    timezone",[1084,1672,1601],{"class":1097},[1084,1674,1675],{"class":1105},"\"Europe\u002FIstanbul\"",[1084,1677,1109],{"class":1101},[1084,1679,1680,1683,1685,1687,1689,1692,1695,1697,1700,1703,1705],{"class":1086,"line":1162},[1084,1681,1682],{"class":1101},"    change_detection",[1084,1684,1601],{"class":1097},[1084,1686,1630],{"class":1101},[1084,1688,1172],{"class":1105},[1084,1690,1691],{"class":1101},": ",[1084,1693,1694],{"class":1177},"True",[1084,1696,1274],{"class":1101},[1084,1698,1699],{"class":1105},"\"fields\"",[1084,1701,1702],{"class":1101},": [",[1084,1704,1192],{"class":1105},[1084,1706,1707],{"class":1101},"]},\n",[1084,1709,1710,1713,1715,1718],{"class":1086,"line":1200},[1084,1711,1712],{"class":1101},"    overlap_policy",[1084,1714,1601],{"class":1097},[1084,1716,1717],{"class":1105},"\"skip\"",[1084,1719,1109],{"class":1101},[1084,1721,1722],{"class":1086,"line":1213},[1084,1723,1724],{"class":1101},")\n",[1084,1726,1727,1730,1733,1735,1738,1740,1743,1745,1747,1749,1752,1754,1756,1758,1761,1763,1765,1767,1770,1772,1774],{"class":1086,"line":1235},[1084,1728,1729],{"class":1405},"print",[1084,1731,1732],{"class":1101},"(",[1084,1734,1624],{"class":1097},[1084,1736,1737],{"class":1105},"'",[1084,1739,1630],{"class":1177},[1084,1741,1742],{"class":1101},"schedule.id",[1084,1744,1431],{"class":1177},[1084,1746,1542],{"class":1105},[1084,1748,1630],{"class":1177},[1084,1750,1751],{"class":1101},"schedule.cron",[1084,1753,1431],{"class":1177},[1084,1755,1554],{"class":1105},[1084,1757,1630],{"class":1177},[1084,1759,1760],{"class":1101},"schedule.timezone",[1084,1762,1431],{"class":1177},[1084,1764,1566],{"class":1105},[1084,1766,1630],{"class":1177},[1084,1768,1769],{"class":1101},"schedule.next_run_at",[1084,1771,1431],{"class":1177},[1084,1773,1737],{"class":1105},[1084,1775,1724],{"class":1101},[1076,1777,1782],{"className":1778,"code":1779,"filename":1780,"language":1781,"meta":1080,"style":1080},"language-go shiki shiki-themes kaab-code kaab-code kaab-code","body, err := kaab.Body[client.CreateScheduleJSONBody](map[string]any{\n    \"program\":          name + \"@latest\", \u002F\u002F follows the alias: publishing a fix changes what runs\n    \"inputs\":           inputs,\n    \"cron\":             \"0 * * * *\",\n    \"timezone\":         \"Europe\u002FIstanbul\",\n    \"change_detection\": map[string]any{\"enabled\": true, \"fields\": []string{\"price\"}},\n    \"overlap_policy\":   \"skip\",\n})\nif err != nil {\n    log.Fatal(err)\n}\nschedule, err := c.Schedules.Create(ctx, body)\nif err != nil {\n    log.Fatal(err)\n}\nnext := \"-\"\nif schedule.NextRunAt != nil {\n    next = schedule.NextRunAt.Format(time.RFC3339)\n}\nfmt.Printf(\"%s: %q %s, next run %s\\n\", schedule.ID, schedule.Cron, schedule.Timezone, next)\n","Go","go",[1047,1783,1784,1827,1846,1854,1866,1878,1920,1932,1937,1954,1965,1969,1986,1999,2008,2013,2024,2038,2055,2060],{"__ignoreMap":1080},[1084,1785,1786,1789,1792,1795,1798,1801,1804,1806,1809,1812,1815,1817,1820,1823,1825],{"class":1086,"line":1087},[1084,1787,1788],{"class":1090},"body, err ",[1084,1790,1791],{"class":1097},":=",[1084,1793,1794],{"class":1090}," kaab.",[1084,1796,1797],{"class":1405},"Body",[1084,1799,1800],{"class":1090},"[",[1084,1802,1803],{"class":1405},"client",[1084,1805,1341],{"class":1090},[1084,1807,1808],{"class":1405},"CreateScheduleJSONBody",[1084,1810,1811],{"class":1090},"](",[1084,1813,1814],{"class":1097},"map",[1084,1816,1800],{"class":1090},[1084,1818,1819],{"class":1097},"string",[1084,1821,1822],{"class":1090},"]",[1084,1824,634],{"class":1405},[1084,1826,1091],{"class":1090},[1084,1828,1829,1832,1835,1838,1841,1843],{"class":1086,"line":1094},[1084,1830,1831],{"class":1105},"    \"program\"",[1084,1833,1834],{"class":1090},":          name ",[1084,1836,1837],{"class":1097},"+",[1084,1839,1840],{"class":1105}," \"@latest\"",[1084,1842,1274],{"class":1090},[1084,1844,1845],{"class":1439},"\u002F\u002F follows the alias: publishing a fix changes what runs\n",[1084,1847,1848,1851],{"class":1086,"line":1112},[1084,1849,1850],{"class":1105},"    \"inputs\"",[1084,1852,1853],{"class":1090},":           inputs,\n",[1084,1855,1856,1859,1862,1864],{"class":1086,"line":1136},[1084,1857,1858],{"class":1105},"    \"cron\"",[1084,1860,1861],{"class":1090},":             ",[1084,1863,1663],{"class":1105},[1084,1865,1109],{"class":1090},[1084,1867,1868,1871,1874,1876],{"class":1086,"line":1149},[1084,1869,1870],{"class":1105},"    \"timezone\"",[1084,1872,1873],{"class":1090},":         ",[1084,1875,1675],{"class":1105},[1084,1877,1109],{"class":1090},[1084,1879,1880,1883,1885,1887,1889,1891,1893,1895,1897,1899,1901,1904,1906,1908,1911,1913,1915,1917],{"class":1086,"line":1162},[1084,1881,1882],{"class":1105},"    \"change_detection\"",[1084,1884,1691],{"class":1090},[1084,1886,1814],{"class":1097},[1084,1888,1800],{"class":1090},[1084,1890,1819],{"class":1097},[1084,1892,1822],{"class":1090},[1084,1894,634],{"class":1405},[1084,1896,1630],{"class":1090},[1084,1898,1172],{"class":1105},[1084,1900,1691],{"class":1090},[1084,1902,1903],{"class":1177},"true",[1084,1905,1274],{"class":1090},[1084,1907,1699],{"class":1105},[1084,1909,1910],{"class":1090},": []",[1084,1912,1819],{"class":1097},[1084,1914,1630],{"class":1090},[1084,1916,1192],{"class":1105},[1084,1918,1919],{"class":1090},"}},\n",[1084,1921,1922,1925,1928,1930],{"class":1086,"line":1200},[1084,1923,1924],{"class":1105},"    \"overlap_policy\"",[1084,1926,1927],{"class":1090},":   ",[1084,1929,1717],{"class":1105},[1084,1931,1109],{"class":1090},[1084,1933,1934],{"class":1086,"line":1213},[1084,1935,1936],{"class":1090},"})\n",[1084,1938,1939,1942,1945,1948,1951],{"class":1086,"line":1235},[1084,1940,1941],{"class":1097},"if",[1084,1943,1944],{"class":1090}," err ",[1084,1946,1947],{"class":1097},"!=",[1084,1949,1950],{"class":1177}," nil",[1084,1952,1953],{"class":1090}," {\n",[1084,1955,1956,1959,1962],{"class":1086,"line":1248},[1084,1957,1958],{"class":1090},"    log.",[1084,1960,1961],{"class":1405},"Fatal",[1084,1963,1964],{"class":1090},"(err)\n",[1084,1966,1967],{"class":1086,"line":1259},[1084,1968,1262],{"class":1090},[1084,1970,1972,1975,1977,1980,1983],{"class":1086,"line":1971},12,[1084,1973,1974],{"class":1090},"schedule, err ",[1084,1976,1791],{"class":1097},[1084,1978,1979],{"class":1090}," c.Schedules.",[1084,1981,1982],{"class":1405},"Create",[1084,1984,1985],{"class":1090},"(ctx, body)\n",[1084,1987,1989,1991,1993,1995,1997],{"class":1086,"line":1988},13,[1084,1990,1941],{"class":1097},[1084,1992,1944],{"class":1090},[1084,1994,1947],{"class":1097},[1084,1996,1950],{"class":1177},[1084,1998,1953],{"class":1090},[1084,2000,2002,2004,2006],{"class":1086,"line":2001},14,[1084,2003,1958],{"class":1090},[1084,2005,1961],{"class":1405},[1084,2007,1964],{"class":1090},[1084,2009,2011],{"class":1086,"line":2010},15,[1084,2012,1262],{"class":1090},[1084,2014,2016,2019,2021],{"class":1086,"line":2015},16,[1084,2017,2018],{"class":1090},"next ",[1084,2020,1791],{"class":1097},[1084,2022,2023],{"class":1105}," \"-\"\n",[1084,2025,2027,2029,2032,2034,2036],{"class":1086,"line":2026},17,[1084,2028,1941],{"class":1097},[1084,2030,2031],{"class":1090}," schedule.NextRunAt ",[1084,2033,1947],{"class":1097},[1084,2035,1950],{"class":1177},[1084,2037,1953],{"class":1090},[1084,2039,2041,2044,2046,2049,2052],{"class":1086,"line":2040},18,[1084,2042,2043],{"class":1090},"    next ",[1084,2045,1601],{"class":1097},[1084,2047,2048],{"class":1090}," schedule.NextRunAt.",[1084,2050,2051],{"class":1405},"Format",[1084,2053,2054],{"class":1090},"(time.RFC3339)\n",[1084,2056,2058],{"class":1086,"line":2057},19,[1084,2059,1262],{"class":1090},[1084,2061,2063,2066,2069,2071,2073,2076,2078,2081,2084,2086,2088,2091],{"class":1086,"line":2062},20,[1084,2064,2065],{"class":1090},"fmt.",[1084,2067,2068],{"class":1405},"Printf",[1084,2070,1732],{"class":1090},[1084,2072,1627],{"class":1105},[1084,2074,2075],{"class":1177},"%s",[1084,2077,1691],{"class":1105},[1084,2079,2080],{"class":1177},"%q",[1084,2082,2083],{"class":1177}," %s",[1084,2085,1566],{"class":1105},[1084,2087,2075],{"class":1177},[1084,2089,2090],{"class":1105},"\\n\"",[1084,2092,2093],{"class":1090},", schedule.ID, schedule.Cron, schedule.Timezone, next)\n",[2095,2096,2098],"h3",{"id":2097},"how-often-a-schedule-may-run","How often a schedule may run",[1025,2100,2101,2102,2105,2106,2109,2110,2113,2114,1274,2117,1274,2120,2123,2124,2127,2128,2131],{},"Your plan sets the shortest interval between two fires: every hour on Free, every five minutes on\nDeveloper, every minute on Team and above (see ",[1066,2103,1009],{"href":2104},"\u002Freference\u002Fplans","). A cron that fires more\noften is refused with ",[1047,2107,2108],{},"422 schedule_interval_too_small","; its ",[1047,2111,2112],{},"details"," carry\n",[1047,2115,2116],{},"min_interval_seconds",[1047,2118,2119],{},"requested_seconds",[1047,2121,2122],{},"plan"," and an ",[1047,2125,2126],{},"upgrade_url",". The interval is measured\nas the shortest gap between the next ten fires in your timezone, so ",[1047,2129,2130],{},"*\u002F5 9-17 * * *"," counts as five\nminutes.",[1029,2133,2135],{"id":2134},"when-it-runs","When it runs",[1025,2137,2138,2139,2142,2143,2146,2147,2150],{},"Each schedule fires a few seconds after its cron time: the same offset every time, between 0 and 29\nseconds, so that thousands of schedules written ",[1047,2140,2141],{},"0 * * * *"," do not all start in the same second.\nDaylight saving follows the zone: a time that does not exist on the spring-forward day runs as far\nafter the gap as it was into it (",[1047,2144,2145],{},"30 2 * * *"," in ",[1047,2148,2149],{},"Europe\u002FBerlin"," runs at 03:30 that day), and a time\nthat happens twice on the fall-back day runs once, at its first occurrence.",[1025,2152,2153,2154,2157,2158,2161],{},"Each fire creates a job tagged ",[1047,2155,2156],{},"kaab:schedule:\u003Cid>"," (",[1047,2159,2160],{},"GET \u002Fv1\u002Fjobs?schedule=sch_…"," lists them), or\nrecords a skipped run:",[2163,2164,2165,2178],"table",{},[2166,2167,2168],"thead",{},[2169,2170,2171,2175],"tr",{},[2172,2173,2174],"th",{},"Situation",[2172,2176,2177],{},"What happens",[2179,2180,2181,2201,2221,2240,2250,2260,2270],"tbody",{},[2169,2182,2183,2187],{},[2184,2185,2186],"td",{},"The previous job is still running",[2184,2188,2189,2192,2193,2196,2197,2200],{},[1047,2190,2191],{},"overlap_policy: \"skip\""," records a skipped run (",[1047,2194,2195],{},"overlap","); ",[1047,2198,2199],{},"\"queue\""," creates another job anyway",[2169,2202,2203,2206],{},[2184,2204,2205],{},"The scheduler was down when a fire was due",[2184,2207,2208,2209,2212,2213,2216,2217,2220],{},"skipped as ",[1047,2210,2211],{},"missed","; with ",[1047,2214,2215],{},"catch_up: true"," it runs ",[1062,2218,2219],{},"once"," for everything it missed, then carries on from the next fire",[2169,2222,2223,2226],{},[2184,2224,2225],{},"Your organisation is out of credits",[2184,2227,2228,2229,2232,2233,1274,2236,2239],{},"skipped (",[1047,2230,2231],{},"no_credits","); every active schedule is paused (",[1047,2234,2235],{},"paused_reason: \"credits\"",[1047,2237,2238],{},"schedule.paused",") and resumed when credits arrive",[2169,2241,2242,2245],{},[2184,2243,2244],{},"The program reference no longer resolves",[2184,2246,2208,2247],{},[1047,2248,2249],{},"program_unavailable",[2169,2251,2252,2255],{},[2184,2253,2254],{},"Your test-mode daily quota is used up",[2184,2256,2208,2257],{},[1047,2258,2259],{},"test_quota",[2169,2261,2262,2265],{},[2184,2263,2264],{},"A bring-your-own provider it uses is failing or deleted",[2184,2266,2208,2267],{},[1047,2268,2269],{},"byo_unavailable",[2169,2271,2272,2275],{},[2184,2273,2274],{},"Starting the run kept failing on our side for five minutes",[2184,2276,2208,2277,2280],{},[1047,2278,2279],{},"fire_failed","; the schedule carries on from its next fire",[1025,2282,2283,2284,2287,2288,1341],{},"A schedule you pause yourself (",[1047,2285,2286],{},"POST \u002Fv1\u002Fschedules\u002F{id}\u002Fpause",") stays paused until you resume it;\nonly a pause for credits is lifted automatically. Resuming while your organisation is still out of\ncredits is refused with ",[1047,2289,2290],{},"402 insufficient_credits",[1029,2292,2294],{"id":2293},"change-detection","Change detection",[1025,2296,2297,2298,2301,2302,2304],{},"After a scheduled job ",[1062,2299,2300],{},"succeeds",", Kaabist takes its ",[1047,2303,1336],{}," restricted to the watched fields and\ncompares it with the previous run's (key order never counts as a change):",[1040,2306,2307,2326],{},[1043,2308,2309,1691,2312,2314,2315,2318,2319,2322,2323,1050],{},[1062,2310,2311],{},"changed",[1047,2313,1362],{},", with up to 50 ",[1047,2316,2317],{},"changed_paths"," (JSON Pointers such as ",[1047,2320,2321],{},"\u002Fprice",")\nand a ",[1047,2324,2325],{},"diff_url",[1043,2327,2328,2331,2332,2335,2336,1341],{},[1062,2329,2330],{},"the same",", or the first run (which has nothing to compare with): ",[1047,2333,2334],{},"schedule.run"," with\n",[1047,2337,2338],{},"changed: false",[1025,2340,2341,2344,2345,2347,2348,2351],{},[1047,2342,2343],{},"GET \u002Fv1\u002Fschedules\u002F{id}\u002Fruns\u002F{job_id}\u002Fdiff"," (the ",[1047,2346,2325],{},") answers ",[1047,2349,2350],{},"302"," with a link, valid for 15\nminutes, to an RFC 6902 JSON Patch from the previous values to the new ones:",[1076,2353,2355],{"className":1078,"code":2354,"language":680,"meta":1080,"style":1080},"[{ \"op\": \"replace\", \"path\": \"\u002Fprice\", \"value\": 1338.4 }]\n",[1047,2356,2357],{"__ignoreMap":1080},[1084,2358,2359,2362,2365,2367,2370,2372,2375,2377,2380,2382,2385,2387,2390],{"class":1086,"line":1087},[1084,2360,2361],{"class":1090},"[{ ",[1084,2363,2364],{"class":1097},"\"op\"",[1084,2366,1102],{"class":1101},[1084,2368,2369],{"class":1105}," \"replace\"",[1084,2371,1181],{"class":1101},[1084,2373,2374],{"class":1097}," \"path\"",[1084,2376,1102],{"class":1101},[1084,2378,2379],{"class":1105}," \"\u002Fprice\"",[1084,2381,1181],{"class":1101},[1084,2383,2384],{"class":1097}," \"value\"",[1084,2386,1102],{"class":1101},[1084,2388,2389],{"class":1177}," 1338.4",[1084,2391,2392],{"class":1090}," }]\n",[1025,2394,2395,2396,2399,2400,2403,2404,2407],{},"A run with no change has no diff (",[1047,2397,2398],{},"404","). Changing ",[1047,2401,2402],{},"change_detection"," with ",[1047,2405,2406],{},"PATCH"," starts comparing\nafresh.",[2095,2409,2411],{"id":2410},"when-runs-fail","When runs fail",[1025,2413,2414,2415,2417,2418,2421,2422,2425,2426,2429],{},"A run that does not succeed sends ",[1047,2416,2334],{}," with its ",[1047,2419,2420],{},"status",". Five in a row send\n",[1047,2423,2424],{},"schedule.failing"," once, with ",[1047,2427,2428],{},"failure_streak",". A failing schedule keeps running: the site may come\nback, and a fix you publish to the alias is picked up at the next fire.",[2095,2431,2433],{"id":2432},"run-history","Run history",[1025,2435,2436,2439,2440,1109,2443,1274,2446,1274,2449,1274,2452,1274,2454,1274,2457,1274,2460,2462,2463,1341],{},[1047,2437,2438],{},"GET \u002Fv1\u002Fschedules\u002F{id}\u002Fruns"," lists every fire, newest first, skipped ones included: ",[1047,2441,2442],{},"job_id",[1047,2444,2445],{},"scheduled_for",[1047,2447,2448],{},"started_at",[1047,2450,2451],{},"finished_at",[1047,2453,2420],{},[1047,2455,2456],{},"skipped",[1047,2458,2459],{},"skip_reason",[1047,2461,2311],{}," and\n",[1047,2464,2325],{},[1376,2466,2467,2685,2850],{},[1076,2468,2470],{"className":1380,"code":2469,"filename":1382,"language":1383,"meta":1080,"style":1080},"\u002F\u002F Each fire is a run: its job, whether it changed, and where the JSON Patch of the change is.\nconst runs = await kaab.schedules.runs(schedule.id);\nfor (const run of runs.data) {\n  console.log(`${run.scheduled_for} ${run.status} changed=${run.changed}`);\n  if (run.changed && run.job_id !== null) {\n    console.log(`  diff: ${await kaab.schedules.runDiff(schedule.id, run.job_id)}`);\n  }\n}\nconsole.log(`${runs.data.length} run(s) so far`);\n",[1047,2471,2472,2477,2504,2524,2571,2600,2645,2650,2654],{"__ignoreMap":1080},[1084,2473,2474],{"class":1086,"line":1087},[1084,2475,2476],{"class":1439},"\u002F\u002F Each fire is a run: its job, whether it changed, and where the JSON Patch of the change is.\n",[1084,2478,2479,2481,2484,2486,2488,2490,2492,2494,2497,2499,2501],{"class":1086,"line":1094},[1084,2480,1390],{"class":1097},[1084,2482,2483],{"class":1177}," runs",[1084,2485,1396],{"class":1097},[1084,2487,1399],{"class":1097},[1084,2489,1402],{"class":1177},[1084,2491,1341],{"class":1405},[1084,2493,318],{"class":1177},[1084,2495,2496],{"class":1405},".runs",[1084,2498,1732],{"class":1090},[1084,2500,501],{"class":1177},[1084,2502,2503],{"class":1090},".id);\n",[1084,2505,2506,2509,2511,2513,2516,2519,2521],{"class":1086,"line":1112},[1084,2507,2508],{"class":1097},"for",[1084,2510,2157],{"class":1090},[1084,2512,1390],{"class":1097},[1084,2514,2515],{"class":1177}," run",[1084,2517,2518],{"class":1097}," of",[1084,2520,2483],{"class":1177},[1084,2522,2523],{"class":1090},".data) {\n",[1084,2525,2526,2529,2531,2533,2535,2537,2540,2543,2545,2548,2550,2553,2555,2558,2560,2562,2565,2567,2569],{"class":1086,"line":1136},[1084,2527,2528],{"class":1177},"  console",[1084,2530,1522],{"class":1405},[1084,2532,1732],{"class":1090},[1084,2534,1578],{"class":1105},[1084,2536,1426],{"class":1097},[1084,2538,2539],{"class":1177},"run",[1084,2541,2542],{"class":1090},".scheduled_for",[1084,2544,1431],{"class":1097},[1084,2546,2547],{"class":1097}," ${",[1084,2549,2539],{"class":1177},[1084,2551,2552],{"class":1090},".status",[1084,2554,1431],{"class":1097},[1084,2556,2557],{"class":1105}," changed=",[1084,2559,1426],{"class":1097},[1084,2561,2539],{"class":1177},[1084,2563,2564],{"class":1090},".changed",[1084,2566,1431],{"class":1097},[1084,2568,1578],{"class":1105},[1084,2570,1585],{"class":1090},[1084,2572,2573,2576,2578,2580,2583,2586,2588,2591,2594,2597],{"class":1086,"line":1149},[1084,2574,2575],{"class":1097},"  if",[1084,2577,2157],{"class":1090},[1084,2579,2539],{"class":1177},[1084,2581,2582],{"class":1090},".changed ",[1084,2584,2585],{"class":1097},"&&",[1084,2587,2515],{"class":1177},[1084,2589,2590],{"class":1090},".job_id ",[1084,2592,2593],{"class":1097},"!==",[1084,2595,2596],{"class":1177}," null",[1084,2598,2599],{"class":1090},") {\n",[1084,2601,2602,2605,2607,2609,2612,2614,2617,2619,2621,2623,2626,2628,2630,2632,2634,2636,2639,2641,2643],{"class":1086,"line":1162},[1084,2603,2604],{"class":1177},"    console",[1084,2606,1522],{"class":1405},[1084,2608,1732],{"class":1090},[1084,2610,2611],{"class":1105},"`  diff: ",[1084,2613,1426],{"class":1097},[1084,2615,2616],{"class":1097},"await",[1084,2618,1402],{"class":1177},[1084,2620,1341],{"class":1405},[1084,2622,318],{"class":1177},[1084,2624,2625],{"class":1405},".runDiff",[1084,2627,1732],{"class":1090},[1084,2629,501],{"class":1177},[1084,2631,1537],{"class":1090},[1084,2633,1181],{"class":1101},[1084,2635,2515],{"class":1177},[1084,2637,2638],{"class":1090},".job_id)",[1084,2640,1431],{"class":1097},[1084,2642,1578],{"class":1105},[1084,2644,1585],{"class":1090},[1084,2646,2647],{"class":1086,"line":1200},[1084,2648,2649],{"class":1090},"  }\n",[1084,2651,2652],{"class":1086,"line":1213},[1084,2653,1262],{"class":1090},[1084,2655,2656,2658,2660,2662,2664,2666,2669,2671,2673,2675,2678,2680,2683],{"class":1086,"line":1235},[1084,2657,1519],{"class":1177},[1084,2659,1522],{"class":1405},[1084,2661,1732],{"class":1090},[1084,2663,1578],{"class":1105},[1084,2665,1426],{"class":1097},[1084,2667,2668],{"class":1177},"runs",[1084,2670,1341],{"class":1090},[1084,2672,1336],{"class":1177},[1084,2674,1341],{"class":1090},[1084,2676,2677],{"class":1177},"length",[1084,2679,1431],{"class":1097},[1084,2681,2682],{"class":1105}," run(s) so far`",[1084,2684,1585],{"class":1090},[1076,2686,2688],{"className":1588,"code":2687,"filename":1590,"language":1591,"meta":1080,"style":1080},"# Each fire is a run: its job, whether it changed, and where the JSON Patch of the change is.\nruns = kaab.schedules.runs(schedule.id)\nfor run in runs.data:\n    print(f\"{run.scheduled_for} {run.status} changed={run.changed}\")\n    if run.changed and run.job_id:\n        print(f\"  diff: {kaab.schedules.run_diff(schedule.id, run.job_id)}\")\nprint(f\"{len(runs.data)} run(s) so far\")\n",[1047,2689,2690,2695,2715,2734,2773,2796,2825],{"__ignoreMap":1080},[1084,2691,2692],{"class":1086,"line":1087},[1084,2693,2694],{"class":1439},"# Each fire is a run: its job, whether it changed, and where the JSON Patch of the change is.\n",[1084,2696,2697,2700,2702,2704,2706,2708,2710,2712],{"class":1086,"line":1094},[1084,2698,2699],{"class":1090},"runs ",[1084,2701,1601],{"class":1097},[1084,2703,1402],{"class":1090},[1084,2705,1341],{"class":1101},[1084,2707,318],{"class":1090},[1084,2709,1341],{"class":1101},[1084,2711,2668],{"class":1405},[1084,2713,2714],{"class":1101},"(schedule.id)\n",[1084,2716,2717,2719,2722,2725,2727,2729,2731],{"class":1086,"line":1112},[1084,2718,2508],{"class":1097},[1084,2720,2721],{"class":1090}," run ",[1084,2723,2724],{"class":1097},"in",[1084,2726,2483],{"class":1090},[1084,2728,1341],{"class":1101},[1084,2730,1336],{"class":1090},[1084,2732,2733],{"class":1101},":\n",[1084,2735,2736,2739,2741,2743,2745,2747,2750,2752,2755,2758,2760,2762,2764,2767,2769,2771],{"class":1086,"line":1136},[1084,2737,2738],{"class":1405},"    print",[1084,2740,1732],{"class":1101},[1084,2742,1624],{"class":1097},[1084,2744,1627],{"class":1105},[1084,2746,1630],{"class":1177},[1084,2748,2749],{"class":1101},"run.scheduled_for",[1084,2751,1431],{"class":1177},[1084,2753,2754],{"class":1177}," {",[1084,2756,2757],{"class":1101},"run.status",[1084,2759,1431],{"class":1177},[1084,2761,2557],{"class":1105},[1084,2763,1630],{"class":1177},[1084,2765,2766],{"class":1101},"run.changed",[1084,2768,1431],{"class":1177},[1084,2770,1627],{"class":1105},[1084,2772,1724],{"class":1101},[1084,2774,2775,2778,2780,2782,2785,2788,2790,2792,2794],{"class":1086,"line":1149},[1084,2776,2777],{"class":1097},"    if",[1084,2779,2515],{"class":1090},[1084,2781,1341],{"class":1101},[1084,2783,2784],{"class":1090},"changed ",[1084,2786,2787],{"class":1097},"and",[1084,2789,2515],{"class":1090},[1084,2791,1341],{"class":1101},[1084,2793,2442],{"class":1090},[1084,2795,2733],{"class":1101},[1084,2797,2798,2801,2803,2805,2808,2810,2813,2816,2819,2821,2823],{"class":1086,"line":1162},[1084,2799,2800],{"class":1405},"        print",[1084,2802,1732],{"class":1101},[1084,2804,1624],{"class":1097},[1084,2806,2807],{"class":1105},"\"  diff: ",[1084,2809,1630],{"class":1177},[1084,2811,2812],{"class":1101},"kaab.schedules.",[1084,2814,2815],{"class":1405},"run_diff",[1084,2817,2818],{"class":1101},"(schedule.id, run.job_id)",[1084,2820,1431],{"class":1177},[1084,2822,1627],{"class":1105},[1084,2824,1724],{"class":1101},[1084,2826,2827,2829,2831,2833,2835,2837,2840,2843,2845,2848],{"class":1086,"line":1200},[1084,2828,1729],{"class":1405},[1084,2830,1732],{"class":1101},[1084,2832,1624],{"class":1097},[1084,2834,1627],{"class":1105},[1084,2836,1630],{"class":1177},[1084,2838,2839],{"class":1405},"len",[1084,2841,2842],{"class":1101},"(runs.data)",[1084,2844,1431],{"class":1177},[1084,2846,2847],{"class":1105}," run(s) so far\"",[1084,2849,1724],{"class":1101},[1076,2851,2853],{"className":1778,"code":2852,"filename":1780,"language":1781,"meta":1080,"style":1080},"\u002F\u002F Each fire is a run: its job, whether it changed, and where the JSON Patch of the change is.\nruns, err := c.Schedules.Runs(ctx, schedule.ID, nil)\nif err != nil {\n    log.Fatal(err)\n}\nfor _, run := range runs.Data {\n    changed := run.Changed != nil && *run.Changed\n    fmt.Printf(\"%v skipped=%v changed=%v\\n\", run.StartedAt, run.Skipped, changed)\n    if changed && run.JobID != nil {\n        diff, err := c.Schedules.RunDiff(ctx, schedule.ID, *run.JobID)\n        if err != nil {\n            log.Fatal(err)\n        }\n        fmt.Printf(\"  diff: %s\\n\", diff)\n    }\n}\nfmt.Printf(\"%d run(s) so far\\n\", len(runs.Data))\n",[1047,2854,2855,2859,2879,2891,2899,2903,2918,2941,2969,2987,3007,3020,3029,3034,3052,3057,3061],{"__ignoreMap":1080},[1084,2856,2857],{"class":1086,"line":1087},[1084,2858,2476],{"class":1439},[1084,2860,2861,2864,2866,2868,2871,2874,2877],{"class":1086,"line":1094},[1084,2862,2863],{"class":1090},"runs, err ",[1084,2865,1791],{"class":1097},[1084,2867,1979],{"class":1090},[1084,2869,2870],{"class":1405},"Runs",[1084,2872,2873],{"class":1090},"(ctx, schedule.ID, ",[1084,2875,2876],{"class":1177},"nil",[1084,2878,1724],{"class":1090},[1084,2880,2881,2883,2885,2887,2889],{"class":1086,"line":1112},[1084,2882,1941],{"class":1097},[1084,2884,1944],{"class":1090},[1084,2886,1947],{"class":1097},[1084,2888,1950],{"class":1177},[1084,2890,1953],{"class":1090},[1084,2892,2893,2895,2897],{"class":1086,"line":1136},[1084,2894,1958],{"class":1090},[1084,2896,1961],{"class":1405},[1084,2898,1964],{"class":1090},[1084,2900,2901],{"class":1086,"line":1149},[1084,2902,1262],{"class":1090},[1084,2904,2905,2907,2910,2912,2915],{"class":1086,"line":1162},[1084,2906,2508],{"class":1097},[1084,2908,2909],{"class":1090}," _, run ",[1084,2911,1791],{"class":1097},[1084,2913,2914],{"class":1097}," range",[1084,2916,2917],{"class":1090}," runs.Data {\n",[1084,2919,2920,2923,2925,2928,2930,2932,2935,2938],{"class":1086,"line":1200},[1084,2921,2922],{"class":1090},"    changed ",[1084,2924,1791],{"class":1097},[1084,2926,2927],{"class":1090}," run.Changed ",[1084,2929,1947],{"class":1097},[1084,2931,1950],{"class":1177},[1084,2933,2934],{"class":1097}," &&",[1084,2936,2937],{"class":1097}," *",[1084,2939,2940],{"class":1090},"run.Changed\n",[1084,2942,2943,2946,2948,2950,2952,2955,2958,2960,2962,2964,2966],{"class":1086,"line":1213},[1084,2944,2945],{"class":1090},"    fmt.",[1084,2947,2068],{"class":1405},[1084,2949,1732],{"class":1090},[1084,2951,1627],{"class":1105},[1084,2953,2954],{"class":1177},"%v",[1084,2956,2957],{"class":1105}," skipped=",[1084,2959,2954],{"class":1177},[1084,2961,2557],{"class":1105},[1084,2963,2954],{"class":1177},[1084,2965,2090],{"class":1105},[1084,2967,2968],{"class":1090},", run.StartedAt, run.Skipped, changed)\n",[1084,2970,2971,2973,2976,2978,2981,2983,2985],{"class":1086,"line":1235},[1084,2972,2777],{"class":1097},[1084,2974,2975],{"class":1090}," changed ",[1084,2977,2585],{"class":1097},[1084,2979,2980],{"class":1090}," run.JobID ",[1084,2982,1947],{"class":1097},[1084,2984,1950],{"class":1177},[1084,2986,1953],{"class":1090},[1084,2988,2989,2992,2994,2996,2999,3001,3004],{"class":1086,"line":1248},[1084,2990,2991],{"class":1090},"        diff, err ",[1084,2993,1791],{"class":1097},[1084,2995,1979],{"class":1090},[1084,2997,2998],{"class":1405},"RunDiff",[1084,3000,2873],{"class":1090},[1084,3002,3003],{"class":1097},"*",[1084,3005,3006],{"class":1090},"run.JobID)\n",[1084,3008,3009,3012,3014,3016,3018],{"class":1086,"line":1259},[1084,3010,3011],{"class":1097},"        if",[1084,3013,1944],{"class":1090},[1084,3015,1947],{"class":1097},[1084,3017,1950],{"class":1177},[1084,3019,1953],{"class":1090},[1084,3021,3022,3025,3027],{"class":1086,"line":1971},[1084,3023,3024],{"class":1090},"            log.",[1084,3026,1961],{"class":1405},[1084,3028,1964],{"class":1090},[1084,3030,3031],{"class":1086,"line":1988},[1084,3032,3033],{"class":1090},"        }\n",[1084,3035,3036,3039,3041,3043,3045,3047,3049],{"class":1086,"line":2001},[1084,3037,3038],{"class":1090},"        fmt.",[1084,3040,2068],{"class":1405},[1084,3042,1732],{"class":1090},[1084,3044,2807],{"class":1105},[1084,3046,2075],{"class":1177},[1084,3048,2090],{"class":1105},[1084,3050,3051],{"class":1090},", diff)\n",[1084,3053,3054],{"class":1086,"line":2010},[1084,3055,3056],{"class":1090},"    }\n",[1084,3058,3059],{"class":1086,"line":2015},[1084,3060,1262],{"class":1090},[1084,3062,3063,3065,3067,3069,3071,3074,3077,3079,3081],{"class":1086,"line":2026},[1084,3064,2065],{"class":1090},[1084,3066,2068],{"class":1405},[1084,3068,1732],{"class":1090},[1084,3070,1627],{"class":1105},[1084,3072,3073],{"class":1177},"%d",[1084,3075,3076],{"class":1105}," run(s) so far\\n\"",[1084,3078,1274],{"class":1090},[1084,3080,2839],{"class":1405},[1084,3082,3083],{"class":1090},"(runs.Data))\n",[1029,3085,3087],{"id":3086},"worked-example","Worked example",[1025,3089,3090,3091,3094],{},"Watch a competitor's price hourly and hear about it only when it changes. The competitor here is a\nshop at ",[1047,3092,3093],{},"https:\u002F\u002Fshop.example.com","; its product page shows a title, a price in Turkish lira and a\nSKU.",[3096,3097,3098,3114,3152,3169,3273],"ol",{},[1043,3099,3100,3103,3104,2403,3106,3109,3110,3113],{},[1062,3101,3102],{},"Publish the program."," It reads ",[1047,3105,1329],{},[1047,3107,3108],{},"\"type\": \"money\""," from ",[1047,3111,3112],{},"\u002Fp\u002F1",", at the http tier.",[1043,3115,3116,3119,3120],{},[1062,3117,3118],{},"Register a webhook endpoint"," for the schedule events, and keep its secret:",[1076,3121,3123],{"className":1078,"code":3122,"language":680,"meta":1080,"style":1080},"{ \"url\": \"https:\u002F\u002Fhooks.example.com\u002Fkaab\", \"events\": [\"schedule.*\"] }\n",[1047,3124,3125],{"__ignoreMap":1080},[1084,3126,3127,3130,3133,3135,3137,3139,3142,3144,3146,3149],{"class":1086,"line":1087},[1084,3128,3129],{"class":1090},"{ ",[1084,3131,3132],{"class":1097},"\"url\"",[1084,3134,1102],{"class":1101},[1084,3136,1208],{"class":1105},[1084,3138,1181],{"class":1101},[1084,3140,3141],{"class":1097}," \"events\"",[1084,3143,1102],{"class":1101},[1084,3145,1189],{"class":1090},[1084,3147,3148],{"class":1105},"\"schedule.*\"",[1084,3150,3151],{"class":1090},"] }\n",[1043,3153,3154,2403,3157,3160,3161,3164,3165,2403,3167,1341],{},[1062,3155,3156],{},"Create the schedule",[1047,3158,3159],{},"\"cron\": \"0 * * * *\"",", your timezone and\n",[1047,3162,3163],{},"\"change_detection\": { \"enabled\": true, \"fields\": [\"price\"] }",", as in the snippet above. Its\nfirst run records the price and sends ",[1047,3166,2334],{},[1047,3168,2338],{},[1043,3170,3171,3174,3175,1102,3177],{},[1062,3172,3173],{},"The price moves."," The competitor raises the price by one lira. The next run sends\n",[1047,3176,1362],{},[1076,3178,3180],{"className":1078,"code":3179,"language":680,"meta":1080,"style":1080},"{\n  \"type\": \"schedule.changed\",\n  \"data\": {\n    \"schedule\": \"sch_…\", \"job\": \"job_…\", \"changed_paths\": [\"\u002Fprice\"],\n    \"url\": \"https:\u002F\u002Fapi.kaab.ist\u002Fv1\u002Fschedules\u002Fsch_…\",\n    \"diff_url\": \"https:\u002F\u002Fapi.kaab.ist\u002Fv1\u002Fschedules\u002Fsch_…\u002Fruns\u002Fjob_…\u002Fdiff\"\n  }\n}\n",[1047,3181,3182,3186,3198,3207,3243,3255,3265,3269],{"__ignoreMap":1080},[1084,3183,3184],{"class":1086,"line":1087},[1084,3185,1091],{"class":1090},[1084,3187,3188,3191,3193,3196],{"class":1086,"line":1094},[1084,3189,3190],{"class":1097},"  \"type\"",[1084,3192,1102],{"class":1101},[1084,3194,3195],{"class":1105}," \"schedule.changed\"",[1084,3197,1109],{"class":1101},[1084,3199,3200,3203,3205],{"class":1086,"line":1112},[1084,3201,3202],{"class":1097},"  \"data\"",[1084,3204,1102],{"class":1101},[1084,3206,1953],{"class":1090},[1084,3208,3209,3212,3214,3217,3219,3222,3224,3227,3229,3232,3234,3236,3239,3241],{"class":1086,"line":1136},[1084,3210,3211],{"class":1097},"    \"schedule\"",[1084,3213,1102],{"class":1101},[1084,3215,3216],{"class":1105}," \"sch_…\"",[1084,3218,1181],{"class":1101},[1084,3220,3221],{"class":1097}," \"job\"",[1084,3223,1102],{"class":1101},[1084,3225,3226],{"class":1105}," \"job_…\"",[1084,3228,1181],{"class":1101},[1084,3230,3231],{"class":1097}," \"changed_paths\"",[1084,3233,1102],{"class":1101},[1084,3235,1189],{"class":1090},[1084,3237,3238],{"class":1105},"\"\u002Fprice\"",[1084,3240,1822],{"class":1090},[1084,3242,1109],{"class":1101},[1084,3244,3245,3248,3250,3253],{"class":1086,"line":1149},[1084,3246,3247],{"class":1097},"    \"url\"",[1084,3249,1102],{"class":1101},[1084,3251,3252],{"class":1105}," \"https:\u002F\u002Fapi.kaab.ist\u002Fv1\u002Fschedules\u002Fsch_…\"",[1084,3254,1109],{"class":1101},[1084,3256,3257,3260,3262],{"class":1086,"line":1162},[1084,3258,3259],{"class":1097},"    \"diff_url\"",[1084,3261,1102],{"class":1101},[1084,3263,3264],{"class":1105}," \"https:\u002F\u002Fapi.kaab.ist\u002Fv1\u002Fschedules\u002Fsch_…\u002Fruns\u002Fjob_…\u002Fdiff\"\n",[1084,3266,3267],{"class":1086,"line":1200},[1084,3268,2649],{"class":1090},[1084,3270,3271],{"class":1086,"line":1213},[1084,3272,1262],{"class":1090},[1043,3274,3275,3278,3279,3282,3283,3286,3287,3289],{},[1062,3276,3277],{},"Receive it."," Your receiver verifies ",[1047,3280,3281],{},"Kaab-Signature",", answers ",[1047,3284,3285],{},"2xx"," at once, skips an event id\nit has already handled, and then reads the new value: the patch at ",[1047,3288,2325],{},", or the job itself.",[1376,3291,3292,3678,4047],{},[1076,3293,3295],{"className":1380,"code":3294,"filename":1382,"language":1383,"meta":1080,"style":1080},"const server = createServer((request, response) => {\n  const chunks: Buffer[] = [];\n  request.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n  request.on(\"end\", () => {\n    try {\n      \u002F\u002F The raw bytes, before any JSON parser: the signature is over them.\n      const event = kaab.webhooks.constructEvent(\n        Buffer.concat(chunks),\n        request.headers[\"kaab-signature\"]?.toString(),\n        secret,\n      );\n      response.writeHead(204).end(); \u002F\u002F answer fast; work afterwards\n      if (seen.has(event.id)) return;\n      seen.add(event.id);\n      console.log(`verified ${event.type} ${event.id}`);\n      resolveFirst(event.type);\n    } catch (error) {\n      response.writeHead(error instanceof KaabSignatureError ? 401 : 400).end();\n      console.log(`refused a delivery: ${(error as Error).message}`);\n    }\n  });\n});\n",[1047,3296,3297,3322,3343,3378,3398,3405,3410,3431,3444,3465,3472,3477,3502,3529,3543,3576,3588,3599,3633,3663,3667,3673],{"__ignoreMap":1080},[1084,3298,3299,3301,3304,3306,3309,3312,3314,3317,3320],{"class":1086,"line":1087},[1084,3300,1390],{"class":1097},[1084,3302,3303],{"class":1177}," server",[1084,3305,1396],{"class":1097},[1084,3307,3308],{"class":1405}," createServer",[1084,3310,3311],{"class":1090},"((request",[1084,3313,1181],{"class":1101},[1084,3315,3316],{"class":1090}," response) ",[1084,3318,3319],{"class":1097},"=>",[1084,3321,1953],{"class":1090},[1084,3323,3324,3327,3330,3332,3335,3338,3340],{"class":1086,"line":1094},[1084,3325,3326],{"class":1097},"  const",[1084,3328,3329],{"class":1177}," chunks",[1084,3331,1102],{"class":1097},[1084,3333,3334],{"class":1405}," Buffer",[1084,3336,3337],{"class":1090},"[] ",[1084,3339,1601],{"class":1097},[1084,3341,3342],{"class":1090}," [];\n",[1084,3344,3345,3348,3351,3353,3356,3358,3361,3363,3365,3368,3370,3372,3375],{"class":1086,"line":1112},[1084,3346,3347],{"class":1177},"  request",[1084,3349,3350],{"class":1405},".on",[1084,3352,1732],{"class":1090},[1084,3354,3355],{"class":1105},"\"data\"",[1084,3357,1181],{"class":1101},[1084,3359,3360],{"class":1090}," (chunk",[1084,3362,1102],{"class":1097},[1084,3364,3334],{"class":1405},[1084,3366,3367],{"class":1090},") ",[1084,3369,3319],{"class":1097},[1084,3371,3329],{"class":1177},[1084,3373,3374],{"class":1405},".push",[1084,3376,3377],{"class":1090},"(chunk));\n",[1084,3379,3380,3382,3384,3386,3389,3391,3394,3396],{"class":1086,"line":1136},[1084,3381,3347],{"class":1177},[1084,3383,3350],{"class":1405},[1084,3385,1732],{"class":1090},[1084,3387,3388],{"class":1105},"\"end\"",[1084,3390,1181],{"class":1101},[1084,3392,3393],{"class":1090}," () ",[1084,3395,3319],{"class":1097},[1084,3397,1953],{"class":1090},[1084,3399,3400,3403],{"class":1086,"line":1149},[1084,3401,3402],{"class":1097},"    try",[1084,3404,1953],{"class":1090},[1084,3406,3407],{"class":1086,"line":1162},[1084,3408,3409],{"class":1439},"      \u002F\u002F The raw bytes, before any JSON parser: the signature is over them.\n",[1084,3411,3412,3415,3418,3420,3422,3424,3426,3429],{"class":1086,"line":1200},[1084,3413,3414],{"class":1097},"      const",[1084,3416,3417],{"class":1177}," event",[1084,3419,1396],{"class":1097},[1084,3421,1402],{"class":1177},[1084,3423,1341],{"class":1405},[1084,3425,105],{"class":1177},[1084,3427,3428],{"class":1405},".constructEvent",[1084,3430,1525],{"class":1090},[1084,3432,3433,3436,3439,3442],{"class":1086,"line":1213},[1084,3434,3435],{"class":1177},"        Buffer",[1084,3437,3438],{"class":1405},".concat",[1084,3440,3441],{"class":1090},"(chunks)",[1084,3443,1109],{"class":1101},[1084,3445,3446,3449,3452,3455,3457,3460,3463],{"class":1086,"line":1235},[1084,3447,3448],{"class":1177},"        request",[1084,3450,3451],{"class":1090},".headers[",[1084,3453,3454],{"class":1105},"\"kaab-signature\"",[1084,3456,1822],{"class":1090},[1084,3458,3459],{"class":1405},"?.toString",[1084,3461,3462],{"class":1090},"()",[1084,3464,1109],{"class":1101},[1084,3466,3467,3470],{"class":1086,"line":1248},[1084,3468,3469],{"class":1090},"        secret",[1084,3471,1109],{"class":1101},[1084,3473,3474],{"class":1086,"line":1259},[1084,3475,3476],{"class":1090},"      );\n",[1084,3478,3479,3482,3485,3487,3490,3493,3496,3499],{"class":1086,"line":1971},[1084,3480,3481],{"class":1177},"      response",[1084,3483,3484],{"class":1405},".writeHead",[1084,3486,1732],{"class":1090},[1084,3488,3489],{"class":1177},"204",[1084,3491,3492],{"class":1090},")",[1084,3494,3495],{"class":1405},".end",[1084,3497,3498],{"class":1090},"(); ",[1084,3500,3501],{"class":1439},"\u002F\u002F answer fast; work afterwards\n",[1084,3503,3504,3507,3509,3512,3515,3517,3520,3523,3526],{"class":1086,"line":1988},[1084,3505,3506],{"class":1097},"      if",[1084,3508,2157],{"class":1090},[1084,3510,3511],{"class":1177},"seen",[1084,3513,3514],{"class":1405},".has",[1084,3516,1732],{"class":1090},[1084,3518,3519],{"class":1177},"event",[1084,3521,3522],{"class":1090},".id)) ",[1084,3524,3525],{"class":1097},"return",[1084,3527,3528],{"class":1090},";\n",[1084,3530,3531,3534,3537,3539,3541],{"class":1086,"line":2001},[1084,3532,3533],{"class":1177},"      seen",[1084,3535,3536],{"class":1405},".add",[1084,3538,1732],{"class":1090},[1084,3540,3519],{"class":1177},[1084,3542,2503],{"class":1090},[1084,3544,3545,3548,3550,3552,3555,3557,3559,3562,3564,3566,3568,3570,3572,3574],{"class":1086,"line":2010},[1084,3546,3547],{"class":1177},"      console",[1084,3549,1522],{"class":1405},[1084,3551,1732],{"class":1090},[1084,3553,3554],{"class":1105},"`verified ",[1084,3556,1426],{"class":1097},[1084,3558,3519],{"class":1177},[1084,3560,3561],{"class":1090},".type",[1084,3563,1431],{"class":1097},[1084,3565,2547],{"class":1097},[1084,3567,3519],{"class":1177},[1084,3569,1537],{"class":1090},[1084,3571,1431],{"class":1097},[1084,3573,1578],{"class":1105},[1084,3575,1585],{"class":1090},[1084,3577,3578,3581,3583,3585],{"class":1086,"line":2015},[1084,3579,3580],{"class":1405},"      resolveFirst",[1084,3582,1732],{"class":1090},[1084,3584,3519],{"class":1177},[1084,3586,3587],{"class":1090},".type);\n",[1084,3589,3590,3593,3596],{"class":1086,"line":2026},[1084,3591,3592],{"class":1090},"    } ",[1084,3594,3595],{"class":1097},"catch",[1084,3597,3598],{"class":1090}," (error) {\n",[1084,3600,3601,3603,3605,3608,3611,3614,3617,3620,3623,3626,3628,3630],{"class":1086,"line":2040},[1084,3602,3481],{"class":1177},[1084,3604,3484],{"class":1405},[1084,3606,3607],{"class":1090},"(error ",[1084,3609,3610],{"class":1097},"instanceof",[1084,3612,3613],{"class":1405}," KaabSignatureError",[1084,3615,3616],{"class":1097}," ?",[1084,3618,3619],{"class":1177}," 401",[1084,3621,3622],{"class":1097}," :",[1084,3624,3625],{"class":1177}," 400",[1084,3627,3492],{"class":1090},[1084,3629,3495],{"class":1405},[1084,3631,3632],{"class":1090},"();\n",[1084,3634,3635,3637,3639,3641,3644,3646,3648,3651,3654,3657,3659,3661],{"class":1086,"line":2057},[1084,3636,3547],{"class":1177},[1084,3638,1522],{"class":1405},[1084,3640,1732],{"class":1090},[1084,3642,3643],{"class":1105},"`refused a delivery: ",[1084,3645,1426],{"class":1097},[1084,3647,3607],{"class":1090},[1084,3649,3650],{"class":1097},"as",[1084,3652,3653],{"class":1405}," Error",[1084,3655,3656],{"class":1090},").message",[1084,3658,1431],{"class":1097},[1084,3660,1578],{"class":1105},[1084,3662,1585],{"class":1090},[1084,3664,3665],{"class":1086,"line":2062},[1084,3666,3056],{"class":1090},[1084,3668,3670],{"class":1086,"line":3669},21,[1084,3671,3672],{"class":1090},"  });\n",[1084,3674,3676],{"class":1086,"line":3675},22,[1084,3677,1514],{"class":1090},[1076,3679,3681],{"className":1588,"code":3680,"filename":1590,"language":1591,"meta":1080,"style":1080},"class Receiver(BaseHTTPRequestHandler):\n    def do_POST(self) -> None:  # noqa: N802\n        raw = self.rfile.read(int(self.headers.get(\"content-length\", \"0\")))  # the bytes, unparsed\n        try:\n            event = webhooks.construct_event(raw, self.headers.get(\"kaab-signature\"), secret)\n        except KaabSignatureError as error:\n            self.send_response(401)\n            self.end_headers()\n            print(f\"refused a delivery: {error}\")\n            return\n        self.send_response(204)  # answer fast; work afterwards\n        self.end_headers()\n        if event[\"id\"] not in seen:\n            seen.add(event[\"id\"])\n            print(f\"verified {event['type']} {event['id']}\")\n            received.put(event[\"type\"])\n\n    def log_message(self, *_: object) -> None:\n        pass\n",[1047,3682,3683,3699,3727,3774,3781,3808,3823,3840,3852,3875,3880,3898,3908,3932,3950,3988,4005,4011,4042],{"__ignoreMap":1080},[1084,3684,3685,3688,3691,3693,3696],{"class":1086,"line":1087},[1084,3686,3687],{"class":1097},"class",[1084,3689,3690],{"class":1405}," Receiver",[1084,3692,1732],{"class":1090},[1084,3694,3695],{"class":1405},"BaseHTTPRequestHandler",[1084,3697,3698],{"class":1090},"):\n",[1084,3700,3701,3704,3707,3709,3713,3715,3718,3721,3724],{"class":1086,"line":1094},[1084,3702,3703],{"class":1097},"    def",[1084,3705,3706],{"class":1405}," do_POST",[1084,3708,1732],{"class":1090},[1084,3710,3712],{"class":3711},"sIH4l","self",[1084,3714,3367],{"class":1090},[1084,3716,3717],{"class":1101},"->",[1084,3719,3720],{"class":1177}," None",[1084,3722,3723],{"class":1090},":  ",[1084,3725,3726],{"class":1439},"# noqa: N802\n",[1084,3728,3729,3732,3734,3737,3739,3742,3744,3747,3749,3752,3755,3758,3760,3763,3765,3768,3771],{"class":1086,"line":1112},[1084,3730,3731],{"class":1090},"        raw ",[1084,3733,1601],{"class":1097},[1084,3735,3736],{"class":1090}," self",[1084,3738,1341],{"class":1101},[1084,3740,3741],{"class":1090},"rfile",[1084,3743,1341],{"class":1101},[1084,3745,3746],{"class":1405},"read",[1084,3748,1732],{"class":1101},[1084,3750,3751],{"class":1177},"int",[1084,3753,3754],{"class":1101},"(self.headers.",[1084,3756,3757],{"class":1405},"get",[1084,3759,1732],{"class":1101},[1084,3761,3762],{"class":1105},"\"content-length\"",[1084,3764,1274],{"class":1101},[1084,3766,3767],{"class":1105},"\"0\"",[1084,3769,3770],{"class":1101},")))",[1084,3772,3773],{"class":1439},"  # the bytes, unparsed\n",[1084,3775,3776,3779],{"class":1086,"line":1136},[1084,3777,3778],{"class":1097},"        try",[1084,3780,2733],{"class":1101},[1084,3782,3783,3786,3788,3791,3793,3796,3799,3801,3803,3805],{"class":1086,"line":1149},[1084,3784,3785],{"class":1090},"            event ",[1084,3787,1601],{"class":1097},[1084,3789,3790],{"class":1090}," webhooks",[1084,3792,1341],{"class":1101},[1084,3794,3795],{"class":1405},"construct_event",[1084,3797,3798],{"class":1101},"(raw, self.headers.",[1084,3800,3757],{"class":1405},[1084,3802,1732],{"class":1101},[1084,3804,3454],{"class":1105},[1084,3806,3807],{"class":1101},"), secret)\n",[1084,3809,3810,3813,3816,3818,3821],{"class":1086,"line":1162},[1084,3811,3812],{"class":1097},"        except",[1084,3814,3815],{"class":1090}," KaabSignatureError ",[1084,3817,3650],{"class":1097},[1084,3819,3820],{"class":1090}," error",[1084,3822,2733],{"class":1101},[1084,3824,3825,3828,3830,3833,3835,3838],{"class":1086,"line":1200},[1084,3826,3827],{"class":1090},"            self",[1084,3829,1341],{"class":1101},[1084,3831,3832],{"class":1405},"send_response",[1084,3834,1732],{"class":1101},[1084,3836,3837],{"class":1177},"401",[1084,3839,1724],{"class":1101},[1084,3841,3842,3844,3846,3849],{"class":1086,"line":1213},[1084,3843,3827],{"class":1090},[1084,3845,1341],{"class":1101},[1084,3847,3848],{"class":1405},"end_headers",[1084,3850,3851],{"class":1101},"()\n",[1084,3853,3854,3857,3859,3861,3864,3866,3869,3871,3873],{"class":1086,"line":1235},[1084,3855,3856],{"class":1405},"            print",[1084,3858,1732],{"class":1101},[1084,3860,1624],{"class":1097},[1084,3862,3863],{"class":1105},"\"refused a delivery: ",[1084,3865,1630],{"class":1177},[1084,3867,3868],{"class":1101},"error",[1084,3870,1431],{"class":1177},[1084,3872,1627],{"class":1105},[1084,3874,1724],{"class":1101},[1084,3876,3877],{"class":1086,"line":1248},[1084,3878,3879],{"class":1097},"            return\n",[1084,3881,3882,3885,3887,3889,3891,3893,3895],{"class":1086,"line":1259},[1084,3883,3884],{"class":1090},"        self",[1084,3886,1341],{"class":1101},[1084,3888,3832],{"class":1405},[1084,3890,1732],{"class":1101},[1084,3892,3489],{"class":1177},[1084,3894,3492],{"class":1101},[1084,3896,3897],{"class":1439},"  # answer fast; work afterwards\n",[1084,3899,3900,3902,3904,3906],{"class":1086,"line":1971},[1084,3901,3884],{"class":1090},[1084,3903,1341],{"class":1101},[1084,3905,3848],{"class":1405},[1084,3907,3851],{"class":1101},[1084,3909,3910,3912,3914,3916,3919,3921,3924,3927,3930],{"class":1086,"line":1988},[1084,3911,3011],{"class":1097},[1084,3913,3417],{"class":1090},[1084,3915,1800],{"class":1101},[1084,3917,3918],{"class":1105},"\"id\"",[1084,3920,1822],{"class":1101},[1084,3922,3923],{"class":1097}," not",[1084,3925,3926],{"class":1097}," in",[1084,3928,3929],{"class":1090}," seen",[1084,3931,2733],{"class":1101},[1084,3933,3934,3937,3939,3942,3945,3947],{"class":1086,"line":2001},[1084,3935,3936],{"class":1090},"            seen",[1084,3938,1341],{"class":1101},[1084,3940,3941],{"class":1405},"add",[1084,3943,3944],{"class":1101},"(event[",[1084,3946,3918],{"class":1105},[1084,3948,3949],{"class":1101},"])\n",[1084,3951,3952,3954,3956,3958,3961,3963,3966,3969,3971,3973,3975,3977,3980,3982,3984,3986],{"class":1086,"line":2010},[1084,3953,3856],{"class":1405},[1084,3955,1732],{"class":1101},[1084,3957,1624],{"class":1097},[1084,3959,3960],{"class":1105},"\"verified ",[1084,3962,1630],{"class":1177},[1084,3964,3965],{"class":1101},"event[",[1084,3967,3968],{"class":1105},"'type'",[1084,3970,1822],{"class":1101},[1084,3972,1431],{"class":1177},[1084,3974,2754],{"class":1177},[1084,3976,3965],{"class":1101},[1084,3978,3979],{"class":1105},"'id'",[1084,3981,1822],{"class":1101},[1084,3983,1431],{"class":1177},[1084,3985,1627],{"class":1105},[1084,3987,1724],{"class":1101},[1084,3989,3990,3993,3995,3998,4000,4003],{"class":1086,"line":2015},[1084,3991,3992],{"class":1090},"            received",[1084,3994,1341],{"class":1101},[1084,3996,3997],{"class":1405},"put",[1084,3999,3944],{"class":1101},[1084,4001,4002],{"class":1105},"\"type\"",[1084,4004,3949],{"class":1101},[1084,4006,4007],{"class":1086,"line":2026},[1084,4008,4010],{"emptyLinePlaceholder":4009},true,"\n",[1084,4012,4013,4015,4018,4020,4022,4024,4026,4029,4031,4034,4036,4038,4040],{"class":1086,"line":2040},[1084,4014,3703],{"class":1097},[1084,4016,4017],{"class":1405}," log_message",[1084,4019,1732],{"class":1090},[1084,4021,3712],{"class":3711},[1084,4023,1181],{"class":1101},[1084,4025,2937],{"class":1097},[1084,4027,4028],{"class":3711},"_",[1084,4030,1102],{"class":1101},[1084,4032,4033],{"class":1177}," object",[1084,4035,3367],{"class":1090},[1084,4037,3717],{"class":1101},[1084,4039,3720],{"class":1177},[1084,4041,2733],{"class":1090},[1084,4043,4044],{"class":1086,"line":2057},[1084,4045,4046],{"class":1097},"        pass\n",[1076,4048,4050],{"className":1778,"code":4049,"filename":1780,"language":1781,"meta":1080,"style":1080},"handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    raw, err := io.ReadAll(r.Body) \u002F\u002F the bytes, before any JSON decoding\n    if err != nil {\n        w.WriteHeader(http.StatusBadRequest)\n        return\n    }\n    mu.Lock()\n    key := secret\n    mu.Unlock()\n    event, err := webhooks.ConstructEvent(raw, r.Header.Get(webhooks.SignatureHeader), key)\n    if err != nil {\n        w.WriteHeader(http.StatusUnauthorized)\n        log.Printf(\"refused a delivery: %v\", err)\n        return\n    }\n    w.WriteHeader(http.StatusNoContent) \u002F\u002F answer fast; work afterwards\n    mu.Lock()\n    defer mu.Unlock()\n    if !seen[event.ID] {\n        seen[event.ID] = true\n        fmt.Printf(\"verified %s %s\\n\", event.Type, event.ID)\n        received \u003C- event.Type\n    }\n})\n",[1047,4051,4052,4095,4114,4126,4137,4142,4146,4156,4166,4175,4197,4209,4218,4236,4240,4244,4256,4264,4276,4286,4296,4315,4326,4331],{"__ignoreMap":1080},[1084,4053,4054,4057,4059,4062,4065,4067,4070,4073,4076,4078,4081,4084,4086,4088,4090,4093],{"class":1086,"line":1087},[1084,4055,4056],{"class":1090},"handler ",[1084,4058,1791],{"class":1097},[1084,4060,4061],{"class":1090}," http.",[1084,4063,4064],{"class":1405},"HandlerFunc",[1084,4066,1732],{"class":1090},[1084,4068,4069],{"class":1097},"func",[1084,4071,4072],{"class":1090},"(w ",[1084,4074,4075],{"class":1405},"http",[1084,4077,1341],{"class":1090},[1084,4079,4080],{"class":1405},"ResponseWriter",[1084,4082,4083],{"class":1090},", r ",[1084,4085,3003],{"class":1097},[1084,4087,4075],{"class":1405},[1084,4089,1341],{"class":1090},[1084,4091,4092],{"class":1405},"Request",[1084,4094,2599],{"class":1090},[1084,4096,4097,4100,4102,4105,4108,4111],{"class":1086,"line":1094},[1084,4098,4099],{"class":1090},"    raw, err ",[1084,4101,1791],{"class":1097},[1084,4103,4104],{"class":1090}," io.",[1084,4106,4107],{"class":1405},"ReadAll",[1084,4109,4110],{"class":1090},"(r.Body) ",[1084,4112,4113],{"class":1439},"\u002F\u002F the bytes, before any JSON decoding\n",[1084,4115,4116,4118,4120,4122,4124],{"class":1086,"line":1112},[1084,4117,2777],{"class":1097},[1084,4119,1944],{"class":1090},[1084,4121,1947],{"class":1097},[1084,4123,1950],{"class":1177},[1084,4125,1953],{"class":1090},[1084,4127,4128,4131,4134],{"class":1086,"line":1136},[1084,4129,4130],{"class":1090},"        w.",[1084,4132,4133],{"class":1405},"WriteHeader",[1084,4135,4136],{"class":1090},"(http.StatusBadRequest)\n",[1084,4138,4139],{"class":1086,"line":1149},[1084,4140,4141],{"class":1097},"        return\n",[1084,4143,4144],{"class":1086,"line":1162},[1084,4145,3056],{"class":1090},[1084,4147,4148,4151,4154],{"class":1086,"line":1200},[1084,4149,4150],{"class":1090},"    mu.",[1084,4152,4153],{"class":1405},"Lock",[1084,4155,3851],{"class":1090},[1084,4157,4158,4161,4163],{"class":1086,"line":1213},[1084,4159,4160],{"class":1090},"    key ",[1084,4162,1791],{"class":1097},[1084,4164,4165],{"class":1090}," secret\n",[1084,4167,4168,4170,4173],{"class":1086,"line":1235},[1084,4169,4150],{"class":1090},[1084,4171,4172],{"class":1405},"Unlock",[1084,4174,3851],{"class":1090},[1084,4176,4177,4180,4182,4185,4188,4191,4194],{"class":1086,"line":1248},[1084,4178,4179],{"class":1090},"    event, err ",[1084,4181,1791],{"class":1097},[1084,4183,4184],{"class":1090}," webhooks.",[1084,4186,4187],{"class":1405},"ConstructEvent",[1084,4189,4190],{"class":1090},"(raw, r.Header.",[1084,4192,4193],{"class":1405},"Get",[1084,4195,4196],{"class":1090},"(webhooks.SignatureHeader), key)\n",[1084,4198,4199,4201,4203,4205,4207],{"class":1086,"line":1259},[1084,4200,2777],{"class":1097},[1084,4202,1944],{"class":1090},[1084,4204,1947],{"class":1097},[1084,4206,1950],{"class":1177},[1084,4208,1953],{"class":1090},[1084,4210,4211,4213,4215],{"class":1086,"line":1971},[1084,4212,4130],{"class":1090},[1084,4214,4133],{"class":1405},[1084,4216,4217],{"class":1090},"(http.StatusUnauthorized)\n",[1084,4219,4220,4223,4225,4227,4229,4231,4233],{"class":1086,"line":1988},[1084,4221,4222],{"class":1090},"        log.",[1084,4224,2068],{"class":1405},[1084,4226,1732],{"class":1090},[1084,4228,3863],{"class":1105},[1084,4230,2954],{"class":1177},[1084,4232,1627],{"class":1105},[1084,4234,4235],{"class":1090},", err)\n",[1084,4237,4238],{"class":1086,"line":2001},[1084,4239,4141],{"class":1097},[1084,4241,4242],{"class":1086,"line":2010},[1084,4243,3056],{"class":1090},[1084,4245,4246,4249,4251,4254],{"class":1086,"line":2015},[1084,4247,4248],{"class":1090},"    w.",[1084,4250,4133],{"class":1405},[1084,4252,4253],{"class":1090},"(http.StatusNoContent) ",[1084,4255,3501],{"class":1439},[1084,4257,4258,4260,4262],{"class":1086,"line":2026},[1084,4259,4150],{"class":1090},[1084,4261,4153],{"class":1405},[1084,4263,3851],{"class":1090},[1084,4265,4266,4269,4272,4274],{"class":1086,"line":2040},[1084,4267,4268],{"class":1097},"    defer",[1084,4270,4271],{"class":1090}," mu.",[1084,4273,4172],{"class":1405},[1084,4275,3851],{"class":1090},[1084,4277,4278,4280,4283],{"class":1086,"line":2057},[1084,4279,2777],{"class":1097},[1084,4281,4282],{"class":1097}," !",[1084,4284,4285],{"class":1090},"seen[event.ID] {\n",[1084,4287,4288,4291,4293],{"class":1086,"line":2062},[1084,4289,4290],{"class":1090},"        seen[event.ID] ",[1084,4292,1601],{"class":1097},[1084,4294,4295],{"class":1177}," true\n",[1084,4297,4298,4300,4302,4304,4306,4308,4310,4312],{"class":1086,"line":3669},[1084,4299,3038],{"class":1090},[1084,4301,2068],{"class":1405},[1084,4303,1732],{"class":1090},[1084,4305,3960],{"class":1105},[1084,4307,2075],{"class":1177},[1084,4309,2083],{"class":1177},[1084,4311,2090],{"class":1105},[1084,4313,4314],{"class":1090},", event.Type, event.ID)\n",[1084,4316,4317,4320,4323],{"class":1086,"line":3675},[1084,4318,4319],{"class":1090},"        received ",[1084,4321,4322],{"class":1097},"\u003C-",[1084,4324,4325],{"class":1090}," event.Type\n",[1084,4327,4329],{"class":1086,"line":4328},23,[1084,4330,3056],{"class":1090},[1084,4332,4334],{"class":1086,"line":4333},24,[1084,4335,1936],{"class":1090},[1025,4337,4338],{},"A webhook never carries the job's data, only where to read it, so the price itself comes from the\nAPI with your key.",[1029,4340,4342],{"id":4341},"pitfalls","Pitfalls",[1040,4344,4345,4357,4371,4383,4395,4404],{},[1043,4346,4347,4350,4351,4353,4354,4356],{},[1062,4348,4349],{},"Watch the fields that matter."," Without ",[1047,4352,642],{},", every value in ",[1047,4355,1336],{}," counts, including ones\nthat change on every load (a timestamp, a \"viewed by\" counter), and every run reports a change.",[1043,4358,4359,4362,4363,2417,4365,4367,4368,4370],{},[1062,4360,4361],{},"A failed run is not a change."," Change detection only compares successful runs; a failure sends\n",[1047,4364,2334],{},[1047,4366,2420],{},", and five in a row ",[1047,4369,2424],{},". Subscribe to both if a\nsilent schedule would hurt.",[1043,4372,4373,4376,4377,4379,4380,4382],{},[1062,4374,4375],{},"The diff link expires."," ",[1047,4378,2325],{}," itself is permanent, but the ",[1047,4381,2350],{}," it answers points at a\nlink valid for 15 minutes. Follow it when you need it rather than storing the redirect.",[1043,4384,4385,4376,4391,4394],{},[1062,4386,4387,4390],{},[1047,4388,4389],{},"queue"," can pile up.",[1047,4392,4393],{},"overlap_policy: \"queue\""," starts a new job even when the previous one is\nstill running; on a slow site and a tight cron, jobs accumulate.",[1043,4396,4397,4400,4401,1070],{},[1062,4398,4399],{},"Delete schedules before programs."," A program cannot be deleted while a schedule points at it\n(",[1047,4402,4403],{},"409 program_has_schedules",[1043,4405,4406,4409,4410,4412],{},[1062,4407,4408],{},"Out of credits pauses everything."," Every active schedule pauses with ",[1047,4411,2238],{}," and\nresumes when credits arrive. A schedule you paused by hand is not resumed with them.",[1029,4414,155],{"id":4415},"reference",[2163,4417,4418,4430],{},[2166,4419,4420],{},[2169,4421,4422,4425,4428],{},[2172,4423,4424],{},"Endpoint",[2172,4426,4427],{},"Scope",[2172,4429],{},[2179,4431,4432,4452,4474,4490,4516,4535,4551,4571,4588],{},[2169,4433,4434,4442,4446],{},[2184,4435,4436],{},[1066,4437,4439],{"href":4438},"\u002Freference\u002Fapi\u002Fschedules\u002Fcreate-schedule",[1047,4440,4441],{},"POST \u002Fschedules",[2184,4443,4444],{},[1047,4445,2539],{},[2184,4447,4448,4451],{},[1047,4449,4450],{},"201"," the schedule",[2169,4453,4454,4462,4466],{},[2184,4455,4456],{},[1066,4457,4459],{"href":4458},"\u002Freference\u002Fapi\u002Fschedules\u002Flist-schedules",[1047,4460,4461],{},"GET \u002Fschedules",[2184,4463,4464],{},[1047,4465,3746],{},[2184,4467,4468,4469,1274,4471,4473],{},"filters ",[1047,4470,2420],{},[1047,4472,489],{},"; cursor pagination",[2169,4475,4476,4484,4488],{},[2184,4477,4478],{},[1066,4479,4481],{"href":4480},"\u002Freference\u002Fapi\u002Fschedules\u002Fget-schedule",[1047,4482,4483],{},"GET \u002Fschedules\u002F{id}",[2184,4485,4486],{},[1047,4487,3746],{},[2184,4489],{},[2169,4491,4492,4500,4504],{},[2184,4493,4494],{},[1066,4495,4497],{"href":4496},"\u002Freference\u002Fapi\u002Fschedules\u002Fupdate-schedule",[1047,4498,4499],{},"PATCH \u002Fschedules\u002F{id}",[2184,4501,4502],{},[1047,4503,2539],{},[2184,4505,4506,4507,4509,4510,4512,4513],{},"a new ",[1047,4508,1309],{}," or ",[1047,4511,737],{}," recomputes ",[1047,4514,4515],{},"next_run_at",[2169,4517,4518,4526,4530],{},[2184,4519,4520],{},[1066,4521,4523],{"href":4522},"\u002Freference\u002Fapi\u002Fschedules\u002Fdelete-schedule",[1047,4524,4525],{},"DELETE \u002Fschedules\u002F{id}",[2184,4527,4528],{},[1047,4529,2539],{},[2184,4531,4532,4534],{},[1047,4533,3489],{},"; its run history goes with it",[2169,4536,4537,4545,4549],{},[2184,4538,4539],{},[1066,4540,4542],{"href":4541},"\u002Freference\u002Fapi\u002Fschedules\u002Fpause-schedule",[1047,4543,4544],{},"POST \u002Fschedules\u002F{id}\u002Fpause",[2184,4546,4547],{},[1047,4548,2539],{},[2184,4550],{},[2169,4552,4553,4561,4565],{},[2184,4554,4555],{},[1066,4556,4558],{"href":4557},"\u002Freference\u002Fapi\u002Fschedules\u002Fresume-schedule",[1047,4559,4560],{},"POST \u002Fschedules\u002F{id}\u002Fresume",[2184,4562,4563],{},[1047,4564,2539],{},[2184,4566,4567,4570],{},[1047,4568,4569],{},"402"," while out of credits",[2169,4572,4573,4581,4585],{},[2184,4574,4575],{},[1066,4576,4578],{"href":4577},"\u002Freference\u002Fapi\u002Fschedules\u002Flist-schedule-runs",[1047,4579,4580],{},"GET \u002Fschedules\u002F{id}\u002Fruns",[2184,4582,4583],{},[1047,4584,3746],{},[2184,4586,4587],{},"every fire, skipped ones included",[2169,4589,4590,4598,4602],{},[2184,4591,4592],{},[1066,4593,4595],{"href":4594},"\u002Freference\u002Fapi\u002Fschedules\u002Fget-schedule-run-diff",[1047,4596,4597],{},"GET \u002Fschedules\u002F{id}\u002Fruns\u002F{job_id}\u002Fdiff",[2184,4599,4600],{},[1047,4601,3746],{},[2184,4603,4604,4606],{},[1047,4605,2350],{}," to the patch, valid 15 minutes",[1040,4608,4609,4626,4639],{},[1043,4610,4611,1274,4615,2157,4618,1109,4620,1274,4622,1274,4624,3492],{},[1066,4612,4614],{"href":4613},"\u002Freference\u002Fapi\u002Fschemas\u002Fschedule","Schedule schema",[1066,4616,839],{"href":4617},"\u002Freference\u002Fevents",[1047,4619,2334],{},[1047,4621,1362],{},[1047,4623,2238],{},[1047,4625,2424],{},[1043,4627,4628,4629,1109,4634],{},"CLI: ",[1066,4630,4632],{"href":4631},"\u002Freference\u002Fcli\u002Fkaab-schedules-create",[1047,4633,956],{},[1066,4635,4637],{"href":4636},"\u002Freference\u002Fcli\u002Fkaab-schedules-runs",[1047,4638,968],{},[1043,4640,4641,4644],{},[1066,4642,4643],{"href":2104},"Plans"," for each plan's minimum interval",[4646,4647,4648],"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 .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)}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 .sIH4l, html code.shiki .sIH4l{--shiki-light:var(--kaab-code-token-parameter);--shiki-default:var(--kaab-code-token-parameter);--shiki-dark:var(--kaab-code-token-parameter)}",{"title":1080,"searchDepth":1112,"depth":1112,"links":4650},[4651,4652,4655,4656,4660,4661,4662],{"id":1031,"depth":1094,"text":1032},{"id":1073,"depth":1094,"text":1074,"children":4653},[4654],{"id":2097,"depth":1112,"text":2098},{"id":2134,"depth":1094,"text":2135},{"id":2293,"depth":1094,"text":2294,"children":4657},[4658,4659],{"id":2410,"depth":1112,"text":2411},{"id":2432,"depth":1112,"text":2433},{"id":3086,"depth":1094,"text":3087},{"id":4341,"depth":1094,"text":4342},{"id":4415,"depth":1094,"text":155},false,null,"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.","md",{},"\u002Fguides\u002Fschedules-and-change-detection",{"title":101,"description":4665},"3.guides\u002F05.schedules-and-change-detection","qVJLlD4uThia19LNUxuWBu4StlS89TK_YV0QH9gedj4",[4673,4677],{"title":98,"path":4674,"stem":4675,"description":4676,"children":-1},"\u002Fguides\u002Fjson-and-network-locators","3.guides\u002F04.json-and-network-locators","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.",{"title":104,"path":1366,"stem":4678,"description":4679,"children":-1},"3.guides\u002F06.webhooks","How Kaabist tells your systems that something happened: the events, the signature, retries, ordering and how to receive them safely.",1793593416127]