Subsidiaries
Create, retrieve, list, and update subsidiaries for white label programs
Overview
A subsidiary is a legal or operational entity under a company. Programs use subsidiaries to scope spend, budgets, cost centers, teams, and employee assignment when the parent company has multiple entities (for example regional offices or brands).
Typical flow:
- Create a subsidiary:
POST /md/api/Subsidiaries - Retrieve by ID:
GET /md/api/Subsidiaries/{id} - List with a filter:
GET /md/api/Subsidiarieswithfilter.where - Update a subsidiary:
PATCH /md/api/Subsidiaries/{id} - Assign employees: set
subsidiaryIdon the user viaPATCH /md/api/User/{id}(see Assign employees)
Authentication: All endpoints require Authorization: Bearer {access_token} and x-appid: {clientId}. The company is resolved from your access token scope: do not send companyId in request bodies. See Authentication.
code must be unique within your company among active subsidiaries. Duplicate codes are rejected on create.
Create Subsidiary
Creates a new subsidiary for the company associated with your access token. The platform sets companyId, id, and status (default active) automatically.
Request Body: mandatory fields
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name for the subsidiary. |
code |
string | Yes | Unique identifier for the subsidiary within the company (max 64 characters). Often mirrors an ERP or legal-entity code. |
Optional fields
| Parameter | Type | Default | Description |
|---|---|---|---|
currency |
string | - | ISO currency code for the subsidiary (for example USD, EUR). Max 4 characters. |
externalId |
string | null |
External system identifier (ERP, HR, or partner reference). |
officeLocationId |
string | null |
Office location UUID associated with the subsidiary, when your program uses offices. |
status |
string | "active" |
Lifecycle status. Values: active, archived, deleted. |
Example Request
Using cURL:
curl -X POST https://sandbox.custodia-tech.com/md/api/Subsidiaries \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme US East",
"code": "US-EAST",
"currency": "USD",
"externalId": "ERP-SUB-1001"
}'
Using JavaScript (fetch):
const response = await fetch('https://sandbox.custodia-tech.com/md/api/Subsidiaries', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Acme US East',
code: 'US-EAST',
currency: 'USD',
externalId: 'ERP-SUB-1001'
})
});
const subsidiary = await response.json();
Response
Success Response (200 OK)
{
"id": "c4d5e6f7-a8b9-0123-cdef-456789012345",
"name": "Acme US East",
"code": "US-EAST",
"currency": "USD",
"companyId": "your-company-id",
"status": "active",
"externalId": "ERP-SUB-1001",
"officeLocationId": null
}
Save the returned id: it is the subsidiaryId used when assigning users and when scoping cost centers, teams, budgets, and related records.
Get Subsidiary by ID
Retrieves a single subsidiary by its ID. Use the id returned from create subsidiary.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique identifier of the subsidiary |
Example Request
Using cURL:
curl -X GET https://sandbox.custodia-tech.com/md/api/Subsidiaries/c4d5e6f7-a8b9-0123-cdef-456789012345 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID"
Using JavaScript (fetch):
const subsidiaryId = 'c4d5e6f7-a8b9-0123-cdef-456789012345';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Subsidiaries/${subsidiaryId}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const subsidiary = await response.json();
Response
Success Response (200 OK)
{
"id": "c4d5e6f7-a8b9-0123-cdef-456789012345",
"name": "Acme US East",
"code": "US-EAST",
"currency": "USD",
"companyId": "your-company-id",
"status": "active",
"externalId": "ERP-SUB-1001",
"officeLocationId": null
}
List Subsidiaries
Retrieves subsidiaries for your company. Use the filter query parameter with a where clause to match by code, status, name, and other fields. Results are scoped to the company associated with your access token: do not include companyId in the filter.
Query Parameters
Pass the filter as a URL-encoded JSON object in the filter query parameter.
| Parameter | Type | Description |
|---|---|---|
filter |
object (JSON) | Filter, sorting, and pagination options. See filter options below. |
Filter Options
The filter object supports the following properties:
| Property | Type | Description |
|---|---|---|
where |
object | Filter conditions. See where clause examples below. |
fields |
array | Array of field names to include in the response (for example ["id", "code", "name", "status"]). |
order |
string | Sort order (for example "name ASC" or "code DESC"). |
limit |
number | Maximum number of results to return. |
skip |
number | Number of results to skip (for pagination). |
Where Clause Examples
Common filter conditions for the where clause:
| Field | Example | Description |
|---|---|---|
code |
{"code": "US-EAST"} |
Match a specific subsidiary code. |
status |
{"status": "active"} |
Filter by status: active, archived, or deleted. |
externalId |
{"externalId": "ERP-SUB-1001"} |
Match by external ERP or partner identifier. |
currency |
{"currency": "USD"} |
Filter subsidiaries by currency. |
name |
{"name": {"like": "%East%", "options": "i"}} |
Search by display name (case-insensitive partial match). |
code + status |
{"code": "US-EAST", "status": "active"} |
Combine conditions to narrow results. |
Example Requests
Find an active subsidiary by code:
Using cURL:
curl -G https://sandbox.custodia-tech.com/md/api/Subsidiaries \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
--data-urlencode 'filter={"where":{"code":"US-EAST","status":"active"}}'
Using JavaScript (fetch):
const filter = {
where: {
code: 'US-EAST',
status: 'active'
},
order: 'name ASC'
};
const filterParam = encodeURIComponent(JSON.stringify(filter));
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Subsidiaries?filter=${filterParam}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const subsidiaries = await response.json();
List active subsidiaries (paginated):
Using JavaScript (fetch):
const filter = {
where: { status: 'active' },
order: 'code ASC',
limit: 25,
skip: 0
};
const filterParam = encodeURIComponent(JSON.stringify(filter));
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Subsidiaries?filter=${filterParam}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const subsidiaries = await response.json();
Response
Success Response (200 OK)
[
{
"id": "c4d5e6f7-a8b9-0123-cdef-456789012345",
"name": "Acme US East",
"code": "US-EAST",
"currency": "USD",
"companyId": "your-company-id",
"status": "active",
"externalId": "ERP-SUB-1001",
"officeLocationId": null
}
]
Returns an array of subsidiary objects. An empty array means no rows matched the filter.
Update Subsidiary
Partially updates an existing subsidiary. Only include fields you want to change. Do not send companyId or id: they cannot be changed via this endpoint.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | UUID of the subsidiary to update |
Request Body
All fields are optional on update. Send only the properties you want to change:
| Parameter | Type | Description |
|---|---|---|
name |
string | Display name for the subsidiary. |
code |
string | Subsidiary code (max 64 characters). Must remain unique within your company among active subsidiaries. |
currency |
string | ISO currency code (for example USD, EUR). |
externalId |
string | External system identifier. |
officeLocationId |
string | Office location UUID associated with the subsidiary. |
status |
string | Lifecycle status: active, archived, or deleted. |
Example Request
Update the display name and currency:
Using cURL:
curl -X PATCH https://sandbox.custodia-tech.com/md/api/Subsidiaries/c4d5e6f7-a8b9-0123-cdef-456789012345 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme United States East",
"currency": "USD"
}'
Using JavaScript (fetch):
const subsidiaryId = 'c4d5e6f7-a8b9-0123-cdef-456789012345';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Subsidiaries/${subsidiaryId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Acme United States East',
currency: 'USD'
})
});
const subsidiary = await response.json();
Response
Success Response (200 OK)
{
"id": "c4d5e6f7-a8b9-0123-cdef-456789012345",
"name": "Acme United States East",
"code": "US-EAST",
"currency": "USD",
"companyId": "your-company-id",
"status": "active",
"externalId": "ERP-SUB-1001",
"officeLocationId": null
}
Assign Employees
Employees are not added to a subsidiary through a dedicated membership endpoint. Assignment is done by updating the user (AppUser) record: set the user’s subsidiaryId field to the subsidiary UUID.
User field: The user record includes subsidiaryId. Create the subsidiary first, then set that field on create (POST /md/api/User) or update (PATCH /md/api/User/{id}). See Update User.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | UUID of the user (employee) to assign |
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
subsidiaryId |
string | Yes (for assignment) | Subsidiary UUID. Use the id returned from create subsidiary. Set to null to clear the assignment. |
Example Request
Using cURL:
curl -X PATCH https://sandbox.custodia-tech.com/md/api/User/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"subsidiaryId": "c4d5e6f7-a8b9-0123-cdef-456789012345"
}'
Using JavaScript (fetch):
const userId = '550e8400-e29b-41d4-a716-446655440000';
const subsidiaryId = 'c4d5e6f7-a8b9-0123-cdef-456789012345';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/User/${userId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
subsidiaryId
})
});
const user = await response.json();
Response
Success Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"firstname": "Jane",
"lastname": "Doe",
"email": "jane.doe@acme.com",
"companyId": "your-company-id",
"subsidiaryId": "c4d5e6f7-a8b9-0123-cdef-456789012345",
"active": true
}
TeamUserMappings), subsidiary membership lives on the user record itself. Do not use TeamUserMappings to attach employees to a subsidiary.
Subsidiary Fields
Field reference for create, update, and list responses:
| Parameter | Type | On create | Description |
|---|---|---|---|
id |
string | Set by platform | UUID of the subsidiary. Use as subsidiaryId on users and other scoped records. |
name |
string | Required in request | Display name for the subsidiary. |
code |
string | Required in request | Unique code within the company (max 64 characters). |
currency |
string | Optional | ISO currency code for the subsidiary. |
externalId |
string | Optional | Identifier in an external ERP or HR system. |
officeLocationId |
string | Optional | Related office location UUID, when applicable. |
status |
string | Optional (default active) |
Lifecycle status: active, archived, or deleted. |
companyId |
string | Set by platform | Company resolved from your access token. |
Error Responses
All endpoints may return the following error responses:
| Status Code | Description | Solution |
|---|---|---|
400 Bad Request |
Missing required field (name or code), invalid currency, or duplicate code |
Include mandatory fields, use a valid ISO currency, and ensure code is unique within your company |
401 Unauthorized |
Invalid or missing access token | Verify your access token is valid and included in the Authorization header |
403 Forbidden |
Insufficient permissions | Verify your access token has the required scopes and permissions |
404 Not Found |
Subsidiary or user not found | Verify the subsidiary or user ID is correct and belongs to your company |
Related documentation
- Companies: parent tenant for subsidiaries
- Update user: set
subsidiaryIdon the employee record - Cost center: optional
subsidiaryIdscope on cost centers - Org teams: optional
subsidiaryIdscope on teams - Authentication: obtain access tokens
- Glossary: platform terminology