Skip to main content

Overview

Tags categorize and allocate payroll amounts across dimensions like department, project, or location, so costs can be tracked, split, and mapped to the right accounting codes automatically. Each line item can carry a tag assignment, a structure that defines how that line item’s dollar amount is distributed across one or more tags. Those allocations are used to determine accounting codes and detailed journal entries. The typical flow looks like this:
  1. Define tag groups and tags: create tag groups (“Department”, “Project”) and tags within them (“Engineering”, “Sales”, “Project Alpha”)
  2. Assign tags: set tag assignments on work assignments, generators, or individual line items to describe how costs are distributed
  3. Configure accounting code rules: define rules that map tags to expense and liability accounting codes, resolved automatically during payroll calculation
  4. Generate journal entries: tag allocations produce journal entry rows, one per allocation per tracking dimension, ready to export to the connected accounting system

Concepts

Setting up tag groups and tags

Tag groups represent a category to track (e.g. “Department”). Tags are the values within that group (e.g. “Engineering”, “Sales”). Each tag group belongs to a business entity. A tag group can also be marked as a journal entry tracking dimension; see Journal entry tracking dimensions.
  1. Create a tag group for each category to track
  2. Create tags within each group
Tag groups carry a few optional properties beyond their label:
  • color: a hex colour (e.g. #AABBCC) used for display.
  • is_component_locked: when true, the tags in this group cannot be edited through the embedded Component. They can still be managed through the API.
  • is_journal_entry_dimension: see Journal entry tracking dimensions.
  • archived_at: archived tag groups (and tags) are excluded from index listings by default. Pass include_archived=true to include them.
  • is_deletable: false while the group is the primary tag group, or while any of its tags are used in active allocations. The same applies to individual tags.
Tag groups and tags imported from an accounting integration carry the external identifiers (integrations.xero, integrations.quickbooks) that link them back to the source system, so they round-trip on re-sync. See Syncing tracking dimensions. See the Tag Groups and Tags API reference for full details.

Tag assignments and allocations

A tag assignment describes how a line item’s amount is distributed across tags. Tag assignments can be set on work assignments, generators, and line items. Each contains a unit that determines how allocations are measured, and one or more tag allocations, each with a set of tags and an allocation value.

Example tag assignment structure

{
  "tag_assignment": {
    "unit": "percentage",
    "tag_allocations": [
      {
        "tags": [
          "<engineering_tag_id>", // From department tag group
          "<project_alpha_tag_id>", // From project tag group
        ],
        "value": 60,
      },
      {
        "tags": [
          "<sales_tag_id>", // From department tag group
        ],
        "value": 40,
      },
    ],
  },
}
In this example, 60% of the amount is attributed to the Engineering department on Project Alpha, and 40% to the Sales department. Each allocation can combine tags from different tag groups, but only one tag per group is allowed in each allocation. Allocations must sum to less than or equal to 100%. Any unallocated remainder falls back to the line item’s own accounting codes. If no accounting code can be determined, the payroll is blocked until the allocation is resolved.

Supported units by resource

The unit on a tag assignment controls how allocation values are interpreted. Available units depend on the resource type. Work assignments and generators only support percentage because they define default allocations before line item amounts are known. Only line items have concrete dollar values and hours that can be allocated directly.
ResourceSupported units
Work assignmentpercentage
Pay rate, overtime rate, employee benefit, employer benefit, reimbursement, earning, allowance, deductionpercentage
Earning line itempercentage, amount, hours
Deduction, allowance, reimbursement, employee benefit, employer benefit line itempercentage, amount

Assigning tags

Work assignments

A tag_assignment on a work assignment defines the default allocation for all of that employee’s line items. Work assignment tag assignments use the percentage unit. Each allocation defines what percentage of the total amount is attributed to those tags. Allocations must sum to less than or equal to 100%. Pass tag_assignment when creating or updating a work assignment. Pass null to remove it. Use ?expand=tag_assignment to include it in responses.

Generators

In this guide, generators refers to the resources that produce line items: pay rates, overtime rates, earnings, deductions, allowances, reimbursements, and benefits. Generators support a tag_assignment that overrides the work assignment’s tag_assignment for line items created by that generator. Generator tag assignments use percentage allocations only. Pass tag_assignment when creating or updating any generator resource.

Line items

Line items support a custom_tag_assignment that overrides the managed tag assignment inherited from the work assignment or generator.

Allocation units

UnitDescriptionValidationUse case
percentageSplit by percentage of total amountAllocations must sum to less than or equal to 100%Default, same as work assignments and generators
hoursSplit by hours workedAllocations must sum to less than or equal to the line item’s hoursEarning line items only, attribute costs by hours per tag
amountSplit by fixed dollar amountsAllocations must sum to less than or equal to the line item’s amountAttribute exact dollar amounts per tag
Earning line items accept all three units. Non-earning line items (deductions, allowances, reimbursements, benefits) accept percentage and amount only.

Expanding tag assignments

Line items expose several expandable tag properties. Each returns the full tag assignment structure:
ExpandDescription
tag_assignmentThe effective tag assignment: the custom_tag_assignment if set, otherwise the managed_tag_assignment
custom_tag_assignmentOptional override: if set, these allocations are used instead of the managed value
managed_tag_assignmentThe auto-inherited allocation from the work assignment or generator
tag_assignment_amountsThe resolved dollar distribution for the line item

Patching a tag assignment

To adjust an existing tag assignment without resending the whole structure, pass tag_assignment_patch instead of tag_assignment on a work assignment or generator. The two keys are mutually exclusive.
FieldDescription
add_tagsTag IDs to add to every existing allocation. Adding a tag replaces any other tag from the same tag group on that allocation.
remove_tagsTag IDs to remove from every existing allocation. An allocation left with no tags is deleted; the distribution strategy decides its value.
distribution_strategyGoverns the value of allocations deleted by remove_tags. Defaults to reallocate.
The distribution_strategy accepts:
  • reallocate: spread the deleted value proportionally across the remaining allocations.
  • unallocated: drop the value; the assignment’s allocations will sum to less than before.
  • error: refuse the patch if any allocation would be deleted.

Tag resolution and precedence

Line items on draft payrolls automatically receive a managed_tag_assignment, resolved from the generator’s tag_assignment if set, otherwise from the work assignment’s tag_assignment. If a custom_tag_assignment is set on the line item, it takes precedence over the managed value. The effective tag_assignment (used for accounting code matching and journal entries) is the custom_tag_assignment if one exists, otherwise the managed_tag_assignment. Tag resolution only applies to draft payrolls. Once a payroll is approved, its tag assignments are locked. Subsequent changes to work assignment or generator tag assignments will not affect it. When a work assignment’s tag_assignment is updated, draft line items whose generator has no tag_assignment, have their managed_tag_assignment updated to match. When a generator’s tag_assignment is updated, all of its draft line items have their managed_tag_assignment updated to match.

Primary tag group

A business entity can designate one tag group as its primary tag group.
  • Tags from this group can be linked to accounting code rules, enabling automatic accounting code matching
  • When set, every tag allocation must include a tag from the primary tag group
Set the primary tag group through the business entity’s accounting_settings.primary_tag_group. The top-level primary_tag_group_id is a deprecated alias. Setting a primary tag group also flags it as a journal entry dimension. If the primary tag group is changed, draft payrolls with allocations missing a tag from the new primary group will be blocked until corrected.

Accounting code rules

Accounting code rules map tags to expense and liability accounting codes. Rules are defined on a business entity and scoped to tags in the primary tag group. Nmbr automatically matches rules against each line item’s tag assignment, assigning the matched expense and liability accounting codes to each allocation.

Rule precedence

Rules are tried in the order shown. If no rule matches the line item at one precedence, the next precedence is tried.
PrecedenceFields set on the ruleExample line item the rule matches
1 (highest)tag_id + business_preset_id”Engineering” tag on a line item with the “Senior Developer Salary” business preset
2tag_id + type + subtype”Engineering” tag on a line item of type earning, subtype salary
3tag_id + type”Engineering” tag on any earning line item
4tag_id”Engineering” tag on any line item
5tag_group_id + business_preset_idAny tag from “Department” on a line item with the “Senior Developer Salary” preset
6tag_group_id + type + subtypeAny tag from “Department” on a line item of type earning, subtype salary
7tag_group_id + typeAny tag from “Department” on any earning line item
8tag_group_idAny tag from “Department” on any line item
9business_preset_idA line item with the “Senior Developer Salary” business preset
10type + subtypeA line item of type earning, subtype salary
11 (lowest)typeAny earning line item
A rule can be scoped to line items with a specific tag (tag_id) or any tag from a group (tag_group_id). When neither is set, the rule must specify a type (optionally with subtype) or a business_preset_id. The expense and liability codes are resolved independently. A line item can take its expense code from one rule and its liability code from another, so a rule that supplies only one of the two is valid. Each side walks the precedence order on its own and uses the first rule that supplies that code. See the Accounting Code Rules API reference for creating and managing rules.

How rules are resolved

When a payroll is calculated, the system processes each line item’s tag allocations:
  1. For each allocation, find the tag that belongs to the primary tag group
  2. Look up rules for that tag in precedence order:
    • If the line item has a business preset, try a preset-level rule first
    • Then try type + subtype
    • Then type only
    • Finally try a tag-only rule
  3. Apply the matched rule’s expense and liability accounting codes to the allocation
Rules are re-evaluated whenever payroll is recalculated, so changes to rules take effect on the next calculation of any draft payroll.

Derived tags on statutory withholdings

Statutory withholding line items (CPP, EI, income tax, etc.) are system-calculated and cannot be directly tagged. Instead, they derive their tag assignments from the applicable remuneration on the pay stub. This behaviour is controlled by the business entity’s accounting_settings.resolve_journal_entry_stat_withholdings setting. When true, each withholding is split across the same tags as its source earnings. When false, each withholding stays a single unsplit row in journal entries. When enabled, after payroll calculation the system examines which remuneration line items contribute to each withholding and builds a weighted percentage distribution based on their resolved dollar amounts, regardless of whether the original tag assignment used percentage, hours, or amount units. This ensures withholding amounts follow the same distribution as the remuneration that generated them.

Example: statutory withholdings derived from pensionable earnings

Earnings on the pay stub:
Line itemAmountEngineeringSales
Salary earning$3,000100%
Bonus earning$2,000100%
Derived statutory withholdings:
Line itemAmountEngineeringSales
CPP withholding$30060% ($180)40% ($120)
EI withholding$15060% ($90)40% ($60)
The withholdings inherit a 60/40 distribution derived from the weighted remuneration ($3,000 Engineering / $2,000 Sales).

Journal entry tracking dimensions

Tag groups can be marked as tracking dimensions on journal entries. When enabled, each line item allocation produces a separate journal entry row, with matched accounting codes and the tag from each tracking dimension. The primary tag group is always a tracking dimension. Up to two additional tag groups can be marked as tracking dimensions by setting is_journal_entry_dimension to true. Tagged payroll data produces structured journal entries with tracking detail per tag group.

Example: journal entry rows with tracking dimensions

Given a salary earning of $5,000 tagged 60% Engineering / 40% Sales: Without tracking dimensions:
AccountDebitCredit
Salary Expense$5,000
Payroll Liability$5,000
With Department and Project as tracking dimensions:
AccountDebitCreditDepartmentProject
Salary Expense$3,000EngineeringProject Alpha
Salary Expense$2,000Sales
Payroll Liability$3,000EngineeringProject Alpha
Payroll Liability$2,000Sales
Each allocation produces its own debit and credit row, with the matched accounting codes and tracking dimension tags.

Retrieving dimension tags

Each journal entry row carries up to three dimension tags, one per tracking dimension: dimension_1_tag, dimension_2_tag, and dimension_3_tag. A tag group keeps the same slot across every row in a payroll. Slots are not pinned to a fixed group, so read each tag’s tag_group to tell which dimension it represents rather than relying on position. The tags sit two levels down: rows are nested under the journal entry, and each tag is nested under a row. Both are returned as stubs by default, so resolving the tags inline takes a nested expand. Expand journal_entry_rows.dimension_1_tag, journal_entry_rows.dimension_2_tag, and journal_entry_rows.dimension_3_tag for the dimensions to resolve. Each expanded row then includes the full tag for every dimension it carries:
{
  "id": "accjr_01...",
  "object": "journal_entry_row",
  "data": {
    "type": "debit",
    "amount": 2500,
    "code": "5110",
    "dimension_1_tag": {
      "id": "tag_01AURORA...",
      "object": "tag",
      "data": {
        "label": "Aurora",
        "tag_group": { "id": "tgrp_01...", "object": "tag_group" }
      }
    },
    "dimension_2_tag": {
      "id": "tag_01MTL...",
      "object": "tag",
      "data": {
        "label": "Montreal",
        "tag_group": { "id": "tgrp_01...", "object": "tag_group" }
      }
    },
    "dimension_3_tag": null
  }
}
A dimension with no tag on a row returns null. Without the expand, each dimension tag is returned as a stub with id and links only.

End-to-end example

This example walks through the full tagging flow, from setup to journal entries.
  • Quebec-based business entity with two employees: Marie (Montreal) and Luc (Quebec City)
  • Both earn $60,000 salary, paid semi-monthly ($2,500 per period)
  • Both work on Project Aurora
  • Luc also receives an $833.33 bonus for work on Project Beacon

1. Set up tags

  1. Create a “Project” tag group with two tags: Aurora and Beacon
  2. Create a “Location” tag group with two tags: Montreal and Quebec City
  3. Set “Project” as the business entity’s primary tag group (accounting_settings.primary_tag_group)
  4. Mark both tag groups as journal entry tracking dimensions (is_journal_entry_dimension: true)

2. Create accounting code rules

Define rules for the primary tag group to map each project to accounting codes:
TagTypeExpense codeLiability code
AuroraEarning5110 (Aurora Salaries)2100 (Aurora Payroll Liability)
AuroraStatutory withholding5120 (Aurora Stat Withholdings)2110 (Aurora Stat Payable)
BeaconEarning5210 (Beacon Salaries)2200 (Beacon Payroll Liability)
BeaconStatutory withholding5220 (Beacon Stat Withholdings)2210 (Beacon Stat Payable)
Each project has an earning rule and a stat withholding rule. No tag-only fallbacks are needed since all line items in this example are covered by type-level rules.

3. Assign tags to work assignments

Both employees’ work assignments are tagged 100% Aurora, with their respective location: Marie:
  • 100% to Project: Aurora, Location: Montreal
Luc:
  • 100% to Project: Aurora, Location: Quebec City

4. Line items on the pay stub

In this example, the salary line items resolve their managed_tag_assignment from the work assignment. Since Luc’s bonus is for work on Project Beacon, a custom_tag_assignment on that line item overrides the managed Aurora tag with Beacon. When expanded, the effective tag_assignment returns the custom_tag_assignment if one is set, otherwise the managed_tag_assignment. Marie’s salary earning ($2,500.00):
  • Managed tag assignment: 100% to Project: Aurora, Location: Montreal
  • Custom tag assignment: none
  • Effective tag assignment: 100% to Project: Aurora, Location: Montreal
Luc’s salary earning ($2,500.00):
  • Managed tag assignment: 100% to Project: Aurora, Location: Quebec City
  • Custom tag assignment: none
  • Effective tag assignment: 100% to Project: Aurora, Location: Quebec City
Luc’s bonus earning ($833.33):
  • Managed tag assignment: 100% to Project: Aurora, Location: Quebec City
  • Custom tag assignment: 100% to Project: Beacon, Location: Quebec City
  • Effective tag assignment: 100% to Project: Beacon, Location: Quebec City

5. Matched accounting codes

Each line item’s tag allocations are matched against accounting code rules:
EmployeeLine itemPrimary tagMatched ruleExpense codeLiability code
MarieSalary earningAuroraEarning5110 (Aurora Salaries)2100 (Aurora Payroll Liability)
LucSalary earningAuroraEarning5110 (Aurora Salaries)2100 (Aurora Payroll Liability)
LucBonus earningBeaconEarning5210 (Beacon Salaries)2200 (Beacon Payroll Liability)
MarieQPP withholdingAuroraStatutory withholding5120 (Aurora Stat Withholdings)2110 (Aurora Stat Payable)
LucQPP withholdingAuroraStatutory withholding5120 (Aurora Stat Withholdings)2110 (Aurora Stat Payable)
LucQPP withholdingBeaconStatutory withholding5220 (Beacon Stat Withholdings)2210 (Beacon Stat Payable)
Luc’s QPP withholding has two allocations (75% Aurora / 25% Beacon), each resolved independently against its matching rule.

6. Derived statutory withholdings

Statutory withholdings derive their tag allocations from the remuneration that generates them. Marie: all remuneration is tagged Project: Aurora, Location: Montreal, so each withholding carries the same single allocation:
  • Federal tax ($184.47)
    • 100% ($184.47) to Project: Aurora, Location: Montreal
  • Provincial tax ($235.29)
    • 100% ($235.29) to Project: Aurora, Location: Montreal
  • QPP ($148.31)
    • 100% ($148.31) to Project: Aurora, Location: Montreal
  • QPIP ($10.75)
    • 100% ($10.75) to Project: Aurora, Location: Montreal
  • EI ($32.50)
    • 100% ($32.50) to Project: Aurora, Location: Montreal
Luc: remuneration is $2,500 (Project: Aurora) + $833.33 (Project: Beacon), a 75/25 split. Both carry Location: Quebec City. Each withholding derives two allocations at that ratio:
  • Federal tax ($325.75)
    • 75% ($244.31) to Project: Aurora, Location: Quebec City
    • 25% ($81.44) to Project: Beacon, Location: Quebec City
  • Provincial tax ($350.77)
    • 75% ($263.08) to Project: Aurora, Location: Quebec City
    • 25% ($87.69) to Project: Beacon, Location: Quebec City
  • QPP ($200.81)
    • 75% ($150.61) to Project: Aurora, Location: Quebec City
    • 25% ($50.20) to Project: Beacon, Location: Quebec City
  • QPIP ($14.33)
    • 75% ($10.75) to Project: Aurora, Location: Quebec City
    • 25% ($3.58) to Project: Beacon, Location: Quebec City
  • EI ($43.33)
    • 75% ($32.50) to Project: Aurora, Location: Quebec City
    • 25% ($10.83) to Project: Beacon, Location: Quebec City

7. Journal entry rows

With Project and Location as journal entry tracking dimensions, each allocation produces its own row. Employer contribution rows are omitted for brevity.
AccountLocationProjectDebitCredit
Aurora SalariesMontrealAurora$2,500.00
Aurora SalariesQuebec CityAurora$2,500.00
Beacon SalariesQuebec CityBeacon$833.33
Aurora Stat PayableMontrealAurora$611.32
Aurora Stat PayableQuebec CityAurora$701.25
Beacon Stat PayableQuebec CityBeacon$233.74
Net Payroll Payable$4,287.02