[{"data":1,"prerenderedAt":717},["ShallowReactive",2],{"page:\u002Ferrors":3},{"id":4,"title":5,"body":6,"description":707,"extension":708,"meta":709,"navigation":710,"operation":711,"path":712,"rawbody":713,"seo":714,"stem":715,"__hash__":716},"docs\u002Ferrors.md","Errors",{"type":7,"value":8,"toc":697},"minimark",[9,18,23,26,58,61,184,216,220,333,337,343,461,465,468,486,507,518,522,530,533,565,571,575,589,593,600,618,631,635,650,673,687,693],[10,11,12,13,17],"p",{},"The API uses HTTP status codes to say what went wrong, and a JSON body with a ",[14,15,16],"code",{},"detail"," field to say why.",[19,20,22],"h2",{"id":21},"error-format","Error format",[10,24,25],{},"Most errors carry a single message:",[27,28,33],"pre",{"className":29,"code":30,"language":31,"meta":32,"style":32},"language-json shiki shiki-themes github-light","{ \"detail\": \"Invalid API key\" }\n","json","",[14,34,35],{"__ignoreMap":32},[36,37,40,44,48,51,55],"span",{"class":38,"line":39},"line",1,[36,41,43],{"class":42},"sgsFI","{ ",[36,45,47],{"class":46},"sYu0t","\"detail\"",[36,49,50],{"class":42},": ",[36,52,54],{"class":53},"sYBdl","\"Invalid API key\"",[36,56,57],{"class":42}," }\n",[10,59,60],{},"Validation errors carry a list, with one entry per invalid field:",[27,62,64],{"className":29,"code":63,"language":31,"meta":32,"style":32},"{\n  \"detail\": [\n    {\n      \"type\": \"greater_than_equal\",\n      \"loc\": [\"query\", \"limit\"],\n      \"msg\": \"Input should be greater than or equal to 1\",\n      \"input\": \"0\",\n      \"ctx\": { \"ge\": 1 }\n    }\n  ]\n}\n",[14,65,66,71,80,86,100,121,134,147,166,172,178],{"__ignoreMap":32},[36,67,68],{"class":38,"line":39},[36,69,70],{"class":42},"{\n",[36,72,74,77],{"class":38,"line":73},2,[36,75,76],{"class":46},"  \"detail\"",[36,78,79],{"class":42},": [\n",[36,81,83],{"class":38,"line":82},3,[36,84,85],{"class":42},"    {\n",[36,87,89,92,94,97],{"class":38,"line":88},4,[36,90,91],{"class":46},"      \"type\"",[36,93,50],{"class":42},[36,95,96],{"class":53},"\"greater_than_equal\"",[36,98,99],{"class":42},",\n",[36,101,103,106,109,112,115,118],{"class":38,"line":102},5,[36,104,105],{"class":46},"      \"loc\"",[36,107,108],{"class":42},": [",[36,110,111],{"class":53},"\"query\"",[36,113,114],{"class":42},", ",[36,116,117],{"class":53},"\"limit\"",[36,119,120],{"class":42},"],\n",[36,122,124,127,129,132],{"class":38,"line":123},6,[36,125,126],{"class":46},"      \"msg\"",[36,128,50],{"class":42},[36,130,131],{"class":53},"\"Input should be greater than or equal to 1\"",[36,133,99],{"class":42},[36,135,137,140,142,145],{"class":38,"line":136},7,[36,138,139],{"class":46},"      \"input\"",[36,141,50],{"class":42},[36,143,144],{"class":53},"\"0\"",[36,146,99],{"class":42},[36,148,150,153,156,159,161,164],{"class":38,"line":149},8,[36,151,152],{"class":46},"      \"ctx\"",[36,154,155],{"class":42},": { ",[36,157,158],{"class":46},"\"ge\"",[36,160,50],{"class":42},[36,162,163],{"class":46},"1",[36,165,57],{"class":42},[36,167,169],{"class":38,"line":168},9,[36,170,171],{"class":42},"    }\n",[36,173,175],{"class":38,"line":174},10,[36,176,177],{"class":42},"  ]\n",[36,179,181],{"class":38,"line":180},11,[36,182,183],{"class":42},"}\n",[10,185,186,189,190,114,193,196,197,200,201,203,204,208,209,212,213,215],{},[14,187,188],{},"loc"," points at the field: where it was sent (",[14,191,192],{},"query",[14,194,195],{},"path"," or ",[14,198,199],{},"body",") followed by its path. Log ",[14,202,16],{}," as it comes, and branch on the ",[205,206,207],"strong",{},"status code"," and, for validation errors, on ",[14,210,211],{},"type"," and ",[14,214,188],{},". Messages are meant for developers and can be reworded.",[19,217,219],{"id":218},"status-codes","Status codes",[221,222,223,239],"table",{},[224,225,226],"thead",{},[227,228,229,233,236],"tr",{},[230,231,232],"th",{},"Status",[230,234,235],{},"Meaning",[230,237,238],{},"Retry?",[240,241,242,256,269,282,295,308,320],"tbody",{},[227,243,244,250,253],{},[245,246,247],"td",{},[14,248,249],{},"200",[245,251,252],{},"Success.",[245,254,255],{},"—",[227,257,258,263,266],{},[245,259,260],{},[14,261,262],{},"400",[245,264,265],{},"An inquiry could not be stored.",[245,267,268],{},"No — fix the request.",[227,270,271,276,279],{},[245,272,273],{},[14,274,275],{},"401",[245,277,278],{},"The key was not accepted, or lacks the scope.",[245,280,281],{},"No — fix the key or its scopes.",[227,283,284,289,292],{},[245,285,286],{},[14,287,288],{},"404",[245,290,291],{},"The property does not exist or is not public.",[245,293,294],{},"No.",[227,296,297,302,305],{},[245,298,299],{},[14,300,301],{},"409",[245,303,304],{},"An inquiry's lead already exists.",[245,306,307],{},"No — the lead is in Vestta.",[227,309,310,315,318],{},[245,311,312],{},[14,313,314],{},"422",[245,316,317],{},"A parameter or body field is invalid.",[245,319,268],{},[227,321,322,327,330],{},[245,323,324],{},[14,325,326],{},"500",[245,328,329],{},"Unexpected server error.",[245,331,332],{},"Yes, with backoff.",[19,334,336],{"id":335},"authentication-failures","Authentication failures",[10,338,339,340,342],{},"Every authentication failure is a ",[14,341,275],{},", with a message that names the cause:",[221,344,345,359],{},[224,346,347],{},[227,348,349,353,356],{},[230,350,351],{},[14,352,16],{},[230,354,355],{},"Cause",[230,357,358],{},"Fix",[240,360,361,382,399,419,432,445],{},[227,362,363,368,375],{},[245,364,365],{},[14,366,367],{},"API key required. Use header X-Api-Key or Authorization: ApiKey \u003Ckey>",[245,369,370,371,374],{},"No key in the request. A ",[14,372,373],{},"Bearer"," token does not count.",[245,376,377,378,381],{},"Send ",[14,379,380],{},"X-Api-Key",". Check that proxies keep the header.",[227,383,384,389,396],{},[245,385,386],{},[14,387,388],{},"Invalid API key format",[245,390,391,392,395],{},"The value is not shaped like ",[14,393,394],{},"AC_LIVE_\u003Ckey_id>.\u003Csecret>",".",[245,397,398],{},"Copy the whole key, with no quotes or spaces.",[227,400,401,406,413],{},[245,402,403],{},[14,404,405],{},"API key not found",[245,407,408,409,412],{},"No key with this ",[14,410,411],{},"key_id"," — it was deleted, or the value is mistyped.",[245,414,415,416,395],{},"Check the key list in ",[205,417,418],{},"Settings → API",[227,420,421,426,429],{},[245,422,423],{},[14,424,425],{},"API key is revoked",[245,427,428],{},"The key was revoked.",[245,430,431],{},"Reactivate it, or switch to a new key.",[227,433,434,439,442],{},[245,435,436],{},[14,437,438],{},"API key expired",[245,440,441],{},"The key's duration has ended.",[245,443,444],{},"Create a new key.",[227,446,447,452,458],{},[245,448,449],{},[14,450,451],{},"Invalid API key",[245,453,454,455,457],{},"The ",[14,456,411],{}," exists but the secret does not match.",[245,459,460],{},"The key was mistyped or truncated.",[19,462,464],{"id":463},"authorization-failures","Authorization failures",[10,466,467],{},"A valid key without the endpoint's scope gets:",[27,469,471],{"className":29,"code":470,"language":31,"meta":32,"style":32},"{ \"detail\": \"Lack of permissions\" }\n",[14,472,473],{"__ignoreMap":32},[36,474,475,477,479,481,484],{"class":38,"line":39},[36,476,43],{"class":42},[36,478,47],{"class":46},[36,480,50],{"class":42},[36,482,483],{"class":53},"\"Lack of permissions\"",[36,485,57],{"class":42},[10,487,488,489,491,492,495,496,501,502,506],{},"with status ",[14,490,275],{},", not ",[14,493,494],{},"403",". Check the scopes of the key with ",[497,498,500],"a",{"href":499},"\u002Fme","Retrieve key context",", and see which scope each endpoint needs in ",[497,503,505],{"href":504},"\u002Fauthentication#scopes","Authentication",". Scopes cannot be added to an existing key: create a new one.",[10,508,509,510,513,514,491,516,395],{},"Parameters are validated ",[205,511,512],{},"before"," scopes, so an invalid request made with the wrong key gets ",[14,515,314],{},[14,517,275],{},[19,519,521],{"id":520},"validation-errors","Validation errors",[10,523,524,526,527,529],{},[14,525,314],{}," means a parameter or a body field does not match the schema: a missing required field, a value of the wrong type, a number out of range. The list in ",[14,528,16],{}," names every problem, so fix them all before retrying.",[10,531,532],{},"Two validation messages come from Vestta's own rules rather than the schema:",[534,535,536,554],"ul",{},[537,538,539,542,543,546,547,550,551,553],"li",{},[205,540,541],{},"Invalid phone in an inquiry"," — ",[14,544,545],{},"msg"," is ",[14,548,549],{},"Value error, El teléfono no es válido para el prefijo internacional seleccionado"," (Spanish, from the Vestta app) and ",[14,552,188],{}," names the phone field.",[537,555,556,542,559,561,562,395],{},[205,557,558],{},"Invalid phone in a rental lead",[14,560,16],{}," is a single string instead of a list: ",[14,563,564],{},"Invalid phone number. Use international format, e.g. +34600111222",[10,566,567,568,570],{},"Handle ",[14,569,16],{}," as either a list or a string when you call the lead endpoints.",[19,572,574],{"id":573},"resource-not-found","Resource not found",[10,576,577,581,582,584,585,588],{},[497,578,580],{"href":579},"\u002Fproperties\u002Fretrieve","Retrieve a property"," returns ",[14,583,288],{}," with ",[14,586,587],{},"Property not found"," when the property does not exist, is not public, is sold, rented or withdrawn, or belongs to another workspace.",[19,590,592],{"id":591},"conflicts-and-rejected-inquiries","Conflicts and rejected inquiries",[10,594,595,599],{},[497,596,598],{"href":597},"\u002Fleads\u002Finquiries","Create an inquiry"," can fail after validation:",[534,601,602,610],{},[537,603,604,584,606,609],{},[14,605,301],{},[14,607,608],{},"Lead already exists"," — a lead with the same primary phone already exists in the workspace. The lead is already in Vestta: do not retry.",[537,611,612,584,614,617],{},[14,613,262],{},[14,615,616],{},"Lead could not be created"," — the lead could not be stored for another data reason, such as a value longer than Vestta accepts.",[10,619,620,624,625,627,628,630],{},[497,621,623],{"href":622},"\u002Fleads\u002Fingest","Ingest a rental lead"," never returns ",[14,626,301],{},": with a known phone it returns ",[14,629,249],{}," and creates nothing.",[19,632,634],{"id":633},"server-errors","Server errors",[10,636,637,639,640,642,643,646,647,395],{},[14,638,326],{}," means the request could not be completed on Vestta's side. ",[14,641,16],{}," is a short message such as ",[14,644,645],{},"Error retrieving properties...","; in rare cases the body is plain text, ",[14,648,649],{},"Internal Server Error",[534,651,652,658,664],{},[537,653,654,657],{},[14,655,656],{},"GET"," requests are safe to retry with exponential backoff.",[537,659,660,661,663],{},"Retrying ",[497,662,623],{"href":622}," is safe: a lead created by the first attempt makes the retry a no-op.",[537,665,666,667,669,670,672],{},"Before retrying ",[497,668,598],{"href":597},", expect a ",[14,671,301],{}," if the first attempt was stored.",[10,674,675,676,678,679,682,683,395],{},"A few ",[14,677,326],{},"s are caused by the request and will fail again on retry — for example, a non-numeric ",[14,680,681],{},"search.budget"," in a rental lead. See ",[497,684,686],{"href":685},"\u002Ftroubleshooting","Troubleshooting",[10,688,689,690,395],{},"There are no rate-limit errors: the API does not currently return ",[14,691,692],{},"429",[694,695,696],"style",{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}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);}",{"title":32,"searchDepth":82,"depth":82,"links":698},[699,700,701,702,703,704,705,706],{"id":21,"depth":73,"text":22},{"id":218,"depth":73,"text":219},{"id":335,"depth":73,"text":336},{"id":463,"depth":73,"text":464},{"id":520,"depth":73,"text":521},{"id":573,"depth":73,"text":574},{"id":591,"depth":73,"text":592},{"id":633,"depth":73,"text":634},"How the Vestta API reports errors, every error it returns, and how to handle each one.","md",{},true,null,"\u002Ferrors","---\ntitle: Errors\ndescription: How the Vestta API reports errors, every error it returns, and how to handle each one.\n---\n\nThe API uses HTTP status codes to say what went wrong, and a JSON body with a `detail` field to say why.\n\n## Error format\n\nMost errors carry a single message:\n\n```json\n{ \"detail\": \"Invalid API key\" }\n```\n\nValidation errors carry a list, with one entry per invalid field:\n\n```json\n{\n  \"detail\": [\n    {\n      \"type\": \"greater_than_equal\",\n      \"loc\": [\"query\", \"limit\"],\n      \"msg\": \"Input should be greater than or equal to 1\",\n      \"input\": \"0\",\n      \"ctx\": { \"ge\": 1 }\n    }\n  ]\n}\n```\n\n`loc` points at the field: where it was sent (`query`, `path` or `body`) followed by its path. Log `detail` as it comes, and branch on the **status code** and, for validation errors, on `type` and `loc`. Messages are meant for developers and can be reworded.\n\n## Status codes\n\n| Status | Meaning | Retry? |\n| --- | --- | --- |\n| `200` | Success. | — |\n| `400` | An inquiry could not be stored. | No — fix the request. |\n| `401` | The key was not accepted, or lacks the scope. | No — fix the key or its scopes. |\n| `404` | The property does not exist or is not public. | No. |\n| `409` | An inquiry's lead already exists. | No — the lead is in Vestta. |\n| `422` | A parameter or body field is invalid. | No — fix the request. |\n| `500` | Unexpected server error. | Yes, with backoff. |\n\n## Authentication failures\n\nEvery authentication failure is a `401`, with a message that names the cause:\n\n| `detail` | Cause | Fix |\n| --- | --- | --- |\n| `API key required. Use header X-Api-Key or Authorization: ApiKey \u003Ckey>` | No key in the request. A `Bearer` token does not count. | Send `X-Api-Key`. Check that proxies keep the header. |\n| `Invalid API key format` | The value is not shaped like `AC_LIVE_\u003Ckey_id>.\u003Csecret>`. | Copy the whole key, with no quotes or spaces. |\n| `API key not found` | No key with this `key_id` — it was deleted, or the value is mistyped. | Check the key list in **Settings → API**. |\n| `API key is revoked` | The key was revoked. | Reactivate it, or switch to a new key. |\n| `API key expired` | The key's duration has ended. | Create a new key. |\n| `Invalid API key` | The `key_id` exists but the secret does not match. | The key was mistyped or truncated. |\n\n## Authorization failures\n\nA valid key without the endpoint's scope gets:\n\n```json\n{ \"detail\": \"Lack of permissions\" }\n```\n\nwith status `401`, not `403`. Check the scopes of the key with [Retrieve key context](\u002Fme), and see which scope each endpoint needs in [Authentication](\u002Fauthentication#scopes). Scopes cannot be added to an existing key: create a new one.\n\nParameters are validated **before** scopes, so an invalid request made with the wrong key gets `422`, not `401`.\n\n## Validation errors\n\n`422` means a parameter or a body field does not match the schema: a missing required field, a value of the wrong type, a number out of range. The list in `detail` names every problem, so fix them all before retrying.\n\nTwo validation messages come from Vestta's own rules rather than the schema:\n\n- **Invalid phone in an inquiry** — `msg` is `Value error, El teléfono no es válido para el prefijo internacional seleccionado` (Spanish, from the Vestta app) and `loc` names the phone field.\n- **Invalid phone in a rental lead** — `detail` is a single string instead of a list: `Invalid phone number. Use international format, e.g. +34600111222`.\n\nHandle `detail` as either a list or a string when you call the lead endpoints.\n\n## Resource not found\n\n[Retrieve a property](\u002Fproperties\u002Fretrieve) returns `404` with `Property not found` when the property does not exist, is not public, is sold, rented or withdrawn, or belongs to another workspace.\n\n## Conflicts and rejected inquiries\n\n[Create an inquiry](\u002Fleads\u002Finquiries) can fail after validation:\n\n- `409` with `Lead already exists` — a lead with the same primary phone already exists in the workspace. The lead is already in Vestta: do not retry.\n- `400` with `Lead could not be created` — the lead could not be stored for another data reason, such as a value longer than Vestta accepts.\n\n[Ingest a rental lead](\u002Fleads\u002Fingest) never returns `409`: with a known phone it returns `200` and creates nothing.\n\n## Server errors\n\n`500` means the request could not be completed on Vestta's side. `detail` is a short message such as `Error retrieving properties...`; in rare cases the body is plain text, `Internal Server Error`.\n\n- `GET` requests are safe to retry with exponential backoff.\n- Retrying [Ingest a rental lead](\u002Fleads\u002Fingest) is safe: a lead created by the first attempt makes the retry a no-op.\n- Before retrying [Create an inquiry](\u002Fleads\u002Finquiries), expect a `409` if the first attempt was stored.\n\nA few `500`s are caused by the request and will fail again on retry — for example, a non-numeric `search.budget` in a rental lead. See [Troubleshooting](\u002Ftroubleshooting).\n\nThere are no rate-limit errors: the API does not currently return `429`.\n",{"title":5,"description":707},"errors","ZbIE0ToFAGq1rkVq7jWGuYa19PnG3QhMK0dW5o1xeUE",1791110048563]