# Organizations and Namespaces

> Who owns what on Switchboard, how API routes name it, and how to manage Namespaces, Members and Invitations.

URL: https://www.caprid.com/docs/guides/organizations/
Source: https://github.com/muxinc/switchboard/blob/main/docs/public/organizations.md

Your company is an Organization on Switchboard. The people who manage it are
its Members. Each Member signs in with their own Account, so nobody shares a
login, and one person can be a Member of several Organizations.

An Organization owns its Namespaces. A Namespace is the first segment of every
path you can sign Client tokens for. If your Namespace is `acme`, you can sign
any path under `acme/`, which covers all your broadcasts and their tracks. The
name is yours for good. Nobody else can ever have it, even after you stop
using it.

Signing up creates an Organization with the Namespace you choose. An AI agent
can also start a trial Organization by itself, which becomes yours when you
claim the agent. See [AI agents](https://www.caprid.com/docs/guides/agents/).

## Find your Organization's id

API routes name what they act on. Signing keys and Client tokens belong to a
Namespace, so their routes start with `/v1/namespaces/acme`. API keys and
Self-hosted relays serve the whole Organization, so their routes start with
`/v1/organizations/{id}`. To find the id, list your Organizations:

```bash
curl https://app.caprid.com/v1/organizations \
  -H "Authorization: Bearer $SB_API_KEY"
```

The response is:

```json
[{"id": 4, "name": "acme", "created_at": 1790298000}]
```

The examples in these docs use Organization `4`, which owns the Namespace
`acme`.

## Paths in the API and in tokens

When you call the API, paths are relative to the Namespace, and Switchboard
adds the Namespace for you. Ask for `room/42` and you get `acme/room/42`.

Inside a Client token, the path is written out in full, Namespace included. So
when you sign tokens yourself, you write `acme/room/42`.

## Create another Organization

You might want a separate Organization for a customer or project that should
have its own API keys and relays. Create one from **New Organization** in the
dashboard. You pick its first Namespace the same way you did at signup, you
become its Owner, and its page shows its first API key once.

You can create 5 Organizations. Organizations you joined by invitation don't
count. Creating one takes a signed-in session, so an API key can't do it.

## Create a Namespace

An Organization can have more than one Namespace. A second Namespace is
useful for keeping prod and staging apart, as
[Prod and staging](https://www.caprid.com/docs/guides/prod-and-staging/) shows. Any Member can create one,
from the Organization's page in the dashboard or with the API:

```bash
curl https://app.caprid.com/v1/organizations/4/namespaces \
  -H "Authorization: Bearer $SB_API_KEY" \
  -d '{"namespace": "acme-staging"}'
```

The response is the new Namespace:

```json
{"name": "acme-staging", "organization_id": 4, "platform_peering": false, "created_at": 1790298000}
```

Names follow the same rules as at signup. Because a name is never reused,
you get a 409 for any name that a Namespace has ever had, including one that
was deleted.

An Organization can have 10 Namespaces at a time. Ask us if you need more.

## Delete a Namespace

Only an Owner signed in to the dashboard can delete a Namespace. Use the
Namespace's settings tab, or call `DELETE /v1/namespaces/acme-staging` with
your session. An API key can never delete one, so a leaked key can't destroy
something you can't get back.

Deleting a Namespace:

- deletes its signing keys, so the Client tokens they signed stop working,
  and relays drop its tracks within about a minute
- removes it from the limit of any API key that was limited to it
- leaves your Self-hosted relays, Regions and enrollments alone, because they
  belong to the Organization

You can't undo the delete, and nobody can use the name again, you included.
You can delete your last Namespace. The Organization stays, with no
Namespaces, until you create another.

## Members and Owners

Every Member can manage everything the Organization owns. Owners can also
change who is an Owner, remove Members, and invite people.

To see who belongs, open your Organization's **Members** page in the
dashboard, or call the API:

```bash
curl https://app.caprid.com/v1/organizations/4/members \
  -H "Authorization: Bearer $SB_API_KEY"
```

The response lists each Member with their role and when they joined, in Unix
seconds:

```json
[
  {"account_id": 7, "email": "bob@acme.example", "role": "owner", "joined_at": 1790294400},
  {"account_id": 12, "email": "alice@acme.example", "role": "member", "joined_at": 1790380800}
]
```

To change someone's role, an Owner sends
`PATCH /v1/organizations/{id}/members/{account_id}` with a body of
`{"role": "owner"}` or `{"role": "member"}`. To remove someone, an Owner sends
`DELETE` to the same path. Any Member can leave by sending `DELETE` with their
own `account_id`.

Changing Members takes a signed-in session. An API key can list Members but
can't change them, so nobody can use a leaked key to add themselves to your
Organization.

An Organization always has at least one Owner. If you're the last one, you
have to make someone else an Owner before you can step down or leave.

When someone leaves, the API keys they made keep working, because the keys
belong to the Organization. Revoke them separately if you need to.

## Invite someone

To add a teammate, an Owner invites their email address from the **Members**
page. Switchboard doesn't send email. You get a link, and you send it to them
yourself, in Slack or wherever your team talks. The link is shown once, works
once, and expires after 7 days.

The dashboard creates the Invitation by sending
`POST /v1/organizations/{id}/invitations` with your signed-in session and a
body like `{"email": "alice@acme.example", "role": "member"}`. The response
includes the link to send:

```json
{
  "id": "3f9c1a2b7d4e",
  "organization_id": 4,
  "email": "alice@acme.example",
  "role": "member",
  "created_at": 1790294400,
  "expires_at": 1790899200,
  "secret": "sbi_mR3x9Qe2vT8wY1zA4bC7dF0gH5jK6lN2pS8uV3xZ1q",
  "link": "https://app.caprid.com/app/invitations/sbi_mR3x9Qe2vT8wY1zA4bC7dF0gH5jK6lN2pS8uV3xZ1q"
}
```

Only an Account with the invited email can accept, so a link forwarded to the
wrong person is no use to them. When Alice opens the link, she signs in, or
signs up, as `alice@acme.example`, and joins with the role you picked. If she
signs up from the Invitation, she joins your Organization instead of creating
her own, so she doesn't need to pick a Namespace.

On app.caprid.com, WorkOS verifies every email address, so Alice
doesn't need the link at all. The first time she signs in, the dashboard
offers to let her join Acme, next to the option to create her own
Organization.

Owners can see pending Invitations on the **Members** page, or by sending
`GET` to the same path. To revoke one, which stops its link working, send
`DELETE /v1/organizations/{id}/invitations/{id}`.

As with Members, an API key can't invite anyone or see Invitations, so nobody
can use a leaked key to let someone in.
