-
-
Notifications
You must be signed in to change notification settings - Fork 0
Legacy Milestones
Manage milestones (phases) within legacy projects in Teamleader Focus.
Legacy Milestones are the phases of a legacy project. Each milestone has its own timeline, billing method, and responsible user. Milestones act as containers for tasks.
Access via Teamleader::legacyMilestones().
Only available on Legacy Projects accounts. Check with
Teamleader::accounts()->isUsingLegacyProjects().
billing_methodis optional on create β but validated when provided (non_invoiceable,time_and_materials,fixed_price).Sort fields are silently clamped β any invalid sort field falls back to
due_on.
close()closes all open tasks (meetings stay open). Closing the last open milestone also closes the project.
open()reopens the project if it was closed.
milestones
| Capability | Supported |
|---|---|
| Pagination | β Supported |
| Filtering | β Supported |
| Sorting | β
Supported (starts_on, due_on) |
| Sideloading | β Not supported |
| Creation | β Supported |
| Update | β Supported |
| Deletion | β Supported |
use McoreServices\TeamleaderSDK\Facades\Teamleader;
$milestones = Teamleader::legacyMilestones()->list();
$milestones = Teamleader::legacyMilestones()->list(
['project_id' => 'project-uuid', 'status' => 'open'],
['sort' => [['field' => 'due_on', 'order' => 'asc']], 'page_size' => 20]
);Throws InvalidArgumentException if $id is empty.
$milestone = Teamleader::legacyMilestones()->info('milestone-uuid');Four fields are required:
| Required | Notes |
|---|---|
project_id |
Project UUID |
name |
Milestone name |
due_on |
Due date (YYYY-MM-DD) β validated |
responsible_user_id |
Responsible user UUID |
billing_method is optional β but validated when provided. starts_on is also optional and validated when provided.
Billing methods (validated when provided): non_invoiceable, time_and_materials, fixed_price
$milestone = Teamleader::legacyMilestones()->create([
'project_id' => 'project-uuid',
'name' => 'Phase 2: Development',
'starts_on' => '2025-06-01',
'due_on' => '2025-07-31',
'responsible_user_id' => 'user-uuid',
'billing_method' => 'time_and_materials',
'description' => 'Main development phase',
]);Injects id into the request body. Throws if $id is empty.
Teamleader::legacyMilestones()->update('milestone-uuid', [
'name' => 'Phase 2 β Updated',
'due_on' => '2025-08-15',
]);Throws if $id is empty.
Teamleader::legacyMilestones()->delete('milestone-uuid');Closes all open tasks within the milestone. Open meetings remain open. If this is the last open milestone on the project, the project itself is also closed.
Teamleader::legacyMilestones()->close('milestone-uuid');Reopens the milestone. If the project was closed, it is also reopened.
Teamleader::legacyMilestones()->open('milestone-uuid');$milestones = Teamleader::legacyMilestones()->forProject('project-uuid');Applies due_after + due_before filters.
$milestones = Teamleader::legacyMilestones()->dueBetween('2025-04-01', '2025-06-30');
// With additional filters
$milestones = Teamleader::legacyMilestones()->dueBetween(
'2025-04-01', '2025-06-30',
['status' => 'open']
);| Filter | Type | Description |
|---|---|---|
ids |
array | Filter by milestone UUIDs |
project_id |
string | Filter by project UUID |
status |
string |
open, closed
|
due_before |
string | YYYY-MM-DD |
due_after |
string | YYYY-MM-DD |
term |
string | Search milestone name |
Valid sort fields: starts_on, due_on. Invalid field values silently fall back to due_on β no exception is thrown.
$milestones = Teamleader::legacyMilestones()->list([], [
'sort' => [['field' => 'due_on', 'order' => 'asc']],
]);use InvalidArgumentException;
// Empty ID
try {
Teamleader::legacyMilestones()->info('');
} catch (InvalidArgumentException $e) {
// 'Milestone ID cannot be empty'
}
// Missing required field
try {
Teamleader::legacyMilestones()->create([
'project_id' => 'uuid', 'name' => 'Phase 1', 'due_on' => '2025-05-31',
// missing responsible_user_id
]);
} catch (InvalidArgumentException $e) {
// "Field 'responsible_user_id' is required for milestone creation"
}
// Invalid billing_method
try {
Teamleader::legacyMilestones()->create([
'project_id' => 'uuid', 'name' => 'Phase 1', 'due_on' => '2025-05-31',
'responsible_user_id' => 'user-uuid', 'billing_method' => 'hourly',
]);
} catch (InvalidArgumentException $e) {
// 'Invalid billing_method. Must be one of: non_invoiceable, time_and_materials, fixed_price'
}
// Invalid date format
try {
Teamleader::legacyMilestones()->create([
'project_id' => 'uuid', 'name' => 'Phase 1',
'due_on' => '31-05-2025', // wrong format
'responsible_user_id' => 'user-uuid',
]);
} catch (InvalidArgumentException $e) {
// 'Invalid due_on date format. Use Y-m-d format.'
}- Legacy Projects β Parent legacy project
- Accounts β Check which project version the account uses
- Groups β Equivalent concept in Projects v2
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