Play & Rewards
API Reference: https://api.play.fun/api-reference
Authentication
For developer endpoints, you need HMAC authentication. See API Reference - Authentication for details on generating signatures.
All dev endpoints also require the header:
x-auth-provider: hmacPlay Endpoints
Batch Save Points
POST /play/dev/batch-save-points
Save points for multiple players in a single request. This is the recommended way to update player scores from your game backend.
Headers:
Content-Type: application/json
x-auth-provider: hmac
Authorization: HMAC-SHA256 apiKey=... signature=... timestamp=...Request Body:
{
"gameApiKey": "your-game-owner-id",
"points": [
{
"playerId": "sol:9qdvVLY3vLhmvV7uBkLJsQKcHDjxhoUWJ9uZASYEfwwC",
"points": "1500"
},
{
"playerId": "email:[email protected]",
"points": "2300"
},
{
"playerId": "550e8400-e29b-41d4-a716-446655440000",
"points": "500"
}
]
}Player ID Formats:
Solana Wallet
sol:9qdvVLY... or solana:9qdvVLY...
Resolves by Solana address, auto-creates user
Ethereum Wallet
eth:0x123... or ethereum:0x123...
Resolves by ETH address, auto-creates user
Twitter/X
twitter:username or x:username
Resolves by Twitter/X handle, auto-creates user
Privy ID
did:privy:abc123...
Direct Privy user lookup
OGP User ID
550e8400-e29b-41d4-...
Raw UUID, fastest (no resolution needed)
Identifiers that are not in type:value format and are not valid UUIDs will throw an error. The identifier parser only accepts the formats listed above.
Response:
JavaScript Example:
Notes:
Points are cumulative — they add to existing points for the day
Users are automatically created if they don't exist (via Privy)
Cache the
playerIdToOgpIdmapping for better performance on subsequent requestsOnly the game owner/creator can save points
Maximum 1000 entries per batch request
Rate limit: 3 requests per second
Get Player Points
GET /play/dev/points
Retrieve the current day's points for a specific player in your game.
Headers:
Query Parameters:
gameId(required) - Your game's UUIDplayerId(required) - Player identifier (same formats as batch-save-points)
Example Request:
Response:
Get Game Leaderboard
GET /play/dev/leaderboard/{gameId}
Retrieve the leaderboard for your game. Returns top players ranked by points.
Headers:
Path Parameters:
gameId(required) - Your game's UUID
Query Parameters:
limit(optional, default: 10, max: 100) - Number of entries to returncursor(optional) - Pagination cursor for next pagedate(optional, default: today) - Date in YYYY-MM-DD format
Response:
Notes:
Leaderboards are calculated per day
Only shows PLAYER type points (not referrer/distributor points)
Rejected/invalidated points are excluded
Only the game owner/creator can access leaderboards
Get Player Sessions
GET /play/dev/sessions/{gameId}
Retrieve player sessions for your game, including anti-cheat and fraud detection data.
Headers:
Path Parameters:
gameId(required) - Your game's UUID
Query Parameters:
date(optional, YYYY-MM-DD) - Filter by dateuserId(optional, UUID) - Filter by player user IDminRiskScore(optional, 0-1) - Minimum risk score filterstatus(optional) -valid,pending_review, orinvalidatedlimit(optional, default: 50, max: 100) - Results per pagecursor(optional) - Pagination cursor
Response:
Session Fields:
riskScore(0-1): Fraud detection score. Higher = more suspiciousriskReasons: Array of detected anomalies (e.g.,unusual_flush_pattern,multiple_client_instances)status:valid(accepted),pending_review(under review),invalidated(removed)flushCount: Number of flush operations in sessionclientInstanceIdChanges: Count of device/client changes (indicator of device switching)
Get Risky Sessions
GET /play/dev/risky-sessions/{gameId}
Same as Get Sessions, but filtered to sessions with riskScore > 0.5. Use this to review suspicious activity.
Query Parameters:
date(optional, YYYY-MM-DD)limit(optional, default: 50, max: 100)cursor(optional)
Invalidate Sessions
POST /play/dev/invalidate-sessions
Invalidate fraudulent sessions and remove their associated points. This fully reverts the session's impact, including referrer and distributor points.
Headers:
Request Body:
Response:
Notes:
Maximum 100 sessions per request
Cascading removal: also removes referrer and distributor points linked to the session
Fully auditable: reason, admin ID, and timestamp are recorded
Only the game owner/creator can invalidate sessions
Validate Session Token
POST /play/dev/validate-session-token
Validate a player session token (player_xxx) issued by the client SDK. Use this to verify that a player sending requests to your backend is genuinely authenticated through Play.fun.
Headers:
Request Body:
Response (valid token):
Response (invalid token):
Response Fields:
valid
boolean
Whether the token is valid
playerId
string
Privy ID (did:privy:xxx) — use to verify the player matches who you expect
gameId
string
Game UUID the token was issued for
ogpId
string
Internal OGP user UUID — use as playerId in savePoints / batchSavePoints for best performance
Notes:
Session tokens are scoped per-game and expire after 30 minutes
The
ogpIdin the response can be passed directly tosavePoints/batchSavePointsto skip identifier resolutionOnly the game owner/creator can validate tokens for their game
Rewards Endpoints
Get Game Rewards Pool
GET /rewards/game-rewards-pool/{gameId}
Get the total rewards pool value and breakdown by token for a specific game.
Path Parameters:
gameId(required) - Game UUID
Example Request:
Response:
Error Responses
All endpoints may return the following error responses:
400 Bad Request:
401 Unauthorized:
403 Forbidden:
429 Too Many Requests:
500 Internal Server Error:
Last updated