BashBrainTeammatesPricingDevelopersGet a test key

Users

Your users: set one up, read their spend, change their cap, export or erase them.

Send Authorization: Bearer vk_test_... on every call.

RoutesOpen one for every field it takes and answers.

POST/v1/usersCreate one of your users, or return the existing one.

Safe to repeat with the same user_id.

Your API key, scope admin or all. On the card: users. Every call here is a checked sample.

Request7 fields

Headers

Idempotency-KeystringSend the same key to retry this call safely for 24 hours.
Type
string

Body

user_idstringrequiredYour own id for the user. Sending one that exists changes nothing and makes no second user.
Example
traveller-42
namestringThe user's name, as Bash may call them: at most 200 characters.
Limits
1 to 200 characters.
Example
Priya Sharma
emailstring (email)The user's email address.
Limits
At most 320 characters.
Example
priya@example.com
localestringThe user's language and region, as a BCP 47 tag.
Limits
2 to 35 characters.
Example
en-IN
timezonestringThe user's time zone, as an IANA name: their routines run in it.
Limits
1 to 64 characters.
Example
Asia/Kolkata
metadatamap of anyYour own facts about the user, as JSON, given back as you sent them.
Type
map of any
Answers 20017 fields
idstringYour own id for the user.
Example
traveller-42
object"user"Always user.
Type
"user"
namestring | nullThe user's name; null when you gave none.
Type
string | null
emailstring | nullThe user's email address; null when you gave none.
Type
string | null
localestring | nullThe user's language and region (BCP 47); null when you gave none.
Type
string | null
timezonestring | nullThe user's time zone (IANA); null when you gave none, and their routines then run in UTC.
Type
string | null
metadatamap of anyYour own facts about the user; empty when you gave none.
Type
map of any
status"active" | "disabled"active, or disabled: a disabled user's calls are refused (403 user_disabled) until you turn them back on.
Type
"active" | "disabled"
spend_cap_usdnumber | nullThe user's own cap per day, in billed US dollars, never above your company's; null: your company's cap for each user, if any.
Type
number | null
monthly_cap_usdnumber | nullThe user's own cap per calendar month (UTC), in billed US dollars; null: your company's cap for each user, if any.
Type
number | null
default_deploymentstring | nullThe deployment their conversations use when none is named (dep_...); null: your company's default.
Type
string | null
memory_mode"vestra" | "customer" | "none"Where Bash's memory of this user lives: vestra, customer (your memory endpoint), or none.
Type
"vestra" | "customer" | "none"
is_service_userbooleantrue for a user Vestra keeps for itself, such as your company's own Bash; false for your users.
Type
boolean
created_atstringWhen the user was made, as an ISO 8601 time.
Type
string
spend_today_usdnumberWhat they have spent today (UTC), in billed US dollars.
Example
1.24
spend_month_usdnumberWhat they have spent this calendar month (UTC), in billed US dollars.
Example
18.6
caps_remainingobjectWhat is left under every cap that applies to them: the smaller of their own and your company's.
day_usdnumber | nullWhat they may still spend today, in US dollars; null when no cap applies.
Type
number | null
month_usdnumber | nullWhat they may still spend this month, in US dollars; null when no cap applies.
Type
number | null
TypeScript
await vestra.users.create('traveller-42');
Python
vestra.users.create("traveller-42")
HTTP
# Create a user. Do it before their first ask to set their name and time zone. It is safe to repeat with the# same user_id.curl "$VESTRA_BASE_URL/v1/users" \  -H "Authorization: Bearer $VESTRA_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "user_id": "traveller-42", "name": "Priya Sharma", "timezone": "Asia/Kolkata" }' # Read their spend. Their profile shows what they spent today and this month, against their caps.curl "$VESTRA_BASE_URL/v1/users/traveller-42" \  -H "Authorization: Bearer $VESTRA_API_KEY" # Set a monthly cap. This one is 20 US dollars.curl -X PATCH "$VESTRA_BASE_URL/v1/users/traveller-42" \  -H "Authorization: Bearer $VESTRA_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "monthly_cap_usd": 20 }' # Wake their computer. Do it before they need it.curl -X POST "$VESTRA_BASE_URL/v1/users/traveller-42/warm" \  -H "Authorization: Bearer $VESTRA_API_KEY" # Open a page in their browser with no model, and keep the page's own data calls. The site must be in their# deployment's browser.allowed_domains.curl -X POST "$VESTRA_BASE_URL/v1/users/traveller-42/browser/fetch" \  -H "Authorization: Bearer $VESTRA_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "url": "https://www.ixigo.com/search/result/flight?from=DEL&to=GOI&date=06112026&adults=2&class=e", "capture": [{ "match": "/flights/v2/search/stream" }] }' # Erase a user. It runs as a job: the response is 202 with deleted false and status deleting, and then# user.deleted says it is done.curl -X DELETE "$VESTRA_BASE_URL/v1/users/traveller-42" \  -H "Authorization: Bearer $VESTRA_API_KEY"
MCP
{  "method": "tools/call",  "params": {    "name": "users_get",    "arguments": { "user": "traveller-42" }  }}
HTTP

No sample in your language for this route, so here it is over HTTP.

# Create a user. Do it before their first ask to set their name and time zone. It is safe to repeat with the# same user_id.curl "$VESTRA_BASE_URL/v1/users" \  -H "Authorization: Bearer $VESTRA_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "user_id": "traveller-42", "name": "Priya Sharma", "timezone": "Asia/Kolkata" }' # Read their spend. Their profile shows what they spent today and this month, against their caps.curl "$VESTRA_BASE_URL/v1/users/traveller-42" \  -H "Authorization: Bearer $VESTRA_API_KEY" # Set a monthly cap. This one is 20 US dollars.curl -X PATCH "$VESTRA_BASE_URL/v1/users/traveller-42" \  -H "Authorization: Bearer $VESTRA_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "monthly_cap_usd": 20 }' # Wake their computer. Do it before they need it.curl -X POST "$VESTRA_BASE_URL/v1/users/traveller-42/warm" \  -H "Authorization: Bearer $VESTRA_API_KEY" # Open a page in their browser with no model, and keep the page's own data calls. The site must be in their# deployment's browser.allowed_domains.curl -X POST "$VESTRA_BASE_URL/v1/users/traveller-42/browser/fetch" \  -H "Authorization: Bearer $VESTRA_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "url": "https://www.ixigo.com/search/result/flight?from=DEL&to=GOI&date=06112026&adults=2&class=e", "capture": [{ "match": "/flights/v2/search/stream" }] }' # Erase a user. It runs as a job: the response is 202 with deleted false and status deleting, and then# user.deleted says it is done.curl -X DELETE "$VESTRA_BASE_URL/v1/users/traveller-42" \  -H "Authorization: Bearer $VESTRA_API_KEY"
GET/v1/usersList your users.

Your API key, scope runtime or all. On the card: users. Over HTTP it is made from the contract: fill in every value.

GET/v1/users/{user_id}One user: status, profile, memory mode, default deployment, and what they spent today and this month against their caps.

Your API key, scope runtime or all. On the card: users. Every call here is a checked sample.

PATCH/v1/users/{user_id}Change name, language, time zone, metadata, day or month spend cap, default deployment, or status (active or disabled).

Your API key, scope admin or all. On the card: users. Every call here is a checked sample.

DELETE/v1/users/{user_id}Erase the user and everything Bash holds for them: computer, files, memory.

Runs as a job; a webhook says when it is done.

Your API key, scope admin or all. On the card: users. Every call here is a checked sample.

POST/v1/users/{user_id}/exportPackage everything held for the user into one download, for data-rights requests.

Your API key, scope admin or all. On the card: users. Over HTTP it is made from the contract: fill in each {…} and every value.