Documentation
Streakline is a REST API with thin SDKs and an agent-native setup flow. Send events, and scoring, levels, streaks, achievements, and leaderboards update for you. Most teams are live the same day.
Preview. The CLI, MCP server, and Agent Skills are early. The REST API and the TypeScript & Swift SDKs are the stable surfaces today.
Quickstart
Install the server SDK in your API, configure its OAuth M2M client, and mint a mobile credential for your app.
bun add @streakline/sdk # or: npm install @streakline/sdkimport { StreaklineServer } from "@streakline/sdk/server";
const streakline = new StreaklineServer({
clientId: process.env.STREAKLINE_CLIENT_ID!,
clientSecret: process.env.STREAKLINE_CLIENT_SECRET!,
});
// Mint this from your API after your own auth and entitlement checks.
const credential = await streakline.createClientCredential({ userId: "user_123" });
// Trusted backend events use the OAuth M2M client directly.
await streakline.track("user_123", "subscription.started");Authentication
Every request carries one Bearer credential. There are two credential types, and the difference matters:
- Client credentials are fixed-scope, five-minute, user-bound credentials minted by your backend after its own session and entitlement checks. Mobile apps use one for the model, event batches, and the current user's profile.
- OAuth M2M clients are server-only and scope trusted server operations. A client created without scopes receives exactly
events:write. Keepclient_credentials:issueon a separate, least-privilege BFF client: it must deriveuser_idfrom its authenticated customer session, because Streakline cannot authenticate that caller for you.
Authorization: Bearer $CLIENT_CREDENTIAL # mobile calls
Authorization: Bearer $OAUTH_ACCESS_TOKEN # server callsCore concepts
The model has eleven composable primitives: Events, Score, Scopes, Levels, Streaks, Leaderboards, Balances, Store, Achievements, Challenges, and Grants. Events and Score are always enabled; every other capability is opt-in. See the complete primitive guide for the full picture.
CLI
The CLI inspects your repository and drafts a scoring model mapped to your real product journeys, then deploys it as a versioned config.
npx streakline init # inspect repo → draft streakline.config.ts
npx streakline preview # dry-run scoring against sample events
npx streakline deploy # publish the active scoring versionMCP server
Connect your agent to Streakline's remote MCP resource to read projects and deployed config, inspect releases, and deploy versions without giving a desktop client a server secret. Your MCP client opens a browser for OAuth consent and uses authorization code with PKCE.
{
"mcpServers": {
"streakline": {
"type": "http",
"url": "https://api.streakline.dev/mcp"
}
}
}Ask a Workspace owner for a controlled public MCP client if your agent does not support automatic OAuth discovery. Dynamic client registration is disabled, and public clients never receive a client secret.
Agent Skills
Drop-in skills give Claude and other coding agents the recipes to wire gamification end-to-end — from mapping events to rendering the SDK in your UI. Point the agent at your repo and let it work.
TypeScript SDK
The server SDK wraps scoped OAuth M2M routes with full types. Use it only where you hold an OAuth client secret.
import { StreaklineServer } from "@streakline/sdk/server";
const streakline = new StreaklineServer({
clientId: process.env.STREAKLINE_CLIENT_ID!,
clientSecret: process.env.STREAKLINE_CLIENT_SECRET!,
});
const credential = await streakline.createClientCredential({ userId: "user_123" });
await streakline.track("user_123", "purchase.made", {
idempotencyKey: "ord_991",
});Swift / iOS SDK
Mobile SDKs accept a structured, short-lived credential from your backend. The SDK validates its subject and expiry before each request, and refreshes once only after a 401 response.
import Streakline
StreaklineSDK.shared.configure(userId: user.id) {
let response = try await api.createStreaklineClientCredential()
return StreaklineClientCredential(
accessToken: response.access_token,
userId: response.user_id,
expiresAt: ISO8601DateFormatter().date(from: response.expires_at)!
)
}
let result = try await StreaklineSDK.shared.track(event: "lesson.completed")
let profile = try await StreaklineSDK.shared.profile()REST
Every SDK is a thin wrapper over the same REST API. Secret routes stay on your API; each mobile request uses one user-bound client credential.
curl https://api.streakline.dev/api/v1/sdk/model \
-H "Authorization: Bearer $CLIENT_CREDENTIAL" \
curl -X POST https://api.streakline.dev/api/v1/events/batch \
-H "Authorization: Bearer $CLIENT_CREDENTIAL" \
-H "Content-Type: application/json" \
-d '{"events":[{"event_type":"lesson.completed"}]}'API endpoints
The full v1 surface. Server routes require scoped OAuth M2M. Mobile model, event, and profile routes require one user-bound client credential.
Open the full interactive reference ↗
Tech stack
Streakline is a Bun monorepo: the hosted API plus its data layer, with the SDKs and marketing site alongside.