API Reference
Independent worker APIs (simplified regime/RNH). For payroll calculations, see the dependent worker API.
Main Function
simulateIndependentWorker(options)
Calculates Portuguese category B (independent worker) income with simplified regime rules, social security, youth IRS, and optional RNH flat tax.
Parameters
interface SimulateIndependentWorkerOptions {
income: number | number[];
incomeFrequency?: FrequencyChoices;
nrDaysOff?: number;
ssDiscount?: number;
maxExpensesTax?: number;
expenses?: number;
ssTax?: number;
currentTaxRankYear?: 2023 | 2024 | 2025 | 2026;
rnh?: boolean;
rnhTax?: number;
dateOfOpeningActivity?: Date | null;
benefitsOfYouthIrs?: boolean;
yearOfYouthIrs?: number;
previousYearQ4MonthlyIncome?: number;
}| Parameter | Type | Default | Description |
|---|---|---|---|
income | number | number[] | Required | Gross income based on incomeFrequency. Can be provided as an array of exactly 12 numbers for variable monthly income. |
incomeFrequency | FrequencyChoices | "year" | Frequency of the income ("year", "month", "day") |
yearBusinessDays | number | year-specific | Optional override for the year business-day baseline |
nrDaysOff | number | 0 | Days off for daily frequency (integer, must be < yearBusinessDays) |
ssDiscount | number | 0 | Social security adjustment (-0.25 to 0.25) applied to the 70% SS base |
maxExpensesTax | number | 15 | Simplified regime percentage for deductible expenses |
expenses | number | 0 | Declared expenses (used before adding missing expenses) |
ssTax | number | 0.214 | Social security rate |
currentTaxRankYear | 2023 | 2024 | 2025 | 2026 | 2025 | IRS progressive table year |
rnh | boolean | false | Apply RNH flat tax instead of progressive brackets |
rnhTax | number | 0.2 | RNH flat tax rate |
dateOfOpeningActivity | Date | null | null | Sets first/second financial year multipliers and first-12-month SS exemption |
benefitsOfYouthIrs | boolean | false | Apply youth IRS discount |
yearOfYouthIrs | number | 1 | Youth IRS benefit year (1-10 for 2025 tables) |
previousYearQ4MonthlyIncome | number | undefined | Average monthly gross income for Oct/Nov/Dec of the previous year. When supplied, Jan/Feb/Mar SS is computed exactly from this value. When omitted, those months are estimated and ssQ1Approximated is true on the result. |
Return Value
interface IndependentWorkerResult {
grossIncome: CurrencyByFrequency;
yearBusinessDays: number;
taxableIncome: number;
ssPay: CurrencyByFrequency;
specificDeductions: number;
expenses: number;
expensesNeeded: number;
youthIrsDiscount: number;
irsPay: CurrencyByFrequency;
netIncome: CurrencyByFrequency;
taxTableUsed: TaxRank[];
taxRank: TaxRank;
currentIas: number;
maxSsIncome: number;
ssTax: number;
maxExpensesTax: number;
workerWithinFirstFinancialYear: boolean;
workerWithinSecondFinancialYear: boolean;
workerWithinFirst12Months: boolean;
rnh: boolean;
rnhTax: number;
benefitsOfYouthIrs: boolean;
yearOfYouthIrs: number;
ssQ1Approximated: boolean;
monthlyBreakdown: IndependentWorkerMonthlyBreakdownResult[];
normalizedInternals: IndependentWorkerNormalizedInternals;
}
interface IndependentWorkerMonthlyBreakdownResult {
month: IndependentMonthName;
grossIncome: number;
taxableIncome: number;
irsPay: number;
ssPay: number;
netIncome: number;
totalTax: number;
overallTaxBurden: number;
effectiveBracketRate: number | null;
marginalRate: number;
}| Property | Type | Description |
|---|---|---|
grossIncome | CurrencyByFrequency | Income per year/month/day (12 months, 248 business days) |
taxableIncome | number | Income used for IRS after simplified regime factors |
ssPay | CurrencyByFrequency | Social security due (respects caps, discounts, first-year exemption) |
specificDeductions | number | Max of €4104 vs. 10% of SS payments |
expenses | number | Declared expenses |
expensesNeeded | number | Extra expenses needed to reach the simplified cap |
youthIrsDiscount | number | Youth IRS deduction limited by IAS multipliers |
irsPay | CurrencyByFrequency | IRS owed (progressive tables or RNH flat) |
netIncome | CurrencyByFrequency | Net income after IRS and SS |
taxRank | TaxRank | Progressive bracket applied |
currentIas | number | IAS value for the selected tax year |
maxSsIncome | number | Cap for SS base (12 × IAS) |
workerWithinFirstFinancialYear | boolean | Uses 37.5% simplified factor |
workerWithinSecondFinancialYear | boolean | Uses 56.25% simplified factor |
workerWithinFirst12Months | boolean | SS waived for first 12 months after opening activity |
ssQ1Approximated | boolean | true when Jan/Feb/Mar SS is estimated (i.e. previousYearQ4MonthlyIncome was not provided). Show a note to the user in this case. |
rnh / rnhTax | boolean / number | Indicates RNH flat rate usage |
benefitsOfYouthIrs / yearOfYouthIrs | boolean / number | Youth IRS inputs echoed back |
monthlyBreakdown | IndependentWorkerMonthlyBreakdownResult[] | Monthly breakdown with taxes and net income |
normalizedInternals | IndependentWorkerNormalizedInternals | Raw and intermediary calculation metrics (e.g. detailed SS outputs) |
Example
Green Receipts
A suite of utilities to parse and analyze CSV exports of green receipts (“Recibos Verdes”) from the Portal das Finanças (SIRE).
parseGreenReceiptsCsv(content)
Parses the raw CSV string from SIRE into an array of GreenReceiptRawRow objects.
toGreenReceipt(rawRow)
Converts a raw row into a typed GreenReceipt, parsing Portuguese-formatted numbers (e.g., "3.945,51") and standardizing dates.
computeGreenReceiptsAnnualStats(receipts)
Aggregates receipts into annual stats (GreenReceiptAnnualStats), grouped by year, with total VAT, IRS withheld, and a per-client breakdown.
simulateFromGreenReceiptsCsv(options)
Parses the CSV and runs simulateIndependentWorker directly, placing receipts in their appropriate months for the `currentTaxRankYear`. If the CSV contains receipts from the previous year’s 4th quarter (Oct, Nov, Dec), it averages them to automatically calculate `previousYearQ4MonthlyIncome`.
Types and Enums
FrequencyChoices
enum FrequencyChoices {
Year = "year",
Month = "month",
Day = "day"
}Used by simulateIndependentWorker to interpret the income amount.
CurrencyByFrequency
interface CurrencyByFrequency {
year: number;
month: number;
day: number;
}Most independent worker results are returned in this shape (always using 12 months and 248 business days).
IndependentMonthName
type IndependentMonthName =
| "january"
| "february"
| "march"
| "april"
| "may"
| "june"
| "july"
| "august"
| "september"
| "october"
| "november"
| "december";TaxRank
interface TaxRank {
id: number;
min: number;
max: number | null;
normalTax: number;
averageTax: number | null;
}Represents a progressive IRS bracket for independent workers (tables for 2023, 2024, and 2025).
Validation Functions
validateIncome,validateIncomeFrequency,validateNrDaysOffvalidateSsDiscount,validateMaxExpensesTax,validateExpenses,validateSsTaxvalidateCurrentTaxRankYear,validateRnhTaxvalidateYearOfYouthIrs(caps years to 1-5 for 2023/2024 and 1-10 for 2025/2026)
Error Handling
Advanced Usage
Opening activity and youth IRS
Variable Income and Social Security
When supplying an array of exactly 12 numbers for income, the simulator processes income as variable across the year. The frequency field (incomeFrequency) is ignored, and Social Security is calculated on a quarterly basis, mirroring the real-world quarterly declarations:
| Income earned | SS payment months |
|---|---|
| Prev-year Q4 (Oct, Nov, Dec) | Jan, Feb, Mar |
| Q1 (Jan, Feb, Mar) | Apr, May, Jun |
| Q2 (Apr, May, Jun) | Jul, Aug, Sep |
| Q3 (Jul, Aug, Sep) | Oct, Nov, Dec |
Because Jan/Feb/Mar SS depends on the previous year’s Oct–Dec income, the simulator accepts an optional previousYearQ4MonthlyIncome parameter. When not provided, those three months fall back to the current-year Q3 average and ssQ1Approximated is true on the result — useful for showing a UI notice.