Menu
Documentation
Integration guides TypeScript SDK

TypeScript SDK

Use the thin server client for the partner payout HTTP API.

The SDK is a typed server client. It does not calculate rewards, verify events, manage wallets, hold funds, or send a transfer from your application.

The package is @slicesmoney/sdk on npm (see Install). The examples below define the v1 client interface; the HTTP contract remains the wire-format authority.

Initialize#

ts
import { Slices } from "@slicesmoney/sdk";

const apiKey = process.env.SLICES_API_KEY;
const baseUrl = process.env.SLICES_BASE_URL;
if (!apiKey || !baseUrl) throw new Error("Missing Slices configuration");

const slices = new Slices({
  apiKey,
  baseUrl,
  timeoutMs: 10_000,
  maxRetries: 2,
});
OptionRequiredMeaning
apiKeyYesProject/environment-scoped server credential.
baseUrlYesApproved service origin, without /v1; remote origins require HTTPS.
timeoutMsNoPositive per-attempt network timeout in milliseconds. Default 10000.
maxRetriesNoMaximum retries after the initial attempt; 0 disables automatic retries. Default 2.

The explicit timeout and retry values above are the package's defaults, written out as example client choices; they are not API latency commitments.

Methods#

MethodResultHTTP operation
rewards.issue(input, options?)RewardPOST /v1/rewards
rewards.get(rewardId, options?)RewardGET /v1/rewards/{rewardId}
rewards.list(query?, options?)Page<Reward>GET /v1/rewards
rewards.cancel(rewardId, input, options?)RewardPOST /v1/rewards/{rewardId}/cancel
campaigns.get(campaignId, options?)CampaignGET /v1/campaigns/{campaignId}
campaigns.list(query?, options?)Page<Campaign>GET /v1/campaigns
events.track(input, options?)RewardPOST /v1/rewards

All methods are asynchronous. Resource methods unwrap the HTTP {data: resource} envelope. List methods keep {data: resource[], nextCursor} intact. events.track() is rewards.issue() for a business event: its amountBaseUnits is optional, and when it is omitted the campaign's reward rule for event.type supplies the amount.

Issue#

ts
const reward = await slices.rewards.issue({
  campaignId: "cmp_pilot001",
  recipient: { walletAddress: "0x0000000000000000000000000000000000001001" },
  amountBaseUnits: "1000000",
  event: { id: "referral_0182", type: "referral.qualified" },
  idempotencyKey: "referral_0182",
});

These are local synthetic values. idempotencyKey becomes the HTTP header, not a JSON body field. The caller creates and persists the key; the SDK must not generate a replacement after a timeout.

List and paginate#

ts
let cursor: string | undefined;
do {
  const page = await slices.rewards.list({
    campaignId: "cmp_pilot001",
    status: "accepted",
    limit: 50,
    ...(cursor ? { cursor } : {}),
  });
  for (const reward of page.data) {
    console.log(reward.id, reward.amountBaseUnits);
  }
  cursor = page.nextCursor ?? undefined;
} while (cursor);

Keep filters unchanged while following a cursor. Lists are not a change stream or historical snapshot; see List rewards.

Cancel#

ts
await slices.rewards.cancel("rwd_demo0001", {
  reason: "Partner eligibility correction before approval",
  idempotencyKey: "cancel_referral_0182",
});

An approved reward cannot be cancelled. See Cancel a reward.

Cancellation and timeouts#

Each method accepts a second options argument containing signal; cancellation places that options argument third because its request input is second.

ts
const controller = new AbortController();
const deadline = setTimeout(() => controller.abort(), 5_000);
try {
  const campaign = await slices.campaigns.get("cmp_pilot001", {
    signal: controller.signal,
  });
  console.log(campaign.id);
} finally {
  clearTimeout(deadline);
}

An abort stops local waiting, including retry backoff. It does not retract a request already committed by the server or cancel a reward.

Errors and retries#

API error responses are exposed as SlicesApiError with status, code, requestId, and optional existingRewardId. Network and local-abort failures may not have a server request ID.

ts
import { SlicesApiError } from "@slicesmoney/sdk";

try {
  await slices.rewards.get("rwd_demo0001");
} catch (error) {
  if (error instanceof SlicesApiError) {
    console.error(error.code, error.requestId);
  }
  throw error;
}

Transient network errors and 429, 502, 503, or 504 responses can be retried within the configured bounds. Writes retain exactly the same key and semantic request. Authorization, validation, and conflict errors are not automatically retried. Do not assume an arbitrary 500 means the write was not committed.

The package exports generated resource and request types. It must preserve quantity strings and remain installable outside the product monorepo.

Related: Install, Idempotency, and Errors.