Start here
Getting started
Record a referral and its first paid order. This walkthrough uses a CAD program that pays the partner 5% of the amount your server reports. Use a separate company for these example records. Live requests create real records and rewards.
Create your company
Open Grizzlee, which starts on Create account, and verify your email. Sign in and enter your company name and currency on Tell us about your company, then check the box that accepts the terms of service. This example uses CAD. An account belongs to one company. A business with several shops is one company with several loyalty locations.
Get your keys
Open Developers in the dashboard sidebar. Under Server API keys, choose New API key, set Access to Custom and select read, programs:write, partners:write and events:write. Copy the full secret when Grizzlee displays it. You cannot read it again. Save it as GRIZZLEE_SERVER_KEY on your backend.
For website capture, use the tracking key called Default under Website and mobile tracking on the same tab. Grizzlee creates it with the company. Choose Edit to copy its publishable key and add the exact origin of your website, such as https://shop.example.com. The key captures nothing until it has an origin or native capture. A native app also needs native capture enabled.
Server keys authorize financial operations. Keep them out of browsers, mobile apps, public repositories and logs. Publishable keys only capture referrals. The company comes from the key, so requests never need a company or company ID.
Choose your client
For Node.js 22 or later, install the SDK:
npm install @grizzlee/sdkCreate a client on your server:
import { GrizzleeServerClient } from "@grizzlee/sdk";
const grizzlee = new GrizzleeServerClient({
baseUrl: "https://app.grizzlee.ca",
apiKey: process.env.GRIZZLEE_SERVER_KEY!,
});PHP, Python, Ruby and other backends can call the same HTTP API. Set your key in the terminal without committing it to a script:
export GRIZZLEE_SERVER_KEY='REPLACE_WITH_YOUR_SERVER_KEY'
export GRIZZLEE_API='https://app.grizzlee.ca/api/v1'HTTP success responses wrap the result in data. The SDK returns that result directly. Choose the SDK examples or the cURL examples below. Running both creates another program.
Create a program
const program = await grizzlee.createProgram({
name: "First purchase referrals",
kind: "referral",
destinationUrl: "https://shop.example.com/",
compensation: { type: "percentage", rateBps: 500 },
duration: { type: "first_order" },
rewardType: "cash",
delivery: { cash: "merchant" },
attributionWindowDays: 30,
reviewRewards: true,
active: true,
});curl --fail-with-body "$GRIZZLEE_API/programs" \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY" \
-H 'Content-Type: application/json' \
--data '{"name":"First purchase referrals","kind":"referral","destinationUrl":"https://shop.example.com/","compensation":{"type":"percentage","rateBps":500},"duration":{"type":"first_order"},"rewardType":"cash","delivery":{"cash":"merchant"},"attributionWindowDays":30,"reviewRewards":true,"active":true}'Copy data.id from the HTTP response and set GRIZZLEE_PROGRAM_ID to that ID. The SDK example keeps it as program.id. 500 basis points is 5%. Rewards wait for approval, and your business delivers them after approval. The program uses the company currency. Partner referral links open destinationUrl.
Register a partner
A partner is the person or business that earns the reward. Use your own stable partner ID as externalId. Link the partner's own customer account with customerIds so Grizzlee can detect self-referral.
const partner = await grizzlee.registerPartner({
externalId: "example-partner-001",
customerIds: ["example-partner-customer-001"],
name: "Example Partner",
email: "partner@example.com",
addProgramIds: [program.id],
});export GRIZZLEE_PROGRAM_ID='REPLACE_WITH_PROGRAM_ID'
curl --fail-with-body "$GRIZZLEE_API/partners" \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY" \
-H 'Content-Type: application/json' \
--data "{\"externalId\":\"example-partner-001\",\"customerIds\":[\"example-partner-customer-001\"],\"name\":\"Example Partner\",\"email\":\"partner@example.com\",\"addProgramIds\":[\"$GRIZZLEE_PROGRAM_ID\"]}"Copy data.referralCode and set GRIZZLEE_REFERRAL_CODE to it. The partner must belong to the program to earn its rewards.
addProgramIds preserves other enrollments when you repeat this request. Remove one program with removeProgramIds. programIds replaces the whole list, so do not use it in a sync that runs alongside dashboard or placement enrollment. Do not combine it with additions or removals. See partner enrollment rules.
Record your first referral
This first request attaches a partner code on your backend. Your backend chooses customerId from its authenticated customer account. Use a customer different from the partner.
await grizzlee.attachReferralCode({
programId: program.id,
referralCode: partner.referralCode,
customerId: "example-customer-001",
channel: "coupon",
});export GRIZZLEE_REFERRAL_CODE='REPLACE_WITH_REFERRAL_CODE'
curl --fail-with-body "$GRIZZLEE_API/referrals/code" \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY" \
-H 'Content-Type: application/json' \
--data "{\"programId\":\"$GRIZZLEE_PROGRAM_ID\",\"referralCode\":\"$GRIZZLEE_REFERRAL_CODE\",\"customerId\":\"example-customer-001\",\"channel\":\"coupon\"}"The response includes a signed receipt and the attribution for this customer program. A referral alone does not earn a reward.
Record your first order
Send this after your server confirms a successful payment. Money uses integer minor units. 10000 is CAD $100.00. Take payment amounts from your payment provider or order database.
const event = {
type: "order.completed" as const,
eventId: "example-payment-001",
orderId: "example-order-001",
customerId: "example-customer-001",
newCustomer: true, // your server checks its own history before saving the order
currency: "CAD" as const,
commissionableCents: 10000,
totalCents: 10000,
occurredAt: new Date().toISOString(),
};
const result = await grizzlee.completeOrder(event);
console.log(result);export GRIZZLEE_OCCURRED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
curl --fail-with-body "$GRIZZLEE_API/orders/complete" \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY" \
-H 'Content-Type: application/json' \
--data "{\"event\":{\"type\":\"order.completed\",\"eventId\":\"example-payment-001\",\"orderId\":\"example-order-001\",\"customerId\":\"example-customer-001\",\"newCustomer\":true,\"currency\":\"CAD\",\"commissionableCents\":10000,\"totalCents\":10000,\"occurredAt\":\"$GRIZZLEE_OCCURRED_AT\"}}"Keep the original event ID and the entire payload, including occurredAt, when retrying. A repeated ID with changed instructions returns HTTP 409. Send newCustomer from your server's order history on each referred order, and skip unrelated orders and past purchase imports. Include placed but unpaid orders in that history check, and save the answer with the order. If you omit the field, report every paid order and import prior purchases so Grizzlee can determine newness.
Check the result
const company = await grizzlee.getCompany();
console.log(company.rewards);curl --fail-with-body "$GRIZZLEE_API/company" \
-H "Authorization: Bearer $GRIZZLEE_SERVER_KEY"Open Commissions in the dashboard. The example order should have a pending CAD $5.00 reward for your partner. Its amount is 500 minor units. Check the decision in the order result if no reward appears. You can inspect and approve rewards in the dashboard. Merchant delivery is a separate step after your business pays the partner. See reward delivery.
Capture website links
If checkout runs on Stripe Payment Links, a Stripe pricing table or buy button, or a Shopify store, the script tag is enough. Add your site's origin to the tracking key, then paste this into the <head> of every page. Developers shows it with your key when you edit the tracking key.
<script
src="https://app.grizzlee.ca/js/grizzlee.js"
data-key="grizzlee_pub_REPLACE_WITH_YOUR_PUBLISHABLE_KEY"
async
></script>It captures the link, stores the receipt where the SDK would, and adds the checkout reference to Stripe Payment Links, pricing tables, buy buttons and the Shopify cart. The Stripe or Shopify connection still reports the payment, so connect it under Settings, then Connections. Subscriptions need invoice recording on the Stripe connection. Stripe Checkout that your server creates still needs your server to pass the reference. See the script tag for each checkout path and its limits.
With your own checkout, use the SDK instead. For links and QR codes, generate a link on your server and send it to the partner:
import { createReferralLink } from "@grizzlee/sdk/links";
const link = createReferralLink({
destination: "https://shop.example.com/",
programId: program.id,
referralCode: partner.referralCode,
channel: "link",
});On the website, use the publishable key:
import { GrizzleeTrackingClient } from "@grizzlee/sdk/tracking";
const tracking = new GrizzleeTrackingClient({
baseUrl: "https://app.grizzlee.ca",
publishableKey: "REPLACE_WITH_YOUR_PUBLISHABLE_KEY",
storage: window.localStorage,
});
await tracking.captureFromUrl(window.location.href);
const receipt = await tracking.receipt(programId);
// Send receipt?.receipt to your backend with the customer's checkout.Your backend saves the receipt with the checkout. After payment, it calls completeOrder(event, { candidates: [{ type: "receipt", receipt: savedReceipt }] }). In HTTP, add candidates beside event in the /orders/complete body. That call claims the referral and records the order together. It needs both events:write and partners:write.
After your backend accepts the order, call tracking.forgetAfterOrder(programId, receipt.receipt) when a receipt was used. See integrations, mobile apps, and the HTTP reference for the rest of the integration.
Loyalty cards
Stamp and points cards use separate records and console operations. See loyalty cards for the model and the merchant guide for card setup.