# Business Made · Tax

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /business-made/payroll/tax-rules

**List tax rules**

`operationId: PayrollConfigController_listTaxRules`

The tax rules on file — brackets, rates and thresholds by jurisdiction and year.

#### Signature

```http
GET /business-made/payroll/tax-rules () -> Tax rules
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/coverage`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Tax rules |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/payroll/tax-rules

**Create a tax rule**

`operationId: PayrollConfigController_createTaxRule`

Creates a single tax rule.

A wrong rule under- or over-withholds from real people and is typically discovered months later by a tax authority. Prefer `seed-us` or `import` for anything beyond a one-off, and verify the year afterwards.

#### Signature

```http
POST /business-made/payroll/tax-rules (body) -> The created rule
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Run `GET /business-made/payroll/tax-rules/verify/{year}` after any manual rule change.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/payroll/tax-rules/import`
- `GET /business-made/payroll/tax-rules/verify/{year}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The rule to create.

```json
{
  "year": 2026,
  "jurisdiction": "US-FED",
  "filingStatus": "single",
  "brackets": [
    {
      "upTo": 11925,
      "rate": 0.1
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created rule |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/payroll/tax-rules/{id}

**Get a tax rule**

`operationId: PayrollConfigController_getTaxRule`

Fetches one tax rule.

#### Signature

```http
GET /business-made/payroll/tax-rules/{id} (id: string) -> The tax rule
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `PATCH /business-made/payroll/tax-rules/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The tax rule |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /business-made/payroll/tax-rules/{id}

**Delete a tax rule**

`operationId: PayrollConfigController_deleteTaxRule`

Deletes a tax rule. Removing one that a jurisdiction still needs leaves a gap the coverage report will flag — check coverage afterwards.

#### Signature

```http
DELETE /business-made/payroll/tax-rules/{id} (id: string) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/coverage`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PATCH /business-made/payroll/tax-rules/{id}

**Update a tax rule**

`operationId: PayrollConfigController_updateTaxRule`

Updates a tax rule. Affects future calculations only — runs already calculated keep the rates they used.

#### Signature

```http
PATCH /business-made/payroll/tax-rules/{id} (id: string, body) -> The updated rule
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Recalculate any open run after changing a rule that applies to it.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/verify/{year}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

Fields to change.

```json
{
  "brackets": [
    {
      "upTo": 12000,
      "rate": 0.1
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated rule |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/payroll/tax-rules/import

**Import tax rules in bulk**

`operationId: PayrollConfigController_importTaxRules`

Bulk-imports tax rules — a state table, a full year of federal brackets, anything.

**Every rule is validated before any is written**, so a malformed table is rejected whole rather than leaving half a year of brackets loaded. That is what makes this safe to run against production.

Set `replace` to overwrite the existing rules for the same scope instead of adding to them.

**Certificate-driven withholding.** Besides `flat`, `bracket`, `wage_base_capped`, `additional_threshold` and `none`, a rule may use:
- `state_withholding` (state_income, or a local with its own schedule like NYC) with a `withholding` block: `method` `annualized_schedule` (`schedules` keyed by name, each with `standardDeduction`, optional `standardDeductionByAllowances`, `lowIncomeExemption`, `brackets`, `wholeIncomeRates`; `scheduleMap` from the certificate's filing status — or `withholdingCode` with `scheduleFrom` — to a schedule; `federalStatusMap` used only when no certificate is on file; wage-keyed look-ups `exemptionByWages`, `addBackByWages`, `recaptureByWages`, `creditRateByWages` (CT); `allowance`/`dependent` `{ mode: deduction|credit, annualAmount }`; `exemptionAmount: { mode }`; `deductionAllowance`; `minimumAnnualWages`; `stateOnlyExemptReasons`; `localityRequired`) or `percent_of_wages` (`allowedPercents`, `defaultPercent`).
- Local rules (`local_income`, need `locality`): `percent_of_state` (`employeeRate` × the state amount), `percent_of_state_taxable` (flat `employeeRate`, marginal `brackets`, or whole-income `tiers` by schedule, on the state's annual taxable wages), `percent_of_wages` (`employeeRate` on `wageBase` less `annualDeductionPerAllowance` per allowance). Match fields: `localityCode`, `localityName`, `aliases`, `localityKind`, `residentCities`; `followsStateExempt` (default true).
Published tables whose accumulated column is rounded may set `flatBaseTolerance` (≤ $5). A table that changes mid-year sets `effectiveFrom` (YYYY-MM-DD) and `effectiveFromBasis` (`pay_date` default, `period_end`, `period_start`).

**Federal (Pub 15-T).** A `federal_income` `bracket` rule may set `method: "pub15t_percentage"` with a `percentageMethod` block (`line1gAdjustment`, `allowanceAmount`, `step2CheckboxBrackets`) to compute by IRS Pub 15-T Worksheet 1A; `brackets` is then the STANDARD schedule.

**Disability and family leave.** `state_disability` and `state_family_leave` are employee contributions matched by work state. `wageBasis` (`state` default, `fica`, `gross`) picks the wages the rate applies to; `employeeMaxPerWeek` caps a `flat` rule per week, scaled to the pay frequency.

#### Signature

```http
POST /business-made/payroll/tax-rules/import (body) -> The import result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- All-or-nothing. A partial table cannot be created by a failed import.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/verify/{year}`
- `GET /business-made/payroll/tax-rules/tables/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The rules to import.

```json
{
  "rules": [
    {
      "year": 2026,
      "jurisdiction": "US-CA",
      "filingStatus": "single",
      "brackets": [
        {
          "upTo": 10756,
          "rate": 0.011
        }
      ]
    }
  ],
  "replace": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The import result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/payroll/tax-rules/verify/{year}

**Verify tax tables for a year**

`operationId: PayrollConfigController_verifyTaxTables`

Produces a verification sheet for a tax year: worked examples at known incomes plus structural checks on the tables.

This exists to be checked **against the published source** by a human. Run it after seeding or importing, compare the worked examples to the authority's own tables, and only then run payroll on the year.

#### Signature

```http
GET /business-made/payroll/tax-rules/verify/{year} (year: string) -> Worked examples and structural checks
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- The point is manual review — a clean structural check does not mean the rates are right.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/compare/{fromYear}/{toYear}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `year` | path | string | yes | Tax year. |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Worked examples and structural checks |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/payroll/tax-rules/compare/{fromYear}/{toYear}

**Compare two tax years**

`operationId: PayrollConfigController_compareTaxTables`

Diffs two years of tax tables and **flags thresholds that moved suspiciously** — the check that catches a transposed digit or a bracket that shifted by an order of magnitude.

Year-on-year thresholds usually move by small inflation adjustments; anything else is worth explaining before you rely on it.

#### Signature

```http
GET /business-made/payroll/tax-rules/compare/{fromYear}/{toYear} (fromYear: string, toYear: string) -> The comparison, with suspicious movements flagged
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/verify/{year}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `fromYear` | path | string | yes | Baseline year. |
| `toYear` | path | string | yes | Year to check. |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The comparison, with suspicious movements flagged |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/payroll/tax-rules/tables/status

**Get tax table load status**

`operationId: PayrollConfigController_taxTableStatus`

Which tax table files loaded successfully and which were rejected. Check this after a deployment — a silently rejected table means calculations fall back to whatever else is on file.

#### Signature

```http
GET /business-made/payroll/tax-rules/tables/status () -> Table load status
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/payroll/tax-rules/import`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Table load status |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/payroll/tax-rules/coverage

**Get state tax coverage**

`operationId: PayrollConfigController_taxRuleCoverage`

Compares the states employees are actually paid in against the states with rules on file — the gap analysis that catches a new hire in a state nobody has loaded tables for.

A missing state means that employee's state tax cannot be calculated correctly. Run it whenever you hire somewhere new.

#### Signature

```http
GET /business-made/payroll/tax-rules/coverage (year?: string) -> Coverage by state
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/payroll/tax-rules/import`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `year` | query | string | — | Tax year to check. Defaults to the current one. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Coverage by state |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/payroll/tax-rules/shadowed

**List org rules that replace an official table**

`operationId: PayrollConfigController_shadowedTaxTables`

Org tax rules that replace a shipped official table for the same jurisdiction, state or locality and year — e.g. a hand-entered flat Illinois rate overriding the IL-W-4-driven IL table, so every allowance an employee claims is ignored. Each row names the official table and, where the table reads a withholding certificate, what the override ignores. A warning only: nothing is changed. Only active rules are checked.

#### Signature

```http
GET /business-made/payroll/tax-rules/shadowed (year?: string) -> Shadowing org rules
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/payroll/tax-rules/{id}/use-official`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `year` | query | string | — | Run year to check. Defaults to the current year. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Shadowing org rules |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "year": 2026,
  "shadowed": [
    {
      "ruleId": "66f1c0ffee",
      "ruleName": "Illinois 4.95%",
      "jurisdiction": "state_income",
      "state": "IL",
      "officialName": "IL State Income 2026 (IL-W-4, IL-700-T automated method)",
      "officialYear": 2026,
      "certificate": "IL-W-4",
      "ignored": "allowances on IL-W-4 are ignored",
      "message": "Your rule \"Illinois 4.95%\" replaces the official IL 2026 table (IL State Income 2026 (IL-W-4, IL-700-T automated method)); allowances on IL-W-4 are ignored."
    }
  ]
}
```

## POST /business-made/payroll/tax-rules/{id}/use-official

**Use the official table instead of an org rule**

`operationId: PayrollConfigController_useOfficialTaxTable`

Retires an org rule that shadows a shipped official table, so the official table applies. The rule is never deleted: it is set inactive and stamped with `retiredAt`, `retiredBy` and `retiredReason`, and can be re-activated from the rule editor.

#### Signature

```http
POST /business-made/payroll/tax-rules/{id}/use-official (id: string, body) -> The retired rule and the table now in force
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `409` | — | Rule <id> does not replace an official table for <year>, so retiring it would leave nothing in its place. Edit or deactivate it from the rule editor instead. | The rule does not shadow an official table for that year (see `GET /business-made/payroll/tax-rules/shadowed`). | — |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/shadowed`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

```json
{
  "year": 2026
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The retired rule and the table now in force |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `409` | Rule <id> does not replace an official table for <year>, so retiring it would leave nothing in its place. Edit or deactivate it from the rule editor instead. — The rule does not shadow an official table for that year (see `GET /business-made/payroll/tax-rules/shadowed`). |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/payroll/tax-rules/seed-us

**Seed US federal tax rules**

`operationId: PayrollConfigController_seedUSRules`

Loads the standard US federal tax rules for a year. **Idempotent**, so re-running it does not duplicate anything — the intended way to set up a new tax year.

#### Signature

```http
POST /business-made/payroll/tax-rules/seed-us (body) -> The seeded rules
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/payroll/tax-rules/verify/{year}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Which year to seed.

```json
{
  "year": 2026
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The seeded rules |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

