> ## Documentation Index
> Fetch the complete documentation index at: https://docs-test.symmetry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Benefit Taxability

> How employee and employer benefits affect taxable wages in the STE, and how to override the defaults.

The STE supports a flexible framework for handling employer and employee benefits. It ships with a set of predefined benefit types, lets you configure custom benefits, and applies default taxability rules that determine — for each tax and benefit type — whether employee contributions are treated as pre-tax and whether employer contributions are included in taxable wages. When those defaults don't fit a specific scenario, you can override them per calculation.

## How benefits affect taxable wages

Benefits change the [gross subject wages](/ste/core-concepts/wages-gross-subject-and-taxable) the engine uses for a tax:

* **Employee pre-tax contributions** reduce the wages subject to a tax.
* **Employer contributions** that are taxable increase the wages subject to a tax.

For each combination of tax and benefit type, the STE knows the default treatment for both sides. These defaults are the baseline for every calculation unless you set an override.

### “Pre-tax” and “post-tax” are per-tax, not global

Whether a benefit is *pre-tax* or *post-tax* is always relative to a **specific tax** — the same benefit can be treated differently by different taxes in the same calculation. A traditional 401(k) employee contribution, for example, is pre-tax for federal income tax (FIT) and most state income taxes (SIT), but **post-tax for FICA** (Social Security and Medicare). The STE applies the correct treatment for each tax and benefit combination automatically.

<Note>
  **"Post-tax" does not mean "taxable."** For an employee contribution, *post-tax* simply means the contribution does **not** reduce the wages subject to that tax — it says nothing about whether any amount is itself added to taxable wages. Whether an *employer* contribution is taxable is a separate question, answered per tax and benefit type.
</Note>

The two sides behave differently:

* **Employee contributions** either reduce the wages subject to a tax (pre-tax) or don't (post-tax).
* **Employer contributions** are never pre-tax. Depending on the benefit type and tax, they are either included in taxable wages or not.

As far as the engine is concerned, all that matters is whether a benefit **impacts a tax it is calculating**. A benefit can be *inert* for a given calculation — an employee contribution treated as post-tax and an employer contribution that isn't taxable — meaning it makes no difference to that result. It's still worth sending: it may affect **other** taxes in the same run, and the STE will apply the correct treatment automatically if the rules change (for example, a new effective date or limit).

## Predefined benefit types

The STE has 16 predefined benefits:

<CardGroup cols={2}>
  <Card title="Retirement">
    [401(k)](/ste/benefits/401-k-benefit-type), [Roth 401(k)](/ste/benefits/roth-401-k-benefit-type), [403(b)](/ste/benefits/403-b-benefit-type), [Roth 403(b)](/ste/benefits/roth-403-b-benefit-type), [457](/ste/benefits/457-benefit-type), [Roth 457](/ste/benefits/roth-457-benefit-type), [Starter 401(k)](/ste/benefits/starter-401-k-benefit-type), and [Roth Starter 401(k)](/ste/benefits/starter-roth-401-k-benefit-type)
  </Card>

  <Card title="SIMPLE IRA">
    [SIMPLE IRA (3% matching)](/ste/benefits/simple-ira-benefit-type-3-matching), [SIMPLE IRA (2% non-elective)](/ste/benefits/simple-ira-benefit-type-2-nonelective), Roth SIMPLE IRA, and Roth SIMPLE IRA Non-elective
  </Card>

  <Card title="Health and spending">
    [Health Savings Account (HSA)](/ste/benefits/health-savings-account-hsa-benefit-type), [Flexible Spending Account (FSA)](/ste/benefits/flexible-spending-account-fsa-benefit-type), and [Dependent Care FSA](/ste/benefits/dependent-care-fsa-benefit-type)
  </Card>

  <Card title="Cafeteria">
    [Section 125 Benefit](/ste/benefits/section-125-cafeteria-plan-benefit-type)
  </Card>
</CardGroup>

In addition to these predefined types, you can configure [custom benefits](/ste/benefits/custom-benefits-in-the-ste) for full control over the taxability and reporting behavior of additional benefits.

## Retrieving benefit information

You can look up general information about any supported benefit type using the get-benefit-information operation. This call is purely informational and is not required before running a calculation.

* **Web API**: `benefitInfo`
* **C & Pascal**: `ste_get_benefit_info_extended()`
* **Java & .NET**: `getBenefitInfoExtended()`

It returns metadata and configuration for the specified benefit based on the pay date provided (set in `ste_payroll_run_parameters` for on-premise clients, or the `BenefitInfoRequest` object for API clients).

| Property                  | Web API / C & Pascal     | Java & .NET                 | Description                                                        |
| ------------------------- | ------------------------ | --------------------------- | ------------------------------------------------------------------ |
| Benefit catch-up amount   | `benefitCatchUpAmt`      | `getBenefitCatchUpAmt`      | Additional amount that may be contributed as catch-up for the year |
| Benefit limit amount      | `benefitLimitAmt`        | `getBenefitLimitAmt`        | Employee contribution limit for the benefit type                   |
| Benefit combined limit    | `benefitCombinedLimit`   | `getBenefitCombinedLimit`   | Combined employee and employer contribution limit                  |
| Benefit annual wage limit | `benefitAnnualWageLimit` | `getBenefitAnnualWageLimit` | Annual wage limit for the benefit type                             |

<Accordion title="Example: 401(k) limits effective January 1, 2026 (Web API)">
  Request:

  ```json theme={null}
  {
    "BenefitInfoRequest": {
      "benefitType": "Benefit401K",
      "payDate": "2026-01-01"
    }
  }
  ```

  Response:

  ```json theme={null}
  {
    "BenefitInfoResponse": {
      "transactionStamp": {
        "totalTransactions": 1,
        "failedTransactions": 0,
        "steVersion": "2026.7.1",
        "transactionType": "BenefitInfo",
        "schemaVersion": "v1",
        "calcDateTime": "2026-01-01T00:00:00Z"
      },
      "benefitInfo": {
        "benefitCombinedLimit": { "combinedLimit": 72000 },
        "benefitAnnualWageLimit": { "annualWageLimit": 360000 },
        "benefitType": "Benefit401K",
        "benefitLimitAmt": { "employeeContributionLimit": 24500 },
        "benefitCatchUpAmt": {
          "higherBenefitCatchUpLimit": 11250,
          "catchUpAmt": 8000
        }
      },
      "errorStatus": { "errorCode": 0, "errorMessage": "No error" }
    }
  }
  ```

  C and Pascal return the response as a JSON string that mirrors the `BenefitInfoResponse` object in the Web API.
</Accordion>

## Benefit taxability overrides

Benefit taxability overrides let you change the default treatment for a given calculation when your business rules require it — for example, employee-specific scenarios such as New Jersey SDI.

<Note>
  Overrides are applied **per pay calculation** and are **not saved** inside the STE's database. Setting an override for the same tax, benefit, and side again replaces the earlier value. Overrides clear when your integration clears the calculation session, after which Symmetry defaults apply again.
</Note>

### What you specify

Each override targets **one** contribution side:

| Contribution | What you control                                                                                 |
| ------------ | ------------------------------------------------------------------------------------------------ |
| Employee     | Whether the employee deduction is pre-tax for that tax (`isTaxImpacting` = pre-tax treatment)    |
| Employer     | Whether the employer contribution is taxable for that tax (`isTaxImpacting` = taxable treatment) |

You pass:

* `uniqueTaxID`: the jurisdiction tax you are overriding (for example, FICA)
* `benefitType`: a standard Symmetry benefit type (the same values used elsewhere in your request)
* `benefitContributionType`: `Employee` or `Employer`
* `isTaxImpacting`: the boolean treatment for that contribution side

### Setting an override

Place overrides on the relevant `taxJurisdictionParms` entry, alongside other jurisdiction options such as year-to-date overrides. For C, Java, .NET, or Pascal, use the equivalent method during setup, before you run the calculation.

<CodeGroup>
  ```json Web API theme={null}
  {
    "payCalc": [
      {
        "taxJurisdictionParms": [
          {
            "uniqueTaxID": "00-000-0000-FICA-000",
            "locationCode": "STATE:00-CNTY:000-CITY:00000",
            "overrideBenefitTaxabilityRules": [
              {
                "benefitType": "BenefitHSA",
                "benefitContributionType": "Employee",
                "isTaxImpacting": true
              },
              {
                "benefitType": "BenefitHSA",
                "benefitContributionType": "Employer",
                "isTaxImpacting": false
              }
            ]
          }
        ]
      }
    ]
  }
  ```

  ```java Java and .NET theme={null}
  public void setOverrideBenefitTaxabilityRule(
      String uniqueTaxID,
      BenefitType benefitType,
      BenefitContributionType benefitContributionType,
      boolean isTaxImpacting
  ) throws STEException
  ```

  ```c C theme={null}
  STE_API(uint16_t) STE_STDCALL ste_set_override_benefit_taxability_rule(
      const ste_handle *ste,
      const char *uniqueTaxID,
      uint16_t benefitType,
      uint16_t benefitContributionType,
      bool isTaxImpacting
  );
  ```

  ```pascal Pascal theme={null}
  function ste_set_override_benefit_taxability_rule(
      ste: Pointer;
      uniqueTaxID: PAnsiChar;
      benefitType: cuint16;
      benefitContributionType: cuint16;
      isTaxImpacting: cint32
  ): cuint16;
  ```
</CodeGroup>

### Limitations

| Topic               | Detail                                                                        |
| ------------------- | ----------------------------------------------------------------------------- |
| Custom benefits     | Not supported; custom benefit types use their existing configuration path.    |
| Tax ID matching     | Only the exact unique tax ID you pass is affected.                            |
| Benefit status APIs | Overrides apply during pay calculation, not to separate benefit-status flows. |

<Warning>
  Overrides change how wages and taxes are computed for your call. You are responsible for ensuring overrides reflect valid payroll tax treatment for your clients. Symmetry's defaults remain the baseline when you do not set an override.
</Warning>

### Checking benefit status

You can retrieve the current taxability status for benefits against a tax using the benefit-status operation:

* **Web API**: `benefitStatus`
* **C & Pascal**: `ste_get_benefit_status_list_ext()`
* **Java & .NET**: `getBenefitStatusListExt()`

<Accordion title="Benefit status example (Web API)">
  Request:

  ```json theme={null}
  {
    "BenefitStatusRequest": {
      "taxIDSearchString": "04-000-0000-SIT-000",
      "payDate": "2026-01-01"
    }
  }
  ```

  Response:

  ```json theme={null}
  {
    "BenefitStatusResponse": {
      "benefitItem": [
        {
          "is403BEmployerContribution": false,
          "is457Pretax": true,
          "isFSADCPretax": true,
          "isRothSimpleIRANonelectiveEmployerContribution": false,
          "uniqueTaxID": "04-000-0000-SIT-000",
          "isStarter401KPretax": true,
          "isRothSimpleIRANonelectivePretax": false,
          "is125EmployerContribution": false,
          "isRothSimpleIRAPretax": false,
          "isRoth401KEmployerContribution": false,
          "isStarter401KEmployerContribution": false,
          "isFSAPretax": true,
          "isRoth401KPretax": false,
          "is457EmployerContribution": false,
          "isHSAEmployerContribution": false,
          "isSimpleIRANonelectiveEmployerContribution": false,
          "isRoth457EmployerContribution": false,
          "isHSAPretax": true,
          "isSimpleIRAPretax": true,
          "isRothStarter401KPretax": false,
          "isRothSimpleIRAEmployerContribution": false,
          "isFSADCEmployerContribution": false,
          "is401KEmployerContribution": false,
          "isRoth403BPretax": false,
          "isRothStarter401KEmployerContribution": false,
          "is401KPretax": true,
          "is125Pretax": true,
          "isSimpleIRANonelectivePretax": true,
          "isFSAEmployerContribution": false,
          "isRoth457Pretax": false,
          "is403BPretax": true,
          "isRoth403BEmployerContribution": false,
          "isSimpleIRAEmployerContribution": false
        }
      ],
      "errorStatus": { "errorMessage": "No error", "errorCode": 0 },
      "transactionStamp": {
        "calcDateTime": "2026-04-10T16:39:55Z",
        "failedTransactions": 0,
        "transactionType": "BenefitStatus",
        "schemaVersion": "v1",
        "steVersion": "2026.4.1.16-SNAPSHOT",
        "totalTransactions": 1
      }
    }
  }
  ```
</Accordion>
