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:

  1. Create a subsidiary: POST /md/api/Subsidiaries
  2. Retrieve by ID: GET /md/api/Subsidiaries/{id}
  3. List with a filter: GET /md/api/Subsidiaries with filter.where
  4. Update a subsidiary: PATCH /md/api/Subsidiaries/{id}
  5. Assign employees: set subsidiaryId on the user via PATCH /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 uniqueness: code must be unique within your company among active subsidiaries. Duplicate codes are rejected on create.

Create Subsidiary

POST /md/api/Subsidiaries

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

GET /md/api/Subsidiaries/{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

GET /md/api/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

PATCH /md/api/Subsidiaries/{id}

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.

PATCH /md/api/User/{id}

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
}
Not a mapping API: Unlike cost centers and org teams (which use 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