{"_id":"@abby-inc/node","_rev":"4-7a3934c24698435578ef5db6b5520ca0","name":"@abby-inc/node","dist-tags":{"latest":"2.1.0"},"versions":{"1.0.0":{"name":"@abby-inc/node","version":"1.0.0","keywords":["abby","api","sdk","client","invoicing","freelance","business","bun","deno"],"author":{"name":"Abby","email":"contact@abby.fr"},"license":"MIT","_id":"@abby-inc/node@1.0.0","maintainers":[{"name":"quanticpotatoes","email":"jeremy@abby.fr"}],"homepage":"https://github.com/abby-inc/abby-node","bugs":{"url":"https://github.com/abby-inc/abby-node/issues"},"dist":{"shasum":"6cdfdcfebe908cd57f201ec580c53b317d12e7b3","tarball":"https://registry.npmjs.org/@abby-inc/node/-/node-1.0.0.tgz","fileCount":91,"integrity":"sha512-CdcLlH6eVvmWbKD+VQLUM3v2eYGKnX5wZxx50GW0Soh4Tlf9VKnoJHGhDJHXPrlzODWo4YJ2jKKPx3cW93FFDA==","signatures":[{"sig":"MEUCIQCEA4leGM8ba+STfxBVL24YHacqGAyrmrWuw0XHJUIPegIgatapipTDXM2s80shrXDFgCespf9uJAbnxRUEm8JfbpU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1843716},"main":"dist/cjs/index.cjs","type":"module","_from":"file:abby-inc-node-1.0.0.tgz","types":"dist/types/index.d.ts","module":"dist/esm/index.js","engines":{"bun":">=1.0.0","node":">=18.0.0"},"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.cjs"},"./package.json":"./package.json"},"scripts":{"lint":"eslint src test --fix","test":"vitest run","build":"pnpm run generate && rollup -c rollup.config.mjs","clean":"rm -rf dist","format":"prettier --write .","generate":"openapi-ts","test:bun":"bunx vitest run","test:deno":"deno run -A --node-modules-dir=auto node_modules/.bin/vitest run","typecheck":"tsc --noEmit","build:only":"rollup -c rollup.config.mjs","commitlint":"commitlint","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"quanticpotatoes","email":"jeremy@abby.fr"},"_resolved":"/private/var/folders/46/bzb5_29x7038ffx28p4yh4540000gn/T/341b39932565148b90101934851a0497/abby-inc-node-1.0.0.tgz","_integrity":"sha512-CdcLlH6eVvmWbKD+VQLUM3v2eYGKnX5wZxx50GW0Soh4Tlf9VKnoJHGhDJHXPrlzODWo4YJ2jKKPx3cW93FFDA==","apiVersion":"1.90.0","repository":{"url":"git+https://github.com/abby-inc/abby-node.git","type":"git"},"_npmVersion":"10.9.4","description":"Node.js, Bun, and Deno library for the Abby API","directories":{},"sideEffects":false,"_nodeVersion":"22.21.1","dependencies":{"zod":"^4.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","tslib":"^2.8.1","eslint":"^9.39.2","rollup":"^4.54.0","vitest":"^4.0.16","prettier":"^3.7.4","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.3","lint-staged":"^16.2.7","@commitlint/cli":"^20.2.0","@hey-api/openapi-ts":"~0.89.2","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.0.16","@rollup/plugin-replace":"^6.0.3","@rollup/plugin-commonjs":"^29.0.0","@rollup/plugin-typescript":"^12.3.0","@typescript-eslint/parser":"^8.50.1","@rollup/plugin-node-resolve":"^16.0.3","@commitlint/config-conventional":"^20.2.0","@typescript-eslint/eslint-plugin":"^8.50.1"},"_npmOperationalInternal":{"tmp":"tmp/node_1.0.0_1766790852454_0.5081033798356722","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@abby-inc/node","version":"1.1.0","keywords":["abby","api","sdk","client","invoicing","freelance","business","bun","deno"],"author":{"name":"Abby","email":"contact@abby.fr"},"license":"MIT","_id":"@abby-inc/node@1.1.0","maintainers":[{"name":"quanticpotatoes","email":"jeremy@abby.fr"}],"homepage":"https://github.com/abby-inc/abby-node","bugs":{"url":"https://github.com/abby-inc/abby-node/issues"},"dist":{"shasum":"b830ca727d6fc5c3b7d4a2e228791ee334d0ffd3","tarball":"https://registry.npmjs.org/@abby-inc/node/-/node-1.1.0.tgz","fileCount":91,"integrity":"sha512-0o2kmZuxntIwDRinHNfNN/R1H7qJLqmK4Rvotg7F3Z99bNNnkd8CVEEyWyCdi5wrek1r0Td/RISu6bx5rlgLig==","signatures":[{"sig":"MEUCIQDcVrzltRbGZBQhF1NBj2/lR+YJtEbKiVOyxVUWvz0mFAIgQr6LwFkRSFxS4y5s/d3M5Y1iVeGHDFnDn4iUe3tz0p4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abby-inc%2fnode@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3111262},"main":"dist/cjs/index.cjs","type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","engines":{"bun":">=1.0.0","node":">=18.0.0"},"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.cjs"},"./package.json":"./package.json"},"gitHead":"8ccf2fe4dc5fa05bdde8175496622f672a302bea","scripts":{"lint":"eslint src test --fix","test":"vitest run","build":"pnpm run generate && rollup -c rollup.config.mjs","clean":"rm -rf dist","format":"prettier --write .","prepare":"husky","generate":"openapi-ts","test:bun":"bunx vitest run","test:deno":"deno run -A --node-modules-dir=auto node_modules/.bin/vitest run","typecheck":"tsc --noEmit","build:only":"rollup -c rollup.config.mjs","commitlint":"commitlint","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run clean && pnpm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc2be006-2752-4058-af44-41de6a0c337a"}},"apiVersion":"1.109.0","repository":{"url":"git+https://github.com/abby-inc/abby-node.git","type":"git"},"_npmVersion":"11.19.1","description":"Node.js, Bun, and Deno library for the Abby API","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.26.2+sha512.0e308ff2005fc7410366f154f625f6631ab2b16b1d2e70238444dd6ae9d630a8482d92a451144debc492416896ed16f7b114a86ec68b8404b2443869e68ffda6","devDependencies":{"husky":"^9.1.7","tslib":"^2.8.1","eslint":"^9.39.5","rollup":"^4.63.0","vitest":"^4.1.11","prettier":"^3.9.6","@eslint/js":"^9.39.5","typescript":"^5.9.3","@types/node":"^25.9.5","lint-staged":"^16.4.0","@commitlint/cli":"^20.5.3","@hey-api/openapi-ts":"~0.89.2","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.1.11","@rollup/plugin-replace":"^6.0.3","@rollup/plugin-commonjs":"^29.0.3","@rollup/plugin-typescript":"^12.3.0","@typescript-eslint/parser":"^8.68.0","@rollup/plugin-node-resolve":"^16.0.3","@commitlint/config-conventional":"^20.5.3","@typescript-eslint/eslint-plugin":"^8.68.0"},"_npmOperationalInternal":{"tmp":"tmp/node_1.1.0_1787823130282_0.4350909993308185","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@abby-inc/node","version":"2.0.0","keywords":["abby","api","sdk","client","invoicing","freelance","business","bun","deno"],"author":{"name":"Abby","email":"contact@abby.fr"},"license":"MIT","_id":"@abby-inc/node@2.0.0","maintainers":[{"name":"quanticpotatoes","email":"jeremy@abby.fr"}],"homepage":"https://github.com/abby-inc/abby-node","bugs":{"url":"https://github.com/abby-inc/abby-node/issues"},"dist":{"shasum":"42fdb7df46fc2c1a36fb16632908e16e95bd1d68","tarball":"https://registry.npmjs.org/@abby-inc/node/-/node-2.0.0.tgz","fileCount":91,"integrity":"sha512-apw5tiMYL5sVIxeSH/erfCHhyqs0jXpcPhunTTtlmcJ0Bprby4ocvodiTfiG7yWKtPZ6LZ+/5jQwBfCA92Gc2Q==","signatures":[{"sig":"MEUCIQD02D2JR0OKnDpVPyiDBs6+EBHz9cnTpC45mCmRxbonsAIgOZ9IHgq4SwOifk8SWoF0pqy0DTreoYt/UfvKk5nmwKw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abby-inc%2fnode@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4230112},"main":"dist/cjs/index.cjs","type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","engines":{"bun":">=1.0.0","node":">=22.13.0"},"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.cjs"},"./package.json":"./package.json"},"gitHead":"acff55db83b002ad74244860442d3c633376ac9a","scripts":{"lint":"oxlint src test","test":"vitest run","build":"pnpm run generate && pnpm run build:only","clean":"rm -rf dist","format":"prettier --write .","prepare":"husky","generate":"openapi-ts","lint:fix":"oxlint src test --fix","test:bun":"bunx vitest run","test:deno":"deno run -A --node-modules-dir=auto node_modules/.bin/vitest run","typecheck":"tsc --noEmit","build:only":"rollup -c rollup.config.mjs && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist/types","commitlint":"commitlint","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run clean && pnpm run build:only"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc2be006-2752-4058-af44-41de6a0c337a"}},"apiVersion":"1.109.0","repository":{"url":"git+https://github.com/abby-inc/abby-node.git","type":"git"},"_npmVersion":"11.19.1","description":"Node.js, Bun, and Deno library for the Abby API","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.24.0+sha512.bd27e345e976dcb0be0b7a1228217b049a817e21b1f355c90dbe7dc46671895a8bc1e6d06c24554505ea93ea0b45f489a27ec1bfbc8de6a9659fca0f16fa0000","devDependencies":{"husky":"^9.1.7","oxlint":"^1.80.0","rollup":"^4.63.0","vitest":"^4.1.11","esbuild":"0.27.7","prettier":"^3.9.6","typescript":"^7.0.2","@types/node":"^25.9.5","lint-staged":"^17.3.0","@commitlint/cli":"^21.2.2","@hey-api/openapi-ts":"~0.97.3","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.1.11","rollup-plugin-esbuild":"6.2.1","@rollup/plugin-replace":"^6.0.3","@rollup/plugin-commonjs":"^29.0.3","@rollup/plugin-node-resolve":"^16.0.3","@commitlint/config-conventional":"^21.2.2"},"_npmOperationalInternal":{"tmp":"tmp/node_2.0.0_1787828912575_0.3624883942134607","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@abby-inc/node","version":"2.1.0","apiVersion":"1.114.0","type":"module","description":"Node.js, Bun, and Deno library for the Abby API","author":{"name":"Abby","email":"contact@abby.fr"},"license":"MIT","homepage":"https://github.com/abby-inc/abby-node","repository":{"type":"git","url":"git+https://github.com/abby-inc/abby-node.git"},"bugs":{"url":"https://github.com/abby-inc/abby-node/issues"},"keywords":["abby","api","sdk","client","invoicing","freelance","business","bun","deno"],"main":"dist/cjs/index.cjs","module":"dist/esm/index.js","types":"dist/types/index.d.ts","sideEffects":false,"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.cjs"},"./package.json":"./package.json"},"packageManager":"pnpm@11.24.0+sha512.bd27e345e976dcb0be0b7a1228217b049a817e21b1f355c90dbe7dc46671895a8bc1e6d06c24554505ea93ea0b45f489a27ec1bfbc8de6a9659fca0f16fa0000","scripts":{"generate":"openapi-ts","build":"pnpm run generate && pnpm run build:only","build:only":"rollup -c rollup.config.mjs && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist/types","clean":"rm -rf dist","lint":"oxlint src test","lint:fix":"oxlint src test --fix","format":"prettier --write .","format:check":"prettier --check .","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","test:bun":"bunx vitest run","test:deno":"deno run -A --node-modules-dir=auto node_modules/.bin/vitest run","prepare":"husky","prepublishOnly":"pnpm run clean && pnpm run build:only","commitlint":"commitlint"},"dependencies":{"zod":"^4.4.3"},"devDependencies":{"@commitlint/cli":"^21.2.2","@commitlint/config-conventional":"^21.2.2","@hey-api/openapi-ts":"~0.97.3","@rollup/plugin-commonjs":"^29.0.3","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.3","@rollup/plugin-replace":"^6.0.3","@types/node":"^25.9.5","@vitest/coverage-v8":"^4.1.11","esbuild":"0.28.1","husky":"^9.1.7","lint-staged":"^17.3.0","oxlint":"^1.80.0","prettier":"^3.9.6","rollup":"^4.63.0","rollup-plugin-esbuild":"6.2.1","typescript":"^5.9.3","vitest":"^4.1.11"},"engines":{"node":">=22.13.0","bun":">=1.0.0"},"publishConfig":{"access":"public"},"gitHead":"24a3f65e6439c11505fcf7c7296cd72a17dff13f","_id":"@abby-inc/node@2.1.0","_nodeVersion":"22.23.2","_npmVersion":"11.19.1","dist":{"integrity":"sha512-NZD/B4/uXg/g5LLGlDJ6/v7qKayZrVWggrJYFYmNZe2KKOBwA+AooArTBY5VCa3hT2c6LR67fcm4oH1sWmbpFw==","shasum":"4ddc4a6f073cbd696bc6af8aa6ec8c34f1162448","tarball":"https://registry.npmjs.org/@abby-inc/node/-/node-2.1.0.tgz","fileCount":91,"unpackedSize":4139791,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abby-inc%2fnode@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD2rprLwXZ3nUzOukbrKeCCFoeKRLVyCPozed7X0OZQ4gIgGBw5MP/2unEMWe74niG80tuOqw/5WLjfVHAbj8NDdk8="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc2be006-2752-4058-af44-41de6a0c337a"}},"directories":{},"maintainers":[{"name":"quanticpotatoes","email":"jeremy@abby.fr"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node_2.1.0_1788254179097_0.38224028152760314"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-26T23:14:12.358Z","modified":"2026-09-01T09:16:19.925Z","1.0.0":"2025-12-26T23:14:12.644Z","1.1.0":"2026-08-27T09:32:10.428Z","2.0.0":"2026-08-27T11:08:32.741Z","2.1.0":"2026-09-01T09:16:19.239Z"},"bugs":{"url":"https://github.com/abby-inc/abby-node/issues"},"author":{"name":"Abby","email":"contact@abby.fr"},"license":"MIT","homepage":"https://github.com/abby-inc/abby-node","keywords":["abby","api","sdk","client","invoicing","freelance","business","bun","deno"],"repository":{"type":"git","url":"git+https://github.com/abby-inc/abby-node.git"},"description":"Node.js, Bun, and Deno library for the Abby API","maintainers":[{"name":"quanticpotatoes","email":"jeremy@abby.fr"}],"readme":"# Abby Node.js, Bun & Deno SDK\n\n[![npm version](https://img.shields.io/npm/v/@abby-inc/node.svg)](https://www.npmjs.com/package/@abby-inc/node)\n[![npm downloads](https://img.shields.io/npm/dm/@abby-inc/node.svg)](https://www.npmjs.com/package/@abby-inc/node)\n[![CI](https://github.com/abby-inc/abby-node/actions/workflows/ci.yml/badge.svg)](https://github.com/abby-inc/abby-node/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/abby-inc/abby-node/branch/master/graph/badge.svg?token=51rRlQV05f)](https://codecov.io/gh/abby-inc/abby-node)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nThe official Node.js, Bun, and Deno library for the [Abby API](https://abby.fr). Abby is an all-in-one business management platform for freelancers and micro-enterprises.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Requirements](#requirements)\n- [Usage](#usage)\n  - [Initialization](#initialization)\n  - [Services](#services)\n  - [Basic Example](#basic-example)\n  - [Configuration](#configuration)\n  - [Custom Fetch & Proxy Support](#custom-fetch--proxy-support)\n  - [Error Handling](#error-handling)\n  - [Event Listeners](#event-listeners)\n  - [Interceptors](#interceptors)\n  - [Raw Requests](#raw-requests)\n- [Validation](#validation)\n  - [Automatic Validation](#automatic-validation)\n  - [Using Zod Schemas Directly](#using-zod-schemas-directly)\n- [TypeScript Support](#typescript-support)\n- [Versioning](#versioning)\n- [Development](#development)\n- [Support](#support)\n- [License](#license)\n\n## Installation\n\nInstall the package using your preferred package manager:\n\n```bash\nnpm install @abby-inc/node\n# or\nyarn add @abby-inc/node\n# or\npnpm add @abby-inc/node\n# or\nbun add @abby-inc/node\n```\n\nFor Deno, you can import directly from npm:\n\n```typescript\nimport Abby from 'npm:@abby-inc/node';\n```\n\n## Requirements\n\n- Node.js 22.13.0 or higher (CI: 22, 24, 26), Bun 1.0.0 or higher, or Deno 2.0.0 or higher\n- An Abby account with an API key\n\n## Usage\n\n### Initialization\n\nGet your API key from the [Abby settings](https://app.abby.fr/settings/integrations).\n\n```typescript\nimport Abby from '@abby-inc/node';\n\nconst abby = new Abby('your_api_key');\n```\n\n### Services\n\nThe SDK provides several services to interact with different parts of the Abby API:\n\n- `abby.company`: Current company info and preferences.\n- `abby.invoice`: Create and manage invoices.\n- `abby.estimate`: Create and manage estimates (quotes).\n- `abby.contact`: Manage your contacts (customers).\n- `abby.organization`: Manage organizations.\n- `abby.billing`: Shared billing utilities (PDFs, emails).\n- `abby.opportunity`: CRM and opportunities management.\n- `abby.asset`: Manage business assets.\n- `abby.advance`: Manage advance payments.\n- `abby.customerPortal`: Customer portal payments and billing themes.\n\n### Basic Example\n\n```typescript\nimport Abby from '@abby-inc/node';\n\nconst abby = new Abby('your_api_key');\n\nasync function main() {\n  // Get current company information\n  const { data: me } = await abby.company.getMe();\n  console.log(`Welcome back, ${me.user.firstname}!`);\n\n  // List all contacts\n  const { data: contacts } = await abby.contact.retrieveContacts({\n    query: { limit: 10 },\n  });\n\n  console.log(`Found ${contacts.docs.length} contacts.`);\n}\n\nmain().catch(console.error);\n```\n\n### Configuration\n\nYou can pass optional configuration settings when initializing the SDK:\n\n```typescript\nimport Abby from '@abby-inc/node';\n\nconst abby = new Abby('your_api_key', {\n  baseUrl: 'https://api.app-abby.com',\n  timeout: 30000,\n  headers: {\n    'X-Custom-Header': 'value',\n  },\n});\n```\n\n| Option    | Default                      | Description                                                                                                                     |\n| --------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| `baseUrl` | `'https://api.app-abby.com'` | Base URL for the Abby API.                                                                                                      |\n| `timeout` | `30000`                      | Request timeout in milliseconds.                                                                                                |\n| `headers` | `undefined`                  | Additional headers to include in every request.                                                                                 |\n| `fetch`   | `globalThis.fetch`           | Custom fetch implementation for proxies, logging, or testing. See [Custom Fetch & Proxy Support](#custom-fetch--proxy-support). |\n\n### Custom Fetch & Proxy Support\n\nThe SDK allows you to provide a custom `fetch` implementation for advanced use cases like proxies, custom logging, or testing.\n\n#### Using a Proxy\n\nWith [undici](https://github.com/nodejs/undici) (recommended for Node.js):\n\n```typescript\nimport Abby from '@abby-inc/node';\nimport { fetch as undiciFetch, ProxyAgent } from 'undici';\n\nconst proxyAgent = new ProxyAgent('http://proxy.example.com:8080');\n\nconst abby = new Abby('your_api_key', {\n  fetch: (url, init) =>\n    undiciFetch(url, {\n      ...init,\n      dispatcher: proxyAgent,\n    }),\n});\n```\n\nWith [node-fetch](https://github.com/node-fetch/node-fetch) and [https-proxy-agent](https://github.com/TooTallNate/proxy-agents):\n\n```typescript\nimport Abby from '@abby-inc/node';\nimport fetch from 'node-fetch';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\n\nconst proxyAgent = new HttpsProxyAgent('http://proxy.example.com:8080');\n\nconst abby = new Abby('your_api_key', {\n  fetch: (url, init) =>\n    fetch(url, {\n      ...init,\n      agent: proxyAgent,\n    }) as Promise<Response>,\n});\n```\n\n#### Custom Logging\n\n```typescript\nconst abby = new Abby('your_api_key', {\n  fetch: async (url, init) => {\n    console.log(`[Abby SDK] ${init?.method ?? 'GET'} ${url}`);\n    const start = Date.now();\n\n    const response = await globalThis.fetch(url, init);\n\n    console.log(`[Abby SDK] ${response.status} in ${Date.now() - start}ms`);\n    return response;\n  },\n});\n```\n\n#### Testing with Mock Fetch\n\n```typescript\nimport { vi } from 'vitest';\n\nconst mockFetch = vi.fn(\n  async () =>\n    new Response(JSON.stringify({ success: true }), {\n      status: 200,\n      headers: { 'Content-Type': 'application/json' },\n    })\n);\n\nconst abby = new Abby('your_api_key', {\n  fetch: mockFetch,\n});\n```\n\n### Error Handling\n\nThe SDK throws descriptive errors when a request fails. You can catch these errors to handle different failure scenarios:\n\n```typescript\ntry {\n  const { data } = await abby.invoice.getInvoice({\n    path: { invoiceId: 'inv_invalid' },\n  });\n} catch (error) {\n  if (error.status === 404) {\n    console.error('Invoice not found');\n  } else if (error.status === 401) {\n    console.error('Invalid API key');\n  } else {\n    console.error('An unexpected error occurred:', error.message);\n  }\n}\n```\n\n### Event Listeners\n\nThe SDK provides an event emitter pattern for global error handling and logging. This is useful for integrating with error tracking services like Sentry or for centralized logging.\n\n#### Listening for Errors\n\nSubscribe to all API errors across your application:\n\n```typescript\nimport Abby from '@abby-inc/node';\n\nconst abby = new Abby('your_api_key');\n\n// Global error handler - fires on any 4xx/5xx response\nabby.on('error', (error) => {\n  console.error(`API Error: ${error.status} ${error.statusText}`);\n  console.error(`URL: ${error.method} ${error.url}`);\n  console.error(`Message: ${error.message}`);\n  console.error(`Duration: ${error.duration}ms`);\n\n  // Send to error tracking service\n  Sentry.captureException(new Error(error.message), {\n    extra: {\n      status: error.status,\n      url: error.url,\n      requestId: error.requestId,\n      body: error.body,\n    },\n  });\n});\n```\n\n#### Listening for All Responses\n\nSubscribe to all API responses (both successful and failed):\n\n```typescript\n// Log all API calls for debugging/monitoring\nabby.on('response', (response) => {\n  console.log(`${response.method} ${response.url} - ${response.status} (${response.duration}ms)`);\n});\n```\n\n#### Removing Listeners\n\nUse `off()` to remove a listener:\n\n```typescript\nconst errorHandler = (error) => console.error(error);\n\n// Add listener\nabby.on('error', errorHandler);\n\n// Remove listener later\nabby.off('error', errorHandler);\n```\n\n#### Event Types\n\n| Event      | Description                | Payload Type        |\n| ---------- | -------------------------- | ------------------- |\n| `error`    | Fires on 4xx/5xx responses | `AbbyErrorEvent`    |\n| `response` | Fires on all responses     | `AbbyResponseEvent` |\n\n**`AbbyErrorEvent` properties:**\n\n| Property     | Type       | Description                                    |\n| ------------ | ---------- | ---------------------------------------------- |\n| `status`     | `number`   | HTTP status code (4xx or 5xx)                  |\n| `statusText` | `string`   | HTTP status text                               |\n| `url`        | `string`   | Request URL                                    |\n| `method`     | `string`   | HTTP method (GET, POST, etc.)                  |\n| `duration`   | `number`   | Request duration in milliseconds               |\n| `message`    | `string?`  | Error message from response body, if available |\n| `body`       | `unknown?` | Response body, if available                    |\n| `requestId`  | `string?`  | X-Request-Id header, if available              |\n\n**`AbbyResponseEvent` properties:**\n\n| Property   | Type      | Description                               |\n| ---------- | --------- | ----------------------------------------- |\n| `status`   | `number`  | HTTP status code                          |\n| `url`      | `string`  | Request URL                               |\n| `method`   | `string`  | HTTP method (GET, POST, etc.)             |\n| `duration` | `number`  | Request duration in milliseconds          |\n| `ok`       | `boolean` | Whether the response was successful (2xx) |\n\n### Interceptors\n\nInterceptors allow you to hook into the request/response lifecycle:\n\n```typescript\nconst client = abby.getClient();\n\n// Request Interceptor: Add a custom header to every request\nclient.interceptors.request.use((request) => {\n  request.headers.set('X-Request-ID', crypto.randomUUID());\n  return request;\n});\n\n// Response Interceptor: Log every response status\nclient.interceptors.response.use((response) => {\n  console.log(`API Response: ${response.status}`);\n  return response;\n});\n```\n\n### Raw Requests\n\nIf you need to call an endpoint that isn't covered by the SDK, or prefer to specify request details directly, you can use the underlying HTTP client:\n\n```typescript\nimport Abby from '@abby-inc/node';\n\nconst abby = new Abby('your_api_key');\nconst client = abby.getClient();\n\n// GET request\nconst { data } = await client.get({\n  url: '/v2/some/endpoint',\n});\n\n// POST request with body\nconst { data: result } = await client.post({\n  url: '/v2/some/endpoint',\n  body: {\n    field: 'value',\n  },\n});\n\n// Other methods available: put, patch, delete, head, options\n```\n\nThe client automatically includes your API key and SDK headers in all requests.\n\n## Validation\n\nThe SDK includes built-in [Zod](https://zod.dev) validation for API requests, catching malformed payloads before they leave your process.\n\n### Automatic Validation\n\nAll SDK methods automatically validate **request data**: parameters, query strings, and request bodies are checked before sending.\n\n**Responses are not validated.** Response schemas are generated and exported (see below), but the SDK does not run them — a spec/API mismatch would otherwise turn a successful call into a thrown error. Types on responses remain compile-time only; parse with the exported `z*Dto` schemas yourself if you need a runtime guarantee.\n\nIf request validation fails, a `ZodError` is thrown with detailed information about what went wrong:\n\n```typescript\nimport Abby from '@abby-inc/node';\nimport { ZodError } from 'zod';\n\nconst abby = new Abby('your_api_key');\n\ntry {\n  // This will fail validation if the request body is invalid\n  await abby.contact.createContact({\n    body: {\n      // Missing required fields will trigger a ZodError\n    },\n  });\n} catch (error) {\n  if (error instanceof ZodError) {\n    console.error('Validation failed:', error.errors);\n  }\n}\n```\n\n### Using Zod Schemas Directly\n\nAll Zod schemas are exported and can be used for your own validation needs:\n\n```typescript\nimport Abby, { zCreateContactDto, zReadContactDto } from '@abby-inc/node';\n\n// Validate user input before sending to the API\nconst userInput = {\n  firstname: 'John',\n  lastname: 'Doe',\n  email: 'john@example.com',\n};\n\n// Parse and validate (throws ZodError if invalid)\nconst validatedContact = zCreateContactDto.parse(userInput);\n\n// Or use safeParse for non-throwing validation\nconst result = zCreateContactDto.safeParse(userInput);\nif (result.success) {\n  console.log('Valid:', result.data);\n} else {\n  console.error('Invalid:', result.error.errors);\n}\n\n// Infer TypeScript types from schemas\nimport { z } from 'zod';\ntype CreateContactInput = z.infer<typeof zCreateContactDto>;\n```\n\nAvailable schema patterns:\n\n- `z{DtoName}` - Schemas for DTOs (e.g., `zCreateContactDto`, `zReadInvoiceDto`)\n- `z{ControllerMethod}Data` - Request data schemas (e.g., `zContactControllerCreateContactData`)\n\n## TypeScript Support\n\nThe SDK is written in TypeScript and provides complete type definitions for all API resources and responses.\n\n```typescript\nimport Abby, { ReadMeDto } from '@abby-inc/node';\n\nconst abby = new Abby('your_api_key');\n\nasync function getCompanyData() {\n  const { data }: { data: ReadMeDto } = await abby.company.getMe();\n  return data;\n}\n```\n\nYou can also infer types directly from Zod schemas:\n\n```typescript\nimport { z } from 'zod';\nimport { zReadContactDto } from '@abby-inc/node';\n\n// Infer the type from the Zod schema\ntype Contact = z.infer<typeof zReadContactDto>;\n```\n\n## Versioning\n\nThis SDK uses **independent versioning** from the Abby API:\n\n- **SDK version** (`version` in `package.json`): Follows [semver](https://semver.org/) for SDK changes (bug fixes, new features, breaking changes)\n- **API version** (`apiVersion` in `package.json`): Tracks which Abby API version was used to generate the SDK\n\n```json\n{\n  \"version\": \"1.2.0\", // SDK version\n  \"apiVersion\": \"1.5.0\" // API spec version used to generate\n}\n```\n\nThis allows the SDK to receive bug fixes and improvements independently from API changes.\n\n## Development\n\nContributions are welcome! Please see our [Contributing Guidelines](CONTRIBUTING.md) for more information.\n\n## Support\n\nIf you encounter any issues or have questions, please check the following resources:\n\n- [Official Documentation](https://docs.abby.fr)\n- [API Reference](https://api.app-abby.com/api-docs/public.json)\n- [GitHub Issues](https://github.com/abby-inc/abby-node/issues)\n- [Abby Support](https://abby.fr/contact)\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n","readmeFilename":"README.md"}