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

# Name the account on every call

> Send accountId on every V3 call so each call runs in the account you mean, and one conversation can work across accounts without moving another.

Every V3 tool call names the Apostra account it runs in. Send `accountId` on
every call, reads and writes alike, including when you can reach only one
account. A call that names its account neither reads nor changes the connection's
stored selection, which stays only as a fallback for older calls until removal
(see below).

```json theme={null}
{ "accountId": 624, "kind": "campaign", "limit": 10 }
```

A model follows one rule more reliably than two. The tool list marks
`accountId` required on every tool except `get_status` (optional there) and two
writes, named below. Its description is "Apostra accountId this call runs in, from get\_status."

Two writes list it as optional for now, because their `accountId` used to name
the thing being written: `save_account` (the child account to edit) and
`save_directed_campaign_subscription` (the account at the outside ad platform).
On those, send `accountId` beside the renamed input (`id` or
`providerAccountId`); an `accountId` sent without it is still read the old way
until the old shape is removed.

## Get the account ID from `get_status`

Call `get_status` with no `accountId`. It lists the accounts you can reach, by
company, with each account's `accountId`. Call it with an `accountId` to read
that account's identity, readiness, blockers and next actions.

If you are not sure which account the person means, ask them. Do not guess
between accounts, and do not pick the first one on the list. Your agent should
remember the account the conversation settled on and send it on every later
call.

## One conversation can work across accounts

Each call runs in the account it names, for that call only. Two calls in the
same conversation can name different accounts, so you can read a Buyer Account
and a Seller Account side by side by naming each one per call.

A named call stores nothing and does not change the connection's stored
selection, so it never moves another conversation on the same connection. Two
conversations can work in two different accounts at the same time.

## Naming an account never grants access

`accountId` says which account you mean. The server still decides whether you
may act there, using the same checks as before: your membership in the account
or an administrator role on its parent organization, the permissions on your
role, and the limits of your credential. A credential fixed to one account
(WorkOS user and organization API keys, machine credentials and buyer agents)
can name only that account.

A Scope3 staff member who names an account they are not a member of gets the
platform support access that applies to that account and nothing more.

## Errors

| Error | What it means | What to do |
| - | - | - |
| `ACCOUNT_NOT_REACHABLE` | You cannot work in the account `accountId` names. Nothing was read or written. | Call `get_status` with no `accountId` to list the accounts you can reach. Ask the person which one they mean, then resend. |
| `ACCOUNT_MISMATCH` | `accountId` and `expectedAccountId` name different accounts, or on the V3 HTTP API `accountId` differs from the `X-SCOPE3-CUSTOMER-ID` header. Nothing was read or written. | Send one account. Use `accountId`, and leave `expectedAccountId` out. |
| `ACCOUNT_CONFIRMATION_REQUIRED` | A write from a connection that can still be switched left out `accountId`. Nothing was written. | Name the account the conversation already settled on with `accountId`. If it has none, call `get_status` with no `accountId`, ask the person which account they mean, then resend with that `accountId`. |

`ACCOUNT_NOT_REACHABLE` repeats the number you sent and looks up nothing from
it. Take the `accountId` from `get_status`, not from the error.

## What still works while this rolls out

Tool lists are cached by hosts until a person reconnects, so many conversations
still run on a list from before `accountId` was required. Until a removal date,
those conversations keep working:

* A call that omits `accountId` still runs, in the account your connection last
  switched to, or in your credential's home account if it never switched. Its
  result carries one line telling you to send `accountId` on every call. A
  write from a connection that can be switched still fails with
  `ACCOUNT_CONFIRMATION_REQUIRED`.
* `expectedAccountId` is no longer listed, because `accountId` replaces it. The
  server still accepts it. Send `accountId` instead.
* `switch_account` is retired and no longer appears in any tool list. A client
  working from a cached list can still call it. The result says it is retired
  and tells you to send `accountId` on every call instead.

We will announce the removal date before it arrives. After it, a call that does
not name its account is refused, and `switch_account` and `expectedAccountId`
are removed. Do not build on the fallback.

## The V3 HTTP API

The V3 HTTP API keeps its `X-SCOPE3-CUSTOMER-ID` header, which names the
account. `accountId` is optional there. If a request sends both and they
differ, it fails with `ACCOUNT_MISMATCH`. A request that sends `accountId` and
no header fails the same way when `accountId` is not its credential's account:
the body never chooses an account the credential and header did not. See
[HTTP API](https://docs.apostra.com/v3/http-api.md).

## Inputs that were called `accountId`

Five inputs used `accountId` for a different account. They have new names, so
`accountId` always means the account the call runs in.

| Tool | Now | What it names |
| - | - | - |
| `get` with `kind: "member"` | `memberAccountId` | The child account the member belongs to |
| `save_account` | `id` | The child account being edited |
| `save_directed_campaign_subscription` | `providerAccountId` | The account at the outside ad platform, within a connection |
| `buyer_sellers_page` (action `map_account`) | `providerAccountId` | The provider account an account mapping maps |
| `open_connections_page` | `connectionAccountId` | The connection account the Page opens on |

During the rollout, an older call that leaves out the new input keeps the old
meaning of `accountId` on the first four. `open_connections_page` has no such
fallback: its `accountId` always names the account the call runs in. See
[v3 Concepts](https://docs.apostra.com/v2/setup/v3/concepts.md#name-the-account-on-every-call) for how
the server tells the two shapes apart.

## Related

* [Account access](https://docs.apostra.com/v3/account-access.md) covers which account a call runs in when
  you name none, organization accounts and account kinds.
* [Errors](https://docs.apostra.com/v3/errors.md) covers the full V3 error envelope.
* [Quickstart](https://docs.apostra.com/v3/quickstart.md) shows the first `get_status` read.


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