TIAN Points API
Integrate TIAN Points into your application to verify balances, deduct points for usage, and set up recurring monthly subscriptions. All endpoints are authenticated via API keys.
External partners can let users authorise TIAN Points deductions without sharing the askTIAN Privy App ID. Users log in on the askTIAN Wallet domain (your Privy cost, your UX) and grant a scoped access token to the partner. The partner stores the token server-side and calls /api/v1/points/deduct with it — no Privy SDK, no session tokens.
- Partner registers with askTIAN and receives a
client_idandclient_secret. - Partner redirects the user to
GET /api/oauth2/authorizewithclient_id,redirect_uri,scope, andstate. - User logs into askTIAN Wallet (Privy on askTIAN's domain) and sees a consent screen listing the requested permissions.
- On approval, askTIAN redirects to the partner's
redirect_uriwith a short-livedcode. - Partner exchanges the code server-to-server:
POST /api/oauth2/token→ receives a long-livedaccess_token(prefixtcat_). - Partner calls
POST /api/v1/points/deductwithAuthorization: Bearer tcat_…. NoprivyIdorsessionTokenneeded.
Send the user to this URL. All params must be URL-encoded.
GET https://wallet.asktian.com/api/oauth2/authorize
?client_id=tc_live_xxx
&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback
&scope=deduct
&state=RANDOM_CSRF_TOKENtc_live_xxx)deduct and/or balanceThe user sees a consent screen on wallet.asktian.com showing your app name and the requested permissions. On approval, they are redirected to your redirect_uri:
https://yourapp.com/callback?code=AUTH_CODE&state=RANDOM_CSRF_TOKENThe code is single-use and expires in 10 minutes.
POST https://wallet.asktian.com/api/oauth2/token
Content-Type: application/json
{
"grant_type": "authorization_code",
"code": "AUTH_CODE",
"redirect_uri": "https://yourapp.com/callback",
"client_id": "tc_live_xxx",
"client_secret": "YOUR_CLIENT_SECRET"
}{
"access_token": "tcat_xxxxxxxxxxxxxxxxxxxx",
"token_type": "Bearer",
"scope": "deduct",
"expires_in": 2592000,
"refresh_token": "tcrt_xxxxxxxxxxxxxxxxxxxx",
"refresh_token_expires_in": 7776000
}Store both tokens securely server-side. The access_token is valid for 30 days; the refresh_token is valid for 90 days and can be used to silently issue a new access token without requiring the user to re-authorise.
POST https://wallet.asktian.com/api/v1/points/deduct
Authorization: Bearer tcat_xxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"amount": 10,
"description": "Feature usage",
"idempotencyKey": "order_abc123"
}{
"success": true,
"creditsDeducted": 10,
"newBalance": 490,
"transactionId": "txn_123",
"webhookDelivered": true
}No privyId or sessionToken required — user identity is derived from the access token.
When an access token is about to expire (or has expired), exchange the refresh token for a new access token + refresh token pair. This is a server-to-server call — the user is never redirected.
POST https://wallet.asktian.com/api/oauth2/token
Content-Type: application/json
{
"grant_type": "refresh_token",
"refresh_token": "tcrt_xxxxxxxxxxxxxxxxxxxx",
"client_id": "tc_live_xxx",
"client_secret": "YOUR_CLIENT_SECRET"
}{
"access_token": "tcat_NEW_TOKEN",
"token_type": "Bearer",
"expires_in": 2592000,
"refresh_token": "tcrt_NEW_REFRESH_TOKEN",
"refresh_token_expires_in": 7776000,
"scope": "deduct"
}Token rotation: each refresh token is single-use. After exchange, both the old access token and old refresh token are immediately invalidated. Always store the new pair.
Replay detection: if a refresh token is submitted a second time, all tokens for that user + partner are revoked as a security measure.
Expiry warning: the askTIAN wallet sends an owner notification 7 days before a token expires. If the user's refresh token also expires (90 days of inactivity), they will need to re-authorise via the full OAuth flow.
Partners can revoke a token at any time. Users can also revoke access from their wallet settings.
POST https://wallet.asktian.com/api/oauth2/revoke
Content-Type: application/json
{ "token": "tcat_xxxxxxxxxxxxxxxxxxxx" }Inspect the current state of any access token without making a deduction. Useful for debugging expired or revoked tokens.
GET https://wallet.asktian.com/api/oauth2/token/info
Authorization: Bearer tcat_xxxxxxxxxxxxxxxxxxxxReturns a JSON object describing the token:
| Field | Type | Description |
|---|---|---|
| active | boolean | Whether the token is currently valid and not revoked |
| scope | string | Granted scope (e.g. deduct) |
| userId | number | askTIAN user ID of the token owner |
| partnerId | number | ID of the partner integration that issued the token |
| expiresAt | ISO 8601 | When the access token expires (30 days from issuance) |
| revokedAt | ISO 8601 | null | Set if the token has been revoked; null otherwise |
{
"active": true,
"scope": "deduct",
"userId": 1001,
"partnerId": 7,
"expiresAt": "2026-05-10T08:00:00.000Z",
"revokedAt": null
}Returns HTTP 401 if the token is missing or malformed. Returns the object with active: false if the token is expired or revoked.
When a user revokes an OAuth token from their wallet, askTIAN fires a token.revoked event to your registered webhook endpoint. Subscribe to it in the Partners dashboard under Event Filter.
| Field | Type | Description |
|---|---|---|
| event | string | token.revoked |
| timestamp | ISO 8601 | When the revocation occurred |
| tokenId | number | Internal ID of the revoked access token |
| userId | number | askTIAN user ID of the token owner |
| scope | string | Scope that was granted (e.g. deduct) |
| revokedAt | ISO 8601 | Timestamp of revocation |
| revokedBy | string | user (wallet self-service) or partner (API revoke endpoint) |
{
"event": "token.revoked",
"timestamp": "2026-04-10T07:00:00.000Z",
"tokenId": 42,
"userId": 1001,
"scope": "deduct",
"revokedAt": "2026-04-10T07:00:00.000Z",
"revokedBy": "user"
}On receiving this event, clear the stored access and refresh tokens for this user and prompt re-authorisation if needed. The webhook is delivered with HMAC-SHA256 signature verification (same as all other events).
| Scope | Permission |
|---|---|
| deduct | Deduct TIAN Points from the user's balance |
| balance | Read the user's current TIAN Points balance (read-only) |
