SDK quickstart
@mooneum/sdk is a typed TypeScript client generated directly from the server's OpenAPI document,
so its types always match the deployed API contract.
npm install @mooneum/sdkAuthenticate
import { MooneumClient, getClientCredentialsToken } from '@mooneum/sdk';
// With an API key (sk_…):
const client = new MooneumClient({
baseUrl: 'https://api.mooneum.com',
token: 'sk_…',
});
// …or with OAuth2 client credentials:
const { access_token } = await getClientCredentialsToken({
baseUrl: 'https://api.mooneum.com',
clientId: 'tc_…',
clientSecret: 'tcs_…',
scope: 'read write',
});
const client2 = new MooneumClient({
baseUrl: 'https://api.mooneum.com',
token: access_token,
});Every response carries an X-Correlation-Id — include it when reporting an issue.
Make a request
Write calls take an optional Idempotency-Key as their last argument — safe to retry the exact
same call (e.g. after a timeout) without double-submitting:
const portfolio = await client.getPortfolio();
const payment = await client.createPayment(
{ walletId, chain: 'ethereum', recipient: '0x…', amount: '0.5' },
crypto.randomUUID(), // Idempotency-Key
);
await client.submitPayment(payment.id);Paginate a list
List methods that can return a lot of rows take a cursor/limit and return a nextCursor to
pass into the next call — null once you've reached the end:
let cursor: string | undefined;
const allPayments = [];
do {
const page = await client.listPayments({ limit: 50, cursor });
allPayments.push(...page.items);
cursor = page.nextCursor ?? undefined;
} while (cursor);Handle errors
A non-2xx response throws TreasuryApiError — status is the HTTP status code, body is the
parsed JSON error response (when the server sent one):
import { TreasuryApiError } from '@mooneum/sdk';
try {
await client.createPayment({
walletId,
chain: 'ethereum',
recipient: '0x…',
amount: '0.5',
});
} catch (err) {
if (err instanceof TreasuryApiError && err.status === 429) {
// rate limited — respect Retry-After and retry
} else {
throw err;
}
}