Menu
Documentation
Getting started Quickstart

Quickstart

Accept your first exact allocation, replay it safely, and read its status.

Connect from your backend, issue one reward, and read it back. This guide stops at API acceptance; your operator's approval and the transfer from their wallet are asynchronous operations.

Before you start#

Obtain an environment-specific API base URL, a scoped server API key, an approved campaign ID, and a recipient wallet authorized for that environment. Confirm the campaign's token, decimals, per-grant limit, and available issuance capacity.

Run examples in an isolated development environment first. The sample wallet is not a destination for real funds.

1. Install the SDK supplied for your integration#

Follow Install. Configure these variables in your server environment:

dotenv
SLICES_BASE_URL=http://localhost:3000
SLICES_API_KEY=
SLICES_CAMPAIGN_ID=cmp_pilot001
SLICES_RECIPIENT_WALLET=0x0000000000000000000000000000000000001001

The local URL and IDs above are examples. Set the actual approved values for your environment. Use HTTPS outside loopback development. Never expose the key through a public environment-variable prefix.

2. Create the server client#

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

function requiredEnv(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Missing ${name}`);
  return value;
}

const slices = new Slices({
  apiKey: requiredEnv("SLICES_API_KEY"),
  baseUrl: requiredEnv("SLICES_BASE_URL"),
});

3. Check the campaign, then submit an allocation#

ts
const campaignId = requiredEnv("SLICES_CAMPAIGN_ID");
const campaign = await slices.campaigns.get(campaignId);

if (campaign.status !== "active" || campaign.issuanceMode === "disabled") {
  throw new Error("Campaign is not accepting new rewards");
}

// Local example only: 1 TST with six decimal places.
if (campaign.asset.chainId !== 31337 || campaign.asset.decimals !== 6) {
  throw new Error("This example requires the local six-decimal test profile");
}

const instruction = {
  campaignId,
  recipient: { walletAddress: requiredEnv("SLICES_RECIPIENT_WALLET") },
  amountBaseUnits: "1000000",
  event: { id: "referral_0182", type: "referral.qualified" },
  idempotencyKey: "referral_0182",
};

const reward = await slices.rewards.issue(instruction);
console.log(reward.id, reward.status, reward.payoutCampaignId);

Your application should persist the original instruction and stable idempotency key before sending it. Store the returned reward ID against the same business event. See Idempotency for crash recovery.

The SDK returns the resource directly. The HTTP API wraps it in { "data": ... }.

4. Replay without issuing twice#

ts
const replay = await slices.rewards.issue(instruction);
if (replay.id !== reward.id) throw new Error("Unexpected reward identity");

An identical replay returns the original reward's current state. It can be further along than the first response. Do not change the amount, recipient, or event while reusing the same key.

5. Read the reward#

ts
const current = await slices.rewards.get(reward.id);
console.log({
  status: current.status,
  recipient: current.recipient.verificationStatus,
  verificationUrl: current.recipient.verificationUrl,
  transaction: current.deliveryEvidence?.transactionHash ?? null,
  confirmations: current.deliveryEvidence?.confirmations ?? null,
});

Do not hold the original HTTP request open until delivery. Use scheduled status tracking instead.

What happens next?#

Once the recipient has verified their wallet, the grant is queued into your open draft campaign. Your operator reviews the draft in the dashboard, signs one approval over the exact allocation, and their wallet sends each transfer; a job verifies every receipt against the chain before a reward is delivered. See Approval and sending.

Next: Grant a reward, Reward states, and Testing your integration.