Skip to Content
Saldo is currently in alpha - report bugs here
Independent WorkerAPI Reference

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; }
ParameterTypeDefaultDescription
incomenumber | number[]RequiredGross income based on incomeFrequency. Can be provided as an array of exactly 12 numbers for variable monthly income.
incomeFrequencyFrequencyChoices"year"Frequency of the income ("year", "month", "day")
yearBusinessDaysnumberyear-specificOptional override for the year business-day baseline
nrDaysOffnumber0Days off for daily frequency (integer, must be < yearBusinessDays)
ssDiscountnumber0Social security adjustment (-0.25 to 0.25) applied to the 70% SS base
maxExpensesTaxnumber15Simplified regime percentage for deductible expenses
expensesnumber0Declared expenses (used before adding missing expenses)
ssTaxnumber0.214Social security rate
currentTaxRankYear2023 | 2024 | 2025 | 20262025IRS progressive table year
rnhbooleanfalseApply RNH flat tax instead of progressive brackets
rnhTaxnumber0.2RNH flat tax rate
dateOfOpeningActivityDate | nullnullSets first/second financial year multipliers and first-12-month SS exemption
benefitsOfYouthIrsbooleanfalseApply youth IRS discount
yearOfYouthIrsnumber1Youth IRS benefit year (1-10 for 2025 tables)
previousYearQ4MonthlyIncomenumberundefinedAverage 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; }
PropertyTypeDescription
grossIncomeCurrencyByFrequencyIncome per year/month/day (12 months, 248 business days)
taxableIncomenumberIncome used for IRS after simplified regime factors
ssPayCurrencyByFrequencySocial security due (respects caps, discounts, first-year exemption)
specificDeductionsnumberMax of €4104 vs. 10% of SS payments
expensesnumberDeclared expenses
expensesNeedednumberExtra expenses needed to reach the simplified cap
youthIrsDiscountnumberYouth IRS deduction limited by IAS multipliers
irsPayCurrencyByFrequencyIRS owed (progressive tables or RNH flat)
netIncomeCurrencyByFrequencyNet income after IRS and SS
taxRankTaxRankProgressive bracket applied
currentIasnumberIAS value for the selected tax year
maxSsIncomenumberCap for SS base (12 × IAS)
workerWithinFirstFinancialYearbooleanUses 37.5% simplified factor
workerWithinSecondFinancialYearbooleanUses 56.25% simplified factor
workerWithinFirst12MonthsbooleanSS waived for first 12 months after opening activity
ssQ1Approximatedbooleantrue when Jan/Feb/Mar SS is estimated (i.e. previousYearQ4MonthlyIncome was not provided). Show a note to the user in this case.
rnh / rnhTaxboolean / numberIndicates RNH flat rate usage
benefitsOfYouthIrs / yearOfYouthIrsboolean / numberYouth IRS inputs echoed back
monthlyBreakdownIndependentWorkerMonthlyBreakdownResult[]Monthly breakdown with taxes and net income
normalizedInternalsIndependentWorkerNormalizedInternalsRaw and intermediary calculation metrics (e.g. detailed SS outputs)

Example

Interactive 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`.

Interactive Example

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, validateNrDaysOff
  • validateSsDiscount, validateMaxExpensesTax, validateExpenses, validateSsTax
  • validateCurrentTaxRankYear, validateRnhTax
  • validateYearOfYouthIrs (caps years to 1-5 for 2023/2024 and 1-10 for 2025/2026)

Error Handling

Interactive Example

Advanced Usage

Opening activity and youth IRS

Interactive Example

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 earnedSS 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.

Interactive Example
Last updated on