<aside> <img src="notion://custom_emoji/492827db-2338-4c87-a34e-b0791a3f29d8/30a81003-6f9d-80c2-bec5-007ad1fa0e67" alt="notion://custom_emoji/492827db-2338-4c87-a34e-b0791a3f29d8/30a81003-6f9d-80c2-bec5-007ad1fa0e67" width="40px" />
This is a publicly shared, world-visible document.
</aside>
Plain has merged companies and tenants into one model, now called accounts. An account is the same record as a tenant, with the same ID (te_…). Every tenant field and operation has an account equivalent, and every company operation maps onto one.
What this means for your code:
company* and tenant* queries, mutations, fields and filters are @deprecated in the GraphQL schema in favour of account* equivalents.tenant* operations keep working exactly as before. They are aliases of the account operations, so migrating them is a rename.company* operations stop behaving like companies once a workspace hides companies. Some are translated onto accounts, some are rejected. Migrate these first.
company* operations will be officially removed from the schema on April 26, 2027, so be sure to migrate before then.This guide is for developers updating integrations. For the product-side migration (hiding companies, updating views, workflows, roles and help center settings in the app) see the help center article: Migrating companies to tenants.
| Company | Tenant | Account (use this) |
|---|---|---|
companies / searchCompanies |
tenants / searchTenants |
accounts / searchAccounts |
company(companyId:) |
tenant(tenantId:) |
account(accountId:) |
upsertCompany |
createTenant / upsertTenant |
createAccount / upsertAccount |
deleteCompany |
deleteTenant |
deleteAccount |
updateCustomerCompany |
addCustomerToTenants / removeCustomerFromTenants / setCustomerTenants |
addCustomerToAccounts / removeCustomerFromAccounts / setCustomerAccounts |
updateCompanyTier |
updateTenantTier |
updateAccountTier |
| — | updateThreadTenant |
updateThreadAccount |
Customer.company |
Customer.tenantMemberships |
Customer.accountMemberships |
| — | Thread.tenant |
Thread.account |
CompanyIdentifierInput { companyId, companyDomainName } |
TenantIdentifierInput { tenantId, externalId } |
AccountIdentifierInput { accountId, externalId } |
contractValue, accountOwner |
tenant fields | account fields contract_value, account_owner |
Key changes
tenant → account (and Tenant → Account) across queries, mutations, inputs, filters and enums. Behaviour is identical.te_…), not the old company ID. The account gets a new Plain-generated externalId (tei_…), so map stored company IDs before you switch (section 10).externalId, not domain. AccountIdentifierInput has no domain name option. Look an account up with accounts and the filter property if you only have a domain.Customer.company (one) becomes Customer.accountMemberships (a paginated list).tenantIdentifiers and accountIdentifiers) fails with BAD_USER_INPUT.tenant:* becomes account:* (section 10). Both spellings are accepted when creating API keys.