Getting Started

This tutorial walks through Simbee's core primitives with real API calls. By the end you'll have created users, recorded signals, observed computed affinities, and queried a personalized feed. The examples use a music creator platform, but every step applies to any domain — see the Concepts guide for how each primitive maps to different applications.

Prerequisites:You need a Simbee account and a JWT token. If you don't have one yet, follow the Authentication guide first. All examples below assume you have a valid token stored in a token variable.

1. Setup

Install the SDK for your language and configure it with your API credentials.

# No installation needed. Set your token:
export SIMBEE_TOKEN="eyJhbGciOiJFZERTQSIs..."
export SIMBEE_URL="https://api.simbee.io"

Configure the client with your base URL and token:

import { Configuration } from "@simbee-io/client";

const config = new Configuration({
  basePath: "https://api.simbee.io",
  accessToken: token,
});

2. Define signal types

Signal types tell Simbee what behaviors mean in your domain. Each type has a key, a default strength, and a decay strategy. Define these before recording signals.

# Create a "listen" signal type (moderate strength)
curl -X POST $SIMBEE_URL/api/v1/config/signal_types \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "key": "listen", "label": "Listen", "strength_override": 0.3 }'

# Create a "follow" signal type (strong signal)
curl -X POST $SIMBEE_URL/api/v1/config/signal_types \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "key": "follow", "label": "Follow", "strength_override": 0.7 }'

# Create a "purchase" signal type (strongest signal)
curl -X POST $SIMBEE_URL/api/v1/config/signal_types \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "key": "purchase", "label": "Purchase", "strength_override": 1.0 }'

Response

// 201 Created
{
  "data": {
    "id": "st_abc123",
    "client_id": "cl_abc123",
    "key": "listen",
    "strategy": "default",
    "created_at": "2026-04-11T12:00:00Z",
    "updated_at": "2026-04-11T12:00:00Z"
  }
}

The keyis what you'll use when recording signals. The id is the internal reference.

3. Create users

Create users with an external_idthat maps to your system's user identifier. You can attach arbitrary traits as a JSON object.

# Create a few users
curl -X POST $SIMBEE_URL/api/v1/users \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "alice",
    "traits": { "name": "Alice", "role": "listener" }
  }'

curl -X POST $SIMBEE_URL/api/v1/users \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "bob",
    "traits": { "name": "Bob", "role": "creator", "genre": "jazz" }
  }'

curl -X POST $SIMBEE_URL/api/v1/users \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "carol",
    "traits": { "name": "Carol", "role": "creator", "genre": "electronic" }
  }'

Response

// 201 Created
{
  "data": {
    "id": "usr_abc123",
    "client_id": "cl_abc123",
    "external_id": "alice",
    "cluster_id": null,
    "cluster_confidence": null,
    "traits": { "name": "Alice", "role": "listener" },
    "created_at": "2026-04-11T12:00:00Z",
    "updated_at": "2026-04-11T12:00:00Z"
  }
}

Use external_id in all subsequent calls. For bulk creation, use POST /api/v1/users/batch with up to 100 users per call.

4. Record signals

Signals capture user behavior. Each signal connects a user to a target (another user, content, or a tag) with a signal type. Record signals as actions happen in your application.

# Alice listens to Bob's track (target_type: "user")
curl -X POST $SIMBEE_URL/api/v1/users/alice/signals \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "signal_type_id": "listen",
    "target_id": "bob",
    "target_type": "user"
  }'

# Alice follows Bob (stronger signal)
curl -X POST $SIMBEE_URL/api/v1/users/alice/signals \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "signal_type_id": "follow",
    "target_id": "bob",
    "target_type": "user"
  }'

# Alice listens to Carol's track
curl -X POST $SIMBEE_URL/api/v1/users/alice/signals \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "signal_type_id": "listen",
    "target_id": "carol",
    "target_type": "user"
  }'

Response

// 201 Created
{
  "data": {
    "id": "sig_abc123",
    "client_id": "cl_abc123",
    "user_id": "usr_abc123",
    "signal_type_id": "listen",
    "target_id": "bob",
    "target_type": "user",
    "strength": 0.3,
    "signaled_at": "2026-04-11T12:01:00Z",
    "created_at": "2026-04-11T12:01:00Z"
  }
}

Notice the strengthis automatically set from the signal type's configured default. Alice now has a listen signal (0.3) and a follow signal (0.7) toward Bob, and a listen signal (0.3) toward Carol. These will be aggregated into affinities.

5. Observe affinities

After recording signals, Simbee computes affinities — aggregated relationship strengths. Query Alice's affinity summary to see how her signals have been processed.

curl $SIMBEE_URL/api/v1/users/alice/affinity/summary \
  -H "Authorization: Bearer $SIMBEE_TOKEN"

The summary shows Alice's computed affinity scores. Bob will rank higher because Alice both listened to and followed him (combined strength), while Carol only has a listen signal. These affinities drive everything downstream — feed ranking, match scoring, and cluster assignment.

6. Query the ranked feed

The ranked feed returns personalized results for a user, ordered by the active scoring configuration. This is the primary endpoint for building discovery experiences.

curl "$SIMBEE_URL/api/v1/users/alice/feed/ranked?limit=10" \
  -H "Authorization: Bearer $SIMBEE_TOKEN"

Results are ordered by relevance to Alice based on her affinity profile. The feed supports cursor-based pagination — use the cursor parameter from the response to fetch the next page. See Scoring for how to change ranking behavior with presets.

7. View clusters

Once you have enough users and signals, Simbee's clustering pipeline groups users into natural segments. Clusters are computed asynchronously — trigger a run and then query the results.

# List clusters
curl $SIMBEE_URL/api/v1/clusters \
  -H "Authorization: Bearer $SIMBEE_TOKEN"

# View members of a specific cluster
curl $SIMBEE_URL/api/v1/clusters/cls_abc123/members \
  -H "Authorization: Bearer $SIMBEE_TOKEN"

Each user's profile includes cluster_id and cluster_confidence after a clustering run completes. See Clustering for how clusters form and how to use them.

8. Create a campaign

Campaigns let you push targeted content into users' feeds. Create a campaign, add content items, and activate it.

# Create a campaign
curl -X POST $SIMBEE_URL/api/v1/campaigns \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "New Artist Spotlight",
    "budget": 1000.0,
    "target_criteria": { "cluster_ids": ["cls_abc123"] },
    "max_impressions_per_user": 3
  }'

# Add a content item to the campaign
curl -X POST $SIMBEE_URL/api/v1/campaigns/cmp_abc123/items \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "external_content_id": "featured-track-42" }'

# Activate the campaign
curl -X POST $SIMBEE_URL/api/v1/campaigns/cmp_abc123/activate \
  -H "Authorization: Bearer $SIMBEE_TOKEN"

Once activated, campaign items appear in targeted users' feeds alongside organic results. Simbee tracks impressions and enforces budget limits automatically. See Campaigns for the full lifecycle.

9. Subscribe to webhooks

Webhooks let you react to platform events in real time. Subscribe to event types and Simbee will POST payloads to your URL as events occur.

curl -X POST $SIMBEE_URL/api/v1/clients/cl_abc123/webhooks \
  -H "Authorization: Bearer $SIMBEE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/simbee",
    "event_types": [
      "match.computed",
      "clustering.completed",
      "campaign.budget_exhausted"
    ],
    "secret": "whsec_your_signing_secret"
  }'

Response

// 201 Created
{
  "data": {
    "id": "wh_abc123",
    "client_id": "cl_abc123",
    "url": "https://your-app.com/webhooks/simbee",
    "status": "active",
    "event_types": [
      "match.computed",
      "clustering.completed",
      "campaign.budget_exhausted"
    ],
    "created_at": "2026-04-11T12:05:00Z"
  }
}

Webhook deliveries include an HMAC signature in the X-Simbee-Signature header for verification. Deliveries retry with exponential backoff on failure.

10. Check analytics

The analytics overview gives you a snapshot of your tenant's activity — total counts and last-24-hour trends.

curl $SIMBEE_URL/api/v1/analytics/overview \
  -H "Authorization: Bearer $SIMBEE_TOKEN"

Response

// 200 OK
{
  "data": {
    "totals": {
      "users": 3,
      "signals": 3,
      "content_items": 0,
      "follows": 1,
      "matches": 0,
      "impressions": 0
    },
    "last_24h": {
      "users_created": 3,
      "signals_created": 3,
      "engagements": 0,
      "matches_computed": 0
    },
    "computed_at": "2026-04-11T12:10:00Z"
  }
}

For deeper insights, explore the topic-specific analytics endpoints: /analytics/signals, /analytics/affinities, /analytics/clustering, and more. See the API Reference for the full list.

Next steps

You've used Simbee's core primitives: signal types, users, signals, affinities, feed, clusters, campaigns, webhooks, and analytics. Here's where to go from here:

  • Concepts — Deeper explanation of each primitive and how they compose.
  • Consent layers — Add opt-in tiers for matching and privacy-scoped discovery.
  • Custom scoring — Tune ranking behavior with scoring presets and custom configurations.
  • API Reference — Full endpoint reference with request/response schemas.