Skip to main content
Every MCP connection to the v3 endpoint (/mcp/v3) is listed the same complete tool catalog, whatever kind of account you are in and whatever role you hold. Apostra’s in-product assistant keeps its account-scoped tool list for now. The account a call names decides whether it can run. Begin every new session by calling get_status with no accountId. When you can reach more than one account it lists them, with each account’s accountId, kind and name, so you can ask the person which one they mean. When you reach one account it returns that account’s status directly. Keep the returned account identity, readiness and blockers for the account you work in. Then name that account on every call with an accountId returned by get_status:
Every tool takes it, reads and writes alike. A call runs in the account it names, for that call only, so one conversation can work across accounts by naming each call’s account, and nothing it does moves another conversation. Naming an account never grants access you do not already have. See Name the account on every call for the errors and for how to work across accounts. switch_account is retired on V3: it is not in any tool list, and it still runs for now from tool lists that hosts cached earlier.

Which account a call runs in when you name none

Send accountId and this section does not apply. Until the removal date announced in Name the account on every call, a call from a cached tool list that names none still runs in the account the server picks, in this order:
  1. The account the connection last switched to, if it has a stored selection and you still reach that account. A stored selection belongs to the connection (the sign-in grant) or, when there is no grant, to the person. Some clients, such as ChatGPT, carry no session, so they read the stored selection on every call. A client that keeps a session, such as Claude, starts a new session on your home account and ignores a selection stored by an earlier one. Naming an account on a call never changes it.
  2. Otherwise your home account. For a Scope3 staff member it is their staff account. For everyone else it is the oldest active membership; a legacy Seller membership that is not yet set up is skipped when you have another account.
Two clients signed in as the same person can therefore start in different accounts: one reads a stored selection and the other starts at home. A credential fixed to one account, and a request that carries its account in a header, always run in that account. Such a call’s result carries one line asking you to send accountId on every call. A buyer agent, and an API key with no user behind it, can name only the account it runs in, so get_status lists no other account it can name, even when a hosted buyer agent is answering a person who belongs to other accounts. A buyer agent whose organization granted it advertisers in other accounts sees each of those accounts in reachableAccounts with nameWith: "advertiserId", up to 10 of its advertiserIds, advertiserCount, and access (read when every grant there is read-only, otherwise read_write). A call that names one of those advertisers in advertiserId runs in that account, and naming the account in accountId is refused. When you can reach more than one account and name none, get_status lists them. The structured result carries accounts, and the text lists the same accounts after a paragraph that says the account was chosen by default. nextActions leads with confirm_account, a recommended step that names the account the call ran in and where it came from. You can answer a read-only question in that account. Tell the person which account you used. Confirm the account with them before your first write, then send that accountId on every call. get_status with accountId reads another account. A page lists up to 25 other accounts. A Scope3 staff member reaches every customer, so their list is paged: the text says how many accounts are not shown, and nextActions carries a list_more_accounts step with the cursor to send. Send cursor only on a call that has no account named; with an account named, or with one account reachable, there is no list to page and the call is refused. A call that names its account, a caller with one account and a credential fixed to one account see none of this. Every authenticated Buyer, Seller and Organization account can connect, and every connection to /mcp/v3 is listed the same complete catalog: Buyer, Seller, Organization and Agents tools, search and get with all their kinds, filters and includes, and every write tool, even for a read-only login or a directory reviewer’s login. Listing a tool is not permission to run it:
  • A tool runs only in an account of its kind. A call in the wrong kind of account is refused with WRONG_ACCOUNT, naming the kinds the tool needs and the accounts you can reach that can run it. Send one of them as accountId and call again.
  • A call needs the role it always needed. Without it, the call is refused with ACCESS_DENIED. A directory reviewer’s login is refused every write with REVIEWER_TOOL_PROHIBITED.
Two kinds of tool stay out of the list: Scope3 staff tools, and tools for a feature your account is not enrolled in, such as notification settings or advertiser grants. Tools that only a Page calls are listed, and their metadata marks them as not for the model. An Organization account’s own tools are navigation, shared settings, and the bounded organization-account task below. get with kind: "advertiser_access" is seller-only by design and shows the seller who may buy for an advertiser; for buyer-side access questions, see organisation delegation.

Manage organization accounts

A direct organization administrator manages the organization’s child accounts with save_account, from the organization account or any child account they administer. Send no id to create a child, id and name to rename one, or id and isArchived to archive (true) or restore (false) it. Each of those is recorded for approval on the website: the tool returns a link, nothing changes until an administrator of that organization approves the exact request, and the agent cannot approve it. Repeat the same call with the same idempotencyKey to see the outcome. Send dryRun: true first to see what the request would do, including the campaigns and media buys that block an archive. A preview runs the same checks and records nothing. See Manage accounts with a V3 agent for the fields each change takes. The in-app Apostra chat also offers save_account to a direct organization administrator using an administered Agents, Buyer, or Seller account. The chat returns the same website approval link, and no account changes until an administrator approves that exact request there. Direct organization administration that takes effect immediately stays available only from a direct session. An Apostra support person with an active staff elevation on the organization (see “When Apostra staff help with your account’s members” below) can list the organization’s accounts and request the same creates, renames, archives and restores from the organization account, under their own name. An elevation on one child account does not reach the organization. While the elevation lasts they can also approve those requests on the website. If the elevation has ended or been revoked by the time an approved change runs, the change is refused and nothing is changed. An organization has no limit on how many Buyer or Seller accounts it holds, so restoring one is never refused for a count, and archiving or restoring an account changes nothing about what else you can add. Restoring or reactivating an account is never refused because of the plan either: an account the organization held keeps its place even if its plan no longer allows that type for a new one. Creating accounts is capped at 25 in any 24 hours per organization. The 26th is refused with 429 RATE_LIMITED, details.reason account_creation_daily_limit and a message to contact support to raise the limit; do not retry it, because the window slides over 24 hours. It counts creations, so an account you created and then archived or deleted still counts, while restoring one does not, and repeating a request with the same idempotencyKey is never refused. A save_account create, including its dryRun preview, is refused with the same error when you ask, so no approval is recorded. See Accounts in an organization. Two other checks remain. The plan must allow the account type you create; otherwise the request is refused with 409 CONFLICT, details.reason plan_does_not_cover_account, the plan that would allow it and the next step. The same check refuses a staff create, moving an account into the organization, and switching an account to Storefront. And an organization holds one Agents account: creating or restoring a second is refused with 409 CONFLICT and details.resource developer_account_limit, so build further agents in the existing one. Repeating a request with the same idempotencyKey returns the first result.

Account types

save_account creates an account of one type. Send accountType and, for a seller, sellingMode: The Agents account is the account type where you build and manage agents. Its wire value is still developer. A seller needs sellingMode; a buyer, an Agents account and a Demo Storefront refuse it with VALIDATION_ERROR. operatingMode (LISTING_ONLY or AGENTIC_MEDIA_COMPANY) still works as the older name for the same choice, and sending it with sellingMode is refused. It will be removed once the hosts that list save_account have approved the new definition. Which of these an organization can add depends on its plan. The Listing plan allows Listing accounts and one Agents account; adding a Campaign management or a Storefront is refused, and the next step is to move to the Standard plan. Read the answer for your organization from the organization account’s get_status instead of trying a create. Its organization.addableAccountTypes lists the four types above, each with canAdd. A type you cannot add also has a reason (code and message) and a nextStep (code, message, and canAct, which is false when only another administrator of the organization can take the step). A save_account create or dryRun for a type that canAdd says no to is refused with that same reason, because both come from one plan check. If the read fails, addableAccountTypes is null and gaps says so. The organization account’s get_status shows the child account counts and which account types the organization can add (see Account types); an organization has no limit on how many accounts it holds. It also says whether the organization has an Agents account. If none exists, its next step is to create one with save_account; an organization holds one Agents account, and a second is refused. get with kind: "account" and include: ["lifecycle", "capacity"] adds one child’s archive state and blockers. These reads and the writes check that you are a direct administrator of that organization. Send organizationId to save_account to act for an organization from a child account you administer; without it the call acts in the organization account you are connected to. A Scope3 platform operator can name any customer organization, and only an operator can create a Demo Storefront (accountType: "seller" with demoStorefront: true). Either way, the call must come from your own direct session. A delegated, agent or support session is refused with ACCESS_DENIED, and so is a call that names another account, including a platform operator working in a customer account: send your home account’s accountId, then retry. Browsing products under your company’s seller account is open to every member of the company and to the company’s service tokens, not only to administrators; buying still needs a Premium or Admin member or a token that is not read-only. See who can browse under a company seller account.

Who decides an account’s approvals

A creative review or a media-buy approval on a Seller account goes to that account’s approval audience. With no saved approval routing, the audience is the account’s own administrators. If the account has none, it is the administrators of the organization the account belongs to. Only the audience is notified about it. An administrator of the organization may also decide any approval that is routed to administrators (the default routing, or saved routing that names the Admin role), even when the account has administrators of its own. They are not notified about it; they decide it from the account’s approvals or with save_work_item. An approval whose saved routing names particular people, and no role, can be decided only by those people.

When a Seller account can’t sign in yet

A Seller account can be used once it has been set up as an Apostra Seller. When an administrator of the account signs in with a work email on the company’s own domain (the domain recorded on the account), sign-in finishes that setup and lets them in, the same way signing up as a new Seller does. You’ll be asked to accept the current Terms of Service if you haven’t yet. Anyone else, for example a member who is not an administrator or who signs in with an email on another domain, can’t sign in until the account is set up. The sign-in page says the Seller account isn’t set up yet, and our team is told which account it is. You don’t need to request access or fill in the Buyer access form. Ask your company’s administrator to sign in, or sign out and sign in again once the account is ready. Sign-in refuses such an account with ALPHA_OPT_IN_REQUIRED and reason: "seller_awaiting_setup". A Buyer account that is not yet in the advertiser beta gets the same error with reason: "buyer_not_enrolled", and can request access. The signed-in account read (/auth/me) reports the same value as accessRefusal, or null when the account is not refused.

Requesting access to your company’s account

When you sign up with a work email and your company already has an account, signup offers Request Access instead of making a second account. The account’s administrators are emailed your request, and you get access when one of them approves it. If the account has no administrator, and neither does the organization above it, nobody there can approve the request. It comes to our account team instead. We email you when you have access, or if we need anything from you. If you have questions in the meantime, write to support@apostra.com. Asking again does not file a second request; your first one stays in place.

When Apostra staff help with your account’s members

An Apostra support person who opens your account sees it read-only. To change anything they need a staff elevation for your account, which is approved inside Apostra, lasts a limited time and is recorded. While it lasts, they can list the account’s members, invite someone, resend or cancel an invitation, change a member’s role and remove a member, the same as an administrator of the account. An elevation on an organization covers the members of the accounts under it. Every change is recorded under the staff member’s own name. Once the elevation ends or is revoked, these actions are refused again.

When your account has been deactivated

An account can be deactivated, for example when it is closed or merged into another account. No one who belongs to it can use it until it is restored. If every account you belong to has been deactivated, signing in does not stop at an error. You are shown any invitation you have to another account first; if there is none, you are taken to signup to set up a new account, and you administer the account you create there. The deactivated account is left as it is: if it is restored later, you can use it again. If you belong to more than one account, deactivation only matters when none of them is active; an active account still signs you in. If you would rather get the deactivated account back, ask its administrator to restore it, or email support@apostra.com. When signup is not offered, sign-in answers a deactivated account with 403, error: "NO_ACTIVE_HOME_CUSTOMER" and reason: "ACCOUNT_DEACTIVATED", with a plain-language message that agents and API clients can show as it is. That happens on token refresh, and on password sign-in when the email address has not been verified. Browser sign-in with OAuth, SSO or a verified password sends the person to signup instead. A sign-in that asks for one particular account, such as a link into a specific seller’s advertiser, is answered about that account: when it is deactivated the sign-in is refused, and the person is not sent to signup, because they asked for that account and not for a new one.

Before your organization accepts the Terms of Service

Until a direct administrator of your organization accepts the current Terms of Service, the Apostra site asks for that before anything else. Only that administrator can accept them; Apostra staff never accept them for you. Managing the account’s members is not blocked. If you are an administrator of the account or its organization, the Terms window offers Manage members, so you can invite or remind the person who should accept. An Apostra support person with an active staff elevation on your account gets the same choice. The member list, invitations and role changes work as usual; most other work waits for the Terms. Conversion events keep flowing. log_event and the conversion endpoint POST /api/v2/buyer/advertisers/{advertiserId}/log-event accept events whether or not the current Terms are accepted, so an integration that sends your conversions never loses data while you sort out the Terms.

Sandbox advertisers and live spend

A sandbox advertiser is an advertiser created with AdCP’s own sandbox flag set to true. You set it once, in save_advertiser when the advertiser is created, and it is carried on the AdCP account identity {brand, operator, sandbox}. It cannot be changed afterwards: save_advertiser on an existing advertiser that names sandbox returns IMMUTABLE_FIELD. To move to live work, create a new advertiser without the flag. Every brief a sandbox advertiser sends carries the same flag on its account, and a seller on Apostra is not charged for answering it. Sandbox briefs are also left out of the seller’s analytics (its run counts, win rate, buyer asks and top products), and out of what the seller’s Merchandising Agent learns from past briefs, so a buyer’s tests do not look like demand to the seller. What the seller teaches the agent on a sandbox brief, such as a lesson, still applies to live briefs. An Apostra Storefront still answers a sandbox brief in full, so you test the answer a live brief would get. A seller’s own sales agent may answer sandbox requests differently. A live advertiser’s brief is also free to the seller while its buyer account cannot book media yet, for example because the account has not finished setup or has no media-buying entitlement. These briefs come from a real advertiser, so unlike sandbox briefs they stay in the seller’s analytics and in what its Merchandising Agent learns. Once the account can book, its live briefs are charged as usual. A brief sent to a seller’s agent with no Apostra buyer account behind it is always charged, and if Apostra cannot check the account’s setup in time, the brief is charged as an ordinary live brief. Each buyer account has 20 sandbox briefs a day that reach an Apostra Storefront, counted in UTC. While the account cannot book media yet, its free live briefs count toward the same 20. One brief sent to many sellers in a single request_proposals call counts once; a direct get_products call to an Apostra Storefront with a sandbox account counts as one brief. A brief Apostra answers from its recent results, such as the same brief sent again shortly after, does not reach the Storefront and does not count. A brief that reaches the Storefront counts even if the Storefront then cannot answer it. Live briefs from an account that can book have no such limit. Past the limit, the limit is Apostra’s, not a seller’s, and the answer says so. A request_proposals call from a sandbox advertiser that has used its 20 briefs is refused once, before any seller is contacted, with RATE_LIMITED. This applies to every new round from that advertiser until the reset, including a round whose sellers are not Apostra Storefronts. The message names the limit and says it resets at midnight UTC, and retry_after is the number of seconds until then. A direct get_products call to an Apostra Storefront gets the same RATE_LIMITED and retry_after. If another round uses the last brief while yours is running, an Apostra Storefront that refuses it reports the same Apostra limit as that seller’s outcome, not as a seller error. If Apostra cannot read today’s count, request_proposals is refused with SERVICE_UNAVAILABLE and a short retry_after, and no brief is sent. An account that cannot book media yet reaches the same limit with its live briefs. The up-front request_proposals refusal, and the refusal a direct get_products call gets, have details.reason not_transacting_brief_daily_limit and list what the account still needs in details.blockers, such as product_entitlement. A seller outcome inside a running round says only that the Apostra limit was reached. The limit lifts as soon as the account can book, as well as at midnight UTC. If Apostra cannot read today’s count for such a brief, the brief is sent and charged as an ordinary live brief rather than refused. A buyer account has no sandbox mode and no live mode. The account is the same in both cases; what changes is which checks an operation has to pass. Setting up a sandbox advertiser (creating, updating or archiving it, and configuring its tracking) does not wait for the verified operator identity, so you can prepare one before claiming it. Creating its campaigns and media buys does. An operation that fails a check is refused with an access-denied error that names the first requirement still missing. See Sandbox mode for the full list of requirements and the buyer REST behavior. Your application should retain the account identity with every workflow checkpoint, send it as accountId on every call, and verify it when resuming. A connection, a seller relationship, or a registered agent does not implicitly grant access to every advertiser.

Full account-access reference

Review customer relationships, role and permission behavior, and stable v2 account switching in the canonical account-access guide. That guide’s customer_switch is v2 only.