Errors
Every error answers one body. Branch on code, never on the message; show the person message when it helps; and send us request_id when it is our side.
The body
errorobjectThe error.
typestringThe kind of error, one per status: invalid_request, authentication, permission, not_found, conflict, rate_limited, cap_reached, upstream or internal.
- Limits
- One of 9 values.
codestringWhat went wrong, exactly: branch on this. The errors reference lists every code, with what to do.
- Example
user_not_found
messagestringWhat went wrong, in a sentence a person can read. It may change: never branch on it.
- Type
string
paramstringmay be absentThe field the error is about, as a path such as tools.0.input; absent when it is about no one field.
- Type
string
namesstring[]may be absentWith secret_missing: the company secrets to store before applying the file again.
- Type
string[]
deploymentsstring[]may be absentWith mcp_server_shared: the other deployments that run the MCP server the file would change.
- Type
string[]
partialobjectmay be absentWith timeout on a browser fetch: what the page had sent before the time ran out.
- Type
object
retry_after_msintegermay be absentWith browser_busy: how long to wait before trying again, in ms.
- Type
integer
request_idstringThis request's id: send it to Vestra when the error is on our side.
- Type
string
{ "error": { "type": "not_found", "code": "user_not_found", "message": "No such user.", "request_id": "req_8f2k" }}400 The request is not one the API takes95 codes
answer_mismatchThe answer's shape is not one this interaction takes.
What to do: Send the body its type takes: an approval approve, a question answers, a call to your tool output or error.
answers_mismatchThe answers do not match the questions.
What to do: Send exactly one answer for each question, in the order they were asked.
answers_not_expectedThis interaction takes a yes or a no, not answers.
What to do: Send { "approve": true } or { "approve": false }.
answers_requiredThis question waits for answers.
What to do: Send answers, one for each question, or { "approve": false } to decline.
app_not_connectableThis app cannot be connected yet.
What to do: Pick another app from GET /v1/apps.
auth_twiceAn MCP tool in the file gives both auth and an Authorization header.
What to do: Keep one of the two.
binary_fileA skill holds a file that is not text.
What to do: Skills take text files only: leave out images and other binaries.
body_too_largeThe request body, or a context inside it, is larger than this route takes.
What to do: Send less, or upload the data as a file with POST /v1/files and name it.
bundle_too_largeA skill is larger than 5 MB.
What to do: Make the skill smaller: keep what Bash reads, and leave out the rest.
cap_above_maximumA cap is above what is allowed: the company cap above its ceiling, or a user cap above the company cap.
What to do: Lower the cap, or ask Vestra to raise the ceiling.
connect_app_insteadThis interaction is an app to connect, and it is not answered with a body.
What to do: Connect the app with POST /v1/connections: the interaction settles itself once the app is connected.
conversation_requiredThe MCP tool needs a conversation and none was named.
What to do: Name the conversation to act on.
conversation_user_mismatchThe conversation belongs to a different user than the one named.
What to do: Name the conversation of the same user, or leave the user out.
decision_not_expectedA hand-off answer was sent to something that is not a hand-off, or the other way round.
What to do: Send done, could_not or not_now to a hand-off only, and the body its type takes to the others.
deployment_requiredThis call needs a deployment and none was named.
What to do: Name the deployment by its name or its dep_ id.
describe_or_answerThe MCP init tool needs a description to start, or a deployment, a conversation and an answer to go on.
What to do: Start with describe, then answer with deployment, conversation and answer.
document_too_largeA notebook document is larger than 512 KB of text.
What to do: Split it into several documents.
duplicate_nameThe file names two tools, tests or routines the same.
What to do: Give each its own name.
duplicate_pathTwo files of a skill share one path.
What to do: Give each file its own path.
file_requiredThe upload has no file in it.
What to do: Send the file as multipart/form-data, in a field named file.
file_too_largealso 413A file is larger than its route takes: a file of a skill over 1 MB, or an upload over its limit.
What to do: Send a smaller file.
install_ability_insteadBash asked to install an ability, and that is not approved through the API.
What to do: Add the skill or MCP server to your deployment instead; this interaction can only be declined.
invalid_conversation_idconversation_id is not a conversation id.
What to do: Send a conv_ id, as the API gave it.
invalid_cursorThe cursor is not one this API gave.
What to do: Send the next_cursor of the page before, unchanged.
invalid_deploymentThat is not a deployment id or name.
What to do: Send a dep_ id, or the name, with an optional @version.
invalid_deployment_iddeployment_id is not a deployment id.
What to do: Send a dep_ id, as the API gave it.
invalid_filenameThe file name is not one plain name.
What to do: Use one name with no slashes or control characters, at most 255 bytes.
invalid_frontmatterA skill's SKILL.md frontmatter is not valid YAML.
What to do: Fix the YAML between the two --- lines at the top of SKILL.md.
invalid_idempotency_keyThe Idempotency-Key header is empty or too long.
What to do: Send 1 to 255 characters.
invalid_jsonThe request body is not valid JSON.
What to do: Send JSON, with Content-Type: application/json.
invalid_languageThat is not a language tag.
What to do: Use auto, or a tag such as en, hi or pt-BR.
invalid_last_event_idLast-Event-ID or after is not a whole number.
What to do: Send the seq of the last event you saw, or 0 for the start.
invalid_limitlimit is not a whole number from 1 to 100.
What to do: Send a limit from 1 to 100, or leave it out.
invalid_manifestThe deployment's settings do not fit together: the message and param say where.
What to do: Fix the field param names and send it again.
invalid_memoryThe memory is not one Bash can keep.
What to do: Send text of 1 to 1,000 characters, and optionally a kind: identity, relationship, commitment, preference, project_state or other.
invalid_modeThe Vestra-Mode header is not live or test.
What to do: Send live or test.
invalid_org_headerThe Vestra-Org header is not an org id.
What to do: Send your org id, like org_....
invalid_originAn allowed origin is not an https origin.
What to do: Write it as https://app.example.com, with no path.
invalid_queryA query field is not valid: param names it.
What to do: Fix that field, or leave it out.
invalid_repoA repository in the file is not an address Bash can clone.
What to do: Write github.com/owner/repo, or its https URL.
invalid_requestThe request is not valid: the message and param say which field and why.
What to do: Fix that field and send it again. The route says what each field takes.
invalid_scheduleThe schedule is not one a routine can keep: an unknown time zone, or a cron that does not read.
What to do: Use an IANA time zone such as Asia/Kolkata, and a cron such as 0 7 * * *, or write every in plain words.
invalid_secret_nameThat is not a secret name.
What to do: Use capitals, digits and underscores, starting with a capital: PNR_API_KEY.
invalid_skillA skill's SKILL.md does not meet the skill format.
What to do: Fix what the message names, and upload the skill again.
invalid_task_idtask_id is not a task id.
What to do: Send a task_ id, as the API gave it.
invalid_tool_inputA function tool's input is neither shorthand nor JSON Schema.
What to do: Write each argument as a type such as string or integer?, or give JSON Schema with type: object.
invalid_triggerA routine's filters are not ones it can match.
What to do: Fix the filter the message names.
invalid_user_timezoneThe user's own time zone is not an IANA name, so every cannot be read in it.
What to do: Send timezone, or fix the user with PATCH /v1/users/{user_id}.
invalid_windowfrom is after to, or one of them is not a date.
What to do: Send dates like 2026-10-01, with from on or before to.
invalid_zipThe skill upload is not a zip archive that reads.
What to do: Zip the skill folder again and upload it.
mcp_server_not_listedA tool policy names an MCP server the version does not list.
What to do: Add the server to mcp_servers, or drop its policy.
memory_endpoint_requiredMemory kept on your side needs an endpoint for Bash to ask.
What to do: Send memory_endpoint with memory_mode: customer.
message_requiredThere is nothing to send: no message, attachment or tool result.
What to do: Send a message, an attachment or tool results.
multipart_requiredThe upload is not multipart/form-data.
What to do: Send the file as multipart/form-data, in a field named file.
name_mismatchThe file's name and the name in the path differ.
What to do: Make them the same.
no_output_schemaThis work was not asked for structured output, so it has no result to read.
What to do: Ask with output_schema when you want a result to read.
nonce_mismatchAn approval that moves money or acts for the user needs its nonce, and it was missing or wrong.
What to do: Read the interaction and send its nonce with approve: true.
not_a_schedule_routineThis routine runs on a call, so it has no schedule to change.
What to do: Change its filters, or make a new routine that runs on a schedule.
not_a_trigger_routineThis routine runs on a schedule, so it takes no payload and has no filters.
What to do: Run it with POST /v1/routines/{routine_id}/run.
notebook_fullThe notebook is full: too many documents, or more than 5 MB of text.
What to do: Delete documents, or start another notebook.
oauth_not_availableOAuth for company MCP servers is not available yet.
What to do: Send headers with ${user_secret:NAME} for each user's own credentials.
output_schema_invalidoutput_schema is not a schema Bash can follow.
What to do: Send a JSON Schema object; the message says what is wrong with it.
output_schema_too_largeoutput_schema is larger than 32 KB.
What to do: Send a smaller schema.
path_not_resolvedThe file names a folder or file on your computer, and HTTP cannot read it.
What to do: Deploy with the CLI or an SDK: they upload it and send what it became.
payload_too_largeA routine's trigger payload is larger than 4 KB.
What to do: Send less, or put the data in a file and name it.
present_user_requiredThis approval moves money or acts for the user, and the user must be there to say yes.
What to do: Approve it only while the user is in your app, and send present_user: true.
query_requiredA memory search needs a question.
What to do: Send q, 1 to 500 characters.
raw_secret_in_headerAn MCP header holds a raw credential.
What to do: Store it with PUT /v1/secrets/{name} and write ${secret:NAME} in the header.
return_url_not_allowedreturn_url is not one of your allowed return URLs.
What to do: Add it with PATCH /v1/org, or send one that is allowed.
schedule_too_frequentA routine runs at most once every 15 minutes.
What to do: Choose a schedule that runs less often.
schedule_unreadableevery does not read as a schedule.
What to do: Write it like weekday at 08:00, mon, wed, fri at 18:30 or 30 minutes.
sdp_requiredA voice call needs the browser's WebRTC offer.
What to do: Send the offer as sdp.
secret_in_urlAn MCP server's URL carries a credential.
What to do: Move it into a header as ${secret:NAME}.
secret_missingThe file names company secrets that are not stored for this mode: names lists them.
What to do: Store each with PUT /v1/secrets/{name} and a key of this mode, then apply the file again.
skill_md_missingA skill folder has no SKILL.md at its top.
What to do: Add SKILL.md at the top of the folder.
skill_name_changedA new version of a skill changes the name in its SKILL.md.
What to do: Keep the name, or upload a new skill to rename it.
skill_name_requiredA skill's SKILL.md has no name.
What to do: Give the frontmatter a name that starts with a letter.
title_requiredA raw text upload to a notebook needs a title.
What to do: Send ?title=.
too_many_filesA skill holds more files than it may.
What to do: Keep the files Bash reads, and leave out the rest.
too_many_headersAn MCP server sends more than 20 headers.
What to do: Send at most 20.
tool_listed_twiceA tool is in more than one of an MCP server's lists.
What to do: Put each tool in one list: deny, require_approval or run_without_asking.
tool_name_reservedA tool, or an MCP server's slug, takes a name Bash already uses for one of its own tools or tool servers.
What to do: Name it something else.
tool_not_declaredA test gives results for a tool the file does not declare.
What to do: Declare the tool in tools, or drop its results from the test's tool_results.
tool_not_on_serverAn MCP server's run_without_asking names a tool the server does not list.
What to do: Use each name exactly as the server lists it (GET /v1/mcp-servers/{server_id}/tools), or drop it.
tool_policy_twiceTwo tool policies name the same MCP server.
What to do: Give each MCP server one policy.
tool_schema_invalidA tool's input schema is not a JSON Schema object.
What to do: Give it type: object and its properties.
unknown_modelThat is not a model a deployment can use.
What to do: Use default, or an id from GET /v1/models.
unsafe_pathA file of a skill has a path that is not allowed.
What to do: Use plain relative paths, with no .. and no leading slash.
unsupported_kindThis kind of interaction cannot be answered, or withdrawn, through the API.
What to do: Decline it, or let the user choose in Vestra.
url_not_publicThe URL is not a public https address.
What to do: Use an https URL that reaches the public internet.
user_must_connectThe user signs in to this app themselves.
What to do: Send the user the connect link. Through the API, this interaction can only be declined.
user_requiredThis company asks for a user on every request, and none was named.
What to do: Name the user, or turn off require_user with PATCH /v1/org.
version_not_allowedThis call runs the current version, so it takes no @version.
What to do: Drop the @version.
voice_unknownThat is not one of the voices.
What to do: Use one of the voices the message lists.
window_too_longThe usage window is longer than the API reads at once.
What to do: Ask for a shorter window, and page through it.
401 Who is calling is not known8 codes
invalid_api_keyThat API key is not valid.
What to do: Send a key from the console, as Authorization: Bearer vk_test_....
invalid_sessionThe console session is not valid.
What to do: Sign in again.
key_expiredThis API key has expired.
What to do: Use the key that replaced it.
key_revokedalso 409This API key was revoked: it calls nothing, and it cannot be rolled.
What to do: Make a new key in the console or with POST /v1/keys.
missing_api_keyThe request has no API key.
What to do: Send Authorization: Bearer vk_test_... (or vk_live_...).
missing_sessionThe console request has no session.
What to do: Send your Vestra session as Bearer <token>.
org_header_requiredA console session must say which company it acts for.
What to do: Send the Vestra-Org header with your org id.
session_endedThis session has ended, and its token stopped working.
What to do: Ask your server for a new session with POST /v1/sessions.
402 Money stops the call5 codes
org_cap_reachedThe company's spending cap is reached: its cap for the day (it resets at midnight UTC) or for the month (it resets on the 1st, UTC).
What to do: GET /v1/limits says which. Raise it with PATCH /v1/limits, or wait for it to reset.
spend_cap_reachedA spending cap is reached, the user's or the company's, for the day or the month, so their computer was not woken, or the voice call did not open.
What to do: GET /v1/users/{user_id} and GET /v1/limits say which. Raise it, or wait for it to reset: a day's cap at midnight UTC, a month's on the 1st.
storage_quota_exceededThis user has used all of their file storage.
What to do: Delete files with DELETE /v1/files/{file_id} to make room.
user_cap_reachedThis user's spending cap is reached: their cap for the day (it resets at midnight UTC) or for the month (it resets on the 1st, UTC).
What to do: GET /v1/users/{user_id} says what they may still spend. Raise their cap with PATCH /v1/users/{user_id}, or wait for it to reset.
wallet_emptyThe wallet for this mode is empty.
What to do: Add credits in the console, then retry.
403 Known, but not allowed19 codes
account_blockedThis account or user is blocked.
What to do: Contact Vestra support.
app_not_allowedThis app is not on the deployment's list of apps.
What to do: Add it to the deployment's apps, or pick an app that is there.
client_token_not_allowedA session's token cannot call this route.
What to do: Call it from your server, with an API key.
domain_not_allowedThe page is on a site the user's deployment does not list in browser.allowed_domains, or a browser fetch's page went to one.
What to do: Add the site to the deployment's browser.allowed_domains, or open a page on a site that is there.
email_requiredThe signed-in Vestra account has no email address, and a company account is made for an email.
What to do: Sign in with an account that has an email address, or contact Vestra support.
insufficient_roleThis caller cannot do this: a console member without the role, or a session token.
What to do: Ask an owner or admin, or call it with an API key.
live_mode_requiredOnly a live key changes what live users run.
What to do: Use a live key, or the console in live mode.
not_an_org_memberYou are not a member of this company account.
What to do: Ask an owner to invite you, or choose a company you belong to.
not_interview_computerOnly the deployment's own interview can save its draft.
What to do: Let the interview finish; it saves the draft itself.
org_disabledThis company account is switched off.
What to do: Contact Vestra support.
origin_not_allowedThis page is not an allowed origin for this company.
What to do: Add the origin to allowed_embed_origins with PATCH /v1/org.
page_blockedThe page is on the deployment's browser.blocked_paths, such as a payment page, so the browser does not open it or act on it.
What to do: Leave payments to the person, on their own device. Change browser.blocked_paths on the deployment only if this page should be open to the browser.
sandbox_token_requiredOnly the interview computer can post this result.
What to do: Nothing to do: this route is for Bash itself.
scope_escalationA key cannot give a scope it does not have.
What to do: Make the new key with a key that has the scopes, or ask for fewer.
scope_missingThis key's scopes do not reach this route.
What to do: Make a key with the scope the message names, in the console or with POST /v1/keys.
staff_onlyThis route is for Vestra staff.
What to do: Nothing to do: it is not part of the API you call.
test_mode_requiredOnly a test key does this: interviews, and changes to what test users run.
What to do: Use a test key, or the console in test mode.
user_disabledThis user is switched off.
What to do: Turn them back on with PATCH /v1/users/{user_id}.
view_onlyThis session can watch the screen but not drive it.
What to do: Open the session with screen: "control" to take the wheel.
404 Not found27 codes
batch_not_foundNo batch by that id, for this key's company and mode.
What to do: Check the id, and that the key is of the mode the thing was made in: a test key never sees live data.
connection_not_foundNo connected app by that id, for this key's company and mode.
What to do: Check the id, and the user it belongs to: list them with GET /v1/connections.
conversation_not_foundNo conversation by that id, for this key's company and mode.
What to do: Check the id and the key's mode. A session token reaches only its own conversation.
delivery_not_foundNo webhook delivery by that id, for this key's company and mode.
What to do: List the deliveries with GET /v1/webhooks/{endpoint_id}/deliveries.
deployment_not_foundalso 400No deployment by that id, for this key's company and mode.
What to do: Check the name or dep_ id. Inside a file or a batch, it answers 400 on the field that names it.
deployment_version_not_foundNo deployment version by that id, for this key's company and mode.
What to do: List the versions with GET /v1/deployments/{deployment_id}/versions.
document_not_foundNo notebook document by that id, for this key's company and mode.
What to do: List the documents with GET /v1/notebooks/{notebook_id}/documents.
event_not_foundNo event by that id, for this key's company and mode.
What to do: List the recent ones with GET /v1/events.
file_not_foundalso 400No file by that id, for this key's company and mode.
What to do: Check the id. A file attached to a message answers 400 on that field.
interaction_not_foundNo interaction by that id, for this key's company and mode.
What to do: List what Bash waits on with GET /v1/interactions. A session token reaches only its own.
key_not_foundNo API key by that id, for this key's company and mode.
What to do: List the keys with GET /v1/keys.
mcp_server_not_foundalso 400No MCP server by that id, for this key's company and mode.
What to do: List them with GET /v1/mcp-servers. Inside a version, it answers 400 on the field.
memory_not_foundNo memory by that id, for this key's company and mode.
What to do: List what Bash remembers with GET /v1/memory.
notebook_not_foundalso 400No notebook by that id, for this key's company and mode.
What to do: List them with GET /v1/notebooks. Inside a version, it answers 400 on the field.
org_not_foundThe company account behind this call was not found.
What to do: Contact Vestra support.
route_not_foundNo route has that method and path.
What to do: Check the path against the API reference, and that it starts /v1/.
routine_not_foundNo routine by that id, for this key's company and mode.
What to do: List them with GET /v1/routines.
scenario_not_foundNo test scenario by that id, for this key's company and mode.
What to do: List them with GET /v1/deployments/{deployment_id}/scenarios.
secret_not_foundNo secret by that name, for this mode and user.
What to do: List the names with GET /v1/secrets.
session_not_foundNo session by that id, for this key's company and mode.
What to do: Check the id. A session ends when its token does.
skill_not_foundalso 400No skill by that id, for this key's company and mode.
What to do: List them with GET /v1/skills. Inside a file or a version, it answers 400 on the field.
task_not_foundNo task by that id, for this key's company and mode.
What to do: List the work with GET /v1/tasks.
test_run_not_foundNo test run by that id, for this key's company and mode.
What to do: List them with GET /v1/deployments/{deployment_id}/test-runs.
tool_call_not_foundNo call to your tool by that id, for this key's company and mode.
What to do: Answer the id the interaction gave you.
turn_not_foundNo turn by that id, for this key's company and mode.
What to do: Check the conversation and the turn id.
user_not_foundalso 400No user by that id, for this key's company and mode.
What to do: Users are made the first time you act for them, or with POST /v1/users. Reads never make one.
webhook_endpoint_not_foundNo webhook endpoint by that id, for this key's company and mode.
What to do: List them with GET /v1/webhooks.
405 Not a method this route takes1 code
method_not_allowedThe MCP endpoint takes POST only.
What to do: Send JSON-RPC to POST /v1/mcp.
409 The state does not allow it now52 codes
already_a_memberYou already belong to a company account, or this email already made one: a person makes only one of their own.
What to do: Open the developer console to use it. To join another, or if yours is gone, ask Vestra to add you.
batch_not_runningThat batch has already finished.
What to do: Read its items with GET /v1/batches/{batch_id}/items.
browser_busyThe user's browser is already running four browser fetches.
What to do: Retry after retry_after_ms, about a second, or run them one after another.
browser_in_useA person is using this browser right now, so a browser fetch yields to them.
What to do: Retry in a few seconds, when they are done.
browser_not_openBash's browser is not open right now.
What to do: Ask Bash for work that opens its browser, then try again.
call_not_openThe call ended before its line opened.
What to do: Start the call again.
conversation_busyBash is still replying in this conversation.
What to do: Wait for the reply, or stop it with POST /v1/conversations/{conversation_id}/stop.
delivery_in_flightThis delivery is being sent right now.
What to do: Try again in a minute.
deployment_archivedThis deployment is archived.
What to do: Unarchive it with PATCH /v1/deployments/{deployment_id} first.
deployment_busySeveral versions were saved at once.
What to do: Try again.
deployment_changedThe deployment changed while this ran.
What to do: Read the deployment again, then retry.
deployment_is_defaultThis deployment is a default, for the company or for users, so it cannot be archived.
What to do: Set another default with PATCH /v1/org or PATCH /v1/users/{user_id}, then archive it.
deployment_not_liveThis deployment has no live version yet.
What to do: Promote a version first, or call it with a test key.
idempotency_in_progressA request with this Idempotency-Key is still running.
What to do: Retry in a moment: you get its answer.
idempotency_key_reusedThis Idempotency-Key was used for a different request.
What to do: Use a new key for a new request.
interaction_already_settledThis interaction was already answered or withdrawn.
What to do: Nothing to do: read it to see how it settled.
limits_changedThe limits changed while you saved.
What to do: Read them with GET /v1/limits and retry.
mcp_server_existsAn MCP server with this slug already exists.
What to do: Use the one there, or give a new slug.
mcp_server_liveA live deployment uses this MCP server.
What to do: Change it with a live key, or as an owner or admin.
memory_not_keptThis company keeps memory on its own side, so Bash holds none here.
What to do: Read the memory from your own store.
memory_offMemory is off for this company.
What to do: Turn it on with PATCH /v1/org and a memory_mode.
memory_panel_offShowing a user what Bash remembers is off for this company.
What to do: Turn it on with PATCH /v1/org and memory_panel: true.
no_open_tabA browser fetch with no url runs on the tab an earlier fetch kept open under its tab name, and none is kept under it now.
What to do: Send url, with keep_open_ms to keep its tab for the next fetch.
no_scenariosThis deployment has no tests yet, so there is nothing to run.
What to do: Add tests to vestra.yaml (or draft some with POST /v1/deployments/{deployment_id}/scenarios/generate), deploy, then run them.
not_a_company_userThis user cannot be erased through the API.
What to do: Contact Vestra support.
notebook_busyThe notebook changed while this call ran.
What to do: Retry it.
notebook_existsA notebook with this slug already exists.
What to do: Use the one there, or give a new slug.
nothing_to_roll_backThere is no earlier live version to go back to.
What to do: Promote the version you want instead.
org_routine_limit_reachedThe company has 200 active routines in this mode.
What to do: Delete some; a copy for each user counts too.
payment_in_progressThe person is paying for something in their browser right now; screenshots and the screen are paused until the payment ends.
What to do: Try again in a minute.
routine_completedThis routine has finished and does not run again.
What to do: Make a new routine.
routine_limit_reachedThis user, or your company's own Bash, has as many active routines as it may.
What to do: Delete or pause one first.
routine_name_takenA routine by this name already exists, and the file does not own it.
What to do: Rename one of them.
routine_not_linkedThis routine was not made through the API, so it has no conversation to run in.
What to do: Make the routine with POST /v1/routines.
routine_pausedThis routine is paused.
What to do: Resume it with PATCH /v1/routines/{routine_id} and enabled: true, then run it.
session_has_no_screenThis session was opened without a screen.
What to do: Open one with screen: "view" or "control".
session_has_no_voiceThis session was opened without voice.
What to do: Open one with voice: true.
skill_existsA skill with this slug already exists.
What to do: Upload a new version with PUT /v1/skills/{skill_id}, or give a new slug.
slug_takenA deployment with this slug already exists.
What to do: Choose another name, or send a slug.
test_run_failedThis version failed its latest test run, so it is not promoted.
What to do: Fix it, run the tests again, then promote.
test_run_in_progressA test run for this version is already running.
What to do: Wait for its verdict with GET /v1/test-runs/{test_run_id}.
test_run_requiredThis version has no passing test run.
What to do: Run the tests with POST /v1/deployments/{deployment_id}/test-runs, then promote.
test_runs_busyToo many test runs are running: this company has as many as it may, or we do.
What to do: Try again when one finishes.
too_many_batchesThe company already runs as many batches as it may in this mode.
What to do: Wait for one to finish, or cancel one.
too_many_scenariosThe deployment would hold more test scenarios than it may.
What to do: Remove scenarios made by hand, or declare fewer tests.
tool_call_not_pendingThat call to your tool is not waiting for a result.
What to do: Nothing to do: it was answered, or it expired.
user_create_in_progressAnother request is making this user right now.
What to do: Retry in a moment.
version_never_liveThat version was never live, so there is nothing to roll back to.
What to do: Promote it instead.
version_not_liveA live key always runs the live version, so it cannot pin one.
What to do: Drop the @version, or pin it with a test key.
410 Gone1 code
stream_expiredThe events after that point are no longer kept.
What to do: Read the conversation again with GET /v1/conversations/{conversation_id}, and follow its events from now.
413 Too large1 code
export_too_largeThis user holds more than an export carries.
What to do: Ask Vestra support for the export.
415 Not a type this route reads1 code
unsupported_media_typeThe body is in a type this route does not read.
What to do: Send JSON with Content-Type: application/json, or the type the route names.
429 Slow down7 codes
export_in_progressAnother export of this user is being built.
What to do: Retry in a minute.
rate_limitedToo many requests.
What to do: Slow down, and retry after the Retry-After seconds.
routine_fire_budgetThis routine, or this company, has used its runs for this hour.
What to do: Try again later.
too_many_in_flightToo many requests at once.
What to do: Wait for one to finish, then retry.
too_many_streamsToo many open streams.
What to do: Close one, then retry.
voice_busyToo many voice calls are open.
What to do: Retry in a minute.
warm_limitMany computers are already waking for this company.
What to do: Retry in a moment.
5xx Our side: retry34 codes
cancel_failed500The interaction was not withdrawn.
What to do: Retry the call.
connect_failed502The connect link could not be made.
What to do: Retry in a moment.
delete_failed502The file could not be deleted.
What to do: Try again.
disconnect_failed502The app could not be disconnected.
What to do: Retry in a moment.
generator_busy503Drafting tests is slow right now.
What to do: Retry after the Retry-After seconds.
internal_error500Something went wrong on our side.
What to do: Retry. If it keeps happening, send Vestra the request_id.
interview_failed502The interview stopped before its draft was saved.
What to do: Start again with a description.
mcp_auth_required502The MCP server asked for credentials it was not given.
What to do: Give the server's credentials as a header with ${secret:NAME}.
mcp_failed500The MCP request failed on our side.
What to do: Retry it.
mcp_missing_secret502The MCP server names secrets that are not stored.
What to do: Store them with PUT /v1/secrets/{name}.
mcp_unreachable502The MCP server did not answer.
What to do: Check that it is up and reachable from the internet, then check it again.
mcp_url_not_public502The MCP server's address is not public.
What to do: Use an https URL that reaches the public internet.
memory_write_failed502The memory could not be saved.
What to do: Retry shortly.
not_implemented501This is not available yet.
What to do: Nothing to do now: the changelog says when it ships.
resolve_failed500The answer was not recorded.
What to do: Retry the call.
route_failed502A call an MCP tool made inside the API failed.
What to do: Retry it.
scenario_generation_failed502Tests could not be drafted this time.
What to do: Try again, or write the tests yourself in vestra.yaml.
screenshot_failed502The browser did not answer with a picture.
What to do: Try again.
timeout504A browser fetch's page did not send every capture in time. partial holds what it did send.
What to do: Use what partial holds, or retry with a longer timeout_ms, up to 20000.
tool_result_undelivered502The result could not reach the work.
What to do: Try again.
upload_failed502The file could not be stored.
What to do: Try again.
user_create_failed502The user could not be made.
What to do: Retry the request.
voice_connect_failed502The call could not be opened.
What to do: Start it again.