🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@ksefnik/http

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ksefnik/http

KSeF HTTP adapter — authentication, challenge, sessions, invoice fetch (Polish e-Invoice API v2)

Source
npmnpm
Version
0.0.1
Version published
Weekly downloads
18
80%
Maintainers
1
Weekly downloads
 
Created
Source

@ksefnik/http

Production HTTP client for KSeF 2.0 (Krajowy System e-Faktur, Polish national e-invoicing system, live from 2026-02-01).

Implements the KsefClient interface from @ksefnik/core against the real api.ksef.mf.gov.pl endpoints. Plug it into the Ksefnik facade via createHttpAdapter(...) and you get end-to-end invoice retrieval, reconciliation, and MCP-mediated automation with zero additional code in consumers.

Research source of truth: CIRFMF/ksef-docs — see NOTES.md for a summary of the auth flow, endpoint map, and rate limits used by this package.

Install

pnpm add @ksefnik/http @ksefnik/core @ksefnik/shared

Usage

import { createKsefnik } from '@ksefnik/core'
import { createHttpAdapter } from '@ksefnik/http'
import { readFileSync } from 'node:fs'

const adapter = createHttpAdapter({
  nip: '7010002137',
  token: process.env.KSEF_TOKEN!,
  environment: 'production',
  publicKeyPem: readFileSync('./ksef-public-key.pem', 'utf8'),
})

const ksef = createKsefnik({
  config: { nip: '7010002137', environment: 'production', token: process.env.KSEF_TOKEN! },
  adapter,
})

await adapter.initSession?.()
const invoices = await ksef.invoices.fetch({ from: '2026-03-01', to: '2026-03-31' })
await adapter.closeSession?.()

Environments

EnvironmentBase URL
productionhttps://api.ksef.mf.gov.pl/v2
demohttps://api-demo.ksef.mf.gov.pl/v2
testhttps://api-test.ksef.mf.gov.pl/v2

Authentication flow (KSeF 2.0)

  • POST /auth/challenge — server returns { challenge, timestamp }.
  • Client encrypts "{ksefToken}|{timestamp}" with RSA-OAEP SHA-256 using the MF public key.
  • POST /auth/ksef-token — server returns { authenticationToken, referenceNumber } (temporary JWT).
  • POST /auth/token/redeem (Authorization: Bearer <authenticationToken>) — returns { accessToken, refreshToken }.
  • All subsequent calls use Authorization: Bearer <accessToken>.
  • Before expiry the client transparently calls POST /auth/token/refresh with the refresh token.

Crypto: RSA-OAEP SHA-256 only, implemented via node:crypto webcrypto.subtle. Zero external dependencies.

Error handling

import { KsefApiError, KsefAuthError, KsefRateLimitError } from '@ksefnik/http'

try {
  await ksef.invoices.fetch(...)
} catch (error) {
  if (error instanceof KsefAuthError) {
    // 401/403 — refresh token expired, re-issue KSeF token in the portal
  } else if (error instanceof KsefRateLimitError) {
    // 429 — honour error.retryAfter (seconds) and retry
  } else if (error instanceof KsefApiError) {
    // 4xx/5xx with error.statusCode and error.detailCode
  }
}

The underlying withRetry from @ksefnik/core automatically retries KsefRateLimitError and 5xx responses with exponential backoff.

Rate limits

Per limity-api.md:

Endpointreq/sreq/minreq/h
POST /invoices/query/metadata81620
GET /invoices/ksef/{ref}81664
Default1030120

fetchInvoices uses mapWithConcurrency(5) by default to stay well within the bursting envelope.

Not implemented in MVP

  • sendInvoice — stub throws "not implemented".
  • getUpo — stub throws "not implemented".
  • Async export flow (POST /invoices/exports + polling) — v2.

Smoke test

KSEF_TEST_NIP=... \
KSEF_TEST_TOKEN=... \
KSEF_TEST_PUBLIC_KEY_PATH=./ksef-test-pub.pem \
pnpm --filter @ksefnik/http smoke

The smoke script talks to api-test.ksef.mf.gov.pl for manual end-to-end verification. It is not run in CI.

Type generation from OpenAPI

Types for every KSeF 2.0 request/response in src/session.ts, src/invoices.ts, and src/public-key.ts are generated from the live production contract via openapi-typescript. The hand-written runtime (HTTP layer, retry, error mapping, session orchestration) is kept, but the shapes themselves are single-source-of-truth from MF.

pnpm --filter @ksefnik/http generate

This fetches https://api.ksef.mf.gov.pl/docs/v2/openapi.json and writes src/generated/ksef-api.ts (≈10k lines, 253 schemas, 59 paths). The generated file is committed to git so the package builds without network access, but should be refreshed whenever MF publishes a spec change.

Workflow for contract changes

  • pnpm --filter @ksefnik/http generate — pulls the latest contract
  • pnpm --filter @ksefnik/http build — TypeScript flags any breaking changes at compile time (missing fields, renamed enums, nullability changes, etc.)
  • Fix the callsites in session.ts/invoices.ts/public-key.ts until the build is green
  • pnpm --filter @ksefnik/http test — unit + integration tests must stay green
  • KSEF_ENV=production pnpm --filter @ksefnik/http smoke — live verification against the real API

What is generated vs hand-written

LayerSource
Request/response shapes (challenge, ksef-token, redeem, refresh, auth status, query metadata, public-key certs)generatedsrc/generated/ksef-api.ts re-exported via src/generated/index.ts
Runtime HTTP client (src/http.ts)hand-written — fetch, AbortSignal timeout, User-Agent, response parsing
Error mapping to KsefAuthError/KsefRateLimitError/KsefApiErrorhand-written — src/errors.ts + src/http.ts
Retry with Retry-After honoringhand-written — src/retry.ts
Auth flow orchestration (challenge → ksef-token → polling → redeem → refresh)hand-written — src/session.ts
Pagination + isTruncated guard + concurrencyhand-written — src/invoices.ts
KsefHttpClient facade implementing @ksefnik/core KsefClient interfacehand-written — src/client.ts

The generated file adds ~600KB to source control but adds zero runtime cost (pure .d.ts-style type exports — TSC erases them at build time).

License

MIT. Part of the ksefnik monorepo.

Keywords

ksef

FAQs

Package last updated on 11 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts