-
-
Notifications
You must be signed in to change notification settings - Fork 0
Sideloading
Complete guide to efficiently loading related data using sideloading (includes) in the Teamleader SDK.
Sideloading allows you to load related resources in a single API request instead of making multiple requests. This significantly improves performance and reduces API call usage.
Without sideloading, you'd need multiple API calls:
// β Bad: 3 API calls
$company = Teamleader::companies()->info('company-uuid');
$user = Teamleader::users()->info($company['responsible_user']['id']);
$businessType = Teamleader::businessTypes()->info($company['business_type']['id']);With sideloading, you get everything in one call:
// β
Good: 1 API call
$company = Teamleader::companies()
->with('responsible_user,business_type')
->info('company-uuid');The fluent with() method is the recommended way to sideload relationships:
use McoreServices\TeamleaderSDK\Facades\Teamleader;
// Single relationship
$company = Teamleader::companies()
->with('responsible_user')
->info('company-uuid');
// Multiple relationships (comma-separated string)
$company = Teamleader::companies()
->with('responsible_user,addresses,business_type')
->info('company-uuid');
// Multiple relationships (array)
$company = Teamleader::companies()
->with(['responsible_user', 'addresses', 'business_type'])
->info('company-uuid');
// Chaining
$company = Teamleader::companies()
->with('responsible_user')
->with('addresses')
->with('business_type')
->info('company-uuid');You can also specify includes in the options:
// In list() calls
$companies = Teamleader::companies()->list([], [
'include' => 'responsible_user,addresses'
]);
// In info() calls
$company = Teamleader::companies()->info('company-uuid', 'responsible_user,addresses');Available includes:
-
responsible_user- The user responsible for the company -
addresses- Company addresses -
business_type- Business type information -
tags- Company tags -
added_by- User who added the company -
language- Language information -
custom_fields- Custom field values -
price_list- Assigned price list for the company
// Load company with all common relationships
$company = Teamleader::companies()
->with('responsible_user,addresses,business_type,tags')
->info('company-uuid');Available includes:
-
responsible_user- The user responsible for the contact -
company- The contact's company -
language- Language information -
tags- Contact tags -
added_by- User who added the contact -
custom_fields- Custom field values -
price_list- Assigned price list for the contact
// Load contact with company and responsible user
$contact = Teamleader::contacts()
->with('company,responsible_user')
->info('contact-uuid');Available includes:
-
lead.customer- Customer information (company or contact) -
responsible_user- The user responsible for the deal -
department- Department information -
phase- Current deal phase -
source- Deal source -
custom_fields- Custom field values
// Load deal with customer and user information
$deal = Teamleader::deals()
->with('lead.customer,responsible_user,phase')
->info('deal-uuid');Available includes:
-
lead.customer- Customer information -
responsible_user- Responsible user -
department- Department information -
deal- Related deal (if any) -
grouped_lines- Grouped quotation lines -
custom_fields- Custom field values
$quotation = Teamleader::quotations()
->with('lead.customer,responsible_user,grouped_lines')
->info('quotation-uuid');Available includes:
-
customer- Customer information -
department- Department information -
invoicee- Invoicee information -
grouped_lines- Grouped invoice lines -
credit_notes- Related credit notes -
custom_fields- Custom field values
$invoice = Teamleader::invoices()
->with('customer,grouped_lines')
->info('invoice-uuid');Available includes:
-
customer- Customer information -
responsible_user- Responsible user -
department- Department information -
custom_fields- Custom field values
$project = Teamleader::projects()
->with('customer,responsible_user')
->info('project-uuid');The SDK provides convenient helper methods for common relationships:
These methods work across most resources:
// Load responsible user
$company = Teamleader::companies()
->withResponsibleUser()
->info('company-uuid');
// Load department
$deal = Teamleader::deals()
->withDepartment()
->info('deal-uuid');
// Load custom fields
$contact = Teamleader::contacts()
->withCustomFields()
->info('contact-uuid');$company = Teamleader::companies()
->withAddresses()
->withBusinessType()
->withResponsibleUser()
->withAddedBy()
->info('company-uuid');
// Or load all common relationships
$company = Teamleader::companies()
->withCommonRelationships()
->info('company-uuid');$contact = Teamleader::contacts()
->withCompany()
->withResponsibleUser()
->info('contact-uuid');$deal = Teamleader::deals()
->withCustomer() // Loads lead.customer
->withResponsibleUser()
->withDepartment()
->info('deal-uuid');Some relationships can be nested using dot notation:
// Load deal with customer information
$deal = Teamleader::deals()
->with('lead.customer')
->info('deal-uuid');
// Access the nested data
$customerName = $deal['data']['lead']['customer']['name'];Sideloading works with both info() and list() calls:
// Load all companies with related data
$companies = Teamleader::companies()
->with('responsible_user,business_type')
->list();
// With filters
$companies = Teamleader::companies()
->with('responsible_user,addresses')
->list([
'status' => 'active'
]);
// With pagination and sorting
$companies = Teamleader::companies()
->with('responsible_user,business_type')
->list(
['status' => 'active'],
[
'page_size' => 50,
'sort' => 'name'
]
);// β Bad: Loading unnecessary data
$company = Teamleader::companies()
->with('responsible_user,addresses,business_type,tags,language,added_by,custom_fields')
->info('company-uuid');
// β
Good: Load only required relationships
$company = Teamleader::companies()
->with('responsible_user')
->info('company-uuid');When processing multiple resources, sideload in the list call:
// β
Efficient: One API call with sideloaded data
$companies = Teamleader::companies()
->with('responsible_user,business_type')
->list([], ['page_size' => 100]);
foreach ($companies['data'] as $company) {
$userName = $company['responsible_user']['first_name'];
$businessType = $company['business_type']['name'];
// Process with included data
}
// β Inefficient: Multiple API calls
$companies = Teamleader::companies()->list([], ['page_size' => 100]);
foreach ($companies['data'] as $company) {
// Each iteration makes 2 additional API calls!
$user = Teamleader::users()->info($company['responsible_user']['id']);
$businessType = Teamleader::businessTypes()->info($company['business_type']['id']);
}If you need to reset includes in a chain:
$resource = Teamleader::companies()
->with('responsible_user')
->withoutIncludes() // Clears all pending includes
->with('addresses') // Start fresh
->info('company-uuid');Check which relationships a resource supports:
// Get resource capabilities
$capabilities = Teamleader::companies()->getCapabilities();
if ($capabilities['supports_sideloading']) {
// This resource supports sideloading
$defaultIncludes = $capabilities['default_includes'];
}$company = Teamleader::companies()
->with('responsible_user,addresses')
->info('company-uuid');
// Access the main resource
$companyName = $company['data']['name'];
// Access sideloaded relationships
$userName = $company['data']['responsible_user']['first_name'];
$userEmail = $company['data']['responsible_user']['email'];
// Access array relationships
foreach ($company['data']['addresses'] as $address) {
echo $address['line_1'];
}$company = Teamleader::companies()
->with('responsible_user')
->info('company-uuid');
if (isset($company['data']['responsible_user'])) {
// Responsible user was loaded
$user = $company['data']['responsible_user'];
} else {
// Responsible user was not loaded
}// β
Good: One API call
$deal = Teamleader::deals()
->with('lead.customer,responsible_user')
->info('deal-uuid');
// β Bad: Three API calls
$deal = Teamleader::deals()->info('deal-uuid');
$customer = Teamleader::companies()->info($deal['lead']['customer']['id']);
$user = Teamleader::users()->info($deal['responsible_user']['id']);// β
Good: Clear and readable
$company = Teamleader::companies()
->withResponsibleUser()
->withAddresses()
->withBusinessType()
->info('company-uuid');
// β Less readable: Magic strings
$company = Teamleader::companies()
->with('responsible_user,addresses,business_type')
->info('company-uuid');// β
Good: Organized by concern
$deal = Teamleader::deals()
->with([
// Customer information
'lead.customer',
// Deal metadata
'phase',
'source',
'responsible_user',
// Department info
'department'
])
->info('deal-uuid');use Illuminate\Support\Facades\Cache;
public function getCompanyWithRelations($companyId)
{
$cacheKey = "company.{$companyId}.with_relations";
return Cache::remember($cacheKey, 3600, function () use ($companyId) {
return Teamleader::companies()
->with('responsible_user,business_type,addresses')
->info($companyId);
});
}When building services, document which relationships are needed:
/**
* Get company summary with all required relationships
*
* Includes:
* - responsible_user: For display name and contact info
* - business_type: For categorization
* - addresses: For location data
*/
public function getCompanySummary(string $companyId): array
{
return Teamleader::companies()
->with('responsible_user,business_type,addresses')
->info($companyId);
}public function show($id)
{
$company = Teamleader::companies()
->with([
'responsible_user',
'addresses',
'business_type',
'tags'
])
->info($id);
return view('companies.show', [
'company' => $company['data']
]);
}public function index(Request $request)
{
$companies = Teamleader::companies()
->with('responsible_user,business_type')
->list(
['status' => 'active'],
[
'page_size' => 20,
'page_number' => $request->get('page', 1)
]
);
return view('companies.index', [
'companies' => $companies['data']
]);
}public function apiShow($id)
{
$deal = Teamleader::deals()
->with([
'lead.customer',
'responsible_user',
'phase',
'department'
])
->info($id);
return response()->json([
'data' => $deal['data'],
'included' => [
'customer' => $deal['data']['lead']['customer'],
'user' => $deal['data']['responsible_user'],
'phase' => $deal['data']['phase']
]
]);
}public function getCompany($id, $includeRelations = false)
{
$query = Teamleader::companies();
if ($includeRelations) {
$query->withCommonRelationships();
}
return $query->info($id);
}Handle cases where includes might not be available:
$company = Teamleader::companies()
->with('responsible_user,addresses')
->info('company-uuid');
// Always check if relationship exists
$responsibleUserName = $company['data']['responsible_user']['first_name']
?? 'No user assigned';
// Or use null coalescing
$addresses = $company['data']['addresses'] ?? [];use Tests\TestCase;
class CompanySideloadingTest extends TestCase
{
public function test_can_load_company_with_relationships()
{
$company = Teamleader::companies()
->with('responsible_user,addresses')
->info('test-company-uuid');
// Verify relationships are loaded
$this->assertArrayHasKey('responsible_user', $company['data']);
$this->assertArrayHasKey('addresses', $company['data']);
// Verify relationship data structure
$this->assertArrayHasKey('first_name', $company['data']['responsible_user']);
$this->assertIsArray($company['data']['addresses']);
}
}You can configure default includes in config/teamleader.php:
'sideloading' => [
'defaults' => [
'companies' => ['responsible_user', 'business_type'],
'contacts' => ['company', 'responsible_user'],
'deals' => ['lead.customer', 'responsible_user', 'phase'],
],
'max_includes' => 10, // Maximum number of includes per request
],- Learn about Filtering to narrow down your results
- See Usage for general SDK usage
- Check individual resource documentation for available relationships (see the [GitHub repo /docs folder](https://github.com/MCore-Services-bv/teamleader-sdk/tree/main/docs))
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