Skip to main content

SDK Quickstart

The official TypeScript SDK handles OAuth token management and event reporting so you can focus on your app.

Install

npm install @profy-ai/sdk
bun add @profy-ai/sdk

Initialize

import { ProfyApp } from "@profy-ai/sdk";

const profy = new ProfyApp({
  clientId: process.env.PROFY_APP_ID!,
  clientSecret: process.env.PROFY_APP_SECRET!,
  baseUrl: "https://app.profy.cn",       // optional, defaults to profy.cn
  onTokenRefresh: (newToken) => {         // optional, fires on token rotation
    saveToDatabase(newToken);
  },
});

Exchange Authorization Code

After the user authorizes, your callback URL receives a code parameter. Exchange it for tokens on the backend:
const token = await profy.exchangeCode(code, redirectUri);
// → { accessToken, refreshToken, expiresAt }
FieldTypeDescription
accessTokenstringJWT, valid for 1 hour
refreshTokenstringValid for 90 days, rotates on each use
expiresAtnumberExpiration timestamp (ms)
exchangeCode must be called server-side. Never expose App Secret in frontend code.

Report Billing Events

const result = await profy.reportEvent("generate_report", {
  token,
  idempotencyKey: "order-12345",  // optional, prevents duplicate charges
  metadata: { plan: "pro" },      // optional, for tracking
});
The SDK automatically handles token expiration: when the Access Token expires, it refreshes using the Refresh Token and retries.

Error Handling

import {
  AuthExpired,
  InsufficientBalance,
  InvalidEvent,
  ProfyApiError,
} from "@profy-ai/sdk";

try {
  await profy.reportEvent("action", { token });
} catch (err) {
  if (err instanceof AuthExpired) {
    // Token expired and refresh failed → re-authorize
  } else if (err instanceof InsufficientBalance) {
    // User needs to top up credits
  } else if (err instanceof InvalidEvent) {
    // Event name not configured in Studio
  } else if (err instanceof ProfyApiError) {
    console.error(err.statusCode, err.body);
  }
}

Error Reference

Error ClassHTTP StatusTriggerAction
AuthExpired401Token expired, refresh failedRe-authorize
InsufficientBalance402Insufficient creditsPrompt top-up
InvalidEvent400Event name not registeredCheck meter config
ProfyApiError*Generic API errorHandle by statusCode

Full Example

profy-app-template (Vite + Hono full-stack scaffold)

Integration Tutorial

Complete integration walkthrough in 5 minutes

API Reference

Full OAuth and Events API documentation