---
title: "Node SDK"
source: https://docs.myappaffiliate.com/sdk-node
docs: "MyAppAffiliate — Developer Documentation"
index: https://docs.myappaffiliate.com/llms.txt
---
# Node SDK

Server-side companion for web backends: record the signup → attribution binding on
your server, instead of (or in addition to) the browser. Pairs with any billing
provider — see the [Web SaaS guide](https://docs.myappaffiliate.com/web-saas) for the full flow.

**Prompt for an AI coding agent**

```text
Integrate MyAppAffiliate into my project.

Documentation (read these first, they are the source of truth):
- Page: https://docs.myappaffiliate.com/sdk-node.md
- Full docs index: https://docs.myappaffiliate.com/llms.txt

Task: Add the MyAppAffiliate Node SDK to my backend: install it, set MAA_SDK_KEY in the environment, and call trackSignup from my signup handler passing the request URL.

Rules:
- Follow the documented API exactly — no invented method names, endpoints, parameters or field names.
- Match the conventions already used in my codebase.
- Ask me for my SDK key instead of guessing, and never hard-code it — read it from config/environment.
- Do NOT set an API base URL anywhere. Every SDK compiles the production host in; a staging or self-hosted host belongs in a build setting, not in code.
- Tell me afterwards which steps I still have to do by hand (dashboard settings, capabilities, webhook configuration).
```

## Install

```bash
npm i @myappaffiliate/sdk-node
```

Node 18+ (global `fetch`), zero dependencies.

## 1. Set the key in the environment

```bash
MAA_SDK_KEY=pk_live_…
```

Server env only — never ship this key to the browser; that's what the
[Web SDK](https://docs.myappaffiliate.com/sdk-web) is for. There is no host to configure: the production API is
compiled in, and `MAA_API_BASE_URL` overrides it for staging or self-hosted.

## 2. Track the signup

One call from your signup handler. Pass the request URL you already have and the SDK
pulls the referral out of it — `?via=`, `?ref=`, `?code=`, `?claim_token=`, `?ct=`:

```ts
import { myAppAffiliate } from "@myappaffiliate/sdk-node";

const result = await myAppAffiliate.trackSignup({
  userId: user.id,     // the id your billing provider will report back to us
  from: req.url,       // or the referer, or the landing URL you stashed at signup
});
// → { affiliateId } when attributed, null otherwise
```

`null` means "organic signup" — it is not an error. Under the hood this is
`POST /sdk/install` + `POST /sdk/identify` in one call, keyed by a deterministic device
id (`srv_<userId>`), so retrying it is safe.

Already parsed the referral yourself? Pass it directly instead of `from`:

```ts
await myAppAffiliate.trackSignup({ userId: user.id, code: form.referralCode });
await myAppAffiliate.trackSignup({ userId: user.id, claimToken: req.cookies.maa_ct });
```

## 3. Make sure the billing provider sends that same id back

Attribution joins on the user id. Whatever bills your customers, the id in the revenue
event has to be the string you passed to `trackSignup`. The field per provider is in
[Billing & Webhooks](https://docs.myappaffiliate.com/webhooks) — for Stripe it's
`metadata.customer_user_id`, for Paddle it's custom data.

## Optional

**Your own client** — two keys in one process, or a key from a secret manager rather
than the environment:

```ts
import { createClient } from "@myappaffiliate/sdk-node";

const maa = createClient({
  apiKey: await secrets.get("maa"),
  apiBaseUrl: "https://staging.example.com",  // optional
  debug: true,                                // optional
});
if (!maa.configured) logger.warn("MyAppAffiliate is inactive — no key");
```

**Stash the referral before signup** — useful when the landing page and the signup
request are different sessions:

```ts
import { referralFrom } from "@myappaffiliate/sdk-node";

const referral = referralFrom(req.url);  // { code } | { claimToken } | {}
session.referral = referral;
```

**Raw endpoints**, when you manage device identity yourself:

```ts
await maa.install({ deviceId, claimToken });
await maa.identify({ deviceId, customerUserId });
```

## API

| Call | Purpose |
|---|---|
| `myAppAffiliate.trackSignup({ userId, from? \| code? \| claimToken? })` | Bind a signup to a referral |
| `myAppAffiliate.identify({ deviceId, customerUserId })` | Bind a user to an existing device attribution |
| `myAppAffiliate.install({ deviceId, claimToken?, affiliateCode? })` | Raw `POST /sdk/install` |
| `createClient({ apiKey?, apiBaseUrl?, debug? })` | Build your own client |
| `referralFrom(url)` | Extract a referral from a URL or query string |

Network failures resolve to `null` — a flaky attribution call must never fail your
signup path.
