Menu

API reference · Accounts

Accounts

child_orgs · accounts · 8 operations

POST/v1/accounts

Create an account (dormant, no charge)

child_orgs.accounts.create

WriteSince 2026-11-01

Creates a new account: a client organization under this agency workspace. It is always created dormant (no members of its own, managed from the workspace, no charge); activating it with its own modules and billing is done in the app. Takes a name and an optional profile (industry, website, country as an ISO code, notes, reporting currency and time zone) and values for the workspace's account custom fields, keyed by slug (child_orgs.custom_fields.list). The URL slug is generated from the name. Fails with limit_reached (409, details.resource accounts, with the limit and how many are active and available) when the plan's cap of active accounts is full (archived and deleted accounts do not count). With dry_run it checks the same (who, the custom field values, the plan's cap: the 409 comes already in the dry run) and says the URL slug it would get and how many slots are left, without creating anything; running it does not need the confirm_token. Only a direct owner or admin of the agency workspace (403 role_required, details.scope direct). Returns the new account id and the account.

Instructions for agents

Tell the person the account was created dormant: to give it modules and billing of its own, they activate it from Accounts in the app.

Scope
child_orgs:write
Permission
Edit in the module · Only owner, admin
MCP tool
child_orgs_accounts_createOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.create".
Events it can emit
child_orgs.account.created

Declared cost: up to 110 reads and 3 writes per call (they count against the daily quota).

Parameters

namestringbodyrequired

Account name, as shown in Accounts.

industrystringbodyoptional

Industry. The app offers a fixed list (e.g. «Retail», «Real Estate», «SaaS / Tecnología», «Otro»); any short text is accepted.

websitestringbodyoptional

Website (a URL or a bare domain).

countrystringbodyoptional

Country, ISO 3166-1 alpha-2 (AR, MX, US…) or 'global'. Stored in lowercase, as the app does.

notesstringbodyoptional

Internal notes about the account.

reportingobjectbodyoptional

Reporting defaults of the account: currency (ISO 4217) and time zone (IANA).

custom_fieldsobjectbodyoptional

Values for the workspace's account custom fields, keyed by slug (child_orgs.custom_fields.list). Files fields are uploaded in the app.

Response

account_idstring
accountobject

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/accounts" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME"
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/accounts" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME"
}'
POST/v1/accounts/bulk/create

Create several accounts at once (dormant, no charge)

child_orgs.accounts.bulk.create

WriteBulk · up to 100Since 2026-11-01

Creates up to 100 dormant accounts in one atomic step (all or none), each with its name and optional profile (industry, website, country, notes, reporting currency and time zone), like the CSV import of Accounts. Each gets its own URL slug. Fails with limit_reached (409, details.resource accounts and details.available: how many fit) if they do not all fit in the plan's cap of active accounts. Outside the app it requires a dry run (which lists the accounts with the slug each would get, as items of type account_slug, and the slots left) and a confirm_token. Only a direct owner or admin of the agency workspace. Returns the created ids in input order.

Instructions for agents

Tell the person how many accounts were created; they are dormant until activated from Accounts in the app.

Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.

Scope
child_orgs:write
Permission
Edit in the module · Only owner, admin
MCP tool
child_orgs_accounts_bulk_createOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.bulk.create".
Events it can emit
child_orgs.account.created

Declared cost: up to 310 reads and 201 writes per call (they count against the daily quota).

Parameters

accountsarray<object>bodyrequired

Up to 100 accounts to create, each with its name and optional profile.

Response

createdarray<object>
summaryobject

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/accounts/bulk/create" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "accounts": [],
  "dry_run": true
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/accounts/bulk/create" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "accounts": [],
  "dry_run": true
}'
POST/v1/accounts/{account_id}/archive

Archive an account

child_orgs.accounts.archive

WriteIdempotentSince 2026-11-01

Archives an account of the workspace: its users lose access, its scheduled work (alerts, site audits, rank tracking, flows, deliveries) is paused, it stops being billed to the workspace if the workspace paid for it, and it frees a slot of the plan. Reversible with child_orgs.accounts.restore. Refused (409) while the account pays its own subscription and it is live (account_has_active_subscription) or while it has phone lines billed to the workspace (account_has_billed_phone_lines). Archiving an archived account changes nothing (changed: false). Only a direct owner or admin of the agency workspace.

Scope
child_orgs:write
Permission
Edit in the module · Only owner, admin
MCP tool
child_orgs_accounts_archiveOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.archive".
Events it can emit
child_orgs.account.archived

Declared cost: up to 12 reads and 2 writes per call (they count against the daily quota).

Parameters

account_idstringpathrequired

Account id: a child organization of this workspace (the ids of platform.orgs.list).

Response

account_idstring
changedboolean
accountobject

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/accounts/{account_id}/archive" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/accounts/{account_id}/archive" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/accounts/{account_id}/restore

Restore an archived account

child_orgs.accounts.restore

WriteIdempotentSince 2026-11-01

Brings an archived account back to active: it takes a slot of the plan again (limit_reached, 409, details.resource accounts, when the cap is full) and what archiving paused starts again. An account paid by the workspace (billing_mode parent_pays) goes back on the workspace's invoice, so through the API it is refused with account_restore_requires_app and is restored from Accounts in the app. Restoring an account that is not archived changes nothing (changed: false). Deleted accounts cannot be restored here. Only a direct owner or admin of the agency workspace.

Scope
child_orgs:write
Permission
Edit in the module · Only owner, admin
MCP tool
child_orgs_accounts_restoreOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.restore".
Events it can emit
child_orgs.account.restored

Declared cost: up to 8 reads and 3 writes per call (they count against the daily quota).

Parameters

account_idstringpathrequired

Account id: a child organization of this workspace (the ids of platform.orgs.list).

Response

account_idstring
changedboolean
accountobject

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/accounts/{account_id}/restore" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/accounts/{account_id}/restore" \
  -H "Authorization: Bearer $MB_TEST_KEY"
DELETE/v1/accounts/{account_id}

Delete an account

child_orgs.accounts.delete

IrreversibleSince 2026-11-01

Deletes an account of the workspace: it disappears from the app, its own integration secrets are purged, it stops being billed to the workspace and it frees its slot of the plan. It cannot be undone from the app (only MB Suite support can bring the account back, without its secrets). Refused (409) while the account pays its own subscription and it is live, while that subscription has unpaid invoices (account_has_outstanding_debt; checked in Stripe: 503 external_unavailable, details.platform stripe, if Stripe does not answer, and nothing is deleted) or while it has phone lines billed to the workspace. Outside the app it always needs a dry run and a confirm_token, and a key allowed to delete. Only a direct owner or admin of the agency workspace.

Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.

Scope
child_orgs:write and “Allow deletions” (child_orgs:delete in OAuth)
Permission
Edit in the module · Only owner, admin
MCP tool
child_orgs_accounts_deleteOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.delete".
Events it can emit
child_orgs.account.deleted

Declared cost: up to 12 reads and 2 writes per call (they count against the daily quota). Touches an external platform (stripe): it counts against the external operations quota.

Parameters

account_idstringpathrequired

Account id: a child organization of this workspace (the ids of platform.orgs.list).

Response

account_idstring
deletedtrue

Errors

Example

curl -X DELETE "https://api.mb-suite.com/v1/accounts/{account_id}" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "dry_run": true
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset. In the practice organization this operation is not simulated (it reaches another platform): it answers 409 sandbox_external_unavailable.

GET/v1/accounts/{account_id}/config

Get an account's module access caps

child_orgs.accounts.get_config

ReadIdempotentSince 2026-11-01

Returns, for each module active in an account, its access cap (hidden, view_only or full_access) and who sets it: the workspace when it pays for the account (parent_pays: the cap applies to the account's own users), the account when it pays for itself (self_pays: the cap applies to the agency's users) or nobody (dormant). Modules without a cap read full_access. Needs to see the account (members only see their assigned ones).

Scope
child_orgs:read
Permission
View the module
MCP tool
child_orgs_accounts_get_configOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.get_config".

Declared cost: up to 1 reads and 0 writes per call (they count against the daily quota).

Parameters

account_idstringpathrequired

Account id: a child organization of this workspace (the ids of platform.orgs.list).

Response

account_idstring
billing_modestring
controlled_byenum

Values: workspace, account, none

modulesarray<object>

Errors

Example

curl "https://api.mb-suite.com/v1/accounts/{account_id}/config" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl "https://api.mb-suite.com/v1/accounts/{account_id}/config" \
  -H "Authorization: Bearer $MB_TEST_KEY"
PATCH/v1/accounts/{account_id}/config

Set an account's module access caps

child_orgs.accounts.update_config

WriteIdempotentSince 2026-11-01

Sets the access cap (hidden, view_only or full_access) of one or more modules active in an account that the workspace pays for (billing_mode parent_pays): what the account's own users can do in each module. Modules not listed keep their cap. Refused (409 account_config_not_managed_by_workspace) for an account that pays for itself (its caps are set by the account) or a dormant one; module_not_enabled (400) for a module the account does not have. Only a direct owner or admin of the agency workspace. Returns the caps after the change.

Scope
child_orgs:write
Permission
Edit in the module · Only owner, admin
MCP tool
child_orgs_accounts_update_configOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.update_config".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

account_idstringpathrequired

Account id: a child organization of this workspace (the ids of platform.orgs.list).

modulesarray<object>bodyrequired

The modules to change; the ones not listed keep their access level.

Response

account_idstring
billing_modestring
controlled_byenum

Values: workspace, account, none

modulesarray<object>

Errors

Example

curl -X PATCH "https://api.mb-suite.com/v1/accounts/{account_id}/config" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "modules": []
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X PATCH "https://api.mb-suite.com/v1/accounts/{account_id}/config" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "modules": []
}'
GET/v1/accounts/data-sources

Census of the accounts with their data sources

child_orgs.accounts.list_with_sources

ReadIdempotentSince 2026-11-01

The census of the workspace's accounts in one paginated call: every account the caller can see, archived ones included (status archived), each with the modules on in it and the platform accounts linked in its Data sources (Google Analytics property, Search Console site, Google Ads customer, Meta ad account, Facebook page, Instagram, TikTok, LinkedIn, Business Profile location, YouTube channel, WhatsApp number). Each row is the account's public profile (id, name, slug, status, child_org_status, billing_mode, industry, website, country, notes, reporting, custom_fields, created_at) plus modules: the modules on in the account as the app resolves them for it (MB Suite's switch for each module in this account, the account's own modules, the base platform and what it inherits from the workspace), each with state (active, or maintenance: shown in the app but not usable for a while, the API answers 503) and inherited (true when the account has it only through its workspace); modules MB Suite keeps off or only for its own team are not listed, and what a person can do in each one still depends on their role and, in an account that pays for itself, on the access it gives the agency (child_orgs.accounts.get_config). And data_sources: the rows integrations.data_sources.list gives for that account (platform, id, composite_id, name, is_default, fields), with inherited and source_org_id resolved from the account's billing mode and integration settings (inherited: read with the workspace's connection) and connection_status: active, error (the connection has to be reconnected), missing (no active or failing connection of that platform in the organization that reads it; for google_analytics, google_search_console and google_business_profile MB Suite may still read it with its own service account if the property granted access) or unknown (too many connections to check). Reads only MB Suite: no platform is called and no token or secret is returned. Who sees what, as in Accounts: owners and admins of the workspace see every account, members and viewers only their assigned ones, a key only the accounts of its child scope. Where the caller cannot see Integrations in an account (the module hidden or under maintenance for it), its row comes without data_sources and with data_sources_hidden: true, and its connections are not read. Needs view access to Accounts and to Integrations in the workspace (a key needs child_orgs:read and integrations:read: 403 scope_insufficient or module_access_denied otherwise). Filter with status (all by default, active, archived) and platforms. Ordered by account id; limit up to 200, follow next_cursor while has_more. A page is filled up to limit (deleted accounts and the ones the status filter leaves out are skipped while reading); it only brings fewer rows when it reached the end or read 200 accounts, and then has_more says whether more follow. An archived account cannot be operated through the API until it is restored (child_orgs.accounts.restore). The workspace's own data sources: integrations.data_sources.list on the workspace. Cost: one read per account read to fill the page (up to 200) plus one query per organization whose connections the page checks (the modules add no reads). With Google Ads, Google Business Profile, LinkedIn, TikTok or YouTube, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records are left out of the response (the permissions guide lists what each platform allows).

Scope
child_orgs:read
Permission
View the module
MCP tool
child_orgs_accounts_list_with_sourcesOn the full surface; on the compact one, mb_execute_operation with id: "child_orgs.accounts.list_with_sources".

Declared cost: up to 2250 reads and 0 writes per call (they count against the daily quota).

Parameters

limitintegerqueryoptional

How many items this page brings at most (see the maximum and the default in the schema).

Default: 50

cursorstringqueryoptional

The next_cursor of the previous page, exactly as it came (only for the same list and filters); without it, the first page.

statusenumqueryoptional

all (default): active and archived accounts, each with its status; active: only the active ones; archived: only the archived ones.

Values: all, active, archived · Default: "all"

platformsarray<enum>queryoptional

Only report the data sources of these platforms (google_analytics, google_search_console, google_ads…). Every account is still listed, with an empty data_sources when it has none of them.

Values: google_ads, meta_ads, facebook_page, instagram, tiktok_ads, tiktok, linkedin_ads, linkedin_page, linkedin_profile, google_analytics, google_search_console, google_business_profile, youtube, whatsapp_business

Response

dataarray<object>
has_moreboolean
next_cursorstring

Errors

Example

curl "https://api.mb-suite.com/v1/accounts/data-sources" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl "https://api.mb-suite.com/v1/accounts/data-sources" \
  -H "Authorization: Bearer $MB_TEST_KEY"