{"_id":"@taxora/sdk","_rev":"15-2f53eb15b3ef9a3ee9200fe0b8d3828e","name":"@taxora/sdk","dist-tags":{"latest":"1.10.0"},"versions":{"1.0.0":{"name":"@taxora/sdk","version":"1.0.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.0.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"a6e48596e49f4f7844761933d9f0cb6db811f0fc","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.0.0.tgz","fileCount":9,"integrity":"sha512-GlmyeaznBIRhAWU5kW4OLnwc3BIqGHW8oSiqMbIK+kUyjzy7LM6LiX/HFhjWzbLTdKuPue0lsiK89C8bIRuzvw==","signatures":[{"sig":"MEYCIQCGYlPAfV51zNNoTRXqcC8dN2WUijD3l9iUuPFKrPN8ZQIhAMm5S8gQU/mZWNkiO9I9r/DC9d3a0JVRBw9WnSlqOL/1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":238367},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"99de64af61aad617fd4658f49b2fd574e03fcc04","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^8.57.1","vitest":"^3.2.4","prettier":"^3.3.3","typescript":"^5.4.0","@types/node":"^22.19.17","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.0.0_1775288931313_0.7637160144219659","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@taxora/sdk","version":"1.0.5","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.0.5","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"67e6865c0b075c259d7b5ff1b2cdeb69b91bfce1","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.0.5.tgz","fileCount":9,"integrity":"sha512-aA5CD2C0FNY+JfEt7PY+M/sdqVgcvIxoxtDmfxMr2IsGd9g0F2SRR0uicPflczKVrjDljZRgOXLVr21/4ri5CQ==","signatures":[{"sig":"MEUCIE9RVxhtC9W/8X60W13mfltJXNI8h7S9KnpxHauob0+1AiEApCHzUp4iP6t4nTmpqq2s6iNo4rrbybp6SU9s67FECIg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.0.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":238366},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"4e76e6e940b7cc2f7d97b3df34c68bcd7ba77c59","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^9.39.4","vitest":"^3.2.4","prettier":"^3.3.3","typescript":"^6.0.3","@types/node":"^25.6.0","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.0.5_1776612130423_0.04440951787958447","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@taxora/sdk","version":"1.0.6","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.0.6","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"0ff39041cc5ff07488ccef3d09d8ba90ea9de6f1","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.0.6.tgz","fileCount":9,"integrity":"sha512-hyEEEKx53OOkM3FGMFENVGIDnV5VnlJ4Cm9LKh/EWuzGQCtDcY0EhNOIzlG/Z82tS959rdU2fkPyI32RMIp8tQ==","signatures":[{"sig":"MEQCIA/OuaS+rOmPyOAOMzsHx7MyJ7sjtj3cMr4zxUe6Wg0TAiByMwHDetkePv+hYwFTKKywHE1qwu62WziGxg8ztbJcug==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.0.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":250501},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"13b39ee027659908f148aae946fddddb10f4b633","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^9.39.4","vitest":"^3.2.4","prettier":"^3.3.3","typescript":"^6.0.3","@types/node":"^25.6.0","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.0.6_1777401490612_0.6179455933584335","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@taxora/sdk","version":"1.0.7","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.0.7","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"30849090821b685faebdf14ba6c9fd74dd9c88a5","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.0.7.tgz","fileCount":9,"integrity":"sha512-+4Sf3cVqJ31rCF8PM0FdRHatgat9YgS12kdVMk/IWdtLO5jgeCC9z+p/koebjPVUqB38aGjcMneCdD7wdIBsKg==","signatures":[{"sig":"MEYCIQDU26pDiigsCTGHafigBN5+C+einx/I0l5xJzCbo1o4GAIhAOREeOvrpoyp6w9ZUQRdCL74R7rtO4hsWWr58mL9T20c","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.0.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":254355},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"dcd436b414ad07ff990acd034281588792e03f0c","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^9.39.4","vitest":"^3.2.4","prettier":"^3.3.3","typescript":"^6.0.3","@types/node":"^25.6.0","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.0.7_1778087085812_0.9149938083709115","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@taxora/sdk","version":"1.1.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.1.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"3a045fb87fbd3a7e7d3eecfd8fbd6d388d461e0f","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.1.0.tgz","fileCount":9,"integrity":"sha512-iI6d9G04pCeYHp7FEpqpav+Oxm9JK29WUskdt5vIvey2zeAOlX3RUpdDI3vKl3EMpHzuRh/ahDw38CtUH23ugg==","signatures":[{"sig":"MEUCIQDCGSX1TYT+yPXzbXauX/EEc2FtwNOyjs88dfoQGN2xugIgQFMkLvSDJQTQkfmBndlw9HkD92j+csz/wF+PyMdGEoI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":779927},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"0af88eb75733f12d6066c2497dbb4b637574df0a","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.10","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.1.0_1783398882819_0.05289425411762383","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@taxora/sdk","version":"1.2.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.2.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"1a56cdc7a6cb1618254b8e3bbea345340b8db3fd","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.2.0.tgz","fileCount":9,"integrity":"sha512-dk+os+Lk0TFv42gOcm0+/Pu6jSEdi37xhkHkAcmTV1GaJ23yxvGSkSRzDNEd9qJTQiCB+LV/r6rDGuPyw+Hn6g==","signatures":[{"sig":"MEUCIC7tr3d9eQf4Xh92tUa7mAHzIpItzj/MP07+sDoxPV9JAiEAj7j3fW2Zo1inmODJuCV8cWk8W1CMsZydGtvZS2UH5LM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":900164},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"c815b52636046edf4675fab7c4a21095bfd38660","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"10.8.2","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.10","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.2.0_1788211790357_0.8460854399392055","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@taxora/sdk","version":"1.3.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.3.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"cb9b44c250d69806f872a0e1602af918e783af35","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.3.0.tgz","fileCount":10,"integrity":"sha512-j61DcmktIWDLSR9LCnRZ4pfy0H+OmzVAiQ/k9Y6D/QucpQsao18Cmy1WbOZ/r3NS9ffqrtnR9VM9pOZS3BVqKg==","signatures":[{"sig":"MEYCIQDeaxe4HfyUwh9VcKzid9zIcAKOLVZ02cgFBGqb5nrtqgIhAJRYB8mHSCnKiCmsB3DMcF0gXEOH+VFhDpFTjml/0AwN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIAeEfV6St4wmadwiqsePBome584L3sEIamlOR56sIVcEAiA9YQ8C13V4xPZmN89CyVgcB0npd0Tgo1l6SryaIGuP0w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1130215},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"7783fba6b6546eca8bc58fae68662287da8b0a87","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.0","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.10","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.3.0_1791916920936_0.030690755131742575","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@taxora/sdk","version":"1.4.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.4.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"cf3a5a8b8a1ff259f83abf5df5aba7e368e61d36","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.4.0.tgz","fileCount":10,"integrity":"sha512-DVOyRigfRULuCzjTUSNDNdq7KymVJI15pZAqRJf5/thaJOBlWrl0V2m5fHBqIIi6aCjNx9UEtCgj0sQYlEiW5g==","signatures":[{"sig":"MEUCIApgM2Jzlk5VTYNYhjAgVSdb108CH3XqbNBqb5Z93Y1bAiEAocKeZLWDIsB7QXBVhFHpDtEabH8V8TrlwmJTofGNwFQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGdEwv2qQoSO/XteyPGkCRysijH/7jfR1BUl70Ztw00bAiBiXYS17p3UqXHpMxeXlQbw32IkVxQ6tP3GU8+xXS853w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1153005},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"dbbd5c18ecbc834c04b4e78621dbac8a1f701131","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.10","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.4.0_1792606713105_0.5674113539844714","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@taxora/sdk","version":"1.5.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.5.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"17df84201c02e52b440b536328350e58ab1d4278","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.5.0.tgz","fileCount":10,"integrity":"sha512-aYQCnjBq97BzBs1X1KP22TYzrN6GkfidG4CnAEyjFthtyMaEB30qYDYfY6OMahnWQokwkumOD5zu4mjzUe/+rg==","signatures":[{"sig":"MEUCIFUHtiQ3SrVSGOku439ePGBbosAW0jo7JIXJF+xo0o30AiEAnXp8m1asHaEwRVNCEtuSUsDpenz1Ue2zAf8fnICkQvQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDa/8du1iruu4PrHHUtyd2GC9+rHS4UTUzO3kilZGFjhAIhAMd/g1qGvvyQfTAk9HXiahxj7SZAPlALCL/Egk7kCK6T","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1163010},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"0ee1a0c38020d9dd62bebc54f9b7c465ff6ecdb1","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.5.0_1792651436465_0.7597544267811582","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@taxora/sdk","version":"1.6.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.6.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"f3236123ca7d12a6da9313785db4a272589f7b2d","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.6.0.tgz","fileCount":10,"integrity":"sha512-LeB582ZlfPV6q/hky8jZjapn6aRQ1+JXQTMdBbRlSLpPzJF5U9IKccOwH32quEY+ohb3Obb8VuuOf4JyfjGhgQ==","signatures":[{"sig":"MEQCIBICb+nlGtbKt1kCg0MmB2J00LH1an58O51vaP2uGlAsAiAPuXXn7tWHA36Po9abiDd9L+Jiro0qHcf5u6A6XRDp5A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIAu44VemtVOfQAxzeXhfrj5WKsGDtII9O35sTgEa5v/bAiBmQ8jHXBpzqcK6ikgNXtwEmDyPtfdVKYOC5S0Ybmj4Gg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1179768},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"46aea23e7772b5dee451e3283544a3ba93016801","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.6.0_1792687865763_0.20047546135393035","host":"s3://npm-registry-packages-npm-production"}},"1.7.0":{"name":"@taxora/sdk","version":"1.7.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.7.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"a142214109e74c2440584999b7e31366dfa85d56","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.7.0.tgz","fileCount":10,"integrity":"sha512-aVu4CM3nfcy3aPb/2xdJ8b+5yXQjfqUUq6YDdaQMFHRSvvWVT5KnmhsV2kLBj6wnxRaR/rLL9hjS92YALyZqbA==","signatures":[{"sig":"MEUCIQCJGvg+hXPoAY/xVWsZxs7+nogMkB8IAL6x9Q3vzljw+AIgZ7aDDDUi/YlkCmz4GgoCxEWRMofmikq6B9JA3W9zhXU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIFuaRjWupt8Me6V0nHGrKRDXeCDU+zADief4v8IWtinDAiEAmMH4kPTLQoGAIsmICfZ+trTeR2Pfh3yWBCkPvPC6JR8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1238830},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"42910781d4c5f8ab1f5389f8e329abb48ba471ed","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.7.0_1792843950828_0.5710516874786011","host":"s3://npm-registry-packages-npm-production"}},"1.7.1":{"name":"@taxora/sdk","version":"1.7.1","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.7.1","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"4c8d0eefded3f6481131ace45cb79c0043ba6669","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.7.1.tgz","fileCount":10,"integrity":"sha512-/nmOVXWrOvCTYhI92EHTd7PabQIszs1Oqul0VqmRXobaoCGXeozSeJ3N20jI5LH2MCb4aV/Jc1JjP4EFE00FCw==","signatures":[{"sig":"MEUCIH7lZdp6UdP3FST084lWhj/JmsfWvzg/unOoQTHna+lBAiEAliZS98IBb2KLidxDhsmXQzQAKzCtkt/3mVtDJNAB+Pc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIAMGCtNRn+Q+jQdopLZkH+G56Y1JE5vpUGnANt+3VzBBAiEAugGk+B3Fnz9dH4RxusYXiW4nf4DM+WbuKJ5dRcnhVUw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.7.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1239613},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"d6919a00e4430308e873c6c9b175792844c447e4","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.7.1_1792844743162_0.48204350697024934","host":"s3://npm-registry-packages-npm-production"}},"1.8.0":{"name":"@taxora/sdk","version":"1.8.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.8.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"f095ede9414526ca7a3e25408505f100ab39d6c1","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.8.0.tgz","fileCount":10,"integrity":"sha512-cnwVfh80pGsd4RUs18JJH/ZtZ6/1VxIZGOZHzqwxGgXZrmUeDRGAkBHjLIGD9JCBP0+gKstAU0s3rsmS3f9xOw==","signatures":[{"sig":"MEUCIA1Jqq/qWySmNBUYVOw9+4yQm2jzCGFCT6N87CrH6/LjAiEA5g4JqatM9rpoLQ4MDY2LmarCvphry4EiQGbh3V/J+/o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGl4yp9JDnw8ad6YJsiokfSw+TNyO8VA7gGDS82a2P/KAiEA5sE5hwxMDQKRpi5yKhGQhLViqKqs5muT/f4PmEj/v44=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1279861},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"a3578678ccab89d4eb8a283ea488f06272b3a9c9","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.8.0_1792940218204_0.08516460646534996","host":"s3://npm-registry-packages-npm-production"}},"1.9.0":{"name":"@taxora/sdk","version":"1.9.0","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"license":"MIT","_id":"@taxora/sdk@1.9.0","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"homepage":"https://taxora.io","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"0da4dffb7660079e9d7947212dcde7083adf07e4","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.9.0.tgz","fileCount":10,"integrity":"sha512-Clx3PZ+ecP5yjtBa1MuVOIDrfavf5tO9c4gi+98TeAcc0ngBkXqI7E1zx7riJd0agosAu2Ybq6f3hVu+CbdsvQ==","signatures":[{"sig":"MEUCIDakynKQGR2DjAqL90VC8y5C5dT7j+Xv+E1TZq1O8Nz8AiEAkcQn9RbvESTMDM/k5bXn+HGYH8xQjh1T70Be2R0YsJ4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDhFlSDJZxbQCUeem4X0oVdg/GYQY8kcRHRqPKs3JvuQAIhALpIn4mFPxA0bRz/xayfyZqENoWw1fuM2W7xHxBGFdMN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1528527},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"a32fff42c83cbe37e58b29397bfce5ea8fa4577a","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"tmp":"tmp/sdk_1.9.0_1793134054259_0.7777925441374332","host":"s3://npm-registry-packages-npm-production"}},"1.10.0":{"_id":"@taxora/sdk@1.10.0","bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"dist":{"shasum":"3335ecf531942ed886979c907eaf6f8e40814f7b","tarball":"https://registry.npmjs.org/@taxora/sdk/-/sdk-1.10.0.tgz","fileCount":10,"integrity":"sha512-kUoFQAG78SbQO0uDQRPw+iU6129Vze678dVlk61vehsC/Pcn1mXM3MmnLyhm04x2rLwU3+vsJtdhqu7HwFnYsw==","signatures":[{"sig":"MEQCICLhwqK2hbAcxS88wM+Myk3xGJLNhSIcI3NVNO3rV8p8AiAe9OpIXa0R9DXX7zKsViPMhMhUkCoIdDmpZRdzZETs0g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD0FleMK7EPmzvrh8t+GDG3wFV7jVJAVJWBtkAHD87ZUwIhALMcuJ07W3qEAS9cjolB9XBIpzJLICx9N++XF2aJPf+1"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@taxora%2fsdk@1.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1662311},"main":"./dist/index.cjs","name":"@taxora/sdk","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"146e247117498bd19ce7e8d5aabf3151a7ab8748","license":"MIT","scripts":{"lint":"eslint src tests --ext .ts","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint src tests --ext .ts --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"version":"1.10.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"ae7ebe4d-a43a-40b7-aaa4-820889fb6766"}},"homepage":"https://taxora.io","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"overrides":{"esbuild":"^0.28.1","minimatch":"^11.0.1"},"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"_npmVersion":"11.21.1","description":"Taxora VAT Validation API SDK for Node.js","directories":{},"maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"_nodeVersion":"24.22.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^10.6.0","vitest":"^4.1.12","globals":"^17.7.0","prettier":"^3.3.3","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^26.1.0","@vitest/coverage-v8":"^4.1.12","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.58.2","@typescript-eslint/eslint-plugin":"^8.58.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_1.10.0_1793712751945_0.07336410137207316"}}},"time":{"created":"2026-04-04T07:48:51.202Z","modified":"2026-11-03T13:32:32.453Z","1.0.0":"2026-04-04T07:48:51.445Z","1.0.5":"2026-04-19T15:22:10.590Z","1.0.6":"2026-04-28T18:38:10.766Z","1.0.7":"2026-05-06T17:04:45.969Z","1.1.0":"2026-07-07T04:34:43.021Z","1.2.0":"2026-08-31T21:29:50.505Z","1.3.0":"2026-10-13T18:42:01.042Z","1.4.0":"2026-10-21T18:18:33.212Z","1.5.0":"2026-10-22T06:43:56.562Z","1.6.0":"2026-10-22T16:51:05.866Z","1.7.0":"2026-10-24T12:12:30.928Z","1.7.1":"2026-10-24T12:25:43.240Z","1.8.0":"2026-10-25T14:56:58.326Z","1.9.0":"2026-10-27T20:47:34.543Z","1.10.0":"2026-11-03T13:32:32.053Z"},"bugs":{"url":"https://github.com/theconcept-technologies/taxora-sdk-node/issues"},"license":"MIT","homepage":"https://taxora.io","keywords":["taxora","vat","validation","vat-validation","eu-vat","tax","sdk","typescript","node"],"repository":{"url":"git+https://github.com/theconcept-technologies/taxora-sdk-node.git","type":"git"},"description":"Taxora VAT Validation API SDK for Node.js","maintainers":[{"name":"theconcept-technologies","email":"dev@theconcept-technologies.com"}],"readme":"<p>\n  <img src=\"https://taxora.io/assets/logo/taxora_logo.svg\" alt=\"Taxora Logo\" width=\"220\"/>\n</p>\n\n# @taxora/sdk\n\n> **Official Node.js/TypeScript SDK for the [Taxora VAT Validation API](https://taxora.io)**\n> Validate EU VAT numbers, generate compliance certificates, and integrate VAT checks into your Node.js services — with clean, modern TypeScript and zero runtime dependencies.\n\n[![CI](https://github.com/theconcept-technologies/taxora-sdk-node/actions/workflows/ci.yml/badge.svg)](https://github.com/theconcept-technologies/taxora-sdk-node/actions)\n[![npm](https://img.shields.io/npm/v/@taxora/sdk?color=cb3837&logo=npm&label=npm)](https://www.npmjs.com/package/@taxora/sdk)\n[![Coverage](https://img.shields.io/badge/coverage-97%25-brightgreen)](#-testing)\n[![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js&logoColor=white)](https://nodejs.org)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)\n[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n\n---\n\n## 🚀 Overview\n\nThe **Taxora SDK** provides a clean, type-safe interface to the [Taxora API](https://taxora.io), supporting:\n\n- ✅ Secure **API-Key** and **Bearer Token** authentication with auto-refresh\n- ✅ Single & multiple VAT validation with AI-based company name matching\n- ✅ VAT state history and full-text search endpoints\n- ✅ Certificate generation (PDF) and bulk/list exports (ZIP or PDF)\n- ✅ Strict TypeScript — full type coverage, zero `any`\n- ✅ Native `fetch` (Node 18+) — **zero runtime dependencies**\n- ✅ Dual **ESM + CJS** output for maximum compatibility\n\n> 🔒 The SDK itself is free to use, but a **Taxora API subscription** is required.\n> Obtain your `x-api-key` from your [Taxora account developer settings](https://app.taxora.io).\n\n---\n\n## 🧮 Installation\n\n```bash\nnpm install @taxora/sdk\n```\n\n**Requirements:** Node.js ≥ 18 (uses native `fetch` — no polyfill needed)\n\n---\n\n## ⚙️ Quick Start\n\n```ts\nimport { TaxoraClientFactory, Environment } from '@taxora/sdk';\n\nconst client = TaxoraClientFactory.create({\n  apiKey: 'YOUR_X_API_KEY',\n  environment: Environment.SANDBOX, // or Environment.PRODUCTION\n});\n\n// 1️⃣ Authenticate\nawait client.auth.login('user@example.com', 'superSecret');\n\n// 2️⃣ Validate a VAT number\nconst vat = await client.vat.validate('ATU12345678', 'Example GmbH');\nconsole.log(vat.state); // 'valid' | 'invalid' | 'fraud' | 'unknown'\nconsole.log(vat.companyName); // Official company name from registry\nconsole.log(vat.score); // Overall confidence score (0.0 – 1.0)\nconsole.log(vat.hasApiError); // true when the official provider had a technical failure\nconsole.log(vat.errorMessage); // technical provider error details, if returned\nconsole.log(vat.nextApiRecheckAt); // planned retry timestamp, if returned\n\nfor (const step of vat.breakdown ?? []) {\n  console.log(`${step.stepName} → ${step.scoreContribution}`);\n}\n\n// Optional: typed address input for fallback name scoring\nimport { VatValidationAddressInput } from '@taxora/sdk';\n\nconst addressInput = new VatValidationAddressInput({\n  addressLine1: 'Ringstraße 1',\n  postalCode: '1010',\n  city: 'Vienna',\n  countryCode: 'AT',\n});\nconst vatWithAddress = await client.vat.validate('ATU12345678', 'Example GmbH', 'vies', addressInput);\n\n// 3️⃣ Access company context\nconst company = await client.company.get();\nconsole.log(company.api_rate_limit); // General API request limit\nconsole.log(company.vat_rate_limit); // VAT validation request limit\nconsole.log(company.rate_limit); // Deprecated legacy field, if returned by older API payloads\n\n// 4️⃣ Export certificates\nconst exportJob = await client.vat.certificatesBulkExport('2024-01-01', '2024-12-31');\nconst zip = await client.vat.downloadBulkExport(exportJob.exportId);\nimport { writeFileSync } from 'fs';\nwriteFileSync('certificates.zip', zip);\n```\n\n`vat.validate()` returns a `VatResource` with the canonical VAT UID, status, company data, optional scoring details, and optional API error metadata. `state` remains backward-compatible and still reflects the canonical business result, while `hasApiError`, `errorMessage`, and `nextApiRecheckAt` let you detect cases where the official provider response was technically unreliable. The `score` reflects overall confidence (higher is better), while `breakdown` is an array of `ScoreBreakdown` objects describing each validation step, its score contribution, and metadata (e.g. matched addresses or mismatched fields).\n\nNeed a custom HTTP client (e.g. for logging or retries)? Pass it via the factory:\n\n```ts\nimport { TaxoraClientFactory, HttpClientInterface } from '@taxora/sdk';\n\nclass LoggingHttpClient implements HttpClientInterface {\n  async request(method: string, url: string, options?: RequestInit): Promise<Response> {\n    console.log(`→ ${method} ${url}`);\n    return fetch(url, { ...options, method });\n  }\n}\n\nconst client = TaxoraClientFactory.create({\n  apiKey: 'YOUR_X_API_KEY',\n  httpClient: new LoggingHttpClient(),\n});\n```\n\n---\n\n## 🧩 Architecture\n\nThe SDK follows clean separation of concerns:\n\n```\nTaxoraClientFactory.create()\n  └── TaxoraClient\n        ├── auth    → AuthEndpoint    (login, loginWithClientId, refresh)\n        ├── vat     → VatEndpoint     (validate, history, search, certificates)\n        ├── company → CompanyEndpoint (company info)\n        ├── smartEnrichment → SmartEnrichmentEndpoint (reverse VAT lookup)\n        ├── eReporting      → EReportingEndpoint      (compliance: enrollments, transactions, plans)\n        └── billing         → BillingEndpoint         (usage summaries)\n```\n\nEach endpoint handles:\n\n- Request signing with `x-api-key`\n- Bearer token injection and proactive refresh if expired\n- JSON/binary response parsing into typed DTOs\n\n`client.company.get()` returns a typed company resource. Prefer `api_rate_limit` and `vat_rate_limit`; legacy `rate_limit` remains available only for older compatibility payloads and is deprecated.\n\n`VatEndpoint` and `CompanyEndpoint` use the `AuthRetryHttpClient` wrapper, which transparently handles preemptive token refresh and 401 retry — `AuthEndpoint` always uses the raw HTTP client to avoid circular refresh calls.\n\n---\n\n## 📦 DTOs\n\n| Class                       | Description                                                                                     |\n| --------------------------- | ----------------------------------------------------------------------------------------------- |\n| `VatResource`               | Single VAT validation result: state, score, breakdown, company name, address, provider document |\n| `VatCollection`             | Iterable collection of `VatResource` objects with optional pagination `self` link               |\n| `ScoreBreakdown`            | Per-step scoring fragment: step name, score contribution, and metadata context                  |\n| `CompanyAddress`            | Structured company address; assembles `fullAddress` from components or parses JSON strings      |\n| `VatValidationAddressInput` | Typed input for address-based fallback scoring (validates lengths, country code format)         |\n| `Token`                     | Access token with type and expiry; 15-second buffer for proactive refresh                       |\n| `VatCertificateExport`      | Bulk export job reference (`exportId` + optional message)                                       |\n| `ProviderDocument`          | Attached provider document metadata (type, date, MIME, hash, nested line item)                  |\n| `ComplianceEnrollment`      | Per-country compliance enrollment: country, regime, `service`, provisioning status              |\n| `ComplianceTransaction`     | Recorded transaction / e-invoice: amounts, state, buyer fields, `documentType`, `providerState` |\n| `ComplianceOfferings`       | Bookable compliance plans per country, coverage, unlocked services                              |\n| `UsageSummary`              | Billed usage of one feature in one billing period (YYYY-MM), optionally with its events         |\n| `ComplianceTaxReport`       | DGFiP tax report lifecycle of a transaction (France)                                            |\n| `SireneLookupResult`        | Company data from the French SIRENE registry                                                    |\n| `RegistryCompany`           | Company from a national register (Norway: Brønnøysund) — org number, VAT / register flags       |\n| `PeppolLookupResult`        | Peppol directory lookup: `status` (reachable / not_reachable / pending), document types         |\n\nAll DTOs expose `toArray()` for serialization and a static `fromArray()` factory.\n\n```ts\nconst dto = await client.vat.validate('ATU12345678');\nconsole.log(dto.toArray());\n```\n\n---\n\n## 🔄 Authentication Flow\n\n### 1. Login\n\n```ts\n// Email + password\nawait client.auth.login('user@example.com', 'password', 'my-server-01');\n// device_name is optional; omitted value falls back to os.hostname()\n\n// Client ID + secret\nawait client.auth.loginWithClientId('client_abc123', 'client-secret', 'integration-box');\n\n// Explicit identifier enum\nimport { LoginIdentifier } from '@taxora/sdk';\nawait client.auth.login('client_abc123', 'client-secret', undefined, LoginIdentifier.CLIENT_ID);\n```\n\n→ Stores and returns a `Token` DTO (valid for ~3600 seconds).\n\n### 2. Auto-refresh\n\nThe SDK automatically refreshes the token in two scenarios:\n\n| Trigger                                      | Behaviour                                       |\n| -------------------------------------------- | ----------------------------------------------- |\n| **Preemptive** (token expired + 15 s buffer) | Refreshes before the next request               |\n| **Reactive** (API returns `401`)             | Refreshes once and retries the original request |\n\nYou never need to call `refresh()` manually in normal usage.\n\n### 3. Manual refresh\n\n```ts\nawait client.auth.refresh();\n```\n\n### 4. Custom token storage\n\nBy default, tokens are stored in-memory and lost on process restart. Provide your own storage for persistence:\n\n```ts\nimport { TokenStorageInterface, Token } from '@taxora/sdk';\n\nclass RedisTokenStorage implements TokenStorageInterface {\n  get(): Token | null {\n    /* read from Redis */ return null;\n  }\n  set(token: Token): void {\n    /* write with TTL = token.expiresAt */\n  }\n  clear(): void {\n    /* delete key */\n  }\n}\n\nconst client = TaxoraClientFactory.create({\n  apiKey: 'YOUR_X_API_KEY',\n  tokenStorage: new RedisTokenStorage(),\n});\n```\n\n---\n\n## 🧾 VAT Validation\n\n### Single Validation\n\n```ts\n// Basic — state only\nconst vat = await client.vat.validate('ATU12345678');\n\n// With company name matching\nconst vat = await client.vat.validate('ATU12345678', 'Alpha Handels GmbH');\n\n// With address input for enhanced score\nconst vat = await client.vat.validate('ATU12345678', 'Alpha Handels GmbH', 'vies', {\n  address_line_1: 'Ringstraße 1',\n  postal_code: '1010',\n  city: 'Wien',\n  country_code: 'AT',\n});\n\nconsole.log(vat.state); // VatState value\nconsole.log(vat.score); // 0.0 – 1.0\nconsole.log(vat.companyAddress?.toString()); // Full address string\nconsole.log(vat.getBackendLink()); // https://app.taxora.io/vat/history/{uuid}\n\n// Technical provider errors are additive and do not replace the canonical state.\nconst retryCase = await client.vat.validate('ATU44000001', 'Example GmbH');\nif (retryCase.state === 'invalid' && retryCase.hasApiError) {\n  console.log(retryCase.errorMessage);\n  console.log(retryCase.nextApiRecheckAt);\n}\n```\n\n### Schema Validation (format check only)\n\n```ts\nconst result = await client.vat.validateSchema('ATU12345678');\n```\n\n### Batch Validation\n\n```ts\nconst collection = await client.vat.validateMultiple(\n  ['ATU12345678', 'DE123456789'],\n  ['Alpha Handels GmbH', 'Beta Technik GmbH'],\n);\n\nfor (const vat of collection) {\n  console.log(vat.vatUid, vat.state);\n}\nconsole.log(collection.length); // 2\n```\n\n### VAT State Snapshot\n\n```ts\nconst vat = await client.vat.state('ATU12345678');\n```\n\n### History\n\n```ts\nconst history = await client.vat.history(); // all entries\nconst history = await client.vat.history('ATU12345678'); // filtered\n\nfor (const entry of history) {\n  console.log(entry.checkedAt, entry.state);\n}\n```\n\n### Search\n\n```ts\nconst results = await client.vat.search('Alpha Handels', 25 /* perPage */);\n```\n\n---\n\n## 🧾 Local tax numbers report\n\nEvery company you checked — single and bulk VAT checks and Smart Enrichment lookups — once, with its **local tax\nnumber** (NIP, SIREN, Partita IVA, Steuernummer …), the number's national name and where it comes from (`vat_id` =\nread off the confirmed VAT ID, `company_website` = published by the company). All filters are optional.\n\n```typescript\nimport { parseLocalTaxNumbersCsv } from '@taxora/sdk';\nimport { writeFileSync } from 'node:fs';\n\n// Parsed rows (BOM dropped, cells trimmed, empty cells null)\nconst rows = await client.vat.localTaxNumbers({\n  dateFrom: '2026-10-01', // optional (YYYY-MM-DD or Date)\n  dateTo: '2026-10-31', // optional\n  countries: ['PL', 'IT'], // optional (ISO-2)\n  onlyWithTaxNumber: true, // optional: skip companies without one\n});\nfor (const row of rows) {\n  // e.g. Orlen S.A. PL 5260250995 (NIP, vat_id)\n  console.log(`${row.companyName} ${row.country} ${row.taxNumber} (${row.taxNumberName}, ${row.taxNumberSource})`);\n}\n// row.vatStatus: valid | invalid | unconfirmed | wrong_company | no_vat_id | not_found\n// row.source: vat_check | smart_enrichment; row.checkId: the VAT check uuid or the lookup job id\n\n// The raw CSV (UTF-8 with BOM) for a spreadsheet. Digit-only tax numbers carry a leading TAB so\n// Excel keeps leading zeros; parseLocalTaxNumbersCsv() turns a saved file into rows.\nwriteFileSync('local-tax-numbers.csv', await client.vat.localTaxNumbersCsv({ countries: ['PL'] }));\n\n// Counts for the same filters\nconst summary = await client.vat.localTaxNumbersSummary({ dateFrom: '2026-10-01' });\nconsole.log(`${summary.withTaxNumber} of ${summary.companies} companies have a local tax number`);\n```\n\n## 🔎 Smart Enrichment (reverse VAT lookup)\n\nResolve a company **name + address + country → VAT number + confidence**. A confident match\nreturns synchronously; harder cases (and all bulk batches) are processed asynchronously and\ndelivered via the `enrichment.completed` webhook — poll with `get(jobId)` in the meantime.\nRequires the Smart Enrichment add-on to be active on your account.\n\n```ts\n// Single lookup\nlet job = await client.smartEnrichment.lookup({\n  companyName: 'Example Company GmbH',\n  country: 'AT',\n  street: 'Main Street 10',\n  postalCode: '1010',\n  city: 'Vienna',\n});\n\nif (job.isProcessing()) {\n  // Resolved asynchronously — poll until done (or wait for the webhook)\n  job = await client.smartEnrichment.waitForCompletion(job.jobId, {\n    pollIntervalMs: 2000, // optional, default 2000\n    timeoutMs: 120_000, // optional, default 120000 — throws TaxoraException on timeout\n  });\n}\n\nconst result = job.result();\nconsole.log(result?.status); // 'found' | 'no_vat_exists' | 'not_found'\nconsole.log(result?.vatNumber); // e.g. 'ATU12345678'\nconsole.log(result?.confidence); // 0–100\n\n// Search mode: 'default' searches with one AI provider and only consults a second one when\n// the first finds nothing. 'complex' has two independent providers search from the start and\n// puts every number either of them proposes through the tax authority's checks. Complex finds\n// companies a single search misses — typically ones whose VAT only appears in a website\n// Impressum — and costs more per lookup, so it is opt-in.\nconst deep = await client.smartEnrichment.lookup({\n  companyName: 'Vodafone D2 GmbH',\n  country: 'DE',\n  postalCode: '40547',\n  mode: SmartEnrichmentMode.COMPLEX,\n});\n\n// When more than one provider searched, you can see what each one concluded on its own.\n// Two of them reporting the same number is the strongest confirmation this layer produces.\nfor (const verdict of deep.result()?.providerVerdicts ?? []) {\n  console.log(`${verdict.provider}: ${verdict.vatNumber ?? 'nothing'}`);\n}\n\n// The API also grades the address you sent. Worth writing back into your own records: a\n// 'postal_code_city_mismatch' / 'postal_code_unassigned' warning means the postal code in\n// your source data is wrong, and `derivedPlace` is the area it actually points at.\nconst quality = deep.result()?.addressQuality;\nif (quality && quality.warnings.length > 0) {\n  console.log(quality.warnings.join(', '), '→', quality.derivedPlace);\n}\n\n// Where the number came from, and who it is registered to. `sourceUrl` is the page it was read\n// from (usually the Impressum). `registeredOwner` is set when the tax authority has the VAT ID\n// under a person rather than the trading name — a German e.K. — and confirmed it for them.\nconsole.log(result?.sourceUrl ?? '—'); // e.g. 'https://example.de/impressum'\nconsole.log(result?.sourceUrls.join(', ')); // every page it was found on, main one first\nconsole.log(result?.registeredOwner ?? '—'); // e.g. 'Kevin Seibel'\n\n// The official VAT check behind a found number. nameMatch 'mismatch' means the register has the\n// number under a different name — another company, unless `registeredOwner` is set (an e.K. filed\n// under its owner): then write officialName / officialAddress into your own records.\nif (result?.nameMismatch()) {\n  console.log(result.officialName, result.officialAddress);\n}\n\n// `taxNumber` is the company's LOCAL tax / business number — what domestic e-invoicing asks for.\n// On 'found' it is read off the confirmed VAT ID where that country's VAT ID contains it\n// (taxNumberSource 'vat_id': FR SIREN, IT Partita IVA, ES NIF, PL NIP, BE, DK CVR, CZ IČO, …).\n// Otherwise it is a number the company published itself ('company_website', e.g. a German\n// Steuernummer shown under the VAT ID heading) — that one is not a VAT ID.\nconsole.log(result?.taxNumber ?? '—'); // e.g. '5260250995'\nconsole.log(result?.taxNumberType ?? '—'); // e.g. 'pl_nip', 'fr_siren', 'de_steuernummer'\nconsole.log(result?.taxNumberLabel ?? '—'); // e.g. 'NIP'\nconsole.log(result?.taxNumberSource ?? '—'); // 'vat_id' | 'company_website'\n\n// 'not_found' doesn't always mean nothing turned up. When the research found a VAT number but\n// the official check threw it out (e.g. the tax authority reports it as invalid), the number\n// and the reason are in `rejectedCandidates` — no need to re-check it yourself.\nfor (const candidate of result?.rejectedCandidates ?? []) {\n  console.log(candidate.vatNumber, candidate.reason); // e.g. 'vat_invalid'\n}\n\n// Bulk lookup (always async → webhook + polling)\n// The batch-level mode applies to every row; a row carrying its own `mode` overrides it,\n// so you can pay for 'complex' on just the rows that need it.\nconst bulk = await client.smartEnrichment.bulkLookup([\n  { companyName: 'A GmbH', country: 'DE', city: 'Berlin' },\n  { companyName: 'B SARL', country: 'FR' },\n]);\nconst done = await client.smartEnrichment.waitForCompletion(bulk.jobId);\nfor (const r of done.results) {\n  console.log(r.status, r.vatNumber ?? '—', r.matchedAddress ?? '');\n}\n\n// Lookup history (paginated, newest first; perPage is capped at 100 server-side)\nconst history = await client.smartEnrichment.history(1, 25, 'Example GmbH' /* optional free-text search */);\nconsole.log(`${history.total} lookups`);\nconsole.log(history.stats?.total, history.stats?.found); // account-wide tiles (independent of the search filter)\nfor (const row of history) {\n  console.log(row.queryCompanyName, '→', row.result?.vatNumber ?? row.status);\n}\n```\n\n### Check rows again\n\nSearch once more for rows without a usable answer (`not_found`, or a number registered to another company). Every\nrecheck counts as a check like a new lookup (Deep Verify ×2), whether a VAT number is found or not. A row can be\nrechecked up to 3 times, 7 days apart; `no_vat_exists` and found rows are never rechecked.\n\n```ts\n// What would run, and what it costs — nothing is started\nconst plan = await client.smartEnrichment.recheck(jobId, { dryRun: true });\nconsole.log(plan.rows.length, 'rows,', plan.checks, 'checks, skipped:', plan.skipped);\n\nawait client.smartEnrichment.recheck(jobId); // every row that qualifies\nawait client.smartEnrichment.recheck(jobId, { rows: [3, 7] }); // or just these rows\n\n// Improved rows arrive via the `enrichment.updated` webhook; or poll:\nconst job = await client.smartEnrichment.get(jobId);\nconsole.log(job.recheck?.isActive() ? 'still rechecking' : 'done');\nconsole.log(job.results[3]?.recheckCount, job.results[3]?.lastRecheckedAt);\n```\n\n### Quota usage & billing history\n\n```ts\nconst usage = await client.smartEnrichment.usage();\nconsole.log(usage.period, `${usage.used}/${usage.included}`, 'remaining:', usage.remaining);\nconsole.log(usage.overageCount, '×', usage.overagePrice, '=', usage.overageAmount);\nfor (const entry of usage.history) {\n  console.log(entry.period, entry.matches, entry.amount, entry.state); // 'billed' | 'pending'\n}\n```\n\n### CSV export\n\nDownload your lookups as CSV in the bulk-input shape plus the resolved VAT columns (bulk jobs\nare flattened to one line per input row). All filters are optional.\n\n```ts\nimport { SmartEnrichmentStatus } from '@taxora/sdk';\nimport { writeFileSync } from 'fs';\n\nconst csv = await client.smartEnrichment.export({\n  dateFrom: '2026-01-01', // job created_at lower bound (YYYY-MM-DD)\n  dateTo: '2026-06-30', // job created_at upper bound (YYYY-MM-DD)\n  minConfidence: 80, // 0–100\n  status: [SmartEnrichmentStatus.FOUND, SmartEnrichmentStatus.NO_VAT_EXISTS],\n  onlyFound: true, // only rows that resolved to a VAT number\n});\nwriteFileSync('smart-enrichment.csv', csv);\n```\n\n### Statistics\n\nAggregated lookup statistics: headline totals, a time series and breakdowns by source, outcome\nand confidence band. Defaults to the last 12 months and a monthly interval (server-side).\n\n```ts\nconst stats = await client.smartEnrichment.statistics({\n  dateFrom: '2026-01-01', // optional (YYYY-MM-DD)\n  dateTo: '2026-06-30', // optional (YYYY-MM-DD)\n  interval: 'month', // 'day' | 'week' | 'month'\n});\n\nconsole.log(stats.totals.items, 'items,', stats.totals.found, `found (${stats.totals.foundRate}%)`);\nconsole.log('avg confidence:', stats.totals.avgConfidence);\nfor (const bucket of stats.timeSeries) {\n  console.log(`${bucket.bucket}: ${bucket.found}/${bucket.items}`);\n}\nfor (const band of stats.confidenceBuckets) {\n  console.log(band.bucket, band.count); // high / medium / low\n}\n```\n\n> Note: `no_vat_exists` means the company was identified but legitimately has **no** VAT/UID\n> number (common for purely-domestic German firms). It is a definitive answer — not a failure —\n> and is not billed.\n\n---\n\n## 🇫🇷 E-Reporting / Compliance (DGFiP Flux 10)\n\nFull French e-reporting integration: enroll a company with the compliance provider, record and\nsubmit transactions (individually or via CSV import), and track the resulting DGFiP tax reports.\nAll `compliance` routes require an active E-Reporting subscription / feature grant on your\naccount — except `requestEReportingAccess()`, which is how you ask for one.\n\n**Per-country services:** each enrollment books one service for one country — `e_reporting`\n(France, regime `dgfip_flux10`) or `e_invoicing` (Norway EHF / Peppol BIS 3.0, regime\n`peppol_bis3`, see [below](#-e-invoicing-norway-ehf--peppol)). Every country is unlocked and\nbilled separately (one-off setup fee + per document). Enrolling for a service your company does not\nhave yields a 403 `HttpException` whose body carries `code: \"service_not_active\"`.\n\n### Request feature activation\n\nNot enabled yet? This route is deliberately **not** gated — it requests activation of the\nE-Reporting feature for your account (the authenticated user's name/email take precedence over\nthe form values):\n\n```ts\nawait client.eReporting.requestEReportingAccess({\n  company: 'Example GmbH',\n  phone: '+43 660 1234567',\n  message: 'Please activate e-reporting for our account.',\n  language: 'de', // locale of the confirmation mail\n  service: 'e_invoicing', // optional: 'e_reporting' (default) | 'e_invoicing'\n  countries: ['NO'], // optional: the countries you want the service for\n});\n```\n\n### 1. SIRENE lookup (prefill enrollment data)\n\nResolve company data by SIRET, SIREN or French VAT number via the French SIRENE registry.\n**Rate-limited to 3 requests/minute per user** (protects the external French government API).\n\n```ts\nconst company = await client.eReporting.sireneLookup('FR32123456789'); // or a SIRET/SIREN\n\nconsole.log(company.companyName, company.siret);\nconsole.log(company.nafCode, company.enterpriseSize); // e.g. \"47\", \"pme\"\n```\n\n### 2. Create an enrollment\n\nCreates the local enrollment, provisions the provider account and (by default) activates the\nDGFiP regime. Either `siret` or `siren` is required. On provider failure the API responds 502\n(an `HttpException`) and the enrollment is persisted in an error state for retries.\n\n```ts\nconst enrollment = await client.eReporting.createEnrollment({\n  siret: company.siret!, // or siren: company.siren\n  companyName: company.companyName,\n  address: company.address ?? undefined,\n  city: company.city ?? undefined,\n  postalcode: company.postalcode ?? undefined,\n  email: 'tax@acme.fr',\n  nafCode: company.nafCode!, // 2-digit NAF division, e.g. \"47\"\n  enterpriseSize: 'pme', // 'micro' | 'pme' | 'eti' | 'ge'\n  typeOperation: 'mixed', // 'services' | 'goods' | 'mixed'\n  reportingStartDate: '2026-09-01', // or a Date\n  autoActivate: true, // optional — false creates the account without regime activation\n});\n\nconsole.log(enrollment.id, enrollment.status, enrollment.statusLabel);\n\nconst page = await client.eReporting.listEnrollments(1, 25); // paginated\nconst single = await client.eReporting.getEnrollment(enrollment.id);\n```\n\n### 3. Record & submit transactions\n\nRecords the transaction and (by default) submits it right away; pass `submitNow: false` to defer.\nCreation is **idempotent** on the invoice's natural key (enrollment, type, invoice number,\ninvoice date, counterparty VAT) — a client retry returns the existing transaction instead of\ncreating a duplicate.\n\n> **Note:** Immediate per-invoice submission (and `submitTransaction()`) requires the\n> **e-invoicing** feature on your account. In pure e-reporting mode transactions are only\n> recorded here and reported automatically via the aggregated daily ledgers —\n> `submitTransaction()` then returns a 422 `ValidationException` explaining this.\n\n```ts\nconst tx = await client.eReporting.createTransaction({\n  complianceEnrollmentId: enrollment.id,\n  transactionType: 'b2c_outbound', // | 'b2b_domestic_outbound' | 'b2b_domestic_inbound'\n  //                                  | 'crossborder_outbound' | 'crossborder_inbound'\n  invoiceNumber: 'TKT-2026-00001',\n  invoiceDate: '2026-07-01', // or a Date\n  currency: 'EUR', // optional, default EUR\n  subtotal: 100,\n  taxAmount: 20,\n  total: 120,\n  invoiceLines: [\n    {\n      description: 'Ticket',\n      quantity: 1,\n      price: 100,\n      taxes: [{ name: 'TVA', percent: 20, category: 'S' }], // category E needs a VATEX `comment`\n    },\n  ],\n  internalReference: 'ORDER-4711', // optional, max 100: your own reference (order no., ERP id) — never sent to the buyer or the tax authority\n  submitNow: false, // record now, submit later\n});\n\n// Submit (or retry) a pending/error transaction later — replays the stored invoice lines\nconst submitted = await client.eReporting.submitTransaction(tx.id);\nconsole.log(submitted.state, submitted.stateLabel); // e.g. \"submitted\"\n\n// Manage recorded transactions (only `pending` ones can be edited/deleted)\nconst transactions = await client.eReporting.listTransactions({\n  dateFrom: '2026-07-01', // or a Date\n  dateTo: '2026-07-31',\n  state: 'pending', // 'pending' | 'sending' | 'submitted' | 'error' | 'not_required'\n  transactionType: 'b2c_outbound',\n  complianceEnrollmentId: enrollment.id, // optional: one enrollment only\n  country: 'FR', // optional: one country only\n  search: 'ACME', // optional: contains-match over invoice number, internal reference and buyer name\n  internalReference: 'ORDER-4711', // optional: exact match on your internal reference\n  providerState: 'refused', // optional: provider delivery state, 'refused' = rejected by the buyer\n  page: 1,\n  perPage: 25,\n});\nconst one = await client.eReporting.getTransaction(tx.id);\n// Non-EUR invoices carry the EUR amounts at the ECB reference rate of the invoice date\n// (null for EUR invoices or when no rate is known):\nif (one.eurEquivalent) {\n  const { total, rate, rateDate, source } = one.eurEquivalent; // decimal strings, e.g. '98.92', '11.6250'\n  console.log(`${total} EUR @ ${rate} (${source}, ${rateDate})`);\n}\n\n// The same filters (without page/perPage) as a semicolon-separated CSV for your bookkeeping —\n// incl. internal reference, delivery state, buyer rejection and the eur_rate / eur_rate_date /\n// eur_subtotal / eur_tax_amount / eur_total columns. Max 50,000 rows; returned verbatim.\nconst bookkeepingCsv = await client.eReporting.exportTransactionsCsv({\n  dateFrom: '2026-01-01',\n  dateTo: '2026-09-30',\n  country: 'NO',\n});\nawait client.eReporting.updateTransaction(tx.id, { total: 130, taxAmount: 21.67 });\nawait client.eReporting.updateTransaction(tx.id, { internalReference: '' }); // empty string clears it\nawait client.eReporting.deleteTransaction(tx.id); // resolves void on 204\n```\n\n### CSV import\n\nBulk-import from a semicolon-separated CSV (one row per invoice line; rows sharing an\n`invoice_number` are grouped into one transaction). Idempotent: re-uploading skips rows whose\ninvoice already exists. An optional `internal_reference` column sets your own reference per\ninvoice.\n\n```ts\nimport { readFileSync } from 'fs';\n\nconst result = await client.eReporting.importTransactions(\n  enrollment.id,\n  readFileSync('transactions.csv', 'utf8'),\n  'transactions.csv', // optional filename\n);\n\nconsole.log(result.created, result.skippedDuplicates);\nfor (const error of result.errors) console.warn(error); // row-level errors\n```\n\n### 4. Track tax reports\n\nEvery submitted transaction is tracked through the aggregated DGFiP ledger lifecycle\n(`new → sent → acknowledged → registered` or `refused`/`error`).\n\n```ts\nconst reports = await client.eReporting.listTaxReports(1, 25, 'refused', 'FR'); // state + country filters optional\nfor (const report of reports) {\n  console.log(report.state, report.stateLabel, report.isTerminal, report.refusalReason);\n}\n\nconst report = await client.eReporting.getTaxReport(reports.rows[0]!.id);\nconsole.log(report.baseAmount, report.taxAmount, report.totalAmount); // precision-safe strings\n```\n\n### VAT rates & DGFiP tax categories\n\nThe canonical rates for a reporting country (the seller's reporting-country rates). Use these to\nbuild the `taxes` entries of your invoice lines.\n\n```ts\nconst rates = await client.eReporting.getVatRates('FR'); // defaults to FR when omitted\n\nfor (const rate of rates.rates) {\n  console.log(rate.percent, rate.category, rate.taxName, rate.requiresVatex);\n  // 20 'S' 'TVA' false … 0 'E' 'TVA' true (VATEX code required in the line's comment)\n}\n```\n\n### Revenue statistics\n\nRead-only turnover aggregation over your e-reporting transactions — totals, a time series and\nbreakdowns by transaction type, counterparty country and state. All headline figures are\nexpressed in the most frequent currency in the range (`primaryCurrency`); when more than one\ncurrency is present, `isMultiCurrency` is `true` and `byCurrency` lists each one. Monetary values\nare returned as 4-decimal strings to preserve precision.\n\n```typescript\nconst stats = await client.eReporting.getRevenueStatistics({\n  dateFrom: '2026-01-01', // optional — defaults to 12 months ago (server-side)\n  dateTo: new Date(), // optional — defaults to today\n  interval: 'month', // 'day' | 'week' | 'month' (default 'month')\n  transactionType: 'b2c_outbound', // optional filter\n  state: 'submitted', // optional filter\n  complianceEnrollmentId: enrollment.id, // optional: one enrollment = one country's figures\n});\n\nconsole.log(stats.primaryCurrency); // e.g. EUR\nconsole.log(stats.totals.total); // e.g. 120000.0000\nfor (const bucket of stats.timeSeries) {\n  console.log(`${bucket.bucket}: ${bucket.total}`); // 2026-01: 10800.0000\n}\nfor (const row of stats.byCountry) {\n  console.log(`${row.country} → ${row.total}`); // 'unknown' groups NULL partners\n}\n```\n\n### Tax-rate CSV\n\nNet and VAT per month, currency and tax rate (semicolon-separated, computed from the invoice lines) — for reconciling\nthe reported figures with your VAT return. Same filters as `getRevenueStatistics()` without `interval`. The body is\nreturned byte-for-byte, a UTF-8 BOM included.\n\n```ts\nimport { writeFileSync } from 'fs';\n\nconst csv = await client.eReporting.exportRevenueTaxRatesCsv({\n  dateFrom: '2026-01-01',\n  dateTo: '2026-12-31',\n  complianceEnrollmentId: enrollment.id, // optional: one country only\n});\nwriteFileSync('tax-rates.csv', csv);\n```\n\n### 🇳🇴 E-Invoicing Norway (EHF / Peppol)\n\nSend EHF e-invoices and credit notes (Peppol BIS Billing 3.0) to Norwegian buyers. The\n`e_invoicing` service for Norway is billed separately from French e-reporting (one-off setup\nfee + per document) — ask for it via `requestEReportingAccess({ service: 'e_invoicing', countries: ['NO'] })`.\n\n**1. Registry lookup** — resolve an organisation number, `NO…MVA` VAT number or company name in\nthe Brønnøysund register (rate-limited to 30 requests/minute; 404 when nothing is found):\n\n```ts\nimport { NorwegianOrgNumber } from '@taxora/sdk';\n\nconst [company] = await client.eReporting.registryLookup('NO', '923609016');\nconsole.log(company.companyName, company.vatNumber, company.vatRegistered, company.enterpriseRegister);\n\n// Client-side helper (mod-11 check digit, accepts spaces / NO prefix / MVA suffix)\nNorwegianOrgNumber.isValid('NO 923 609 016 MVA'); // true\nNorwegianOrgNumber.normalize('923609016MVA'); // '923609016'\nNorwegianOrgNumber.toVatNumber('923609016'); // 'NO923609016MVA'\n```\n\n**2. Enrollment** — registers your company as a Peppol participant. The organisation number is\nvalidated and normalized before sending:\n\n```ts\nconst noEnrollment = await client.eReporting.createNorwayEnrollment({\n  orgNumber: company.orgNumber,\n  companyName: company.companyName,\n  address: company.address!,\n  city: company.city!,\n  postalcode: company.postalcode!,\n  email: 'faktura@acme.no',\n  vatRegistered: company.vatRegistered, // optional, default true → \"MVA\" on invoices\n  enterpriseRegister: company.enterpriseRegister, // optional, default false → \"Foretaksregisteret\"\n  reception: false, // optional: also receive e-invoices over Peppol\n});\n// Equivalent: client.eReporting.createEnrollment({ country: 'NO', ... })\n\nconsole.log(noEnrollment.service, noEnrollment.regime); // 'e_invoicing' 'peppol_bis3'\n```\n\n**3. Peppol lookup** — check that the buyer can receive EHF invoices (free of charge). The\ndirectory resolves asynchronously: `pending` means ask again in a few seconds.\n\n```ts\nlet reach = await client.eReporting.peppolLookup('NO', '974760673'); // scheme defaults to 0192\nif (reach.isPending) {\n  await new Promise((r) => setTimeout(r, 3000));\n  reach = await client.eReporting.peppolLookup('NO', '974760673');\n}\nconsole.log(reach.status, reach.reachable, reach.documentTypes); // 'reachable' true [...]\n```\n\nOr let the SDK turn the answer into an action (shop checkout, one call):\n\n```ts\nconst decision = await client.eReporting.decideDelivery('NO', '974760673');\nswitch (decision.action) {\n  case 'einvoice': // create the transaction, Taxora sends the e-invoice\n  case 'einvoice_pending': // no answer yet: create it anyway, Taxora asks again before sending\n    break;\n  case 'regular_invoice': // not on Peppol: send your usual invoice, nothing is billed\n    break;\n}\n```\n\nThe SDK refuses input that cannot be right before any request: unknown tax categories\n(`ComplianceTaxCategory`: `S`, `AA`, `AAA`, `K`, `G`, `AE`, `E`, `Z`, any case), a category `E` line without its VATEX\nexemption code, currency and country codes that are not letters (they are upper-cased), a due date before the invoice\ndate, and credit notes without (or invoices with) a corrected invoice. The API additionally checks that an e-invoice's\n`subtotal`, `taxAmount` and `total` match its lines — compute them from the lines:\n\n```ts\nimport { calculateInvoiceTotals } from '@taxora/sdk';\n\nconst { subtotal, taxAmount, total } = calculateInvoiceTotals(invoiceLines); // rounded like the e-invoice\n```\n\nTaxes without remembering category codes: `ComplianceTax.rate(25)` (category `S`, any rate above 0 %; in Norway 25/15/12 % are all `S`, for France's reduced rates pass `ComplianceTax.rate(10, 'TVA', 'AA')`), `zeroRated()` (`Z`),\n`exempt('VATEX-EU-132')` (`E`, code mandatory) and `reverseCharge()` (`AE`). The rate itself is yours to know; the API checks\nit against the country's catalogue. The tax name defaults to `VAT` (`ComplianceTax.rate(25, 'MVA')`).\n\nIf your own system already shows the buyer a total, pass it as a safety net:\n`calculateInvoiceTotals(lines, { expectedTotal: 1249.99 })`. The totals always follow the lines, because the e-invoice is built\nfrom them. A difference up to 0.05 is reported as `roundingDifference`; anything larger throws, since then quantities, prices or\nrates are wrong. The invoice number is printed on the buyer's e-invoice and must be unique per enrollment (a different invoice\nwith a used number answers `409 invoice_number_taken`).\n\n**4. Send an invoice** — Norway requires `transactionType: 'b2b_domestic_outbound'`, the buyer's\norganisation number (`counterpartyRegisterId`) and `counterpartyName` (enforced server-side, 422):\n\n```ts\nconst invoice = await client.eReporting.createTransaction({\n  complianceEnrollmentId: noEnrollment.id,\n  transactionType: 'b2b_domestic_outbound',\n  invoiceNumber: 'NO-2026-0001',\n  invoiceDate: '2026-09-25',\n  dueDate: '2026-10-09',\n  currency: 'NOK',\n  subtotal: 2000,\n  taxAmount: 500,\n  total: 2500,\n  counterpartyName: 'EXAMPLE BUYER AS',\n  counterpartyCountry: 'NO',\n  counterpartyRegisterId: '974760673',\n  counterpartyAddress: 'Storgata 1',\n  counterpartyCity: 'Oslo',\n  counterpartyPostalcode: '0155',\n  counterpartyEmail: 'ap@buyer.example', // optional\n  buyerReference: 'PO-4711', // optional, defaults to the buyer's org number\n  invoiceLines: [\n    { description: 'Consulting', quantity: 2, price: 1000, taxes: [{ name: 'MVA', percent: 25, category: 'S' }] },\n  ],\n});\n\n// `state` tracks submission; `providerState` the Peppol delivery (e.g. sent, accepted, refused, paid)\nconst current = await client.eReporting.getTransaction(invoice.id);\nconsole.log(current.state, current.providerState, current.documentType); // … 'invoice'\n```\n\n**5. Send a credit note** — set `isCreditNote` and reference the corrected invoice:\n\n```ts\nconst creditNote = await client.eReporting.createTransaction({\n  complianceEnrollmentId: noEnrollment.id,\n  transactionType: 'b2b_domestic_outbound',\n  invoiceNumber: 'NO-2026-0001-CN',\n  invoiceDate: '2026-09-30',\n  currency: 'NOK',\n  subtotal: 1000,\n  taxAmount: 250,\n  total: 1250,\n  counterpartyName: 'EXAMPLE BUYER AS',\n  counterpartyRegisterId: '974760673',\n  isCreditNote: true,\n  amendedNumber: 'NO-2026-0001', // required for credit notes in Norway\n  amendedDate: '2026-09-25',\n  extraInfo: 'Credit for one returned consulting day',\n  invoiceLines: [\n    { description: 'Consulting', quantity: 1, price: 1000, taxes: [{ name: 'MVA', percent: 25, category: 'S' }] },\n  ],\n});\nconsole.log(creditNote.isCreditNote); // true\n\n// Shorter and harder to get wrong: credit an invoice you already sent. Buyer, lines, amounts,\n// currency and the reference to the corrected invoice are taken from it.\nconst credit = await client.eReporting.createCreditNote(invoice, { creditNoteNumber: 'NO-2026-0001-CN' });\n\n// Partial credit: pass the credited lines and all amounts together.\nawait client.eReporting.createCreditNote(invoice, {\n  creditNoteNumber: 'NO-2026-0001-CN2',\n  invoiceLines: [\n    { description: 'Consulting', quantity: 1, price: 1000, taxes: [{ name: 'MVA', percent: 25, category: 'S' }] },\n  ],\n  subtotal: 1000,\n  taxAmount: 250,\n  total: 1250,\n});\n\n// All Norwegian documents\nconst noDocs = await client.eReporting.listTransactions({ country: 'NO' });\n```\n\n**6. Attach your own invoice PDF** (e-invoicing only, max 10 MB) — pass the bytes (`Buffer` / `Uint8Array` /\n`ArrayBuffer`); the SDK base64-encodes them. A string is sent as-is and must already be base64. The structured\ne-invoice stays the legal document; whether the buyer's system shows the PDF depends on that system.\n\n```ts\nimport { readFileSync } from 'fs';\n\nconst withPdf = await client.eReporting.createTransaction({\n  ...invoiceInput,\n  invoicePdf: readFileSync('NO-2026-0002.pdf'),\n  invoicePdfFilename: 'NO-2026-0002.pdf', // optional, defaults to the invoice number\n});\nconsole.log(withPdf.invoicePdf); // { filename, size, attached } — attached once uploaded with the e-invoice\n\nawait client.eReporting.updateTransaction(withPdf.id, { invoicePdf: readFileSync('fixed.pdf') }); // replaces it\n```\n\n**7. Buyer not on Peppol / download the legal document**\n\n```ts\nconst tx = await client.eReporting.getTransaction(invoice.id);\n\nif (tx.state === 'not_required') {\n  // The buyer cannot receive e-invoices: nothing was sent or billed — send your regular invoice.\n  console.log(tx.deliveryCheck); // Peppol directory answer, e.g. { status: 'not_reachable', … }\n}\n\nif (tx.documentUrl !== null) {\n  const doc = await client.eReporting.getTransactionDocument(tx.id); // 409 while not available yet\n  writeFileSync(doc.filename ?? `${tx.invoiceNumber}.xml`, doc.content); // doc.contentType e.g. application/xml\n}\n\n// The invoice as a readable PDF (your attached PDF, or the provider's rendering of the e-invoice)\nif (tx.pdfUrl !== null) {\n  const pdf = await client.eReporting.getTransactionPdf(tx.id); // 409 while no PDF is available\n  writeFileSync(pdf.filename ?? `${tx.invoiceNumber}.pdf`, pdf.content); // pdf.contentType: application/pdf\n}\n```\n\n### Self-service plans (Stripe)\n\nBook compliance plans without contacting sales. These routes work for companies **without** compliance access.\n\n```ts\nconst { offerings, coverage, access, accessByCountry } = await client.eReporting.getOfferings();\nconst plan = offerings.find((o) => o.country === 'NO')?.plans.find((p) => p.checkoutAvailable);\n\nconst session = await client.eReporting.createCheckout('NO', plan!.key); // 422 if contact-only / already active\n// open session.url in the browser; Stripe returns the user to the Taxora portal\nconst state = await client.eReporting.confirmCheckout(session.id); // idempotent → { active, country, service, plan, status }\n\nconst portalUrl = await client.eReporting.createBillingPortalSession(); // invoices, payment method, cancel; 404 without a Stripe plan\n```\n\n### Notification emails\n\nOpt-in e-reporting / e-invoicing emails for your company — readable by every member, changeable by company **admins**\nonly.\n\n```ts\nconst settings = await client.eReporting.getNotificationSettings();\n// { recipients: ['accounting@example.com'], language: 'de' | 'en', notOnPeppol: boolean,\n//   digest: 'off' | 'daily' | 'weekly', digestSentAt: string | null }\n\n// Only the provided fields change (at least one is required); recipients replaces the whole list (max 5):\nawait client.eReporting.updateNotificationSettings({\n  recipients: ['accounting@example.com', 'cfo@example.com'],\n  language: 'en',\n  notOnPeppol: true, // hourly email listing invoices held back because the buyer is not on Peppol\n  digest: 'weekly', // 'daily' = 08:00 for the day before, 'weekly' = Mondays for the last 7 days\n});\n```\n\nInvalid input (more than 5 or invalid addresses, unknown `language` / `digest`, no field) throws a `TaxoraException`\nbefore any request. Switching an email on without any recipient answers `422` (`ValidationException`); a non-admin\ngets `403` with body code `admin_only` (or `read_only_role`) as `HttpException`. `notOnPeppol` only reports invoices\nheld back after it was switched on.\n\n### Billing usage summaries\n\nRead-only usage of your billable modules (E-Reporting / E-Invoicing, Smart Enrichment), per feature and billing\nperiod.\n\n```ts\nconst page = await client.billing.listUsageSummaries(1, 25); // newest period first\nfor (const summary of page) {\n  console.log(summary.billingPeriod, summary.feature, summary.eventCount, summary.billableAmount, summary.state);\n}\n\nconst september = await client.billing.getUsageSummaries('2026-09'); // with events; 404 for a period without usage\nconsole.log(september[0]?.events.length);\n\n// E-invoicing allowance: documents included per month, used, still free, what is due beyond it (null without e-invoicing)\nconst quota = await client.billing.getEInvoicingQuota();\nconsole.log(quota?.current.freeRemaining, 'of', quota?.current.included, 'documents free this month');\n```\n\n---\n\n## 📜 Certificates\n\n### Single Certificate (PDF)\n\n```ts\nimport { Language } from '@taxora/sdk';\nimport { writeFileSync } from 'fs';\n\nconst pdf = await client.vat.certificate('uuid-123', Language.GERMAN);\nwriteFileSync('certificate.pdf', pdf);\n```\n\n### Bulk Export (ZIP)\n\n```ts\nconst exportJob = await client.vat.certificatesBulkExport(\n  '2024-01-01', // or new Date('2024-01-01')\n  '2024-12-31',\n  ['AT', 'DE'], // optional: filter by country\n  Language.ENGLISH, // optional: language\n);\n\nconsole.log(exportJob.exportId); // poll or use directly\n\nconst zip = await client.vat.downloadBulkExport(exportJob.exportId);\nwriteFileSync('certificates.zip', zip);\n```\n\n### List Export\n\n```ts\nconst exportJob = await client.vat.certificatesListExport(new Date('2024-01-01'), new Date('2024-12-31'));\n```\n\n---\n\n## 🌍 Environments\n\n| Environment              | Base URL                       |\n| ------------------------ | ------------------------------ |\n| `Environment.SANDBOX`    | `https://sandbox.taxora.io/v1` |\n| `Environment.PRODUCTION` | `https://api.taxora.io/v1`     |\n\n```ts\nconst client = TaxoraClientFactory.create({\n  apiKey: 'YOUR_X_API_KEY',\n  environment: Environment.PRODUCTION,\n});\n```\n\nNeed sandbox sample data? Known VAT UIDs with deterministic responses live in `tests/fixtures/SandboxVatFixtures.ts`.\n\n---\n\n## ⚠️ Error Handling\n\n```ts\nimport { AuthenticationException, HttpException, ValidationException } from '@taxora/sdk';\n\ntry {\n  await client.vat.validate('ATU12345678');\n} catch (err) {\n  if (err instanceof AuthenticationException) {\n    // HTTP 401 — credentials invalid or token refresh failed\n    console.error('Auth failed:', err.message);\n  } else if (err instanceof ValidationException) {\n    // HTTP 422 — request payload rejected by the API\n    console.error('Validation errors:', err.getErrors()); // Record<string, string[]>\n  } else if (err instanceof HttpException) {\n    // Any other HTTP error\n    console.error(`HTTP ${err.getStatusCode()}:`, err.message);\n  }\n}\n```\n\n**Exception messages are always short and safe to log.** A response body is\nnever used as the message: gateways in front of the API answer `502`/`503`/`504`\nwith a full HTML error page, and that page would otherwise land in every log\nline of your application. The SDK uses the `message` / `error` field of a JSON\nerror body when there is one, and falls back to the status line\n(`Taxora API request failed (HTTP 504 Gateway Timeout).`) otherwise. The\nuntouched body stays available via `err.getResponseBody()`.\n\n**Compliance 403 codes.** Compliance 403s are `HttpException`s; the reason is the `code` in the JSON body\n(`err.getResponseBody()`): `service_not_active` (the company has not booked the service/country),\n`read_only_role` (a write request — create, update, delete, submit, import — by a user whose only role is\nread-only) or `admin_only` (body `{ message, code: 'admin_only' }`: a developer-role user tried to create an\nenrollment, `createCheckout()`, `confirmCheckout()`, `createBillingPortalSession()` or\n`updateNotificationSettings()` — only admins can add countries, change plans or change the notification emails).\n\n### Automatic retries\n\nThe SDK retries what never produced an answer from the API itself: **3 attempts,\nwith 500 ms and 1000 ms of backoff in between**. That covers\n\n- **gateway failures (`502`, `503`, `504`)** — the infrastructure in front of the\n  API, where a second attempt a moment later usually succeeds;\n- **connection-level failures** — reset connections, client-side timeouts, DNS\n  hiccups (`fetch failed`, `ECONNRESET`, `UND_ERR_CONNECT_TIMEOUT`, …). Once the\n  attempts are used up, the original error is rethrown unchanged;\n- **`429 Too Many Requests`, but only with a `Retry-After`** — then the SDK waits\n  exactly as long as the API asked instead of using its own backoff. Without that\n  header a retry would only hammer a rate limit that is already tripped, so the\n  error is surfaced immediately. A `Retry-After` longer than `maxRetryAfterMs`\n  (10 s by default) also fails immediately rather than blocking your worker — the\n  raw header stays readable via `err.getRetryAfter()`.\n\nEverything else fails on the first attempt, including any `5xx` the API produced\nitself (a `500` is a bug, not a hiccup — repeating it just costs time).\n\nRetries apply to read-only calls only — VAT validation, lookups, state, history,\nsearch, certificate downloads, company and e-reporting reads, login and token\nrefresh. Calls that change state or cost quota (`certificatesBulkExport()`,\n`smartEnrichment.lookup()`, e-reporting enrollment/transaction writes) are\n**never** retried automatically, because a gateway timeout does not tell us\nwhether the API already processed the request.\n\nOnce the attempts are used up you get one clean error:\n\n```\nTaxora VAT validation failed after 3 attempts (HTTP 504 Gateway Timeout).\n```\n\nTune or disable it via `RetryPolicy`:\n\n```ts\nimport { RetryPolicy, TaxoraClientFactory } from '@taxora/sdk';\n\nconst client = TaxoraClientFactory.create({\n  apiKey: 'YOUR_X_API_KEY',\n  retryPolicy: new RetryPolicy({\n    maxAttempts: 5,\n    initialDelayMs: 250,\n    retryableStatusCodes: [502, 503, 504], // add or drop status codes\n    respectRetryAfter: true, // false = ignore the header entirely\n    maxRetryAfterMs: 10_000, // longest wait accepted from Retry-After\n    retryOnNetworkErrors: true, // false = surface transport errors at once\n  }),\n});\n\n// or, for callers that do their own retrying (queue workers, cron jobs):\nconst noRetries = TaxoraClientFactory.create({ apiKey: '…', retryPolicy: RetryPolicy.disabled() });\n```\n\n---\n\n## 🔐 Webhook Signatures\n\nTaxora can sign every webhook request with HMAC-SHA256 (opt-in per endpoint: dashboard → **Developer → Webhooks**,\nor `POST /v1/webhooks/{id}/signing/enable`). Signed requests carry:\n\n```\nTaxora-Signature: t=1716115200,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd\nTaxora-Webhook-Id: 550e8400-e29b-41d4-a716-446655440000\n```\n\n`constructWebhookEvent` verifies the signature (constant-time, 5-minute replay window) and returns a typed event:\n\n```ts\nimport express from 'express';\nimport { constructWebhookEvent, WebhookSignatureVerificationError } from '@taxora/sdk';\n\nconst app = express();\n\n// express.raw — NOT express.json: the signature covers the exact bytes Taxora sent.\napp.post('/taxora-webhook', express.raw({ type: 'application/json' }), (req, res) => {\n  let event;\n  try {\n    event = constructWebhookEvent(req.body, req.header('Taxora-Signature'), process.env.TAXORA_WEBHOOK_SECRET!, {\n      tolerance: 300, // seconds, default\n    });\n  } catch (err) {\n    if (err instanceof WebhookSignatureVerificationError) {\n      return res.status(400).send(err.message); // err.reason: 'no_matching_signature' | 'timestamp_outside_tolerance' | …\n    }\n    throw err;\n  }\n\n  switch (event.event) {\n    case 'vat.validated':\n      console.log(event.data.object.vat_uid, event.data.object.state); // typed\n      break;\n    case 'enrichment.completed':\n      console.log(event.data.object.foundCount);\n      break;\n  }\n\n  res.sendStatus(200);\n});\n```\n\nNext.js App Router: `const rawBody = await request.text();` (not `request.json()`).\n\n| Helper                                                                 | Purpose                                                      |\n| ---------------------------------------------------------------------- | ------------------------------------------------------------ |\n| `verifyWebhookSignature(rawBody, header, secret, { tolerance })`       | Returns `true` or throws `WebhookSignatureVerificationError` |\n| `constructWebhookEvent(rawBody, header, secret, { tolerance })`        | Verifies, then parses into `TaxoraWebhookEvent`              |\n| `generateWebhookSignatureHeader(rawBody, secret, timestamp?)`          | Builds a valid header — for testing your own handler         |\n| `parseWebhookSignatureHeader(header)` / `computeWebhookSignature(...)` | Low-level building blocks                                    |\n\n- **Rotation:** while Taxora rotates your secret, requests carry one `v1=` per live secret — any match is accepted.\n  `secret` may also be an array, so you can accept old and new secret on your side during a deploy.\n- **Raw body:** pass a `string`, `Buffer` or `Uint8Array`. Passing an already parsed object throws\n  `reason: 'invalid_body'`.\n- **Idempotency:** dedupe on `event.id` (= `Taxora-Webhook-Id`), which stays the same across retries.\n\n### Events\n\n| Event                                  | `data.object`                                                                                                 |\n| -------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| `vat.validated` / `vat.state_changed`  | `VatWebhookObject` (`id`, `vat_uid`, `state`, `company_name`, …)                                              |\n| `compliance.transaction.state_changed` | `ComplianceTransactionWebhookObject` (`id`, `state`, `previous_state`, `provider_state`, `buyer_rejected`, …) |\n| `compliance.ledger.state_changed`      | `ComplianceLedgerWebhookObject` (`id`, `state`, `ledger_type`, `ledger_date`)                                 |\n| `enrichment.completed`                 | `EnrichmentCompletedWebhookObject` (`jobId`, `status`, `results`, …)                                          |\n| `enrichment.updated`                   | `EnrichmentUpdatedWebhookObject` (`jobId`, `rowIndex`, `result`, …)                                           |\n| `webhook.test`                         | `TestWebhookObject` (`message`)                                                                               |\n\n`compliance.transaction.state_changed` fires for **every real change** of a transaction: Taxora's own state\n(`submitted`, `error`, `not_required`) and the provider's delivery state (`accepted`, `refused`, `paid`, …). It is\nnever sent twice for the same state and never for the transient `sending`. Besides `id`, `invoice_number`,\n`country` (lowercase), `state` and `provider_state` the object carries `internal_reference`, `previous_state`,\n`previous_provider_state`, `buyer_rejected`, `rejection_reason`, `submission_error` and `delivery_check` — these are\noptional in the type because older deliveries lack them.\n\n```ts\nimport { isTransactionBuyerRejected } from '@taxora/sdk';\n\nif (event.event === 'compliance.transaction.state_changed') {\n  const tx = event.data.object;\n  if (tx.state === 'not_required') {\n    // The buyer cannot receive e-invoices (tx.delivery_check e.g. 'not_reachable'):\n    // nothing was sent or billed — send your PDF to the buyer by e-mail yourself.\n  }\n  if (isTransactionBuyerRejected(tx)) {\n    // The buyer refused the e-invoice (tx.rejection_reason) — issue a credit note.\n  }\n  if (tx.state === 'error') console.warn(tx.submission_error);\n}\n```\n\nTransactions carry the same signal (`tx.buyerRejected`, `tx.rejectionReason`); find rejected invoices with\n`listTransactions({ providerState: 'refused' })`.\n\n---\n\n## 🔌 VatState Helpers\n\n```ts\nimport { VatState, getFailedVatStates, describeVatState } from '@taxora/sdk';\n\nVatState.VALID; // 'valid'\nVatState.INVALID; // 'invalid'\nVatState.FRAUD; // 'fraud'\nVatState.UNKNOWN; // 'unknown'\n\ngetFailedVatStates(); // ['invalid', 'fraud']\ndescribeVatState(VatState.VALID); // 'The VAT number is valid and active.'\n```\n\n---\n\n## 🧪 Testing\n\n```bash\nnpm test                # Run all 129 tests\nnpm run test:coverage   # Run with v8 coverage report\nnpm run test:watch      # Watch mode during development\n```\n\nCI runs on **Node 18**, **20**, and **22**, verifying:\n\n- 129 Vitest unit tests across 18 test files\n- 97.8 % statement coverage / 87 % branch coverage / 100 % function coverage\n- Strict TypeScript compilation\n\n---\n\n## 🏗️ Build\n\n```bash\nnpm run build\n# → dist/index.js   (ESM)\n# → dist/index.cjs  (CommonJS)\n# → dist/index.d.ts (TypeScript declarations)\n```\n\n---\n\n## ⚠️ Deprecations\n\nSo fresh there aren't even any deprecated features yet. Check back in a few months when we're on v47 and have made some regrettable decisions. 🎉\n\n---\n\n## 🪪 License\n\nLicensed under the **MIT License** © 2025 [theconcept technologies](https://www.theconcept-technologies.com).\nThe SDK is open-source, but API usage requires a valid **Taxora subscription**.\n\n---\n\n## 🤝 Contributing\n\nContributions and pull requests are welcome!\n\n- Follow the existing TypeScript code style (strict mode, no `any`).\n- Run `npm test` before submitting a PR.\n- Ensure new endpoints include DTOs + tests.\n\n---\n\n## 💬 Support\n\nNeed help or enterprise support?\n📧 **[support@taxora.io](mailto:support@taxora.io)**\n🌐 [https://taxora.io](https://taxora.io)\n","readmeFilename":"README.md"}