> ## Documentation Index
> Fetch the complete documentation index at: https://facturas-sdk.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure the facturas Client: Env Vars and Options

> Set required environment variables and pass optional client options to createArcaClient() to control timeouts, retries, logging, and WSAA sessions.

`createArcaClient()` discovers its credentials and settings from environment variables first, then merges any explicit options you pass — explicit values always win. You can run a single-process script with nothing but four environment variables, or override every field programmatically for multi-tenant or serverless deployments.

## Required environment variables

Set these four variables before your process starts. If any are missing and you haven't supplied them as options, `createArcaClient()` throws `ArcaConfigurationError` immediately.

| Variable               | Description                             |
| ---------------------- | --------------------------------------- |
| `ARCA_TAX_ID`          | Your 11-digit CUIT (e.g. `20123456786`) |
| `ARCA_CERTIFICATE_PEM` | Your PEM-encoded AFIP certificate       |
| `ARCA_PRIVATE_KEY_PEM` | Your PEM-encoded private key            |
| `ARCA_ENVIRONMENT`     | `test` or `production` — **no default** |

<Warning>
  `ARCA_ENVIRONMENT` has no default value. Omitting it — whether from `.env`, your platform's secrets manager, or the options object — causes `createArcaClient()` to throw immediately. This is intentional: the SDK will never silently fall through to production.
</Warning>

## Optional environment variable

| Variable         | Values                                 | Description                                                              |
| ---------------- | -------------------------------------- | ------------------------------------------------------------------------ |
| `ARCA_LOG_LEVEL` | `debug` \| `info` \| `warn` \| `error` | Minimum log level for the built-in structured logger. Default is `warn`. |

Use `ARCA_LOG_LEVEL=debug` to log SOAP requests and responses, response times, WSAA ticket origin (`cached` or `fresh`), and transport retries — without touching your code.

## `createArcaClient()` options

All fields are optional when the corresponding environment variable is set. Pass an options object to override env vars, configure timeouts and retries, attach a custom logger, or connect a persistence store.

<ParamField body="taxId" type="string">
  Your 11-digit CUIT. Falls back to `ARCA_TAX_ID`.
</ParamField>

<ParamField body="certificatePem" type="string">
  PEM-encoded AFIP certificate. Falls back to `ARCA_CERTIFICATE_PEM`.
</ParamField>

<ParamField body="privateKeyPem" type="string">
  PEM-encoded private key matching your certificate. Falls back to `ARCA_PRIVATE_KEY_PEM`.
</ParamField>

<ParamField body="environment" type="&#x22;test&#x22; | &#x22;production&#x22;">
  Target ARCA environment. Falls back to `ARCA_ENVIRONMENT`. No default — must be explicit on at least one side.
</ParamField>

<ParamField body="timeout" type="number" default="30000">
  HTTP request timeout in milliseconds.
</ParamField>

<ParamField body="retries" type="number" default="0">
  Number of additional attempts on transport failures (`ArcaTransportError` only — network errors, connection drops, non-XML HTTP error responses). SOAP faults and ARCA business rejections are never retried automatically.
</ParamField>

<ParamField body="retryDelay" type="number" default="500">
  Milliseconds to wait between transport retry attempts.
</ParamField>

<ParamField body="logger" type="ArcaLoggerConfig">
  Custom logger configuration. Pass `{ level: "debug" }` to enable verbose logging to the built-in sink, or supply a `log(level, message, ...args)` function to route entries to your own logger. Disable all logging with `{ disabled: true }`.
</ParamField>

<ParamField body="store" type="ArcaStore">
  A persistence store for voucher idempotency keys and WSAA session tickets. Providing a store automatically enables durable WSAA ticket caching. See [Stores](/guides/stores) for adapter options.
</ParamField>

<ParamField body="wsaaSessionStore" type="ArcaWsaaSessionStore">
  An explicit store for WSAA login tickets only. Takes priority over the unified `store` for ticket caching. Use this in multi-worker or serverless deployments where multiple processes might request tokens concurrently.
</ParamField>

## Configuration examples

<CodeGroup>
  ```typescript Environment variables only theme={null}
  import { createArcaClient } from "facturas";

  // ARCA_TAX_ID, ARCA_CERTIFICATE_PEM, ARCA_PRIVATE_KEY_PEM, ARCA_ENVIRONMENT
  // are all read from process.env automatically.
  const arca = createArcaClient();
  ```

  ```typescript Programmatic configuration theme={null}
  import { createArcaClient } from "facturas";

  const arca = createArcaClient({
    taxId: "20123456786",
    certificatePem: process.env.ARCA_CERTIFICATE_PEM!,
    privateKeyPem: process.env.ARCA_PRIVATE_KEY_PEM!,
    environment: "production",
    timeout: 30_000,
    retries: 2,
    retryDelay: 500,
    logger: { level: "info" },
  });
  ```

  ```typescript Custom logger sink theme={null}
  import { createArcaClient } from "facturas";

  const arca = createArcaClient({
    taxId: "20123456786",
    certificatePem: process.env.ARCA_CERTIFICATE_PEM!,
    privateKeyPem: process.env.ARCA_PRIVATE_KEY_PEM!,
    environment: "production",
    logger: {
      level: "info",
      log(level, message, ...args) {
        // Forward to your own logging infrastructure (e.g. Pino, Winston).
        myLogger[level](message, ...args);
      },
    },
  });
  ```
</CodeGroup>

## WSAA session caching

Every call to WSFE or WSMTXCA requires a valid WSAA login ticket. By default, the SDK caches these tickets in memory for the lifetime of the current process — no configuration needed for single-process applications.

<Note>
  The in-memory WSAA cache does not survive process restarts and cannot be shared across workers. In serverless functions, container replicas, or queue workers, each cold start fetches a new ticket independently. Configure a `store` or an explicit `wsaaSessionStore` so that warm processes can reuse valid tickets obtained by their peers.
</Note>

To share tickets across processes, pass either a unified `store` (which provides ticket caching automatically) or a dedicated `wsaaSessionStore`. The `wsaaSessionStore` interface supports an optional `withLock` method to serialize concurrent cold-start refreshes and avoid thundering-herd token requests:

```typescript theme={null}
import {
  type ArcaAuthCredentials,
  type ArcaWsaaSessionKey,
  createArcaClient,
} from "facturas";

const wsaaSessionStore = {
  async get(key: ArcaWsaaSessionKey): Promise<ArcaAuthCredentials | null> {
    // Read from your shared store (Postgres, Redis, etc.).
    return null;
  },
  async set(
    key: ArcaWsaaSessionKey,
    credentials: ArcaAuthCredentials
  ): Promise<void> {
    // Persist token, sign, and expiresAt for the given key.
  },
  async withLock<T>(
    key: ArcaWsaaSessionKey,
    fn: () => Promise<T>
  ): Promise<T> {
    // Serialize concurrent refreshes with an advisory lock or Redis lock.
    return await fn();
  },
};

const arca = createArcaClient({
  taxId: "20123456786",
  certificatePem: process.env.ARCA_CERTIFICATE_PEM!,
  privateKeyPem: process.env.ARCA_PRIVATE_KEY_PEM!,
  environment: "production",
  wsaaSessionStore,
});
```

The session store key is scoped by environment, WSAA service, and certificate fingerprint. The SDK still enforces its own expiry margin on every read, so a stale ticket in the store is refreshed transparently.

For testing and local coordination, the package also exports `createMemoryWsaaSessionStore()` as a shared in-process alternative.

## Retries and timeouts

Transport retries apply only to `ArcaTransportError`: connection failures, request timeouts, and HTTP error responses that are not valid XML. SOAP faults (returned as XML with HTTP 500) and ARCA business rejections are parsed and surfaced as typed errors — they are never silently retried.

WSFE and WSMTXCA convenience operations make exactly one authorization attempt per call. If that attempt encounters an `ArcaAuthenticationError`, the SDK performs one additional try with a forced token refresh. No other error type triggers the auth-recovery path.
