Skip to main content
Returns all accounts the authenticated agent can operate on this vendor agent. Use this to discover existing accounts, check status changes on pending accounts, and retrieve account_id values for use in protocol operations. list_accounts works across all vendor protocols — media buy agents, signals agents, governance agents, and creative agents all return accounts through this same task. Response Time: ~1s. Request Schema: /schemas/v3/account/list-accounts-request.json Response Schema: /schemas/v3/account/list-accounts-response.json

Quick Start

List all accounts this agent can operate:
import { testAgent } from "@adcp/client/testing";
import { ListAccountsResponseSchema } from "@adcp/client";

const result = await testAgent.listAccounts({});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListAccountsResponseSchema.parse(result.data);

if ("errors" in validated && validated.errors) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
}

for (const account of validated.accounts) {
  console.log(`${account.account_id}: ${account.name} (${account.status})`);
}

Request Parameters

All parameters are optional. An empty request returns all accounts.
ParameterTypeRequiredDescription
statusstringNoFilter by account status: active, pending_approval, rejected, payment_required, suspended, or closed.
sandboxbooleanNoWhen true, return only sandbox accounts. When false or omitted, return only production accounts. Primarily used with explicit accounts (require_operator_auth: true) where sandbox accounts are pre-existing test accounts on the platform.
paginationobjectNoPagination cursor for large account sets.

Response

FieldDescription
accountsArray of account objects (see below)
errorsArray of errors, if the request failed
paginationPagination cursor for the next page, if more results exist
Each account includes:
FieldDescription
account_idVendor agent’s identifier. Pass this to protocol tasks: create_media_buy, get_signals, activate_signal, report_usage, and other operations. May be absent when status: "rejected".
nameVendor agent’s display name for the account
brandBrand reference object: domain (the brand registry house domain) and optional brand_id (sub-brand within the house)
operatorOperator domain. Always present — when the brand operates directly, operator equals the brand’s domain.
statusCurrent account state: active, pending_approval, rejected, payment_required, suspended, or closed
billingBilling model in effect: operator or agent
account_scopeHow the seller scoped this account: operator, brand, operator_brand, or agent. See account scope.
payment_termsPayment terms agreed for this account: net_15, net_30, net_45, net_60, net_90, or prepay. Binding for all invoices when the account is active.
governance_agentsGovernance agent endpoints registered on this account. Present when governance agents have been configured via sync_governance.
setupPresent when status: "pending_approval". Contains url for completing setup and message explaining what’s needed.

Common Scenarios

Poll until account becomes active

After sync_accounts returns pending_approval, poll until the account is ready:
import { testAgent } from "@adcp/client/testing";
import { ListAccountsResponseSchema } from "@adcp/client";

async function waitForAccount(targetAccountId, maxAttempts = 20) {
  for (let i = 0; i < maxAttempts; i++) {
    const result = await testAgent.listAccounts({ status: "active" });

    if (!result.success) {
      throw new Error(`Request failed: ${result.error}`);
    }

    const validated = ListAccountsResponseSchema.parse(result.data);

    if ("errors" in validated && validated.errors) {
      throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
    }

    if ("accounts" in validated) {
      const account = validated.accounts.find(a => a.account_id === targetAccountId);
      if (account) {
        console.log(`Account active: ${account.account_id}`);
        return account;
      }
    }

    // Wait 30 seconds before polling again
    await new Promise(resolve => setTimeout(resolve, 30_000));
  }

  throw new Error(`Account ${targetAccountId} did not become active`);
}

Filter active accounts only

import { testAgent } from "@adcp/client/testing";
import { ListAccountsResponseSchema } from "@adcp/client";

const result = await testAgent.listAccounts({ status: "active" });

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListAccountsResponseSchema.parse(result.data);

if ("accounts" in validated) {
  for (const account of validated.accounts) {
    console.log(`${account.account_id}: ${account.name} — billing: ${account.billing}`);
  }
}

Error Handling

Error CodeDescriptionResolution
ACCOUNT_NOT_FOUNDNo accounts found for this agentRun sync_accounts first to establish a buying relationship

Next Steps