

# Safe SDK [#safe-sdk]

Use the safe SDK when expected failures should be returned as values instead of
rejected Promises.

## Call `TaxKit.safe.calculate` [#call-taxkitsafecalculate]

```ts
import { Cents, aud } from "@taxkit/core/primitives";
import { TaxKit } from "@taxkit/sdk";
import { au } from "@taxkit/sdk/au";

const result = await TaxKit.safe.calculate(au.calculations.annualIncomeTax, {
  taxableIncome: aud(Cents.make(9_000_000)),
});

if (result._tag === "TaxKitSuccess") {
  console.log(result.value.liability.cents);
}

if (result._tag === "TaxKitFailure") {
  console.error(result.error._tag);
}
```

The result is either `TaxKitSuccess` with the calculator report or
`TaxKitFailure` with an SDK-owned error value.

## Call AU safe helpers [#call-au-safe-helpers]

```ts
import { Cents, aud } from "@taxkit/core/primitives";
import { au } from "@taxkit/sdk/au";

const result = await au.incomeTax.safe.annual({
  taxableIncome: aud(Cents.make(9_000_000)),
});
```

## When to use it [#when-to-use-it]

Use the safe facade when your application already models expected failures as
data, or when you want to handle schema decode errors in the same branch as
calculation failures. A client that has been closed returns `TaxKitFailure` with
`TaxKitClientDisposedError` in `result.error.error`. Await `client.dispose()` when
finished; the [Plain SDK](/sdk/plain-sdk) shows a `try`/`finally` example.

Use `TaxKit.calculate` when rejected Promises fit your existing control flow.

## Related pages [#related-pages]

* [Plain SDK](/sdk/plain-sdk)
* [Schemas](/sdk/schemas)
* [Type safety](/sdk/type-safety)
