GitHub

Operations Reference

Transport configuration, retry behavior, workflow timeouts, logging fields, and resumable KSeF references.

On this page

This page records operational behavior that affects production integrations. It is not a sending or authentication walkthrough.

TransportConfig

TransportConfig is used only when the SDK creates the underlying httpx client. If you pass http_client, that supplied client owns HTTP timeout, pool, TLS, proxy, trust_env, HTTP/2, custom transport, and event-hook settings.

TransportConfig(
    timeouts=TimeoutConfig(),
    pool=ConnectionPoolConfig(),
    retry=RetryConfig(),
    tls=TlsConfig(),
    proxy_url=None,
    trust_env=True,
    http2=True,
    auto_refresh_tokens=True,
    error_format="problem-details",
)
python
FieldTypeDefaultPassed to
timeoutsTimeoutConfigTimeoutConfig()httpx.Timeout
poolConnectionPoolConfigConnectionPoolConfig()httpx.Limits
retryRetryConfigRetryConfig()SDK retry middleware
tlsTlsConfigTlsConfig()httpx TLS verification
proxy_url`strNone`None
trust_envboolTruehttpx environment-variable behavior
http2boolTruehttpx HTTP/2 flag
auto_refresh_tokensboolTrueAccess-token refresh of authenticated clients, see Access-token refresh
error_formatLiteral["problem-details", "legacy"]"problem-details"X-Error-Format header on KSeF API requests, see Error format

auto_refresh_tokens and error_format do not configure httpx, so they apply even when you pass your own http_client.

TimeoutConfig

TimeoutConfig controls one HTTP request. It does not control how long the SDK polls KSeF workflow state.

FieldDefaultMeaning
connect5.0Time allowed to establish a connection.
read30.0Time allowed while waiting for response bytes.
write30.0Time allowed while sending request bytes.
pool5.0Time allowed while waiting for a connection from the pool.

ConnectionPoolConfig

FieldDefaultMeaning
max_connections100Maximum open connections.
max_keepalive_connections20Maximum idle keep-alive connections.
keepalive_expiry30.0Idle keep-alive expiry in seconds.

TlsConfig

FieldDefaultMeaning
verifyTruePassed to httpx unless ca_bundle_path is set.
ca_bundle_pathNoneCA bundle path used as the httpx verify value when provided.

RetryConfig

RetryConfig controls SDK retry middleware. It applies to transport errors and retryable HTTP responses for retryable request types.

FieldDefault
max_attempts3
initial_delay0.5
max_delay4.0
max_retry_after120.0
backoff_multiplier2.0
retryable_status_codes(429, 502, 503, 504)

Retry delay is exponential:

min(initial_delay * backoff_multiplier ** (attempt - 1), max_delay)
text

max_delay caps only the exponential backoff. A Retry-After header (seconds or HTTP-date form) is honored exactly when it is at or below max_retry_after. When it exceeds the ceiling, the SDK does not sleep and does not retry: it gives up immediately and raises KSeFRateLimitError carrying the true header value, so the app can reschedule. The ceiling keeps a multi-hour Retry-After from stalling a process forever.

The ceiling bounds one sleep, not the whole request. If KSeF repeats the same Retry-After on every attempt, a single request waits up to (max_attempts - 1) * max_retry_after before it gives up. With the defaults that is 240 seconds, because the SDK sleeps 120 seconds twice. Lower max_attempts or max_retry_after when a request handler cannot afford that.

Retryable requests

The SDK retries only request shapes that are safe enough to repeat at the transport layer.

Request kindRetry behavior
GETRetryable.
DELETERetryable.
Most POST requestsNot retried automatically.
Selected POST requestsRetried automatically when listed below.

Retryable POST groups:

AreaOperations
Authenticationchallenge, refresh token
Invoicesmetadata query
Certificatesquery, retrieve
Permissionspersonal, authorization, EU entity, person, subordinate entity, and subunit queries

Invoice submission, permission grants, certificate enrollment, token generation, online-session opening, and batch-session opening are not retried by the SDK retry middleware. Persist returned references and resume by status instead of recreating those operations blindly.

Authentication token redemption is also never retried because KSeF returns its access/refresh pair only once. A lost redemption response raises KSeFAuthTokenRedemptionError with outcome_ambiguous=True; do not repeat the redemption automatically.

Access-token refresh

Authenticated clients refresh their access token themselves, using the refresh token from authentication or from the AuthenticationResumeState they were resumed from.

TriggerBehavior
ProactiveA request that finds the access token within 60 seconds of access_token_valid_until first refreshes it, then is sent with the new token.
ReactiveA 401 response triggers one refresh and one retry of the same request. A second 401 is raised as KSeFAuthError.
ConcurrencyRequests share a single refresh: a lock in Client, an asyncio.Lock in AsyncClient.
Other statuses403 and every other error are not refreshed.

One refresh is not a full re-login: the SDK replays the original request once with the refreshed token. If that replay gets another 401, the KSeFAuthError reaches the app, and the app decides whether to authenticate again or surface the failure.

auth.auth_tokens, auth.access_token and auth.resume_state() always return the current tokens, so persist resume_state() again after long-running work.

When the refresh token is expired, or KSeF rejects it, the request raises KSeFAuthenticationExpiredError, a subclass of KSeFAuthError. The only remedy is to authenticate again. If the refresh token is already expired but the access token still has time left, requests keep using the access token until KSeF rejects it. Transport failures and other errors raised by the refresh call propagate unchanged.

Refresh never applies to the one-shot authentication redemption or to presigned external-storage transfers (batch part uploads, export downloads). They use separate paths and carry no bearer token.

To manage tokens yourself, turn the behavior off. Expired tokens then surface as KSeFAuthError and client.authentication.refresh() stays available.

client = Client(Environment.PRODUCTION, transport_config=TransportConfig(auto_refresh_tokens=False))
python

Workflow polling timeouts

Polling helpers use timeout and poll_interval arguments. Those values are workflow deadlines, not HTTP request timeouts. When a polling timeout is raised, the remote KSeF workflow may still finish later.

WorkflowTimeout exceptionIdentifier carried by exception
Authentication pollingKSeFAuthPollingTimeoutErrorreference_number
Token activation/status pollingKSeFTokenStatusTimeoutErrorreference_number
Metadata visibility pollingKSeFInvoiceQueryTimeoutErrortimeout only
Direct invoice download readinessKSeFInvoiceDownloadTimeoutErrorksef_number
Online invoice processingKSeFInvoiceProcessingTimeoutErrorinvoice_reference_number
Export package readinessKSeFExportTimeoutErrorreference_number
Permission grant or revokeKSeFPermissionOperationTimeoutErrorreference_number
Certificate issuanceKSeFCertificateEnrollmentTimeoutErrorreference_number
Batch session completionKSeFBatchSessionTimeoutErrorreference_number
Online session completionKSeFOnlineSessionTimeoutErrorreference_number

Resume polling with stored identifiers after a timeout. Do not infer that the remote operation failed only because the local wait deadline expired.

Rate limits

KSeF 429 responses are classified as KSeFRateLimitError. The exception exposes:

AttributeMeaning
retry_afterSeconds from Retry-After (seconds or HTTP-date form) when KSeF returned the header; otherwise None.
status_codeAlways 429.
responseParsed KSeF error payload when available.

For a 429, the retry middleware honors Retry-After exactly when the value is at or below max_retry_after, sleeping and retrying up to max_attempts. When the header exceeds the ceiling, the middleware gives up immediately: no sleep, no retry, and the request fails with KSeFRateLimitError whose retry_after is the true header value. The ceiling bounds each sleep, so a repeated header can hold one request for (max_attempts - 1) * max_retry_after, which is 240 seconds with the defaults.

What the app still owns: a KSeFRateLimitError means the SDK already gave up, so schedule the work for later instead of retrying blindly. Use retry_after to schedule background work. In request handlers, prefer returning or enqueueing retryable work over sleeping inside the request.

Secret and logging boundaries

Do not log:

  • access tokens;
  • refresh tokens;
  • KSeF token values;
  • private keys;
  • PEM or PKCS#12 passwords;
  • raw invoice XML unless your retention policy explicitly allows it;
  • serialized online or batch session state.

Useful production log fields:

FieldMeaning
environmenttest, demo, or production.
workflowApplication-level operation name.
session_reference_numberOnline or batch session reference.
invoice_reference_numberPer-invoice session reference.
ksef_numberFinal KSeF invoice number after acceptance.
operation_reference_numberToken, permission, certificate, auth, or export operation reference.
sdk_error_codeKSeFException.context["code"] when present.
ksef_codeRaw KSeF error code from KSeFApiError.ksef_code when present.
trace_idKSeF trace ID from KSeFApiError.trace_id; quote it when contacting KSeF support.

Resumable workflow state

Most KSeF workflows start with a reference and finish through polling or later download. Store the reference before waiting.

WorkflowPersist before waiting
Authenticationauthentication operation reference and temporary authentication-token lifetime
Online invoice sendingsession reference and invoice reference number
Batch uploadbatch session reference, upload references, package metadata, and batch state while needed
Invoice exportexport reference number and protected export handle material
Token generationtoken reference number and returned token secret
Permission grants/revokespermission operation reference number
Certificate enrollment/revokecertificate operation reference or certificate serial number
  • Client lifecycle: Review constructors, branch ownership, close behavior, and lifecycle errors.
  • Error handling: Inspect SDK exception classes, KSeF API errors, and timeout handling.
  • Client setup: Apply these settings in runnable sync and async client setup examples.
  • Status and UPO: Understand status surfaces, UPO documents, polling, and local deadlines.