> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cabalspy.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# White-Label quickstart

> From your existing user base to profiles, a leaderboard and a trading competition: import users with their wallets, read a profile, rank your users and start a competition.

This guide takes your existing users and their wallets, from Privy, Dynamic or your own database, to a profile page, a leaderboard and a running trading competition. All calls go from your backend to the Data API with your API key.

**1. Get an API key for your instance**

Create a CabalSpy ID instance in the [API Dashboard](https://apidashboard.cabalspy.xyz) and switch on **CabalSpy ID** for your API key on the **API keys** page, see [Authentication](https://docs.cabalspy.xyz/cabalspy-id/data-api.md#authentication). Check the key with [GET /v1/me](https://docs.cabalspy.xyz/cabalspy-id/me.md).

A sandbox or development instance holds up to 25 platform users, enough to build and test. A live instance uses your plan's user limit.

**2. Import your users**

Send your users with your own user id as `external_id` and their existing wallets. Up to 1,000 users per call. Each user is handled on its own, so one bad entry never undoes the others.

```bash cURL theme={null}
curl -X POST "https://api-id.cabalspy.xyz/v1/platform-users/import" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "users": [
      {"external_id": "user_8412", "display_name": "Maze",
       "wallets": [{"address": "7j7AA3HZR2zEjwAQEKPFh2qucLY4fqZpB9iodf39w8xW", "source": "privy"}]},
      {"external_id": "user_8413",
       "wallets": ["0x4b1e9c0d2a7f3e5b8c6d1a9f0e2b7c4d5a6e8f01"]}
    ]
  }'
```

```python Python theme={null}
import requests

H = {"Authorization": "Bearer YOUR_KEY"}
users = [
    {"external_id": u.id, "display_name": u.name,
     "wallets": [{"address": w, "source": "privy"} for w in u.wallets]}
    for u in my_users   # your own user objects
]
for i in range(0, len(users), 1000):
    r = requests.post("https://api-id.cabalspy.xyz/v1/platform-users/import",
                      json={"users": users[i:i + 1000]}, headers=H).json()
    print(r["data"]["summary"])
```

```javascript JavaScript theme={null}
const res = await fetch("https://api-id.cabalspy.xyz/v1/platform-users/import", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    users: [
      { external_id: "user_8412", wallets: [{ address: "7j7AA3HZR2zEjwAQEKPFh2qucLY4fqZpB9iodf39w8xW", source: "privy" }] },
    ],
  }),
});
const { data } = await res.json();
console.log(data.summary); // { created, updated, unchanged, rejected }
```

For users who sign up later, call [Create or update a user](https://docs.cabalspy.xyz/cabalspy-id/platform-users-create.md) from your sign-up flow, or let Privy, Dynamic or your backend post sign-ups to your [inbound URL](https://docs.cabalspy.xyz/cabalspy-id/platform-users-inbound.md).

**3. Show a profile**

One call returns everything for a profile page: the user, their wallets, trading stats per chain for a period, the 20 most recent trades, theses and the KOL status.

```bash theme={null}
curl "https://api-id.cabalspy.xyz/v1/platform-users/profile?external_id=user_8412&period=7d" \
  -H "Authorization: Bearer YOUR_KEY"
```

For charts and detail pages, every other Data API endpoint accepts `external_id` in place of `csid_id`, for example [tracker](https://docs.cabalspy.xyz/cabalspy-id/tracker.md), [holdings](https://docs.cabalspy.xyz/cabalspy-id/holdings.md), [history](https://docs.cabalspy.xyz/cabalspy-id/history.md) and the [PnL calendar](https://docs.cabalspy.xyz/cabalspy-id/pnl-calendar.md). The profile's `links` field has the ready-made paths for each wallet. See [Platform user profile](https://docs.cabalspy.xyz/cabalspy-id/platform-users-profile.md).

**4. Rank your users**

The platform leaderboard ranks the wallets of your users and tells you whose wallet each entry is, by `external_id`.

```bash theme={null}
curl "https://api-id.cabalspy.xyz/v1/platform-users/leaderboard?blockchain=solana&period=7d&sort=pnl_usd&limit=25" \
  -H "Authorization: Bearer YOUR_KEY"
```

To rank only payment-verified wallets, add `trust=verified` or set `leaderboard_trust` to `verified_only` in the [settings](https://docs.cabalspy.xyz/cabalspy-id/platform-users-settings.md). See [Platform leaderboard](https://docs.cabalspy.xyz/cabalspy-id/platform-users-leaderboard.md).

**5. Start a competition**

Create a 48-hour PnL competition on Solana that enters every user automatically.

```bash cURL theme={null}
curl -X POST "https://api-id.cabalspy.xyz/v1/competitions" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekend PnL Cup",
    "chain": "solana",
    "metric": "pnl_usd",
    "duration_hours": 48,
    "starts_at": "2026-11-01T18:00:00Z",
    "enrollment": "all_users",
    "min_trades": 3
  }'
```

```python Python theme={null}
import requests

r = requests.post("https://api-id.cabalspy.xyz/v1/competitions", json={
    "name": "Weekend PnL Cup", "chain": "solana", "metric": "pnl_usd",
    "duration_hours": 48, "starts_at": "2026-11-01T18:00:00Z",
    "enrollment": "all_users", "min_trades": 3,
}, headers={"Authorization": "Bearer YOUR_KEY"})
comp = r.json()["data"]
print(comp["id"], comp["status"])
```

```javascript JavaScript theme={null}
const res = await fetch("https://api-id.cabalspy.xyz/v1/competitions", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Weekend PnL Cup", chain: "solana", metric: "pnl_usd",
    duration_hours: 48, starts_at: "2026-11-01T18:00:00Z",
    enrollment: "all_users", min_trades: 3,
  }),
});
const { data } = await res.json();
console.log(data.id, data.status);
```

Once it runs, read the [standings](https://docs.cabalspy.xyz/cabalspy-id/competitions-standings.md), recomputed every 5 minutes, or subscribe to the `competition.standings` and `competition.ended` [webhooks](https://docs.cabalspy.xyz/cabalspy-id/webhooks.md#competition-events). See [Competitions](https://docs.cabalspy.xyz/cabalspy-id/competitions.md).

## Next steps

* Choose how much you trust the wallets you send: [settings](https://docs.cabalspy.xyz/cabalspy-id/platform-users-settings.md) `wallet_trust` and `leaderboard_trust`.
* Offer payment verification as a trust badge: [Verify a wallet](https://docs.cabalspy.xyz/cabalspy-id/platform-users-verification.md).
* Let users connect [X](https://docs.cabalspy.xyz/cabalspy-id/platform-users-x.md) and [Telegram](https://docs.cabalspy.xyz/cabalspy-id/platform-users-telegram.md), and apply for the [KOL badge](https://docs.cabalspy.xyz/cabalspy-id/platform-users-kol.md).
* Subscribe to the [White-Label webhooks](https://docs.cabalspy.xyz/cabalspy-id/webhooks.md#white-label-events).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.