> ## Documentation Index
> Fetch the complete documentation index at: https://vetta.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Organizations

> The billing entity that owns members, keys, and resources.

An **organization** is the top-level container and billing entity. It holds the [credit balance](https://vetta.sh/docs/api/credits.md), owns every agent, computer, skill, and file, and has **members** (users with a role) and **API keys** (programmatic access). Every request is scoped to exactly one organization via its [API key](https://vetta.sh/docs/api/authentication.md).

## The organization object

**id** `string`

Unique id (e.g. `org_01H...`).

**name** `string`

Display name.

**balance\_micro\_usd** `integer`

Current [credit balance](https://vetta.sh/docs/api/credits.md), in micro-USD.

**timezone** `string`

The company's timezone, an IANA name such as `America/New_York` (every company starts there). A [deployment](https://vetta.sh/docs/api/deployments.md) created without a `timezone` takes this one, and the studio says when a post goes out in it.

**logo\_svg** `string | null`

The company's logo, an SVG (see [The logo](#the-logo)); `null` until one is set. The studio shows it in its top-left corner and in its apps.

**brand** `object | null`

The company's brand kit (see [The brand kit](#the-brand-kit)): `{ palette, typeface, tagline }`; `null` until one is set. Whoever makes things in the company's look reads it.

**setting\_up** `boolean`

`true` while the company is being set up: made in a chat with its CEO and not yet activated by a paid [plan](https://vetta.sh/docs/api/credits.md). It turns `false` the first time the plan reads active and never back, even if the plan later lapses.

**start\_template** `string | null`

The `blueprint/template` a link named when the company was made (see [Set up a company](#set-up-a-company)); `null` otherwise.

**ceo\_agent\_id** `string | null`

The company's CEO: the one agent whose turns are given the control plane. Recorded when an admin binds this API's `/v1/mcp` to an agent in the "Orchestrator control plane" vault (see [Vaults](https://vetta.sh/docs/api/vaults.md)); `null` while there is none, or after the CEO is deleted. The setup chat responds without it.

**created\_at** `string`

Creation timestamp.

## Create an organization

`POST /v1/organizations` → `201 Created`

The only write that is **not** scoped to an organization — it is how an existing caller gets *another* one. Authenticate with either an `admin` [API key](https://vetta.sh/docs/api/authentication.md) or a signed-in user session; an unauthenticated call is refused with `401`. Your first organization comes from signing up, not from this route.

**name** `string` *required*

Display name for the organization.

**referral\_code** `string`

A creator's referral code, accepted from a signed-in user session only. Attributes the new organization to that creator; a code that cannot be honoured is ignored and the organization is still created.

```bash theme={"system"}
curl -fsSL https://api.vetta.sh/v1/organizations \
  -H "authorization: Bearer sk_live_..." \
  -H "content-type: application/json" \
  -d '{ "name": "Acme" }'
```

```json Response theme={"system"}
{
  "organization": { "id": "org_01H8AA...", "object": "organization", "name": "Acme", "balance_micro_usd": 0, "created_at": "2026-08-20T17:00:00Z" },
  "api_key": { "id": "key_01H8AB...", "object": "api_key", "name": "Acme", "prefix": "sk_live_9f2c", "scopes": ["admin"], "org_id": "org_01H8AA...", "mode": "live", "secret": "sk_live_9f2c...redacted", "created_at": "2026-08-20T17:00:00Z" }
}
```

The reply carries **two** objects: the organization and the first `admin` key that opens it, whose `secret` is returned here and never again. A caller signed in as a person also becomes the founding `owner`.

For a signed-in person whose only company is the one [being set up](#set-up-a-company) for them when they confirmed their email, the first create takes that company if nothing has touched it yet (still "New company", no template, no CEO chat, no key): it is renamed to `name` and returned with whatever setup credit it was given, still `setting_up` until its plan is paid. Otherwise a new organization is made. An API key's create always makes a new one.

## Set up a company

`POST /v1/organizations/setup` → `201 Created`, or `200 OK` when it already exists

The company a **signed-in person** is setting up, found or made. A person with no company starts here: the company is made unnamed ("New company"), live, with them as its `owner`, and it is set up in a chat with its CEO before it is paid for. Until it is paid for, asking again — another tab, a retry, another Deploy — answers the same one. Once it is activated by a payment, the next call makes a new one. (The dashboard calls this for New company. A Deploy from a company that already runs a template adds it to that company instead, as a second [install](https://vetta.sh/docs/api/apps.md).) One exception: a call that names a `template` while the person owns an activated company on a live plan that runs nothing answers that company (`200`, `setting_up: false`, no setup credit), so its first template is set up there rather than beside it. It mints no API key. An API key, or a call with no session, is refused with `403` or `401`.

**template** `string`

The `blueprint/template` a link named, such as `media/faceless`. Stored as `start_template` when the company is made, and replaces it when the company is found again; leaving it out clears it. A `held` install in it is kept; holding another template replaces it. Anything that is not two lower-case names joined by `/` is `400 validation_failed`.

**referral\_code** `string`

A creator's referral code, as on [create](#create-an-organization).

```json Response theme={"system"}
{ "organization": { "id": "org_01H8AA...", "object": "organization", "name": "New company", "balance_micro_usd": 1000000, "timezone": "America/New_York", "logo_svg": null, "brand": null, "setting_up": true, "start_template": "media/faceless", "created_at": "2026-09-30T17:00:00Z" } }
```

**Before it is activated**, only its CEO chat runs, on the setup model, paid for by a one-time setup credit the company is given here. The credit is **once per person**: an address that is another spelling of one whose company is still being set up (a `+tag`, or Gmail's dots) gets its company but no second credit. A person whose earlier company was activated is credited again. A company being set up cannot [top up](https://vetta.sh/docs/api/credits.md#top-up) (`402`); its next step is the plan. A template set up in that chat is recorded as `held` and built when the company is activated ([installs](https://vetta.sh/docs/api/apps.md)).

## List, retrieve & update

```bash theme={"system"}
GET   /v1/organizations         # list the orgs the caller belongs to
GET   /v1/organizations/{id}    # retrieve
```

`GET /v1/organizations` is **orgless** — it answers on a user session rather than an org-scoped key, which is what makes org switching possible. See [Authentication](https://vetta.sh/docs/api/authentication.md).

```json Response theme={"system"}
{ "id": "org_01H8AA...", "object": "organization", "name": "Acme", "balance_micro_usd": 48250000, "timezone": "America/New_York", "logo_svg": null, "brand": null, "setting_up": false, "start_template": null, "created_at": "2026-08-20T17:00:00Z" }
```

### Update an organization

`PATCH /v1/organizations/{id}`

**name** `string`

New display name.

**timezone** `string`

New timezone, an IANA name (`America/Los_Angeles`). It is stored under its canonical name (`US/Eastern` is kept as `America/New_York`). An abbreviation (`EST`), an offset (`+05:00`) or a name the platform does not know is `400 validation_failed` on `timezone`. Only the fields you send are changed: a rename leaves the timezone as it is.

**logo\_svg** `string | null`

A new logo, as SVG text; `null` removes it. It is stored trimmed, with `xmlns="http://www.w3.org/2000/svg"` added to the root when it has none. A logo the rules below refuse is `400 validation_failed` on `logo_svg`, and the message says what to change.

**brand** `object | null`

A new brand kit; `null` removes it. See [The brand kit](#the-brand-kit). A kit that does not match it exactly is `400 validation_failed` on `brand`.

Send at least one of them. Only the fields you send are changed. Returns the updated organization object. A company [being set up](#set-up-a-company) can be updated too: its CEO names it and sets its logo and brand kit before it is activated.

### The logo

A logo is one `<svg>` element that the platform checks before it stores it. The check is an allow-list:

* At most 16 KB, and exactly one root `<svg>` with a `viewBox` of four numbers. No nested `<svg>`.
* Elements: `svg`, `g`, `path`, `rect`, `circle`, `ellipse`, `line`, `polyline`, `polygon`, `defs`, `linearGradient`, `radialGradient`, `stop`, `title`, `desc`, `clipPath`, `mask`. `<title>` and `<desc>` hold words only. Anything else is refused, including `<text>` (draw letters as paths), `<image>`, `<use>`, `<style>`, `<script>`, `<a>` and animation.
* Attributes: geometry and presentation only (`viewBox`, `xmlns`, `width`, `height`, `x`…`y2`, `cx`, `cy`, `r`, `rx`, `ry`, `d`, `points`, `fill`, `stroke` and its `stroke-*` family, `opacity`, `fill-opacity`, `fill-rule`, `clip-rule`, `transform`, `offset`, `stop-color`, `stop-opacity`, `gradientUnits`, `gradientTransform`, `id`, `clip-path`, `mask`, `preserveAspectRatio`, `fx`, `fy`, `spreadMethod`, `role`, `aria-hidden`). Every value is quoted. No `on…` handlers, `href`, `style` or `class`.
* A value holds numbers, names, `#colours` and `url(#id)` only: no other `url(…)`, no `javascript:`, `data:` or `http`, no entities, and no `<`.
* No comments, CDATA, DOCTYPE, entities or processing instructions.

An agent can set the logo too, with the [`company.set_logo`](https://vetta.sh/docs/capabilities/tools#company-settings-tools) tool. It passes the same check.

### The brand kit

The company's look, beside its logo: a palette, a typeface and a tagline.

**palette** `object[]`

3 to 6 colours, each `{ name, hex }`: a name of 1–24 characters and a lower-case `#rrggbb`.

**typeface** `string`

`grotesk`, `serif`, `rounded` or `mono`.

**tagline** `string`

One line of up to 80 characters; `""` for none.

```json theme={"system"}
{ "palette": [{ "name": "Ink", "hex": "#1b1f3a" }, { "name": "Tide", "hex": "#2f6fdf" }, { "name": "Foam", "hex": "#eef3fb" }], "typeface": "grotesk", "tagline": "Small-batch bread, daily." }
```

No other field is accepted. An agent sets it with [`company.set_brand`](https://vetta.sh/docs/capabilities/tools#company-settings-tools), which builds the palette from one colour.

## Members

Users belong to an organization with a role that controls what they can do.

| Role | Can do |
| - | - |
| `owner` | Everything, including billing, members, and deleting the org. |
| `admin` | Manage agents, computers, skills, keys, and view billing. |
| `member` | Create and run agents within the org's resources. |

### The member object

**id** `string`

Member id (e.g. `usr_01H...`). It is the id the member routes address and the id the [audit log](https://vetta.sh/docs/api/audit-logs.md) records as the actor.

**email** `string`

The member's email address.

**role** `string`

`owner | admin | member`.

**invited\_by** `string | null`

Id of the member who invited them; `null` for the founding owner.

**created\_at** `string`

When the member joined the organization.

### List members

`GET /v1/organizations/{id}/members` — cursor-paginated. See [Pagination](https://vetta.sh/docs/api/pagination.md). Readable before the organization has a [plan](https://vetta.sh/docs/api/credits.md), so you can find its owner before paying; adding, changing and removing members need one.

```json Response theme={"system"}
{
  "data": [
    { "id": "usr_01H...", "email": "owner@acme.com", "role": "owner", "invited_by": null, "created_at": "2026-06-01T09:00:00Z" },
    { "id": "usr_01H...", "email": "alice@acme.com", "role": "admin", "invited_by": "usr_01H...", "created_at": "2026-08-20T17:00:00Z" }
  ],
  "has_more": false,
  "next_cursor": null
}
```

### Add a member

`POST /v1/organizations/{id}/members`

**email** `string` *required*

Email address to invite.

**role** `string` *required*

`owner | admin | member`.

```bash theme={"system"}
curl -fsSL https://api.vetta.sh/v1/organizations/org_01H8AA.../members \
  -H "authorization: Bearer sk_live_..." \
  -H "content-type: application/json" \
  -d '{ "email": "alice@acme.com", "role": "admin" }'
```

```json Response theme={"system"}
{ "id": "usr_01H9JJ...", "object": "member", "email": "alice@acme.com", "role": "admin", "invited_by": "usr_01H...", "created_at": "2026-08-20T17:00:00Z" }
```

### Update a member's role

`PATCH /v1/organizations/{id}/members/{member_id}`

**role** `string` *required*

`owner | admin | member`.

### Remove a member

`DELETE /v1/organizations/{id}/members/{member_id}`

Both mutations are recorded in the [audit log](https://vetta.sh/docs/api/audit-logs.md) as `member.role_changed` and `member.removed`, attributed to the acting principal.

> [!WARNING]
>
> **Removal does not cascade.** It deletes the membership row and nothing else. API keys that member created keep working and sessions running under them keep running — revoke each one you want stopped with `DELETE /v1/api_keys/{id}`, reading `GET /v1/api_keys` first, because a key's `created_by` is the only record of who minted it. Agents, skills and files are org-owned and remain. Re-inviting the same email creates a new member.

## API keys

Programmatic access uses org-scoped API keys, managed under `/v1/api_keys`. For creation, scopes, and rotation, see [Authentication](https://vetta.sh/docs/api/authentication.md).

```bash theme={"system"}
POST   /v1/api_keys              # create
GET    /v1/api_keys              # list (cursor-paginated)
POST   /v1/api_keys/{id}/rotate  # rotate
DELETE /v1/api_keys/{id}         # revoke
```

> [!WARNING]
>
> Only `owner` and `admin` members (or a key with the `admin` scope) can manage members and API keys.

> [card] [Credits & billing](https://vetta.sh/docs/api/credits.md)
>
> The org's real-USD balance, ledger, and top-ups.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.