Skip to content

AssetPay TypeScript SDK

By AssetPayUpdated Read as Markdown

@assetpay/assetpay-sdk is the official TypeScript SDK for the AssetPay API. It gives a Node.js backend typed methods for every public endpoint: CS2 and Rust skin deposits and withdrawals, crypto cashouts, wallet and ledger reads, and the webhook verification your settlement depends on. It is open source under the MIT license, developed on GitHub and published on npm.

The REST API is still the contract, and anything that can send an HTTPS request can integrate without the SDK. The SDK exists for the parts that are easy to get wrong by hand: retrying a request that moves money, keeping client tokens fresh, and verifying a signed webhook against the raw body.

Install

npm install @assetpay/assetpay-sdk

It needs Node.js 22.19 or newer and has one runtime dependency. The package is ESM, and CommonJS projects can require() it on the same Node versions. pnpm, yarn and bun install it the same way.

Quickstart: a CS2 skin deposit

Create one client with your API key and secret, then scope it to the Steam user who is depositing. The SDK mints that user's client token locally, so there is no extra request per user.

import { AssetPay } from '@assetpay/assetpay-sdk';

const ap = new AssetPay({
  apiKey: process.env.ASSETPAY_API_KEY!,
  apiSecret: process.env.ASSETPAY_API_SECRET,
  merchantId: process.env.ASSETPAY_MERCHANT_ID,
});

const user = ap.asClient({ steamId: account.steamId, tradeUrl: account.tradeUrl });

const { inventory } = await user.inventory.get({ game: 730 });
const trade = await user.trades.deposit({
  items: [{ itemId: inventory[0].id, price: inventory[0].offer!.price }],
  externalId: `deposit-${order.id}`,
});

Rust works the same way with game: 252490. Point baseUrl at https://api-staging.assetpay.gg to run the same code against staging.

What the SDK handles for you

  • Both scopes from one client. Merchant calls use your API key. ap.asClient() returns the same modules scoped to one Steam user, for the whitelabel checkout flow where your users deposit and cash out inside your UI.
  • Client tokens. Minted from your API secret, renewed before they expire, and reissued once if the API refuses one. Identities are validated before a token is made, and ap.mintClientToken() hands one to your frontend.
  • Retries that never double-spend. Reads retry freely. Deposits, sells, buys and withdrawals retry only when the failure proves nothing was sent. When the outcome is uncertain the error says so (ambiguous: true), and the reconcile option settles it through your externalId.
  • Webhook verification. verifyWebhook checks the HMAC-SHA256 signature over the raw body, rejects replays, accepts both secrets during a rotation and tells trade events apart from withdrawal approvals. It ships as its own entry point with no HTTP dependency, so a webhook-only service stays small.
  • Typed errors. Every failure is an AssetPayError with a stable key, the HTTP status, field-level validation messages and the requestId to quote to support.
  • Pagination. for await iterators over trades, crypto deposits and ledger transactions, each following that endpoint's own cursor style.
  • Socket.IO events. @assetpay/assetpay-sdk/realtime streams trade, deposit and market updates, with reconnects handled. socket.io-client is an optional peer, installed only if you use it.

Verify webhooks and approve withdrawals

Every state change is posted to your callback URL and signed with your API secret. Withdrawals also ask your backend for approval before anything ships, and a plain 200 counts as a yes, so approvals must be answered explicitly. A complete Express handler:

import express from 'express';
import { approve, isCallbackTest, reject, verifyWebhook } from '@assetpay/assetpay-sdk/webhooks';

app.post('/webhooks/assetpay', express.raw({ type: 'application/json' }), async (req, res) => {
  if (isCallbackTest(req.body, req.headers)) return res.sendStatus(200);

  let event;
  try {
    event = verifyWebhook(req.body, req.headers, { secret: process.env.ASSETPAY_API_SECRET! });
  } catch {
    return res.sendStatus(401);
  }

  if (event.type === 'withdraw.approval' || event.type === 'crypto_withdraw.approval') {
    const verdict = (await canPay(event)) ? approve() : reject('insufficient balance');
    return res.status(verdict.status).json(verdict.body);
  }

  if (!(await alreadyHandled(event.dedupeKey))) await apply(event);
  res.sendStatus(200);
});

The README has the same handler for Fastify and the Next.js App Router, the deduplication rules and the approval timeouts.

SDK or plain REST?

TypeScript SDKREST API
LanguagesTypeScript and JavaScript on Node.jsAny language with HTTPS
Client tokensMinted and refreshed for youYou call /auth/authenticate-client
RetriesDecided per endpoint, never duplicates a tradeYours to design
Webhook verificationOne call, rotation includedHMAC code you write and test
TypesEvery request and responseFrom the OpenAPI description

Both hit the same endpoints with the same credentials, so you can start with the SDK and drop to ap.raw for anything it does not wrap yet. For another language, generate a client from the OpenAPI 3.1 description or follow the API walkthrough.

Frequently asked questions

Is there an official AssetPay SDK?

Yes. @assetpay/assetpay-sdk is the official TypeScript SDK, maintained by the AssetPay team, open source under the MIT license on GitHub and published on npm.

Which languages does the SDK support?

TypeScript and JavaScript on Node.js 22.19 or newer. Every other language integrates against the REST API directly; the docs cover every endpoint, and the OpenAPI description generates a typed client for most stacks.

Can I use the SDK in the browser?

No, by design. It holds your API key and secret, which must never reach a browser. To let your frontend call the end-user endpoints, mint a client token on your server with ap.mintClientToken() and pass that token to the page.

Does it work with Next.js, Express, Fastify and NestJS?

Yes. It runs in any Node.js server. The only thing webhook verification needs from your framework is the raw request body, and the README has the recipe for Express, Fastify and the Next.js App Router.

Does the SDK cost anything?

No. It is free and MIT licensed. AssetPay charges one fee per cleared trade and nothing else, as described on the pricing page.

Where do I report a bug or ask for a feature?

Open an issue on GitHub, or reach the team on Discord.


Ready to build? Install @assetpay/assetpay-sdk, create a merchant account for your API key, and read the CS2 skin payment gateway page for how deposits settle.