SDK for JavaScript and TypeScript
The official package for Node.js 18 and later. No dependencies, with types for every response.
Installation
#The package @quellenkontor/sdk runs on Node.js 18 and later. It only uses fetch, not any Node modules, has no dependencies and ships with types for TypeScript.
const { Quellenkontor } = await import("@quellenkontor/sdk").Setup
#| Option | Default | Meaning |
|---|---|---|
apiKey | Environment variable QK_KEY | Your API key. You can also pass it as the first argument: new Quellenkontor(schluessel) |
basisUrl | https://api.quellenkontor.dev/v1 | Only for testing against a different server |
timeoutMs | 15000 | Timeout per request, in milliseconds |
wiederholungen | 2 | Retries on network errors and status 502, 503, 504, with 300 and 600 millisecond delays |
fetch | global fetch | Your own fetch function, for example for proxies or tests |
cache | true | Turn the in-memory cache for this instance on or off, see below |
cacheTtlMs | 300000 (5 minutes) | How long a response comes from the cache without a new request |
offline | true | Use the bundled offline data as a fallback when the API is unreachable, see below |
Cache and ETag
Within cacheTtlMs, a repeated request with the same parameters comes back from this instance's cache without any network call. After that, the SDK asks again with the stored ETag in the If-None-Match header: if the value has not changed, the API responds with 304, the SDK returns the cached response, and the request does not count against your quota. More on saving requests under Quotas and limits.
Offline data
If the API is unreachable after every retry, the SDK falls back to bundled offline data: the history of every table with a history, generated into the package from the current data set (the same data as /export). That response then carries offline: true and the package's own datenstand instead of the currently official one, without the computed extra fields such as zitat. Plain calculators without a table, for example notice period, vacation entitlement or company car, have no offline data and stay a QuellenkontorFehler with code netzwerk without a connection.
All methods
#Every dataset is a method under qk.hr. It returns a Promise for the same object the API returns. The fields are listed in the reference.
| Method | Reference |
|---|---|
qk.hr.mindestlohn({ datum?: string } = {}) | Minimum wage |
qk.hr.mindestausbildungsverguetung({ beginn?: string; ausbildungsjahr?: number; bestandteil?: "ausbildungsjahr_1" | "ausbildungsjahr_2" | "ausbildungsjahr_3" | "ausbildungsjahr_4" } = {}) | Apprentice pay |
qk.hr.pflegemindestlohn({ datum?: string; bestandteil?: "pflegehilfskraft" | "pflegehilfskraft_ost" | "qualifizierte_pflegehilfskraft" | "qualifizierte_pflegehilfskraft_ost" | "pflegefachkraft" | "zusatzurlaub_tage" } = {}) | Care minimum wage |
qk.hr.rechengroessen({ jahr?: number; datum?: string } = {}) | Contribution ceilings |
qk.hr.beitragssaetze({ datum?: string } = {}) | Contribution rates |
qk.hr.sachbezugswerte({ jahr?: number; datum?: string } = {}) | Meal and lodging values |
qk.hr.pfaendungsfreigrenzen({ datum?: string; unterhaltspflichten?: number; netto?: number } = {}) | Garnishment exemptions |
qk.hr.uebergangsbereich({ datum?: string } = {}) | Midi-job zone |
qk.hr.minijobAbgaben({ datum?: string; bestandteil?: "gewerblich_kv" | "gewerblich_rv" | "gewerblich_rv_eigenanteil" | "gewerblich_pauschsteuer" | "gewerblich_u1" | "gewerblich_u2" | "gewerblich_insolvenzgeldumlage" | "privat_kv" | "privat_rv" | "privat_rv_eigenanteil" | "privat_pauschsteuer" | "privat_u1" | "privat_u2" | "privat_unfallversicherung" } = {}) | Mini-job levies |
qk.hr.kuenstlersozialabgabe({ jahr?: number; datum?: string; bestandteil?: "abgabesatz" } = {}) | Artists' social levy |
qk.hr.ausgleichsabgabe({ jahr?: number; datum?: string; arbeitsplaetze?: number; besetzt?: number; bestandteil?: "quote_3_bis_unter_5" | "quote_2_bis_unter_3" | "quote_ueber_0_bis_unter_2" | "quote_0" | "klein_unter_40_weniger_als_1" | "klein_unter_40_null" | "klein_unter_60_weniger_als_2" | "klein_unter_60_weniger_als_1" | "klein_unter_60_null" | "pflichtquote_prozent" | "pflicht_ab_arbeitsplaetzen" } = {}) | Compensatory levy |
qk.hr.steuerfreieBetraege({ datum?: string; bestandteil?: "sachbezug_freigrenze" | "aufmerksamkeiten_freigrenze" | "betriebsveranstaltung_freibetrag" | "rabatt_freibetrag" | "gesundheitsfoerderung_freibetrag" | "mahlzeit_auswaerts_preisgrenze" | "aktivrente_freibetrag" | "vermoegensbeteiligung_freibetrag" | "kurzfristige_betreuung_freibetrag" | "bav_steuerfrei_prozent_bbg" | "bav_zusatzbetrag_neuzusage" | "inflationsausgleichspraemie" | "corona_praemie" | "pflegebonus" | "uebungsleiter_freibetrag" | "ehrenamt_freibetrag" | "fahrtkostenzuschuss_pauschalsteuer" | "erholungsbeihilfe_arbeitnehmer" | "erholungsbeihilfe_ehegatte" | "erholungsbeihilfe_kind" | "sachzuwendungen_37b_hoechstbetrag" | "sachzuwendungen_37b_steuersatz" | "arbeitnehmer_pauschbetrag" | "homeoffice_tag" | "homeoffice_hoechstbetrag" | "entfernungspauschale_bis_20_km" | "entfernungspauschale_ab_21_km" | "entfernungspauschale_hoechstbetrag" } = {}) | Tax-free amounts |
qk.hr.reisekostenInland({ datum?: string; bestandteil?: "verpflegung_24_stunden" | "verpflegung_an_abreisetag" | "verpflegung_ueber_8_stunden" | "kuerzung_fruehstueck_prozent" | "kuerzung_mittag_abend_prozent" | "uebernachtung_pauschale_arbeitgeber" | "uebernachtung_berufskraftfahrer" | "kilometer_pkw" | "kilometer_andere_kfz" } = {}) | Travel expenses |
qk.hr.sfnZuschlaege({ datum?: string; grundlohn_stunde?: number; bestandteil?: "nachtarbeit" | "nachtarbeit_0_bis_4_uhr" | "sonntagsarbeit" | "feiertagsarbeit" | "weihnachten_und_1_mai" | "grundlohn_hoechstbetrag_steuer" | "grundlohn_hoechstbetrag_sv" } = {}) | Night and holiday premiums |
qk.hr.dienstwagen({ listenpreis: number; antrieb?: "verbrenner" | "elektro" | "hybrid"; anschaffung?: string; ueberlassung?: string; entfernung_km?: number; fahrten_monat?: number; zuzahlung_monat?: number; co2_g_km?: number; reichweite_km?: number; batterie_kwh?: number; datum?: string }) | Company car |
qk.hr.einkommensteuerEckwerte({ jahr?: number; datum?: string; bestandteil?: "grundfreibetrag" | "spitzensteuersatz_ab" | "reichensteuer_ab" | "eingangssteuersatz" | "spitzensteuersatz" | "reichensteuersatz" | "kinderfreibetrag_je_elternteil" | "bea_freibetrag_je_elternteil" | "soli_freigrenze" | "soli_satz" } = {}) | Basic tax allowance |
qk.hr.kuendigungsfrist({ eintritt: string; zugang: string; seite?: "arbeitgeber" | "arbeitnehmer"; probezeit?: boolean }) | Notice period |
qk.hr.urlaubsanspruch({ arbeitstage_pro_woche: number; jahr?: number; eintritt?: string; austritt?: string }) | Vacation entitlement |
qk.hr.mutterschutz({ termin?: string; geburt?: string; fall?: "standard" | "fruehgeburt" | "mehrlinge" | "behinderung" | "fehlgeburt"; ssw?: number } = {}) | Maternity protection |
qk.hr.feiertage({ jahr?: number; land?: "BW" | "BY" | "BE" | "BB" | "HB" | "HH" | "HE" | "MV" | "NI" | "NW" | "RP" | "SL" | "SN" | "ST" | "SH" | "TH" } = {}) | Public holidays |
qk.hr.arbeitstage({ von: string; bis: string; land: "BW" | "BY" | "BE" | "BB" | "HB" | "HH" | "HE" | "MV" | "NI" | "NW" | "RP" | "SL" | "SN" | "ST" | "SH" | "TH"; samstag?: boolean; regionale?: boolean }) | Working days |
qk.hr.regelaltersgrenze({ geburtsdatum?: string; geburtsjahr?: number; vertrauensschutz?: boolean } = {}) | Retirement age |
qk.hr.pausen({ arbeitszeit_stunden: number; jugendlich?: boolean }) | Rest breaks |
qk.hr.verlauf(datensatz) | all steps of a table since 2015 |
qk.datensaetze() | Catalog, no key needed |
qk.aenderungen() | Changelog, no key needed |
qk.anfrage(pfad, werte, format) | raw request to any path, including CSV |
Examples
#Notice period (Kündigungsfrist)
Public holidays for multiple locations
Working days in a month
History into your own database
Handling errors
#If the API responds with an error, the SDK throws a QuellenkontorFehler with status, code, parameter and the message. Without a connection, the status is 0 and the code is netzwerk.
All codes are listed under Errors.
CSV and raw requests
#With anfrage you can reach any path of the API. With "csv" as the third argument, it returns the CSV text:
Using it in Next.js and serverless
#Only call the SDK on the server: in Server Components, Route Handlers or Server Actions. Store the key on Vercel under Environment Variables as QK_KEY.
The custom cache header in the example stores the response for one day at the edge of your hosting, so not every page view counts against your quota. More on this under Saving requests.
Something missing or unclear? Write to us and we will extend the docs.