# Join a Firm

> Gain partner authority over a firm in two control-plane calls: an administrator offers it, and the operator joining accepts it on their own key.

*Source: https://www.whisper.security/docs/partners/join*

---
Partner authority over a firm is granted in two calls. An administrator who already holds authority offers it, and the person joining takes the offer up. Nothing is written to the joining operator's key until the second call, so the accept is the moment the authority exists.

Membership of the firm in the identity provider and authority over the firm in the portal are separate grants. Holding one is not holding the other, and the steps below grant the second.

## Before you start

You sign in with your own Whisper account, so there is nothing to create first. The administrator making the first call needs the user id of the account you sign in with, so sign in before you ask for the offer.

## Step 1: sign in with your own account

Open `https://partners.whisper.online`. You are sent to the shared sign-in at `https://console.whisper.security` and returned to the portal afterwards. One account covers the portal and the rest of Whisper.

At this point the portal renders, and its surfaces show their empty state: no firm is in scope, and each one tells you to pick a firm in the switcher or to ask an administrator to add you to one. That is the state to be in before step 2, and it means you are signed in and hold authority over no firm yet.

## Step 2: an administrator offers the authority

An administrator who already holds authority over the firm makes the first call against the control plane, naming your account:

```whisper-call
CALL whisper.agents({op: 'partner', args: {op: 'operator.add', account: '<the user id of the account you signed in with>'}})
```

The firm is never an argument here. It is read from the scope on the caller's own key, so authority over a firm can only be offered by someone who already holds it.

This records the offer against the firm. Your key is unchanged.

## Step 3: accept the offer on your own key

You make the second call yourself, naming the firm:

```whisper-call
CALL whisper.agents({op: 'partner', args: {op: 'operator.accept', org: '<the organization id of the firm>'}})
```

Only the person joining can make this call. It is the accept that writes the authority onto your key.

Both calls carry their own operation inside `args`, under the same key the envelope uses outside it. That nesting is required rather than stylistic: one map cannot hold the key `op` twice, so a call written with both at the top level loses the inner one. [The request envelope](/docs/control-plane/envelope) describes the single row that comes back and how to read its status.

## What you should see

Your key now carries the scope `partner:<organization id>`. The portal's organization switcher lists the firm, and the navigation renders with the firm's book behind it rather than an empty state.

If the switcher still shows nothing, the accept has not landed: re-read the row the second call returned before asking for the offer again, because the offer from step 2 stays valid until it is taken up.

## Why the accept belongs to the joiner

An administrator can name anyone, and naming is not granting. Splitting the two means the authority on a key was always put there by the person holding that key, which is what makes an action later attributable to them. That attribution is what [audit and compliance](/docs/partners/audit) reads, and [your team and roles](/docs/partners/team) covers the role that authority then carries inside the firm.
