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
Go to Profy Studio
Click “Create App” and enter your app name
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.
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
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
Parameter Description 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