-
-
Notifications
You must be signed in to change notification settings - Fork 0
Accounts
Read account-level settings in Teamleader Focus.
The Accounts resource exposes the Projects version status for the connected Teamleader account. This determines whether the account is on the current ("nextgen") project system or the legacy one β which in turn determines which project-related SDK resources will actually return useful data.
Access via Teamleader::accounts().
This is the answer to "which project system is this account on?" Both project endpoints answer, so you cannot tell by calling one and seeing whether rows come back. See Why this resource matters.
list()andinfo()throwInvalidArgumentException. The API exposes exactly one endpoint here,accounts.projects-v2-status.Every convenience method calls the API.
isUsingProjectsV2(),getProjectsVersion()and the rest all callprojectsV2Status()internally. Cache the result if you need more than one.
accounts
| Capability | Supported |
|---|---|
| Pagination | β Not supported |
| Filtering | β Not supported |
| Sorting | β Not supported |
| Sideloading | β Not supported |
| Creation | β Not supported |
| Update | β Not supported |
| Deletion | β Not supported |
Teamleader uses three different names across the two project systems, and they do not line up:
| Current system | Legacy system | |
|---|---|---|
| SDK method |
projects() / nextgenProjects()
|
legacyProjects() |
| API path | projects-v2/projects.* |
projects.* |
| Webhooks | nextgenProject.* |
project.* |
Reading the webhook names, it is natural to assume projects() is the legacy resource. It isn't. And because both endpoints answer on any account, a list call that returns twenty real projects tells you nothing about which system is in use β that exact mistake is what this resource exists to prevent.
// Do not do this
$projects = Teamleader::projects()->list();
$isOnNextgen = ! empty($projects['data']); // meaningless
// Do this
$isOnNextgen = Teamleader::accounts()->isUsingProjectsV2();See Projects and Legacy Projects.
The only API call in this resource. Posts to accounts.projects-v2-status.
use McoreServices\TeamleaderSDK\Facades\Teamleader;
$status = Teamleader::accounts()->projectsV2Status();Response:
[
'data' => [
'status' => 'legacy', // or 'projects-v2'
'will_be_automatically_switched_on' => '2025-12-31', // optional β only for legacy accounts scheduled to migrate
],
'headers' => ['X-RateLimit-Remaining' => ['199'], /* ... */],
]status is one of exactly two values: projects-v2 or legacy. will_be_automatically_switched_on is absent, not null, when no migration is scheduled β use ?? rather than checking for null.
All helpers call projectsV2Status() internally, so each one is its own API request.
| Method | Returns |
|---|---|
isUsingProjectsV2(): bool |
true if status is projects-v2
|
isUsingLegacyProjects(): bool |
true if status is legacy
|
getProjectsVersion(): string |
'projects-v2' or 'legacy'
|
getAutoSwitchDate(): ?string |
YYYY-MM-DD or null
|
hasScheduledAutoSwitch(): bool |
true if an auto-switch date is set |
getDaysUntilAutoSwitch(): ?int |
Days remaining (negative if the date has passed), or null
|
isAutoSwitchApproaching(int $days = 30): bool |
true if the switch is within $days days |
getAccountStatus(): array |
Formatted summary of all status fields |
getProjectVersions(): array |
['projects-v2', 'legacy'] β local, no API call |
getResponseStructure(): array |
Field-level documentation β local, no API call |
There is no
getDefaultId()on this resource. Earlier versions of this page listed one, described as an alias forgetAutoSwitchDate(). No such method exists in the source β calling it raisesError: Call to undefined method. UsegetAutoSwitchDate().
| Resource | Current (projects-v2) |
Legacy |
|---|---|---|
Teamleader::projects() |
β | β |
Teamleader::nextgenProjects() |
β | β |
Teamleader::projectLines() |
β | β |
Teamleader::projectTasks() |
β | β |
Teamleader::groups() |
β | β |
Teamleader::materials() |
β | β |
Teamleader::external_parties() |
β | β |
Teamleader::legacyProjects() |
β | β |
Teamleader::legacyMilestones() |
β | β |
"β" here means the endpoint will not return meaningful data for that account β not that the SDK method throws. Calling the wrong one generally succeeds and returns an empty or unrelated result, which is why checking first matters.
if (Teamleader::accounts()->isUsingProjectsV2()) {
$projects = Teamleader::projects()->list(['status' => 'open']);
} else {
$projects = Teamleader::legacyProjects()->active();
}Remember the two systems use different status vocabularies β open versus active β and different customer filter shapes. See the comparison table on Legacy Projects.
Each helper is a request, so chaining four of them costs four calls. Fetch once:
$status = Teamleader::accounts()->projectsV2Status();
$isV2 = $status['data']['status'] === 'projects-v2';
$switchOn = $status['data']['will_be_automatically_switched_on'] ?? null;
if (! $isV2 && $switchOn) {
$days = (new DateTime)->diff(new DateTime($switchOn))->days;
Log::warning("Account migrates to Projects v2 in {$days} days ({$switchOn})");
}The version changes rarely β at most once per account, on migration β so it is a good candidate for a long cache:
$isV2 = Cache::remember('tl_projects_v2', 3600, fn () =>
Teamleader::accounts()->isUsingProjectsV2()
);Keep the TTL well short of the auto-switch date if one is scheduled, or your integration will keep calling the legacy endpoints after the account has moved.
if (Teamleader::accounts()->isAutoSwitchApproaching(30)) {
$days = Teamleader::accounts()->getDaysUntilAutoSwitch();
$date = Teamleader::accounts()->getAutoSwitchDate();
// show banner: "Your account migrates to Projects v2 in $days days ($date)."
}That is three API calls. For a banner rendered on every page load, use getAccountStatus() once, or cache.
Since an account only fires one project event family, subscribing to both keeps an integration working straight through a migration:
Teamleader::webhooks()->register(
config('app.url').'/webhooks/teamleader',
Teamleader::webhooks()->getProjectEventTypes() // project.* + nextgenProject.*
);See Webhooks.
use InvalidArgumentException;
// list() not supported
try {
Teamleader::accounts()->list();
} catch (InvalidArgumentException $e) {
// 'The accounts resource does not support list operations. Use projectsV2Status() method instead.'
}
// info() not supported
try {
Teamleader::accounts()->info('uuid');
} catch (InvalidArgumentException $e) {
// 'The accounts resource does not support info operations. Use projectsV2Status() method instead.'
}-
Projects β The current system; fires
nextgenProject.*despite the method name -
Legacy Projects β The older system, on the bare
projects.*path - Legacy Milestones β Phases within a legacy project
- Project Tasks β Tasks in the current system
-
Time Tracking β
relates_toaccepts bothprojectandnextgenProject -
Files β Subject types include both
projectandnextgenProject -
Webhooks β Both
project.*andnextgenProject.*event families - Migrate β Translate legacy numeric IDs to new UUIDs
Last Updated: August 2026 β’ SDK Version: 2.2.2 β’ Made with β€οΈ by MCore Services
- Departments
- Users
- Teams
- Custom Fields
- Work Types
- Document Templates
- Currencies
- Notes
- Email Tracking
- Closing Days
- Day Off Types
- Days Off
- User Schedules
- Invoices
- Credit Notes
- Subscriptions
- Payment Methods
- Payment Terms
- Tax Rates
- Withholding Tax Rates
- Commercial Discounts
Next Gen Projects
Legacy Projects