# TypeScript SDK

Source: https://docs.settlemint.com/docs/developer-guides/api-integration/sdk
Install and use the @settlemint/dalp-sdk package for fully typed, auto-completed access to the DALP API from any TypeScript project.



The `@settlemint/dalp-sdk` package is the recommended way to interact with the DALP API from TypeScript. It provides a fully typed client with auto-complete for every API namespace — tokens, identities, compliance, transactions, and more — without code generation or OpenAPI tooling.

**Why use the SDK over the OpenAPI client?**

* **Zero code generation** — install the package and start calling methods immediately
* **Contract-first types** — auto-complete for every route, input, and output derived from the API contract
* **Custom serializers** — `BigInt`, `BigDecimal`, and `Timestamp` values serialize correctly out of the box
* **Opt-in client-side validation** — enable request validation to check outgoing requests against the API schema before sending
* **Tree-shakeable** — import only what you need; unused namespaces are removed at build time

***

## Installation [#installation]

```bash
# npm
npm install @settlemint/dalp-sdk

# bun
bun add @settlemint/dalp-sdk
```

**Peer dependency**: the SDK requires `zod >= 4.0.0`. Most projects already have it — if not, install it alongside the SDK.

***

## Create a client [#create-a-client]

```typescript
import { createDalpClient } from "@settlemint/dalp-sdk";

const dalp = createDalpClient({
  url: "https://your-platform.example.com",
  apiKey: "sm_dalp_xxxxxxxxxxxxxxxx",
});
```

That's it. `dalp` is now a fully typed client with auto-complete for every API namespace.

### Configuration options [#configuration-options]

| Option               | Type                                    | Default | Description                                                                                                      |
| -------------------- | --------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `url`                | `string`                                | —       | Base URL of your DALP deployment (e.g., `"https://dalp.example.com"`)                                            |
| `apiKey`             | `string`                                | —       | API key from the DALP dashboard (Settings → API Keys) or `dalp login`. Required for authenticated routes.        |
| `organizationId`     | `string`                                | —       | Organization ID for multi-org setups. Required when the key spans multiple organizations.                        |
| `headers`            | `Record<string, string>` or `() => ...` | —       | Additional headers merged into every request. Can override `User-Agent` but not security headers.                |
| `idempotencyKey`     | `string`                                | —       | Sent as `Idempotency-Key` header on **every** request. Only use for single-mutation clients (see warning below). |
| `requestValidation`  | `boolean`                               | `false` | Validate outgoing requests against the API contract before sending. Useful during development.                   |
| `responseValidation` | `boolean`                               | `false` | Validate incoming responses against the API contract. Useful during development.                                 |
| `fetch`              | `typeof globalThis.fetch`               | —       | Custom `fetch` implementation for proxies, logging, or test doubles.                                             |

### Authenticated and public clients [#authenticated-and-public-clients]

Pass an `apiKey` for authenticated routes. The SDK sends it as the `x-api-key` request header and trims surrounding whitespace before use.

You may omit `apiKey` when you only call public DALP API routes:

```typescript
const publicDalp = createDalpClient({
  url: "https://your-platform.example.com",
});
```

If you provide an empty or whitespace-only API key, the SDK raises a configuration error instead of sending an invalid credential. When `apiKey` is omitted, the SDK does not send the `x-api-key` header.

***

## Usage examples [#usage-examples]

### List tokens [#list-tokens]

```typescript
const tokens = await dalp.token.list({ query: {} });

for (const token of tokens.items) {
  console.log(token.name, token.symbol, token.tokenAddress);
}
```

### Get system info [#get-system-info]

```typescript
const system = await dalp.system.read({});

console.log("Platform:", system.name);
console.log("Version:", system.version);
```

### Create a token [#create-a-token]

```typescript
const token = await dalp.token.create({
  body: {
    name: "Acme Bond",
    symbol: "ABOND",
    assetType: "bond",
    decimals: 18,
  },
});

console.log("Created:", token.tokenAddress);
```

### Mint tokens [#mint-tokens]

```typescript
import { from as dnumFrom } from "dnum";

await dalp.token.mint({
  body: {
    tokenAddress: "0xABCD...",
    recipients: ["0x1234..."],
    amounts: [dnumFrom("1000", 18)],
  },
});
```

### Search [#search]

```typescript
const results = await dalp.search.query({
  query: { q: "Acme" },
});

for (const hit of results.items) {
  console.log(hit.type, hit.name);
}
```

***

## Type-only imports [#type-only-imports]

When you only need types for function signatures (not runtime code), import from the `/types` subpath to keep your bundle lean:

```typescript
import type { DalpClient, DalpClientConfig } from "@settlemint/dalp-sdk/types";

function createMyClient(config: DalpClientConfig): DalpClient {
  // ...
}
```

***

## Plugins [#plugins]

The SDK ships optional oRPC link plugins for advanced use cases:

```typescript
import { BatchLinkPlugin, RequestValidationPlugin } from "@settlemint/dalp-sdk/plugins";
```

These are re-exports from `@orpc/client` and `@orpc/contract` — use them if you need to customize the link pipeline beyond the defaults.

***

## Error handling [#error-handling]

The SDK uses oRPC's error model. All errors are instances of `ORPCError` with a `code` property:

```typescript
import { ORPCError } from "@orpc/client";
import { CUSTOM_ERROR_CODES } from "@settlemint/dalp-sdk";

try {
  await dalp.token.read({ query: { address: "0x0000..." } });
} catch (error) {
  if (error instanceof ORPCError) {
    if (error.code === "NOT_FOUND") {
      console.log("Token does not exist");
    } else if (error.code === CUSTOM_ERROR_CODES.USER_NOT_AUTHORIZED) {
      console.log("This operation requires elevated permissions");
    } else {
      throw error;
    }
  } else {
    throw error;
  }
}
```

For the complete list of error codes and handling strategies, see [Error handling](/docs/developer-guides/api-integration/error-handling).

***

## Using with the DALP CLI [#using-with-the-dalp-cli]

The DALP CLI uses the SDK internally. If you already have the CLI installed, you can reuse its authentication:

```bash
# Authenticate and get an API key
dalp login

# Show your credentials
dalp whoami --format json
```

Then use the API key from `dalp login` in your SDK client configuration.

***

## Next steps [#next-steps]

* **[API reference](/docs/developer-guides/api-integration/api-reference)** — explore all available endpoints and schemas
* **[Error handling](/docs/developer-guides/api-integration/error-handling)** — handle errors gracefully in production
* **[Token lifecycle](/docs/developer-guides/api-integration/token-lifecycle)** — understand the full token operation flow
* **[Asset decimals](/docs/developer-guides/api-integration/asset-decimals)** — work correctly with token precision and BigDecimal values
