User API API Reference
Points, sessions, ads, connected apps, and user profile endpoints available to operator apps via OAuth.
11 endpoints
- POST
/api/external/ads/event - GET
/api/external/ads/serve - GET
/api/external/app/balance - GET
/api/external/points - POST
/api/external/points/spend - POST
/api/external/points/transfer - POST
/api/external/session/end - GET
/api/external/session/status - GET
/api/external/user - GET
/api/user/connected-apps - DELETE
/api/user/connected-apps/{app_id}
Record an ad impression or click event
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 profile:read
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
campaign_id |
string (uuid) |
required | |
event_type |
"impression" | "click" |
required | |
surface_type |
string |
optional | Ad surface type (defaults to banner) |
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
event |
object |
required |
Example Request
curl -X POST "https://api.buddo.xyz/api/external/ads/event" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": "00000000-0000-0000-0000-000000000000",
"event_type": "impression",
"surface_type": "string"
}'
Example Response
{
"event": {
"campaign_id": "00000000-0000-0000-0000-000000000000",
"event_type": "impression",
"id": "00000000-0000-0000-0000-000000000000",
"inserted_at": "2026-01-01T00:00:00Z",
"payout_rate_snapshot": 0,
"surface_type": "string"
}
}
Serve an ad campaign for a given surface type
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 profile:read
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
surface_type |
query | "banner" | "video" | "interstitial" | "native" | "rewarded" |
required | The ad surface type to serve |
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
campaign |
object |
required |
Example Request
curl -X GET "https://api.buddo.xyz/api/external/ads/serve?surface_type=VALUE" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"campaign": {
"bitcoin_tier": {},
"id": "00000000-0000-0000-0000-000000000000",
"name": "string",
"payout_rate": 0,
"surface_type": "string",
"targeting_metadata": {}
}
}
Get the operator app's earned-point balance
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 app:balance:read
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
points |
integer |
required |
Example Request
curl -X GET "https://api.buddo.xyz/api/external/app/balance" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"points": 0
}
Get user point balance
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 points:read
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
points |
integer |
required |
Example Request
curl -X GET "https://api.buddo.xyz/api/external/points" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"points": 0
}
Spend user points, crediting the operator account
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 points:spend
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
amount |
integer |
required | |
description |
string |
optional |
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
amount_spent |
integer |
required | |
points |
integer |
required | |
success |
boolean |
required |
Example Request
curl -X POST "https://api.buddo.xyz/api/external/points/spend" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 1,
"description": "string"
}'
Example Response
{
"amount_spent": 0,
"points": 0,
"success": false
}
Transfer points from the authenticated user to another user
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 points:transfer
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
amount |
integer |
required | |
description |
string |
optional | |
to_user_id |
string (uuid) |
required |
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
amount_transferred |
integer |
required | |
points |
integer |
required | |
success |
boolean |
required |
Example Request
curl -X POST "https://api.buddo.xyz/api/external/points/transfer" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 1,
"description": "string",
"to_user_id": "00000000-0000-0000-0000-000000000000"
}'
Example Response
{
"amount_transferred": 0,
"points": 0,
"success": false
}
End the user's active session with this app
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 profile:read
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
message |
string |
required | |
session_id |
string |
required |
Example Request
curl -X POST "https://api.buddo.xyz/api/external/session/end" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"message": "string",
"session_id": "string"
}
Check whether the user has an active session with this app
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 profile:read
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
is_alive |
boolean |
required | |
last_heartbeat |
string | null |
required | |
points_earned |
integer | null |
required | |
session_active |
boolean |
required | |
session_id |
string | null |
required |
Example Request
curl -X GET "https://api.buddo.xyz/api/external/session/status" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"is_alive": false,
"last_heartbeat": {},
"points_earned": {},
"session_active": false,
"session_id": {}
}
Get authenticated user profile
**Authentication:** Requires an OAuth access token (Bearer) with the appropriate scope, not a JWT. Use the token returned by POST /api/oauth/token.
Authentication
OAuth2 profile:read
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
user |
object |
required | User profile object |
Example Request
curl -X GET "https://api.buddo.xyz/api/external/user" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"user": {}
}
List user's connected OAuth apps
Returns all OAuth apps the authenticated user has authorized.
Authentication
JWT Bearer Token
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
connected_apps |
array<object> |
required |
Example Request
curl -X GET "https://api.buddo.xyz/api/user/connected-apps" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Example Response
{
"connected_apps": [
{
"app_description": {},
"app_id": "00000000-0000-0000-0000-000000000000",
"app_name": "string",
"connected_at": "2026-01-01T00:00:00Z",
"last_used": {},
"logo_url": {},
"scopes": [
{}
]
}
]
}
Revoke app access
Revokes all OAuth tokens for the specified app and removes the connection.
Authentication
JWT Bearer Token
Path Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
app_id |
path | string (uuid) |
required | The app's ID to revoke |
Response (Success)
| Name | Type | Required | Description |
|---|---|---|---|
message |
string |
required |
Example Request
curl -X DELETE "https://api.buddo.xyz/api/user/connected-apps/:app_id" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Example Response
{
"message": "string"
}