Dimensions
Configure custom dimensions, populate list values, and assign approvers for an organization.
What are dimensions?
Dimensions are custom fields attached to expenses or expense reports that map to your organization's accounting structure. You define the dimensions that match your business — there are no fixed categories.
Track which budget pays for each expense.
Link expenses to specific projects or initiatives.
Identify the organizational unit responsible.
Separate expenses across subsidiaries or legal entities.
Attribute expenses to a client for rebilling.
Map expenses directly to general ledger accounts.
Because dimensions are fully configurable, they also enable flexible approval structures. Assign approvers to specific dimension values — for example, route all "Marketing" cost center expenses to a marketing manager — and build multi-step approval chains that mirror your organization's policies.
Each dimension has a definition (its name, type, and behavior) and optionally a set of list values that users can select from.
API endpoints
All dimension endpoints use the organization's externalId as the base path:
/organizations/externalid/{externalId}/customdimensions/
| Operation | Method | Path |
|---|---|---|
| Get dimension definitions | GET | /organizations/externalid/{externalId}/customdimensions/ |
| Create or update definitions | PUT | /organizations/externalid/{externalId}/customdimensions/ |
| Get list values | GET | /organizations/externalid/{externalId}/customdimensions/{definitionExternalId}/list/ |
| Create or update list values | PUT | /organizations/externalid/{externalId}/customdimensions/{definitionExternalId}/list/ |
| Get approvers for values | GET | /organizations/externalid/{externalId}/customdimensions/{definitionExternalId}/list/approvers/ |
| Create or update approvers | PUT | /organizations/externalid/{externalId}/customdimensions/{definitionExternalId}/list/approvers/ |
Step 1: Create or update dimension definitions
Send a PUT request with an array of dimension definitions. This is an upsert operation — existing dimensions with the same externalSourceId are updated, and new ones are created.
Definition properties
| Property | Type | Required | Description |
|---|---|---|---|
externalSourceId | string | Yes | Your unique identifier for this dimension. Used to match dimensions across syncs. |
description | string | Yes | Display name shown to users (e.g., "Cost Center", "Project"). |
level | string | Yes | Where the dimension appears: EXPENSE (on each expense line) or EXPENSE_REPORT (on the report header). |
controlType | string | Yes | Input type: LIST_SEARCHABLE (user picks from a predefined list) or TEXT (free-text input). |
presetLocation | string | No | Auto-fill source: NONE, EMPLOYEE, DEPARTMENT, or CATEGORY. Defaults to NONE. |
userOverridable | boolean | No | Whether users can change a preset value. Only applies when presetLocation is not NONE. |
visibleIfNoPreset | boolean | No | Whether the dimension is visible when no preset value is available. |
Example request
curl -X PUT \
"https://api.findity.com/api/v1/admin/organizations/externalid/org-acme-123/customdimensions/" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"externalSourceId": "dim-costcenter",
"description": "Cost Center",
"level": "EXPENSE",
"controlType": "LIST_SEARCHABLE",
"presetLocation": "DEPARTMENT",
"userOverridable": true,
"visibleIfNoPreset": true
},
{
"externalSourceId": "dim-project",
"description": "Project",
"level": "EXPENSE",
"controlType": "LIST_SEARCHABLE",
"presetLocation": "NONE"
},
{
"externalSourceId": "dim-invoice-ref",
"description": "Invoice Reference",
"level": "EXPENSE_REPORT",
"controlType": "TEXT",
"presetLocation": "NONE"
}
]'This creates three dimensions:
- Cost Center — a searchable list on each expense, auto-filled from the user's department but overridable
- Project — a searchable list on each expense with no preset
- Invoice Reference — a free-text field on the expense report header
Step 2: Populate list values
Dimensions with controlType: LIST_SEARCHABLE need list values for users to select from. Send a PUT request with the values array.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
clearBeforeUpdate | boolean | false | When true, removes all existing values before inserting the new ones. Use this for a full sync from your ERP. When false, existing values are preserved and new values are upserted. |
cascade | boolean | false | When true, applies the changes to all sub-organizations under the target organization. |
List value properties
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Your unique identifier for this value. |
value | string | Yes | Display text shown to users. |
sortOrder | integer | No | Position in the list. Lower numbers appear first. |
startDate | string (ISO 8601) | No | Date from which this value is available for selection. |
endDate | string (ISO 8601) | No | Date after which this value is no longer available. |
Example request
curl -X PUT \
"https://api.findity.com/api/v1/admin/organizations/externalid/org-acme-123/customdimensions/dim-project/list/?clearBeforeUpdate=true" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"id": "proj-001",
"value": "Website Redesign",
"sortOrder": 1,
"startDate": "2025-01-01",
"endDate": "2025-12-31"
},
{
"id": "proj-002",
"value": "Mobile App v2",
"sortOrder": 2,
"startDate": "2025-03-01"
},
{
"id": "proj-003",
"value": "Internal Tools",
"sortOrder": 3
}
]'In this example:
- Website Redesign is available only during 2025
- Mobile App v2 becomes available from March 2025 onward (no end date)
- Internal Tools has no date restrictions
clearBeforeUpdate=truereplaces all existing project values with these three
Setting
clearBeforeUpdate=trueremoves all existing values before inserting. Make sure your request includes the complete set of values you want to keep.
Step 3: Manage approvers (optional)
Assign approvers to specific dimension values to automatically route expense approvals based on the selected dimension value.
Example request
curl -X PUT \
"https://api.findity.com/api/v1/admin/organizations/externalid/org-acme-123/customdimensions/dim-project/list/approvers/" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"dimensionValueId": "proj-001",
"approverExternalId": "emp-jane-smith"
},
{
"dimensionValueId": "proj-002",
"approverExternalId": "emp-john-doe"
}
]'This assigns Jane Smith as the approver for "Website Redesign" expenses and John Doe for "Mobile App v2" expenses.
Understanding presets
Presets auto-fill dimension values based on existing data, reducing manual input for users. The presetLocation, userOverridable, and visibleIfNoPreset properties work together:
presetLocation | Behavior |
|---|---|
NONE | No auto-fill. The user selects or enters a value manually. |
EMPLOYEE | Auto-fills from the employee's profile. |
DEPARTMENT | Auto-fills from the employee's department. |
CATEGORY | Auto-fills from the expense category. |
When a preset is configured:
userOverridable: true— The dimension is auto-filled but the user can change it. Use this when presets are a helpful default but exceptions are common.userOverridable: false— The dimension is auto-filled and locked. Use this to enforce accounting rules.visibleIfNoPreset: true— If no preset value exists for the user/department/category, the dimension still appears and the user enters a value manually.visibleIfNoPreset: false— If no preset value exists, the dimension is hidden entirely.
Common integration patterns
Full sync from ERP
When syncing dimensions from an ERP system, use clearBeforeUpdate=true to replace all values with the current ERP state. This ensures deleted values in the ERP are also removed from Findity.
- Fetch dimension definitions from ERP →
PUTto/customdimensions/ - For each list dimension, fetch values from ERP →
PUTto/customdimensions/{id}/list/?clearBeforeUpdate=true - Fetch approver mappings →
PUTto/customdimensions/{id}/list/approvers/
Run this on a schedule (e.g., nightly) to keep Findity in sync.
Incremental updates
To add or update individual values without affecting existing ones, use clearBeforeUpdate=false (the default). This is useful when:
- A new project is created and needs to be available immediately
- A value's display name changes
- You need to set an
endDateon a value to deactivate it
Send only the changed or new values in the request body. Existing values with different id values are not affected.
Multi-level organizations
Use cascade=true to push dimension values down to all sub-organizations. This is useful when:
- Your organization has a shared set of cost centers across all subsidiaries
- You manage dimensions centrally and want sub-organizations to inherit them
Set cascade=true as a query parameter on the list values PUT request.
Next step
Updated 4 days ago
