[{"data":1,"prerenderedAt":934},["ShallowReactive",2],{"doc-\u002Fapi\u002Ferrors":3},{"id":4,"title":5,"body":6,"description":924,"edit":925,"extension":926,"meta":927,"navigation":928,"path":929,"seo":930,"stem":931,"vertical":925,"weight":932,"__hash__":933},"content\u002Fapi\u002Ferrors.md","Error codes",{"type":7,"value":8,"toc":915},"minimark",[9,24,33,38,140,144,215,219,361,365,496,500,569,573,644,648,651,905,911],[10,11,12,13,16,17,20,21,23],"p",{},"This is the consolidated table of error ",[14,15,14],"code",{}," values returned by the\nHTTP API. The text of ",[14,18,19],{},"message"," is human-readable and may change without\nnotice; the ",[14,22,14],{}," is stable and is what you should branch on.",[10,25,26,27,32],{},"For the error-envelope shape see the\n",[28,29,31],"a",{"href":30},"\u002Fapi\u002Foverview#errors","API overview",".",[34,35,37],"h2",{"id":36},"authentication-and-authorisation","Authentication and authorisation",[39,40,41,58],"table",{},[42,43,44],"thead",{},[45,46,47,51,55],"tr",{},[48,49,50],"th",{},"HTTP",[48,52,53],{},[14,54,14],{},[48,56,57],{},"When",[59,60,61,75,87,99,112,128],"tbody",{},[45,62,63,67,72],{},[64,65,66],"td",{},"401",[64,68,69],{},[14,70,71],{},"auth_required",[64,73,74],{},"No Authorization header on a protected route",[45,76,77,79,84],{},[64,78,66],{},[64,80,81],{},[14,82,83],{},"token_invalid",[64,85,86],{},"Token is malformed or revoked",[45,88,89,91,96],{},[64,90,66],{},[64,92,93],{},[14,94,95],{},"token_expired",[64,97,98],{},"Token has expired (session tokens only)",[45,100,101,104,109],{},[64,102,103],{},"403",[64,105,106],{},[14,107,108],{},"forbidden",[64,110,111],{},"Token correct, but scope does not cover route",[45,113,114,116,121],{},[64,115,103],{},[64,117,118],{},[14,119,120],{},"device_not_in_token",[64,122,123,124,127],{},"Device token does not own the ",[14,125,126],{},"device"," in body",[45,129,130,132,137],{},[64,131,103],{},[64,133,134],{},[14,135,136],{},"account_suspended",[64,138,139],{},"Account is past-due or admin-suspended",[34,141,143],{"id":142},"request-validation","Request validation",[39,145,146,158],{},[42,147,148],{},[45,149,150,152,156],{},[48,151,50],{},[48,153,154],{},[14,155,14],{},[48,157,57],{},[59,159,160,173,185,200],{},[45,161,162,165,170],{},[64,163,164],{},"400",[64,166,167],{},[14,168,169],{},"bad_json",[64,171,172],{},"Body is not valid JSON",[45,174,175,177,182],{},[64,176,164],{},[64,178,179],{},[14,180,181],{},"bad_query",[64,183,184],{},"Query string parameter has wrong type",[45,186,187,189,194],{},[64,188,164],{},[64,190,191],{},[14,192,193],{},"missing_field",[64,195,196,197,199],{},"Required field omitted; ",[14,198,19],{}," names the field",[45,201,202,204,209],{},[64,203,164],{},[64,205,206],{},[14,207,208],{},"no_measurements",[64,210,211,214],{},[14,212,213],{},"measurements"," array is empty on ingest",[34,216,218],{"id":217},"semantic-validation-422","Semantic validation (422)",[39,220,221,233],{},[42,222,223],{},[45,224,225,227,231],{},[48,226,50],{},[48,228,229],{},[14,230,14],{},[48,232,57],{},[59,234,235,252,269,284,298,313,325,337,349],{},[45,236,237,240,245],{},[64,238,239],{},"422",[64,241,242],{},[14,243,244],{},"unknown_kind",[64,246,247,248,251],{},"Measurement ",[14,249,250],{},"type"," not in supported set",[45,253,254,256,261],{},[64,255,239],{},[64,257,258],{},[14,259,260],{},"out_of_range",[64,262,263,264,268],{},"Sanity-check bound exceeded (see ",[28,265,267],{"href":266},"\u002Fapi\u002Fingest","POST \u002Fv1\u002Fingest",")",[45,270,271,273,278],{},[64,272,239],{},[64,274,275],{},[14,276,277],{},"ts_in_future",[64,279,280,283],{},[14,281,282],{},"ts"," more than 30 s in the future",[45,285,286,288,293],{},[64,287,239],{},[64,289,290],{},[14,291,292],{},"ts_too_old",[64,294,295,297],{},[14,296,282],{}," more than 30 days in the past",[45,299,300,302,307],{},[64,301,239],{},[64,303,304],{},[14,305,306],{},"invalid_range",[64,308,309,310],{},"Rule ",[14,311,312],{},"ok_min > ok_max",[45,314,315,317,322],{},[64,316,239],{},[64,318,319],{},[14,320,321],{},"grace_too_long",[64,323,324],{},"Rule grace > 6 h",[45,326,327,329,334],{},[64,328,239],{},[64,330,331],{},[14,332,333],{},"period_empty",[64,335,336],{},"Report period contains no measurements",[45,338,339,341,346],{},[64,340,239],{},[64,342,343],{},[14,344,345],{},"period_too_long",[64,347,348],{},"Report period > 13 months (beyond raw retention)",[45,350,351,353,358],{},[64,352,239],{},[64,354,355],{},[14,356,357],{},"unknown_template",[64,359,360],{},"Report template not in supported set",[34,362,364],{"id":363},"resource-state-404-409","Resource state (404 \u002F 409)",[39,366,367,379],{},[42,368,369],{},[45,370,371,373,377],{},[48,372,50],{},[48,374,375],{},[14,376,14],{},[48,378,57],{},[59,380,381,394,405,416,427,438,449,460,471,484],{},[45,382,383,386,391],{},[64,384,385],{},"404",[64,387,388],{},[14,389,390],{},"account_not_found",[64,392,393],{},"(Diagnostic only — never leaks existence)",[45,395,396,398,403],{},[64,397,385],{},[64,399,400],{},[14,401,402],{},"site_not_found",[64,404],{},[45,406,407,409,414],{},[64,408,385],{},[64,410,411],{},[14,412,413],{},"device_not_found",[64,415],{},[45,417,418,420,425],{},[64,419,385],{},[64,421,422],{},[14,423,424],{},"sensor_not_found",[64,426],{},[45,428,429,431,436],{},[64,430,385],{},[64,432,433],{},[14,434,435],{},"channel_not_found",[64,437],{},[45,439,440,442,447],{},[64,441,385],{},[64,443,444],{},[14,445,446],{},"rule_not_found",[64,448],{},[45,450,451,453,458],{},[64,452,385],{},[64,454,455],{},[14,456,457],{},"event_not_found",[64,459],{},[45,461,462,464,469],{},[64,463,385],{},[64,465,466],{},[14,467,468],{},"report_not_found",[64,470],{},[45,472,473,476,481],{},[64,474,475],{},"409",[64,477,478],{},[14,479,480],{},"local_id_taken",[64,482,483],{},"Another device on the site has the same local_id",[45,485,486,488,493],{},[64,487,475],{},[64,489,490],{},[14,491,492],{},"idempotency_conflict",[64,494,495],{},"Same key, different body, within 24 h",[34,497,499],{"id":498},"rate-limits","Rate limits",[39,501,502,514],{},[42,503,504],{},[45,505,506,508,512],{},[48,507,50],{},[48,509,510],{},[14,511,14],{},[48,513,57],{},[59,515,516,533,545,557],{},[45,517,518,521,526],{},[64,519,520],{},"429",[64,522,523],{},[14,524,525],{},"rate_limited",[64,527,528,529,532],{},"Generic — see ",[14,530,531],{},"X-RateLimit-*"," headers",[45,534,535,537,542],{},[64,536,520],{},[64,538,539],{},[14,540,541],{},"report_rate_limit",[64,543,544],{},"> 4 reports \u002F min \u002F account",[45,546,547,549,554],{},[64,548,520],{},[64,550,551],{},[14,552,553],{},"ingest_rate_limit",[64,555,556],{},"> 60 req \u002F min \u002F device",[45,558,559,561,566],{},[64,560,520],{},[64,562,563],{},[14,564,565],{},"export_rate_limit",[64,567,568],{},"> 1 export \u002F 5 min \u002F account",[34,570,572],{"id":571},"server","Server",[39,574,575,587],{},[42,576,577],{},[45,578,579,581,585],{},[48,580,50],{},[48,582,583],{},[14,584,14],{},[48,586,57],{},[59,588,589,606,619,631],{},[45,590,591,594,599],{},[64,592,593],{},"500",[64,595,596],{},[14,597,598],{},"internal",[64,600,601,602,605],{},"Catch-all — ",[14,603,604],{},"request_id"," in the body",[45,607,608,611,616],{},[64,609,610],{},"503",[64,612,613],{},[14,614,615],{},"db_unavailable",[64,617,618],{},"Postgres unreachable; retry with backoff",[45,620,621,623,628],{},[64,622,610],{},[64,624,625],{},[14,626,627],{},"pdf_unavailable",[64,629,630],{},"PDF service container restarting",[45,632,633,636,641],{},[64,634,635],{},"504",[64,637,638],{},[14,639,640],{},"webhook_timeout",[64,642,643],{},"Customer-supplied webhook destination > 5 s",[34,645,647],{"id":646},"what-to-do-per-code","What to do per code",[10,649,650],{},"For client code:",[652,653,658],"pre",{"className":654,"code":655,"language":656,"meta":657,"style":657},"language-python shiki shiki-themes github-dark github-dark","# Pseudocode for a defensive ingest client\ntry:\n    post_ingest(payload)\nexcept HTTPError as e:\n    code = e.json()['error']['code']\n    if code in ('rate_limited', 'ingest_rate_limit'):\n        sleep(retry_after_seconds); retry()\n    elif code in ('bad_json', 'no_measurements', 'unknown_kind',\n                  'out_of_range', 'ts_in_future', 'ts_too_old'):\n        log_locally(payload, e); drop()    # do NOT retry, fix client\n    elif code in ('auth_required', 'token_invalid', 'token_expired',\n                  'device_not_in_token', 'forbidden'):\n        alert_operator(e); halt()           # human intervention\n    elif code in ('internal', 'db_unavailable'):\n        sleep(exponential_backoff); retry()\n    else:\n        log_locally(payload, e); drop()    # unknown error — fail safe\n","python","",[14,659,660,669,680,686,701,726,753,759,787,805,814,840,853,862,883,889,897],{"__ignoreMap":657},[661,662,665],"span",{"class":663,"line":664},"line",1,[661,666,668],{"class":667},"sJ8bj","# Pseudocode for a defensive ingest client\n",[661,670,672,676],{"class":663,"line":671},2,[661,673,675],{"class":674},"sOPea","try",[661,677,679],{"class":678},"suv1-",":\n",[661,681,683],{"class":663,"line":682},3,[661,684,685],{"class":678},"    post_ingest(payload)\n",[661,687,689,692,695,698],{"class":663,"line":688},4,[661,690,691],{"class":674},"except",[661,693,694],{"class":678}," HTTPError ",[661,696,697],{"class":674},"as",[661,699,700],{"class":678}," e:\n",[661,702,704,707,710,713,717,720,723],{"class":663,"line":703},5,[661,705,706],{"class":678},"    code ",[661,708,709],{"class":674},"=",[661,711,712],{"class":678}," e.json()[",[661,714,716],{"class":715},"s4wv1","'error'",[661,718,719],{"class":678},"][",[661,721,722],{"class":715},"'code'",[661,724,725],{"class":678},"]\n",[661,727,729,732,735,738,741,744,747,750],{"class":663,"line":728},6,[661,730,731],{"class":674},"    if",[661,733,734],{"class":678}," code ",[661,736,737],{"class":674},"in",[661,739,740],{"class":678}," (",[661,742,743],{"class":715},"'rate_limited'",[661,745,746],{"class":678},", ",[661,748,749],{"class":715},"'ingest_rate_limit'",[661,751,752],{"class":678},"):\n",[661,754,756],{"class":663,"line":755},7,[661,757,758],{"class":678},"        sleep(retry_after_seconds); retry()\n",[661,760,762,765,767,769,771,774,776,779,781,784],{"class":663,"line":761},8,[661,763,764],{"class":674},"    elif",[661,766,734],{"class":678},[661,768,737],{"class":674},[661,770,740],{"class":678},[661,772,773],{"class":715},"'bad_json'",[661,775,746],{"class":678},[661,777,778],{"class":715},"'no_measurements'",[661,780,746],{"class":678},[661,782,783],{"class":715},"'unknown_kind'",[661,785,786],{"class":678},",\n",[661,788,790,793,795,798,800,803],{"class":663,"line":789},9,[661,791,792],{"class":715},"                  'out_of_range'",[661,794,746],{"class":678},[661,796,797],{"class":715},"'ts_in_future'",[661,799,746],{"class":678},[661,801,802],{"class":715},"'ts_too_old'",[661,804,752],{"class":678},[661,806,808,811],{"class":663,"line":807},10,[661,809,810],{"class":678},"        log_locally(payload, e); drop()    ",[661,812,813],{"class":667},"# do NOT retry, fix client\n",[661,815,817,819,821,823,825,828,830,833,835,838],{"class":663,"line":816},11,[661,818,764],{"class":674},[661,820,734],{"class":678},[661,822,737],{"class":674},[661,824,740],{"class":678},[661,826,827],{"class":715},"'auth_required'",[661,829,746],{"class":678},[661,831,832],{"class":715},"'token_invalid'",[661,834,746],{"class":678},[661,836,837],{"class":715},"'token_expired'",[661,839,786],{"class":678},[661,841,843,846,848,851],{"class":663,"line":842},12,[661,844,845],{"class":715},"                  'device_not_in_token'",[661,847,746],{"class":678},[661,849,850],{"class":715},"'forbidden'",[661,852,752],{"class":678},[661,854,856,859],{"class":663,"line":855},13,[661,857,858],{"class":678},"        alert_operator(e); halt()           ",[661,860,861],{"class":667},"# human intervention\n",[661,863,865,867,869,871,873,876,878,881],{"class":663,"line":864},14,[661,866,764],{"class":674},[661,868,734],{"class":678},[661,870,737],{"class":674},[661,872,740],{"class":678},[661,874,875],{"class":715},"'internal'",[661,877,746],{"class":678},[661,879,880],{"class":715},"'db_unavailable'",[661,882,752],{"class":678},[661,884,886],{"class":663,"line":885},15,[661,887,888],{"class":678},"        sleep(exponential_backoff); retry()\n",[661,890,892,895],{"class":663,"line":891},16,[661,893,894],{"class":674},"    else",[661,896,679],{"class":678},[661,898,900,902],{"class":663,"line":899},17,[661,901,810],{"class":678},[661,903,904],{"class":667},"# unknown error — fail safe\n",[10,906,907,908,910],{},"For your own integration tests, asserting on ",[14,909,14],{}," rather than HTTP\nstatus preserves correctness across our internal refactors.",[912,913,914],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sOPea, html code.shiki .sOPea{--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .suv1-, html code.shiki .suv1-{--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .s4wv1, html code.shiki .s4wv1{--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":657,"searchDepth":682,"depth":682,"links":916},[917,918,919,920,921,922,923],{"id":36,"depth":671,"text":37},{"id":142,"depth":671,"text":143},{"id":217,"depth":671,"text":218},{"id":363,"depth":671,"text":364},{"id":498,"depth":671,"text":499},{"id":571,"depth":671,"text":572},{"id":646,"depth":671,"text":647},"Every machine-readable error code we emit",null,"md",{},true,"\u002Fapi\u002Ferrors",{"title":5,"description":924},"api\u002Ferrors",296,"kqfPEN1RPg0E-wD_uKr6G1lmT-ZeSb7eCRuvpha1G_0",1779022954254]