Skip to main content

Quickstart

This guide walks you through integrating with Profy: create an app → user authorization → report billing events.

Prerequisites

  • A Profy account with creator access
  • Node.js >= 18

Step 1: Create an App

  1. Go to Profy Studio
  2. Click “Create App” and enter your app name
  3. Save your App ID and App Secret
App Secret is only shown in full once. Store it securely and never commit it to version control.

Step 2: Configure Redirect URI

In your app management page → Dev Config → Redirect URIs, add your callback URL.
  • Production must use HTTPS
  • http://localhost is allowed for local development
http://localhost:5180/callback

Step 3: Install the SDK

npm install @profy-ai/sdk
bun add @profy-ai/sdk
pip install profy-sdk
# With optional SQLAlchemy auto-table support:
pip install profy-sdk[sqlalchemy]

Step 4: Initiate OAuth Authorization

Redirect the user to Profy’s authorization page:
https://app.profy.cn/oauth/authorize?client_id={APP_ID}&redirect_uri={CALLBACK_URL}&scope=events:write&response_type=code
ParameterDescription
client_idYour App ID
redirect_uriMust match what you registered
scopeRequested permissions. Currently: events:write
response_typeMust be code
After the user approves, Profy redirects to your callback URL with an authorization code:
http://localhost:5180/callback?code=abc123...

Step 5: Exchange Code for Token

In your backend, use the SDK to exchange the authorization code for an Access Token:
import { ProfyApp } from "@profy-ai/sdk";

const profy = new ProfyApp({
  clientId: process.env.PROFY_APP_ID,
  clientSecret: process.env.PROFY_APP_SECRET,
});

const token = await profy.exchangeCode(code, "http://localhost:5180/callback");

// token contains:
// - accessToken:  JWT, valid for 1 hour
// - refreshToken: valid for 90 days, auto-rotates
// - expiresAt:    expiration timestamp (ms)
Never call exchangeCode from the frontend. App Secret must stay on the server. Code exchange must happen server-side.

Step 6: Report Billing Events

When a user triggers a paid action in your app, report the event:
const result = await profy.reportEvent("generate_report", {
  token,
  metadata: { source: "web", userId: "user-123" },
});
The SDK automatically handles token refresh — if the Access Token has expired, it refreshes using the Refresh Token before retrying.

Full Example

import { Hono } from "hono";
import { ProfyApp, type TokenData } from "@profy-ai/sdk";

const profy = new ProfyApp({
  clientId: process.env.PROFY_APP_ID!,
  clientSecret: process.env.PROFY_APP_SECRET!,
});

let tokenStore: TokenData | null = null;

const app = new Hono();

// Handle OAuth callback
app.post("/api/exchange", async (c) => {
  const { code } = await c.req.json();
  tokenStore = await profy.exchangeCode(code, "http://localhost:5180/callback");
  return c.json({ ok: true });
});

// Report billing event
app.post("/api/report", async (c) => {
  if (!tokenStore) return c.json({ error: "Not authenticated" }, 401);
  const result = await profy.reportEvent("generate_report", { token: tokenStore });
  return c.json(result);
});

export default app;

Starter Template

We provide a complete full-stack starter project with Vite frontend + Hono backend: profy-app-template
git clone https://github.com/user/profy-app-template.git
cd profy-app-template
cp .env.example .env  # Fill in App ID and App Secret
npm install && npm run dev

Flow Diagram

Next Steps

SDK Guide

Full SDK reference: dual-language support + token persistence (Contrib)

API Reference

Full OAuth endpoints and Events API documentation

Billing Configuration

Learn how to configure event pricing in Studio