Overview
A DALP client holds the instance URL, credential, and acting context for API calls. Use a session cookie in a browser and an API key on a server.
An API key grants the access allowed by its scope and the identity it belongs to. A key included in browser or app code is exposed to every user. The SDK rejects an API key on a client whose runtime is browser or react-native. It trusts the runtime you pass, so never set runtime: "server" in code that ships in a browser or app bundle.
Install
The SDK is published as @settlemint/dalp-sdk. It supports browser applications, server applications on a runtime version that the package's engines field accepts, and React Native apps that pass fetch from expo/fetch, which React Native covers.
Each DALP release publishes the SDK under the release's own version number. Install the release line that matches your instance's major and minor version:
npm install @settlemint/dalp-sdk@<major>.<minor>Replace <major>.<minor> with your instance's version, then set the range in package.json to ~<major>.<minor>.0 so a later install stays inside that minor version. An install with no version takes the latest tag, which moves to each tagged release as it is published, including a patch to an older release line, so it does not match your instance by itself. To list the published versions and read the engines field:
npm view @settlemint/dalp-sdk versions
npm view @settlemint/dalp-sdk enginesThe route surface is generated from the instance's own declaration, so a client from a later release knows about routes an older instance does not serve. Calling one fails when the call runs, not as a type error at build time.
The client these pages describe, with baseUrl and dalp.api, replaces the 3.1 client. An instance on DALP 3.1 takes the 3.1 client, and Migrate from SDK 3.1 to 3.2 maps one to the other.
Three peer dependencies are optional and none is installed for you. Add @tanstack/react-query only if you use the query factories. Add effect only if you use the Effect surface. Add zod only if you use the auth subpath, whose Better Auth client types reference it. A project that uses none of the three needs none of them installed, and the package imports no schema library at run time.
Construct a client
import { createDalpClient } from "@settlemint/dalp-sdk";
const dalp = createDalpClient({
baseUrl: process.env.DALP_API_URL!,
apiKey: process.env.DALP_API_KEY!,
runtime: "server",
});
const me = await dalp.api.party.users.me();createDalpClient returns six members. Three of them cover most code:
The other three dispatch by raw request parts rather than by flat arguments, for callers that assemble the path, query and body themselves: sendParts, streamParts and downloadParts. Each takes a route id and a params, query and body object, and downloadParts answers the response body as a stream of bytes.
Options
Choose the credential
Two credentials reach the Platform API.
Session cookie, in a browser
The user signed in and the browser holds the session. Construct the client with no credential at all. It sends the cookie because it runs on your origin. This is what the Console and the Investor portal do.
API key, on a server
A backend service, a scheduled job, a CLI. The key acts in one organisation, up to its read or read-write scope. Keep it in your infrastructure and send it only to your DALP instance.
In a browser
export const dalp = createDalpClient({
baseUrl: window.location.origin,
runtime: "browser",
});No credential is passed. The client sends credentials with each request, so a session cookie set on the page's own origin travels automatically, without an API key in the bundle. A baseUrl on another origin throws at construction, because the session cookie is host-only. Mount createDalpProxy on your app origin and keep baseUrl at window.location.origin.
Passing an apiKey here throws at construction with a configuration error that names the problem. The check runs at construction, so a key in a bundle fails when the client is built, before any request goes out.
If a key reaches a browser bundle, revoke it on the platform and replace it wherever it is used. Removing it from the next bundle does not invalidate copies already downloaded.
On a server
import { createDalpClient } from "@settlemint/dalp-sdk";
const dalp = createDalpClient({
baseUrl: process.env.DALP_API_URL!,
apiKey: process.env.DALP_API_KEY!,
runtime: "server",
});Read the key from the environment or a secret manager while the application runs. In Next.js, name the variable without the NEXT_PUBLIC_ prefix so the bundler cannot inline it into a client component. In Vite, keep it off the VITE_ prefix for the same reason. Create the key with the read or read-write scope the integration needs, as Authentication and API keys describes.
To keep the key out of stack traces and logs, wrap it:
import { createDalpClient, secret } from "@settlemint/dalp-sdk";
const dalp = createDalpClient({
baseUrl: process.env.DALP_API_URL!,
apiKey: secret(process.env.DALP_API_KEY!),
runtime: "server",
});A Secret prints as a redaction marker wherever something stringifies it, and the SDK unwraps it only at the moment it sets the header. This protects against accidental disclosure, not against an attacker: a thrown error whose message interpolates the config, a structured log that serialises it, or a crash reporter that captures locals. Each of these stringifies the value, so each prints the marker.
The acting context
Some requests also need an acting context, such as the network or the signing wallet. The SDK sends it as request headers. The organisation is not one of them: a session acts in its active organisation, which the auth client's organization.setActive call changes, and an API key in the organisation it was issued for.
const dalp = createDalpClient({
baseUrl,
runtime: "browser",
context: {
chainId: 137,
},
});The context is fixed for the life of the client. When it changes, for example because the user switched organisation, build a new client and discard the old one. If you keep the old client, clear its held response tags, because a version tag from the old organisation means nothing under the new one:
dalp.conditionalRequests.clear();The client also drops its held responses on its own when the X-Organization-Id or X-Participant header of a request differs from the previous request, so a client that forwards a tenant header per call never answers one tenant with another tenant's held body.
A single call can add headers of its own without rebuilding anything. See Per-call options.
Sign in and manage sessions
createDalpClient calls Platform API routes. Sign-in, sessions, organisations, invitations, API keys, passkeys, two-factor codes, and wallet verification go through a second client from the @settlemint/ entry. The entry is separate because it loads the authentication library, which code that only calls routes does not need.
import { createDalpAuthClient } from "@settlemint/dalp-sdk/auth";
const auth = await createDalpAuthClient({ url: "https://your-instance.example.com" });
const session = await auth.getSession();createDalpAuthClient is asynchronous and takes url, not baseUrl. Every operation resolves to { data, error } and does not throw for a refused request, so check error before you read data.
The client takes one credential source: an API key, a cookie header in cookie, or a cookieStore. It rejects an API key together with a cookie header or with a cookie store that already holds cookies, and a browser or React Native client rejects an API key, as createDalpClient does. With no source, it creates an in-memory cookie store, so the session lasts as long as that client. It also takes authSurface, extra headers that cannot replace the credential headers, fetch, runtime, and a passkey ceremony, and it has no organisation option: it signs in to the organisation the session's active organisation names, and organization.setActive changes that. A configuration it cannot accept rejects with a DalpSdkError.
With an API key, the auth client reaches only the nine routes that Authentication and API keys lists, such as the session, organisation and key lookups. Every other auth route answers 403 API_, so sign-in, key creation and passkey registration need a session.
The auth client does not share its held responses with createDalpClient. After you sign out or switch organisation through the auth client, call dalp. on the route client.
Verify the setup
Check the setup with a read that needs only authentication:
const me = await dalp.api.party.users.me();
console.log(me.data.id);A DalpApiError with status 401 means the credential did not arrive or the platform did not accept it. In a browser, the session is missing or expired. On a server, the key is absent or not valid. Status 403 means the platform accepted the credential and refused the request. That can be a role question, a read key on a write route, or a missing acting context such as no active organisation. Read error.id to tell them apart. Errors covers the other failures.
Next
Route calls, paging, and what comes back: Calling routes.