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

# Organizations

> Accounts, members, invites, and organization-scoped API keys

# Organizations

An **Organization** is the top-level account in Bedrock. Every AgentTemplate, Agent, API Key, and private Adapter belongs to exactly one organization. Users become members of an organization when they sign up (they create a new org) or when they accept an invite to an existing one.

Organizations also hold the org-wide LLM provider keys (`openai_api_key`, `anthropic_api_key`). These are used for every agent run in the organization, with a fallback to the `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` environment variables.

## Structure

* **Organization** — owns everything else
  * **Members** — Bedrock portal users with `OrganizationMembership`
  * **Invites** — pending email invites that create a member on acceptance
  * **API Keys** — organization-scoped Bearer keys
  * **Templates** — [AgentTemplates](/concepts/templates) that blueprint new agents
  * **Adapters (private)** — custom adapters visible only to this org
  * **LLM Provider Keys** — `openai_api_key` / `anthropic_api_key` used by every agent in the org

<Note>
  Each user can belong to exactly one organization at a time (`OrganizationMembership` is one-to-one on `user`). To switch orgs, a user must be invited to the other org and create a new account.
</Note>

## Admin Orgs

Organizations have an `is_admin` flag. Admin orgs unlock access to the full list
of organizations via `GET /api/organizations/organizations/`.

Non-admin orgs only see themselves. `is_admin` is set manually by Bedrock operators; it is not exposed as a mutation in the API.

## Authentication Endpoints

All endpoints below live under `/api/organizations/auth/`.

### Sign Up

Creates an organization, user, membership, and token in a single transaction.

```bash theme={null}
curl -X POST https://api.bedrock.orinlabs.org/api/organizations/auth/signup/ \
  -H "Content-Type: application/json" \
  -d '{
    "org_name": "Acme",
    "email": "founder@acme.com",
    "password": "supersecret"
  }'
```

Response:

```json theme={null}
{
  "token": "abcd1234...",
  "user": {"id": 1, "email": "founder@acme.com"},
  "organization": {"id": "org-uuid", "name": "Acme"}
}
```

### Log In

```bash theme={null}
curl -X POST https://api.bedrock.orinlabs.org/api/organizations/auth/login/ \
  -H "Content-Type: application/json" \
  -d '{"email": "founder@acme.com", "password": "supersecret"}'
```

Returns the same shape as signup (token + user + organization). The token is what the Bedrock portal stores and sends as `Authorization: Token <value>`.

### Current User

```bash theme={null}
curl -X GET https://api.bedrock.orinlabs.org/api/organizations/auth/me/ \
  -H "Authorization: Token USER_TOKEN"
```

```json theme={null}
{
  "id": 1,
  "email": "founder@acme.com",
  "username": "founder@acme.com",
  "first_name": "",
  "last_name": "",
  "organization": {
    "id": "org-uuid",
    "name": "Acme",
    "is_admin": false
  }
}
```

### Log Out

Deletes the caller's token. Subsequent requests with that token will fail with `401`.

```bash theme={null}
curl -X POST https://api.bedrock.orinlabs.org/api/organizations/auth/logout/ \
  -H "Authorization: Token USER_TOKEN"
```

## Members

List members of the current organization:

```bash theme={null}
curl -X GET https://api.bedrock.orinlabs.org/api/organizations/members/ \
  -H "Authorization: Token USER_TOKEN"
```

Remove a member:

```bash theme={null}
curl -X DELETE https://api.bedrock.orinlabs.org/api/organizations/members/USER_ID/ \
  -H "Authorization: Token USER_TOKEN"
```

<Warning>
  You cannot remove yourself — the API returns `400 Bad Request`. Have another member remove you if needed.
</Warning>

Member objects look like:

```json theme={null}
{
  "id": "membership-uuid",
  "user_id": 42,
  "email": "alice@acme.com",
  "first_name": "Alice",
  "last_name": "Anders",
  "joined_at": "2025-03-14T10:30:00Z"
}
```

## Invites

Send an email invite for someone to join the org:

```bash theme={null}
curl -X POST https://api.bedrock.orinlabs.org/api/organizations/invites/ \
  -H "Authorization: Token USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email": "bob@acme.com"}'
```

Constraints:

* The email must not already be invited (pending) or an active member.
* Only the `email` is accepted; `invited_by`, `created_at`, and `accepted_at` are set automatically.

List pending (uncaccepted) invites:

```bash theme={null}
curl -X GET https://api.bedrock.orinlabs.org/api/organizations/invites/ \
  -H "Authorization: Token USER_TOKEN"
```

Revoke a pending invite:

```bash theme={null}
curl -X DELETE https://api.bedrock.orinlabs.org/api/organizations/invites/INVITE_ID/ \
  -H "Authorization: Token USER_TOKEN"
```

### Accepting an Invite

The accept endpoint is **unauthenticated** — the invite ID is the capability. The invitee provides a password and (optionally) name, and Bedrock creates the user + membership + token:

```bash theme={null}
curl -X POST https://api.bedrock.orinlabs.org/api/organizations/invites/INVITE_ID/accept/ \
  -H "Content-Type: application/json" \
  -d '{
    "password": "newsecret",
    "first_name": "Bob",
    "last_name": "Brown"
  }'
```

Response mirrors signup (token + user + organization). The invite is marked `accepted_at` after this call.

## Organization API Keys

Organization-scoped API keys live at `/api/organizations/api-keys/` and grant Bearer access to every resource owned by the organization — templates, agents, memory, tools, tracing, and default adapter state.

When you create an API key, the response returns the full key **once**:

```bash theme={null}
curl -X POST https://api.bedrock.orinlabs.org/api/organizations/api-keys/ \
  -H "Authorization: Token USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Ops / eval runner"}'
```

```json theme={null}
{
  "id": "apikey-uuid",
  "key": "full-secret-key-shown-once",
  "name": "Ops / eval runner",
  "is_active": true,
  "created_at": "2025-03-14T10:30:00Z"
}
```

Subsequent list/get calls return a **masked** key like `abcd1234...wxyz`. Save the full value immediately.

## Organization CRUD

Organizations are returned by `GET /api/organizations/organizations/` and are **filtered to your own org** unless `is_admin` is set. You'll typically only touch this endpoint to read or rename your own org, or to set org-wide LLM provider keys:

```bash theme={null}
curl -X PATCH https://api.bedrock.orinlabs.org/api/organizations/organizations/ORG_ID/ \
  -H "Authorization: Bearer YOUR_ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "openai_api_key": "sk-...",
    "anthropic_api_key": "sk-ant-..."
  }'
```

<Note>
  `openai_api_key` and `anthropic_api_key` are write-only. They can be set or replaced but are never returned on read.
</Note>

## API Summary

| Method                     | Endpoint                                  | Description             |
| -------------------------- | ----------------------------------------- | ----------------------- |
| `POST`                     | `/api/organizations/auth/signup/`         | Create org + user       |
| `POST`                     | `/api/organizations/auth/login/`          | Log in                  |
| `GET`                      | `/api/organizations/auth/me/`             | Current user + org      |
| `POST`                     | `/api/organizations/auth/logout/`         | Invalidate token        |
| `GET` / `PATCH` / `DELETE` | `/api/organizations/organizations/{id}/`  | Organization CRUD       |
| `GET` / `POST` / `DELETE`  | `/api/organizations/api-keys/`            | Org-scoped API keys     |
| `GET` / `DELETE`           | `/api/organizations/members/{user_id}/`   | Manage members          |
| `GET` / `POST` / `DELETE`  | `/api/organizations/invites/`             | Manage invites          |
| `POST`                     | `/api/organizations/invites/{id}/accept/` | Accept invite (no auth) |
