[{"data":1,"prerenderedAt":2405},["ShallowReactive",2],{"navigation":3,"page:\u002Fgetting-started\u002Fkeys-and-modes":1019,"surround:\u002Fgetting-started\u002Fkeys-and-modes":2397},[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":13,"body":1021,"breaking":2388,"date":2389,"description":2390,"extension":2391,"generated":2388,"meta":2392,"navigation":2017,"path":2393,"seo":2394,"stem":2395,"version":2389,"__hash__":2396},"docs\u002F1.getting-started\u002F02.keys-and-modes.md",{"type":1022,"value":1023,"toc":2366},"minimark",[1024,1028,1033,1045,1049,1058,1077,1081,1105,1116,1120,1173,1180,1184,1187,1269,1276,1280,1308,1312,1330,1334,1348,1352,1356,1397,1401,1404,1503,1520,1554,1564,1568,1601,1605,1626,1647,1651,1658,1673,1687,1691,1771,1775,1782,1929,1932,2244,2254,2258,2314,2317,2362],[1025,1026,1027],"p",{},"Every request to the Kaabist API carries a key, and the key decides which organisation the request acts for, what it may do, and whether its jobs are live or test. The conventions on this page (errors, pagination, idempotency, waiting and response headers) are the same on every endpoint, so you read them once.",[1029,1030,1032],"h2",{"id":1031},"when-to-use-it","When to use it",[1025,1034,1035,1036,1040,1041,1044],{},"Read this page before you write a client. Use an ",[1037,1038,1039],"code",{},"sk_test_"," key while you develop and in CI, and an ",[1037,1042,1043],{},"sk_live_"," key with the narrowest scope that works in production. If you use an SDK or the CLI, most of the conventions below are handled for you; the error codes and the meaning of each mode still apply.",[1029,1046,1048],{"id":1047},"the-base-url","The base URL",[1050,1051,1056],"pre",{"className":1052,"code":1054,"language":622,"meta":1055},[1053],"language-text","https:\u002F\u002Fapi.kaab.ist\u002Fv1\n","",[1037,1057,1054],{"__ignoreMap":1055},[1025,1059,1060,1061,1064,1065,1068,1069,1072,1073,1076],{},"JSON in, JSON out, ",[1037,1062,1063],{},"snake_case"," keys, UTF-8, timestamps in ISO-8601 UTC (",[1037,1066,1067],{},"2026-09-18T10:00:00Z",") and durations in milliseconds unless the key ends in ",[1037,1070,1071],{},"_seconds",". The OpenAPI document every SDK is generated from is served at ",[1037,1074,1075],{},"GET \u002Fv1\u002Fopenapi.json",".",[1029,1078,1080],{"id":1079},"authenticating","Authenticating",[1050,1082,1086],{"className":1083,"code":1084,"language":1085,"meta":1055,"style":1055},"language-http shiki shiki-themes kaab-code kaab-code kaab-code","Authorization: Bearer sk_test_…\n","http",[1037,1087,1088],{"__ignoreMap":1055},[1089,1090,1093,1097,1101],"span",{"class":1091,"line":1092},"line",1,[1089,1094,1096],{"class":1095},"suOy4","Authorization",[1089,1098,1100],{"class":1099},"sqn18",":",[1089,1102,1104],{"class":1103},"sx8Bj"," Bearer sk_test_…\n",[1025,1106,1107,1108,1112,1113,1076],{},"A key belongs to one organisation and carries a ",[1109,1110,1111],"strong",{},"mode"," and one or more ",[1109,1114,1115],{},"scopes",[1117,1118,1119],"h3",{"id":1115},"Scopes",[1121,1122,1123,1136],"table",{},[1124,1125,1126],"thead",{},[1127,1128,1129,1133],"tr",{},[1130,1131,1132],"th",{},"Scope",[1130,1134,1135],{},"Allows",[1137,1138,1139,1150,1163],"tbody",{},[1127,1140,1141,1147],{},[1142,1143,1144],"td",{},[1037,1145,1146],{},"read",[1142,1148,1149],{},"every read: jobs, programs, sessions, proposals, schedules, usage",[1127,1151,1152,1157],{},[1142,1153,1154],{},[1037,1155,1156],{},"run",[1142,1158,1159,1160,1162],{},"everything ",[1037,1161,1146],{}," allows, plus creating and acting on jobs, programs, aliases, proposals, sessions and schedules",[1127,1164,1165,1170],{},[1142,1166,1167],{},[1037,1168,1169],{},"admin",[1142,1171,1172],{},"everything a key can do, including keys, webhooks, bring-your-own providers, organisation settings and deleting a program",[1025,1174,1175,1176,1179],{},"A request outside the key's scopes is ",[1037,1177,1178],{},"403",". No key can delete an organisation or manage its members; those are for people, in the panel.",[1117,1181,1183],{"id":1182},"modes","Modes",[1025,1185,1186],{},"The prefix is the mode, and a request cannot override it: you change mode by using a different key.",[1121,1188,1189,1205],{},[1124,1190,1191],{},[1127,1192,1193,1195,1200],{},[1130,1194],{},[1130,1196,1197],{},[1037,1198,1199],{},"sk_live_…",[1130,1201,1202],{},[1037,1203,1204],{},"sk_test_…",[1137,1206,1207,1218,1228,1243,1254],{},[1127,1208,1209,1212,1215],{},[1142,1210,1211],{},"Execution",[1142,1213,1214],{},"real",[1142,1216,1217],{},"real: the same engine, tiers and sites",[1127,1219,1220,1222,1225],{},[1142,1221,390],{},[1142,1223,1224],{},"reserved and settled",[1142,1226,1227],{},"none reserved",[1127,1229,1230,1233,1236],{},[1142,1231,1232],{},"Limit",[1142,1234,1235],{},"your credits and plan",[1142,1237,1238,1239,1242],{},"a daily number of jobs per plan, counted per UTC day (",[1037,1240,1241],{},"429 test_quota_exceeded",")",[1127,1244,1245,1248,1251],{},[1142,1246,1247],{},"Results kept",[1142,1249,1250],{},"your plan's retention",[1142,1252,1253],{},"24 hours",[1127,1255,1256,1259,1264],{},[1142,1257,1258],{},"Events and webhooks",[1142,1260,1261],{},[1037,1262,1263],{},"mode: \"live\"",[1142,1265,1266],{},[1037,1267,1268],{},"mode: \"test\"",[1025,1270,1271,1272,1076],{},"A schedule created with a test key runs test jobs. The daily test quota for each plan is on ",[1273,1274,59],"a",{"href":1275},"\u002Fconcepts\u002Flimits",[1117,1277,1279],{"id":1278},"creating-a-key","Creating a key",[1025,1281,1282,1283,1286,1287,1290,1291,1293,1294,1297,1298,1301,1302,1304,1305,1307],{},"Create keys in the panel, or with ",[1037,1284,1285],{},"POST \u002Fv1\u002Fapi-keys"," and ",[1037,1288,1289],{},"{ \"name\", \"scopes\", \"mode\", \"expires_at\" }"," using an ",[1037,1292,1169],{}," key. The answer contains the key once, in ",[1037,1295,1296],{},"key",". Kaabist stores only a hash of it and its first twelve characters (",[1037,1299,1300],{},"sk_live_ab12","), which is what every later read and the panel show. A key may create keys of its own mode only, and only an owner, an admin or an ",[1037,1303,1169],{}," key may grant the ",[1037,1306,1169],{}," scope.",[1117,1309,1311],{"id":1310},"rotating-a-key","Rotating a key",[1025,1313,1314,1317,1318,1321,1322,1325,1326,1329],{},[1037,1315,1316],{},"POST \u002Fv1\u002Fapi-keys\u002F{id}\u002Frotate"," with ",[1037,1319,1320],{},"{ \"grace_seconds\": 3600 }"," issues a new key with the same name, scopes, mode and expiry, and keeps the old one working until the grace period ends, at most a day (",[1037,1323,1324],{},"86400","). Move your clients to the new key inside that window. ",[1037,1327,1328],{},"grace_seconds: 0"," cuts the old key off at once.",[1117,1331,1333],{"id":1332},"revoking-and-expiry","Revoking and expiry",[1025,1335,1336,1339,1340,1343,1344,1347],{},[1037,1337,1338],{},"DELETE \u002Fv1\u002Fapi-keys\u002F{id}"," stops a key immediately, including one in its grace period after a rotation. A key created with ",[1037,1341,1342],{},"expires_at"," stops at that instant; in its last week, every response to it carries ",[1037,1345,1346],{},"X-Kaab-Key-Expires"," with the expiry, so a client can warn before it breaks.",[1029,1349,1351],{"id":1350},"conventions","Conventions",[1117,1353,1355],{"id":1354},"ids","IDs",[1025,1357,1358,1359,1362,1363,1366,1367,1370,1371,1374,1375,1378,1379,1382,1383,1386,1387,1362,1390,1362,1393,1396],{},"Every object has a prefixed, opaque id: ",[1037,1360,1361],{},"job_…",", ",[1037,1364,1365],{},"prg_…"," (program), ",[1037,1368,1369],{},"pv_…"," (program version), ",[1037,1372,1373],{},"ses_…"," (session), ",[1037,1376,1377],{},"prp_…"," (proposal), ",[1037,1380,1381],{},"sch_…"," (schedule), ",[1037,1384,1385],{},"whk_…"," (webhook), ",[1037,1388,1389],{},"key_…",[1037,1391,1392],{},"byo_…",[1037,1394,1395],{},"bat_…"," (batch). Treat them as strings; do not parse them.",[1117,1398,1400],{"id":1399},"errors","Errors",[1025,1402,1403],{},"Every non-2xx answer has the same shape:",[1050,1405,1408],{"className":1406,"code":1407,"language":680,"meta":1055,"style":1055},"language-json shiki shiki-themes kaab-code kaab-code kaab-code","{\n  \"error\": {\n    \"code\": \"insufficient_credits\",\n    \"message\": \"this job reserves 12 credits and the organisation does not have them\",\n    \"details\": { \"required\": 12 },\n    \"request_id\": \"req_01J…\"\n  }\n}\n",[1037,1409,1410,1416,1428,1442,1455,1480,1491,1497],{"__ignoreMap":1055},[1089,1411,1412],{"class":1091,"line":1092},[1089,1413,1415],{"class":1414},"sTzsn","{\n",[1089,1417,1419,1422,1425],{"class":1091,"line":1418},2,[1089,1420,1421],{"class":1099},"  \"error\"",[1089,1423,1100],{"class":1424},"sQm2-",[1089,1426,1427],{"class":1414}," {\n",[1089,1429,1431,1434,1436,1439],{"class":1091,"line":1430},3,[1089,1432,1433],{"class":1099},"    \"code\"",[1089,1435,1100],{"class":1424},[1089,1437,1438],{"class":1095}," \"insufficient_credits\"",[1089,1440,1441],{"class":1424},",\n",[1089,1443,1445,1448,1450,1453],{"class":1091,"line":1444},4,[1089,1446,1447],{"class":1099},"    \"message\"",[1089,1449,1100],{"class":1424},[1089,1451,1452],{"class":1095}," \"this job reserves 12 credits and the organisation does not have them\"",[1089,1454,1441],{"class":1424},[1089,1456,1458,1461,1463,1466,1469,1471,1475,1478],{"class":1091,"line":1457},5,[1089,1459,1460],{"class":1099},"    \"details\"",[1089,1462,1100],{"class":1424},[1089,1464,1465],{"class":1414}," { ",[1089,1467,1468],{"class":1099},"\"required\"",[1089,1470,1100],{"class":1424},[1089,1472,1474],{"class":1473},"sHJIl"," 12",[1089,1476,1477],{"class":1414}," }",[1089,1479,1441],{"class":1424},[1089,1481,1483,1486,1488],{"class":1091,"line":1482},6,[1089,1484,1485],{"class":1099},"    \"request_id\"",[1089,1487,1100],{"class":1424},[1089,1489,1490],{"class":1095}," \"req_01J…\"\n",[1089,1492,1494],{"class":1091,"line":1493},7,[1089,1495,1496],{"class":1414},"  }\n",[1089,1498,1500],{"class":1091,"line":1499},8,[1089,1501,1502],{"class":1414},"}\n",[1025,1504,1505,1507,1508,1511,1512,1515,1516,1519],{},[1037,1506,1037],{}," is from a closed set, so switching on it is safe; ",[1037,1509,1510],{},"message"," is for a person; ",[1037,1513,1514],{},"request_id"," is what to quote when you contact support. Two codes carry structured ",[1037,1517,1518],{},"details"," worth handling:",[1521,1522,1523,1538],"ul",{},[1524,1525,1526,1529,1530,1533,1534,1537],"li",{},[1037,1527,1528],{},"request_invalid"," (400): ",[1037,1531,1532],{},"details.issues[]"," of ",[1037,1535,1536],{},"{ path, message }",";",[1524,1539,1540,1543,1544,1286,1547,1550,1551,1553],{},[1037,1541,1542],{},"program_invalid"," (422): ",[1037,1545,1546],{},"details.errors[]",[1037,1548,1549],{},"details.warnings[]"," in the lint vocabulary (",[1037,1552,772],{},"), each with the path inside your program.",[1025,1555,1556,1559,1560,1076],{},[1037,1557,1558],{},"not_implemented"," (501) marks an operation that is documented but not yet available; the set of such operations only shrinks. The full list is under ",[1273,1561,1563],{"href":1562},"\u002Freference\u002Fcodes#errors","error codes",[1117,1565,1567],{"id":1566},"pagination","Pagination",[1025,1569,1570,1571,1574,1575,1578,1579,1582,1583,1586,1587,1590,1591,1362,1594,1286,1597,1600],{},"List endpoints take ",[1037,1572,1573],{},"?limit="," (1 to 100, default 25) and ",[1037,1576,1577],{},"?cursor=",", and answer ",[1037,1580,1581],{},"{ \"data\": [...], \"next_cursor\": \"…\" }",", newest first, by creation time and then id: rows created together, such as a batch's jobs, page completely. The cursor is opaque. Pass ",[1037,1584,1585],{},"next_cursor"," back until it is ",[1037,1588,1589],{},"null",". Filters such as ",[1037,1592,1593],{},"created_after",[1037,1595,1596],{},"created_before",[1037,1598,1599],{},"status"," narrow the query itself, so a page is never emptied by a filter. The SDKs iterate across pages for you.",[1117,1602,1604],{"id":1603},"idempotency","Idempotency",[1025,1606,1607,1286,1610,1613,1614,1617,1618,1621,1622,1625],{},[1037,1608,1609],{},"POST \u002Fv1\u002Fjobs",[1037,1611,1612],{},"POST \u002Fv1\u002Fjobs\u002Fbatch"," accept ",[1037,1615,1616],{},"Idempotency-Key"," (up to 255 characters). Within 24 hours, the same key with the same body returns the original response with ",[1037,1619,1620],{},"Idempotent-Replayed: true","; the same key with a different body is ",[1037,1623,1624],{},"409 idempotency_conflict",". Use one key per logical piece of work (an order id, a row id, a date) and retry as often as you need. The SDKs send one on every job creation.",[1025,1627,1628,1629,1631,1632,1634,1635,1638,1639,1642,1643,1646],{},"Keys are scoped to your organisation and the key's mode: a test key and a live key that send the same ",[1037,1630,1616],{}," each get a job of their own. A key used for a single job cannot be reused for a batch, or the other way round (",[1037,1633,1624],{},"). A retry that is recognised as a replay spends nothing: it is never refused for credits (",[1037,1636,1637],{},"402",") or for the test-mode daily quota (",[1037,1640,1641],{},"429","), and a retried batch returns the same ",[1037,1644,1645],{},"bat_"," id without creating or reserving anything again.",[1117,1648,1650],{"id":1649},"waiting-for-a-job","Waiting for a job",[1025,1652,1653,1654,1657],{},"Job creation is asynchronous and answers ",[1037,1655,1656],{},"202",". To block instead of polling, send:",[1050,1659,1661],{"className":1083,"code":1660,"language":1085,"meta":1055,"style":1055},"Prefer: wait=30\n",[1037,1662,1663],{"__ignoreMap":1055},[1089,1664,1665,1668,1670],{"class":1091,"line":1092},[1089,1666,1667],{"class":1095},"Prefer",[1089,1669,1100],{"class":1099},[1089,1671,1672],{"class":1103}," wait=30\n",[1025,1674,1675,1676,1679,1680,1682,1683,1686],{},"The value is 1 to 60 seconds. You get ",[1037,1677,1678],{},"200"," with the finished envelope if the job settles in time, and ",[1037,1681,1656],{}," with its current state if it does not. A job that parks has settled: it is in a state you can act on. The same header on ",[1037,1684,1685],{},"GET \u002Fv1\u002Fjobs\u002F{id}"," long-polls until the status changes; a job that has already finished is answered at once.",[1117,1688,1690],{"id":1689},"headers-on-every-response","Headers on every response",[1121,1692,1693,1703],{},[1124,1694,1695],{},[1127,1696,1697,1700],{},[1130,1698,1699],{},"Header",[1130,1701,1702],{},"Meaning",[1137,1704,1705,1715,1725,1735,1745,1755],{},[1127,1706,1707,1712],{},[1142,1708,1709],{},[1037,1710,1711],{},"X-Kaab-Request-Id",[1142,1713,1714],{},"this request's id; send your own and Kaabist uses it",[1127,1716,1717,1722],{},[1142,1718,1719],{},[1037,1720,1721],{},"X-Credits-Remaining",[1142,1723,1724],{},"the organisation's available balance, cached for up to 10 seconds",[1127,1726,1727,1732],{},[1142,1728,1729],{},[1037,1730,1731],{},"X-RateLimit-Limit",[1142,1733,1734],{},"requests a minute in the bucket this request was judged by",[1127,1736,1737,1742],{},[1142,1738,1739],{},[1037,1740,1741],{},"X-RateLimit-Remaining",[1142,1743,1744],{},"requests left in that bucket",[1127,1746,1747,1752],{},[1142,1748,1749],{},[1037,1750,1751],{},"X-RateLimit-Reset",[1142,1753,1754],{},"the Unix second at which the bucket is full again",[1127,1756,1757,1762],{},[1142,1758,1759],{},[1037,1760,1761],{},"Retry-After",[1142,1763,1764,1765,1286,1767,1770],{},"on ",[1037,1766,1641],{},[1037,1768,1769],{},"503",": seconds to wait before retrying",[1029,1772,1774],{"id":1773},"worked-example","Worked example",[1025,1776,1777,1778,1781],{},"With a test key in ",[1037,1779,1780],{},"KAAB_API_KEY",", this runs a real job against a product page and shows that it was a test job, which reserved nothing:",[1783,1784,1785],"code-group",{},[1050,1786,1791],{"className":1787,"code":1788,"filename":1789,"language":1790,"meta":1055,"style":1055},"language-ts shiki shiki-themes kaab-code kaab-code kaab-code","\u002F\u002F The key decides the mode: an sk_test_ key runs test jobs, which the live data never sees.\nconst probe = await kaab.jobs.create({\n  url: `${site}\u002Fp\u002F1`,\n  extract: { title: \"h1\" },\n  wait: 30,\n});\nconsole.log(`${probe.id} ran in ${probe.mode} mode`);\n","TypeScript","ts",[1037,1792,1793,1799,1827,1851,1870,1882,1887],{"__ignoreMap":1055},[1089,1794,1795],{"class":1091,"line":1092},[1089,1796,1798],{"class":1797},"sKog0","\u002F\u002F The key decides the mode: an sk_test_ key runs test jobs, which the live data never sees.\n",[1089,1800,1801,1804,1807,1810,1813,1816,1819,1821,1824],{"class":1091,"line":1418},[1089,1802,1803],{"class":1099},"const",[1089,1805,1806],{"class":1473}," probe",[1089,1808,1809],{"class":1099}," =",[1089,1811,1812],{"class":1099}," await",[1089,1814,1815],{"class":1473}," kaab",[1089,1817,1076],{"class":1818},"sJugJ",[1089,1820,171],{"class":1473},[1089,1822,1823],{"class":1818},".create",[1089,1825,1826],{"class":1414},"({\n",[1089,1828,1829,1832,1834,1837,1840,1843,1846,1849],{"class":1091,"line":1430},[1089,1830,1831],{"class":1414},"  url",[1089,1833,1100],{"class":1099},[1089,1835,1836],{"class":1095}," `",[1089,1838,1839],{"class":1099},"${",[1089,1841,1842],{"class":1414},"site",[1089,1844,1845],{"class":1099},"}",[1089,1847,1848],{"class":1095},"\u002Fp\u002F1`",[1089,1850,1441],{"class":1424},[1089,1852,1853,1856,1858,1861,1863,1866,1868],{"class":1091,"line":1444},[1089,1854,1855],{"class":1414},"  extract",[1089,1857,1100],{"class":1099},[1089,1859,1860],{"class":1414}," { title",[1089,1862,1100],{"class":1099},[1089,1864,1865],{"class":1095}," \"h1\"",[1089,1867,1477],{"class":1414},[1089,1869,1441],{"class":1424},[1089,1871,1872,1875,1877,1880],{"class":1091,"line":1457},[1089,1873,1874],{"class":1414},"  wait",[1089,1876,1100],{"class":1099},[1089,1878,1879],{"class":1473}," 30",[1089,1881,1441],{"class":1424},[1089,1883,1884],{"class":1091,"line":1482},[1089,1885,1886],{"class":1414},"});\n",[1089,1888,1889,1892,1895,1898,1901,1903,1906,1909,1911,1914,1916,1918,1921,1923,1926],{"class":1091,"line":1493},[1089,1890,1891],{"class":1473},"console",[1089,1893,1894],{"class":1818},".log",[1089,1896,1897],{"class":1414},"(",[1089,1899,1900],{"class":1095},"`",[1089,1902,1839],{"class":1099},[1089,1904,1905],{"class":1473},"probe",[1089,1907,1908],{"class":1414},".id",[1089,1910,1845],{"class":1099},[1089,1912,1913],{"class":1095}," ran in ",[1089,1915,1839],{"class":1099},[1089,1917,1905],{"class":1473},[1089,1919,1920],{"class":1414},".mode",[1089,1922,1845],{"class":1099},[1089,1924,1925],{"class":1095}," mode`",[1089,1927,1928],{"class":1414},");\n",[1025,1930,1931],{},"And this creates a job with an idempotency key, sends the same request again, and gets the first job back rather than a second one:",[1783,1933,1934],{},[1050,1935,1937],{"className":1787,"code":1936,"filename":1789,"language":1790,"meta":1055,"style":1055},"\u002F\u002F One key per order you mean to place; store it with the order on your side.\nconst idempotencyKey = `order-${name}`;\nconst request = { program: name, inputs: { sku: \"HP-1037\", qty: 2 } };\n\nconst first = await kaab.jobs.create({ ...request, idempotencyKey });\n\u002F\u002F A retry (after a timeout, a crash, a deploy) sends the same key and the same body…\nconst again = await kaab.jobs.create({ ...request, idempotencyKey });\n\u002F\u002F …and gets the same job back: nothing new is queued, no second order.\nconsole.log(`${first.id} === ${again.id}: ${first.id === again.id}`);\n\nconst done = await kaab.jobs.wait(first.id, { timeoutMs: 120_000 });\nconsole.log(`${done.id}: ${done.status} ${JSON.stringify(done.data)}`);\n",[1037,1938,1939,1944,1967,2013,2019,2052,2057,2086,2091,2146,2151,2191],{"__ignoreMap":1055},[1089,1940,1941],{"class":1091,"line":1092},[1089,1942,1943],{"class":1797},"\u002F\u002F One key per order you mean to place; store it with the order on your side.\n",[1089,1945,1946,1948,1951,1953,1956,1958,1960,1962,1964],{"class":1091,"line":1418},[1089,1947,1803],{"class":1099},[1089,1949,1950],{"class":1473}," idempotencyKey",[1089,1952,1809],{"class":1099},[1089,1954,1955],{"class":1095}," `order-",[1089,1957,1839],{"class":1099},[1089,1959,702],{"class":1414},[1089,1961,1845],{"class":1099},[1089,1963,1900],{"class":1095},[1089,1965,1966],{"class":1414},";\n",[1089,1968,1969,1971,1974,1976,1979,1981,1984,1987,1990,1992,1995,1997,2000,2002,2005,2007,2010],{"class":1091,"line":1430},[1089,1970,1803],{"class":1099},[1089,1972,1973],{"class":1473}," request",[1089,1975,1809],{"class":1099},[1089,1977,1978],{"class":1414}," { program",[1089,1980,1100],{"class":1099},[1089,1982,1983],{"class":1414}," name",[1089,1985,1986],{"class":1424},",",[1089,1988,1989],{"class":1414}," inputs",[1089,1991,1100],{"class":1099},[1089,1993,1994],{"class":1414}," { sku",[1089,1996,1100],{"class":1099},[1089,1998,1999],{"class":1095}," \"HP-1037\"",[1089,2001,1986],{"class":1424},[1089,2003,2004],{"class":1414}," qty",[1089,2006,1100],{"class":1099},[1089,2008,2009],{"class":1473}," 2",[1089,2011,2012],{"class":1414}," } };\n",[1089,2014,2015],{"class":1091,"line":1444},[1089,2016,2018],{"emptyLinePlaceholder":2017},true,"\n",[1089,2020,2021,2023,2026,2028,2030,2032,2034,2036,2038,2041,2044,2047,2049],{"class":1091,"line":1457},[1089,2022,1803],{"class":1099},[1089,2024,2025],{"class":1473}," first",[1089,2027,1809],{"class":1099},[1089,2029,1812],{"class":1099},[1089,2031,1815],{"class":1473},[1089,2033,1076],{"class":1818},[1089,2035,171],{"class":1473},[1089,2037,1823],{"class":1818},[1089,2039,2040],{"class":1414},"({ ",[1089,2042,2043],{"class":1099},"...",[1089,2045,2046],{"class":1414},"request",[1089,2048,1986],{"class":1424},[1089,2050,2051],{"class":1414}," idempotencyKey });\n",[1089,2053,2054],{"class":1091,"line":1482},[1089,2055,2056],{"class":1797},"\u002F\u002F A retry (after a timeout, a crash, a deploy) sends the same key and the same body…\n",[1089,2058,2059,2061,2064,2066,2068,2070,2072,2074,2076,2078,2080,2082,2084],{"class":1091,"line":1493},[1089,2060,1803],{"class":1099},[1089,2062,2063],{"class":1473}," again",[1089,2065,1809],{"class":1099},[1089,2067,1812],{"class":1099},[1089,2069,1815],{"class":1473},[1089,2071,1076],{"class":1818},[1089,2073,171],{"class":1473},[1089,2075,1823],{"class":1818},[1089,2077,2040],{"class":1414},[1089,2079,2043],{"class":1099},[1089,2081,2046],{"class":1414},[1089,2083,1986],{"class":1424},[1089,2085,2051],{"class":1414},[1089,2087,2088],{"class":1091,"line":1499},[1089,2089,2090],{"class":1797},"\u002F\u002F …and gets the same job back: nothing new is queued, no second order.\n",[1089,2092,2094,2096,2098,2100,2102,2104,2107,2109,2111,2114,2116,2119,2121,2123,2126,2128,2130,2133,2136,2138,2140,2142,2144],{"class":1091,"line":2093},9,[1089,2095,1891],{"class":1473},[1089,2097,1894],{"class":1818},[1089,2099,1897],{"class":1414},[1089,2101,1900],{"class":1095},[1089,2103,1839],{"class":1099},[1089,2105,2106],{"class":1473},"first",[1089,2108,1908],{"class":1414},[1089,2110,1845],{"class":1099},[1089,2112,2113],{"class":1095}," === ",[1089,2115,1839],{"class":1099},[1089,2117,2118],{"class":1473},"again",[1089,2120,1908],{"class":1414},[1089,2122,1845],{"class":1099},[1089,2124,2125],{"class":1095},": ",[1089,2127,1839],{"class":1099},[1089,2129,2106],{"class":1473},[1089,2131,2132],{"class":1414},".id ",[1089,2134,2135],{"class":1099},"===",[1089,2137,2063],{"class":1473},[1089,2139,1908],{"class":1414},[1089,2141,1845],{"class":1099},[1089,2143,1900],{"class":1095},[1089,2145,1928],{"class":1414},[1089,2147,2149],{"class":1091,"line":2148},10,[1089,2150,2018],{"emptyLinePlaceholder":2017},[1089,2152,2154,2156,2159,2161,2163,2165,2167,2169,2172,2174,2176,2178,2180,2183,2185,2188],{"class":1091,"line":2153},11,[1089,2155,1803],{"class":1099},[1089,2157,2158],{"class":1473}," done",[1089,2160,1809],{"class":1099},[1089,2162,1812],{"class":1099},[1089,2164,1815],{"class":1473},[1089,2166,1076],{"class":1818},[1089,2168,171],{"class":1473},[1089,2170,2171],{"class":1818},".wait",[1089,2173,1897],{"class":1414},[1089,2175,2106],{"class":1473},[1089,2177,1908],{"class":1414},[1089,2179,1986],{"class":1424},[1089,2181,2182],{"class":1414}," { timeoutMs",[1089,2184,1100],{"class":1099},[1089,2186,2187],{"class":1473}," 120_000",[1089,2189,2190],{"class":1414}," });\n",[1089,2192,2194,2196,2198,2200,2202,2204,2207,2209,2211,2213,2215,2217,2220,2222,2225,2228,2231,2233,2235,2238,2240,2242],{"class":1091,"line":2193},12,[1089,2195,1891],{"class":1473},[1089,2197,1894],{"class":1818},[1089,2199,1897],{"class":1414},[1089,2201,1900],{"class":1095},[1089,2203,1839],{"class":1099},[1089,2205,2206],{"class":1473},"done",[1089,2208,1908],{"class":1414},[1089,2210,1845],{"class":1099},[1089,2212,2125],{"class":1095},[1089,2214,1839],{"class":1099},[1089,2216,2206],{"class":1473},[1089,2218,2219],{"class":1414},".status",[1089,2221,1845],{"class":1099},[1089,2223,2224],{"class":1099}," ${",[1089,2226,2227],{"class":1473},"JSON",[1089,2229,2230],{"class":1818},".stringify",[1089,2232,1897],{"class":1414},[1089,2234,2206],{"class":1473},[1089,2236,2237],{"class":1414},".data)",[1089,2239,1845],{"class":1099},[1089,2241,1900],{"class":1095},[1089,2243,1928],{"class":1414},[1025,2245,2246,1286,2250,2253],{},[1273,2247,2249],{"href":2248},"\u002Fguides\u002Ftesting","Testing",[1273,2251,113],{"href":2252},"\u002Fguides\u002Fside-effect-safety"," put both in context.",[1029,2255,2257],{"id":2256},"pitfalls","Pitfalls",[1521,2259,2260,2269,2275,2284,2305],{},[1524,2261,2262,2265,2266,2268],{},[1109,2263,2264],{},"A live key in a test suite."," It runs live jobs and spends credits. Keep ",[1037,2267,1043],{}," keys in production secrets only.",[1524,2270,2271,2274],{},[1109,2272,2273],{},"Losing the key at creation."," Kaabist cannot show it again. Store it when you create it, or rotate to get a new one.",[1524,2276,2277,2280,2281,2283],{},[1109,2278,2279],{},"Reusing an idempotency key for different work."," The second request is refused with ",[1037,2282,1624],{},"; derive the key from the thing you are doing, not from a counter.",[1524,2285,2286,2292,2293,2295,2296,1362,2299,1286,2301,2304],{},[1109,2287,2288,2289,2291],{},"Retrying ",[1037,2290,1641],{}," immediately."," Wait for ",[1037,2294,1761],{},". The SDKs retry ",[1037,2297,2298],{},"408",[1037,2300,1641],{},[1037,2302,2303],{},"5xx"," with backoff.",[1524,2306,2307,2313],{},[1109,2308,2309,2310,2312],{},"Rotating with ",[1037,2311,1328],{}," before deploying the new key."," Every client still on the old key stops at once.",[1029,2315,155],{"id":2316},"reference",[1521,2318,2319,2333,2339,2347,2356],{},[1524,2320,2321,1362,2325,1362,2329],{},[1273,2322,2324],{"href":2323},"\u002Freference\u002Fapi\u002Fapi-keys\u002Fcreate-api-key","Create an API key",[1273,2326,2328],{"href":2327},"\u002Freference\u002Fapi\u002Fapi-keys\u002Frotate-api-key","rotate",[1273,2330,2332],{"href":2331},"\u002Freference\u002Fapi\u002Fapi-keys\u002Frevoke-api-key","revoke",[1524,2334,2335],{},[1273,2336,2338],{"href":2337},"\u002Freference\u002Fapi\u002Fschemas\u002Fapi-key","The API key object",[1524,2340,2341,1286,2345],{},[1273,2342,2344],{"href":2343},"\u002Freference\u002Fapi\u002Fschemas\u002Ferror-response","The error response",[1273,2346,1563],{"href":1562},[1524,2348,2349,1286,2353],{},[1273,2350,2352],{"href":2351},"\u002Freference\u002Fcodes#key-scopes","Key scopes",[1273,2354,1182],{"href":2355},"\u002Freference\u002Fcodes#modes",[1524,2357,2358],{},[1273,2359,2361],{"href":2360},"\u002Freference\u002Fplans","Plans",[2363,2364,2365],"style",{},"html pre.shiki code .sTzsn, html code.shiki .sTzsn{--shiki-light:var(--kaab-code-foreground);--shiki-default:var(--kaab-code-foreground);--shiki-dark:var(--kaab-code-foreground)}html pre.shiki code .sqn18, html code.shiki .sqn18{--shiki-light:var(--kaab-code-token-keyword);--shiki-default:var(--kaab-code-token-keyword);--shiki-dark:var(--kaab-code-token-keyword)}html pre.shiki code .sQm2-, html code.shiki .sQm2-{--shiki-light:var(--kaab-code-token-punctuation);--shiki-default:var(--kaab-code-token-punctuation);--shiki-dark:var(--kaab-code-token-punctuation)}html pre.shiki code .suOy4, html code.shiki .suOy4{--shiki-light:var(--kaab-code-token-string-expression);--shiki-default:var(--kaab-code-token-string-expression);--shiki-dark:var(--kaab-code-token-string-expression)}html pre.shiki code .sHJIl, html code.shiki .sHJIl{--shiki-light:var(--kaab-code-token-constant);--shiki-default:var(--kaab-code-token-constant);--shiki-dark:var(--kaab-code-token-constant)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sKog0, html code.shiki .sKog0{--shiki-light:var(--kaab-code-token-comment);--shiki-default:var(--kaab-code-token-comment);--shiki-dark:var(--kaab-code-token-comment)}html pre.shiki code .sJugJ, html code.shiki .sJugJ{--shiki-light:var(--kaab-code-token-function);--shiki-default:var(--kaab-code-token-function);--shiki-dark:var(--kaab-code-token-function)}html pre.shiki code .sx8Bj, html code.shiki .sx8Bj{--shiki-light:var(--kaab-code-token-string);--shiki-default:var(--kaab-code-token-string);--shiki-dark:var(--kaab-code-token-string)}",{"title":1055,"searchDepth":1430,"depth":1430,"links":2367},[2368,2369,2370,2377,2385,2386,2387],{"id":1031,"depth":1418,"text":1032},{"id":1047,"depth":1418,"text":1048},{"id":1079,"depth":1418,"text":1080,"children":2371},[2372,2373,2374,2375,2376],{"id":1115,"depth":1430,"text":1119},{"id":1182,"depth":1430,"text":1183},{"id":1278,"depth":1430,"text":1279},{"id":1310,"depth":1430,"text":1311},{"id":1332,"depth":1430,"text":1333},{"id":1350,"depth":1418,"text":1351,"children":2378},[2379,2380,2381,2382,2383,2384],{"id":1354,"depth":1430,"text":1355},{"id":1399,"depth":1430,"text":1400},{"id":1566,"depth":1430,"text":1567},{"id":1603,"depth":1430,"text":1604},{"id":1649,"depth":1430,"text":1650},{"id":1689,"depth":1430,"text":1690},{"id":1773,"depth":1418,"text":1774},{"id":2256,"depth":1418,"text":2257},{"id":2316,"depth":1418,"text":155},false,null,"API keys, their scopes and rotation, live and test mode, and the conventions every Kaabist endpoint shares: errors, pagination, idempotency and waiting.","md",{},"\u002Fgetting-started\u002Fkeys-and-modes",{"title":13,"description":2390},"1.getting-started\u002F02.keys-and-modes","P6QalRJVmgWvMVa6t1q9vk5nYswuXx1haZ0Ybyl2NOM",[2398,2401],{"title":10,"path":6,"stem":2399,"description":2400,"children":-1},"1.getting-started\u002F01.index","The Kaabist model in one page (programs, jobs, tiers, parking, healing and side-effect safety) and the path through Getting started.",{"title":16,"path":2402,"stem":2403,"description":2404,"children":-1},"\u002Fgetting-started\u002Ffirst-job","1.getting-started\u002F03.first-job","Install an SDK or the kaab CLI, run one job against a product page, and read the envelope that comes back.",1793593409289]