BUZZ AI Gateway
Docs · API Reference · GET /api/user/self

User Profile

Fetch the currently authenticated user's profile in a single call: identity, role, group, remaining quota, request count, affiliate state, and sidebar permissions. The response is a deliberately whitelisted projection of the user record, not the raw database row.

GET https://buzzai.cc/api/user/self
Use this endpoint to power dashboards. It returns everything the BUZZ web console reads on page load: balance, group, affiliate code, and the per-user UI permission flags. It is the only endpoint that exposes the raw quota integer alongside the human-readable group.

Authentication

This endpoint sits behind the standard user-auth middleware and requires both headers:

HeaderNotes
Authorization: <ACCESS_TOKEN>Raw access token. The Bearer prefix is accepted but not required. A session cookie also satisfies this check when the request originates from the BUZZ web console.
Buzz-User: <user_id>Mandatory. Must equal the authenticated user's id. Mismatch or omission returns HTTP 401.
Heads up on the legacy error message. If the Buzz-User header is missing, the gateway returns the legacy text "Unauthorized, New-Api-User header not provided". The header the server actually reads is Buzz-User — the New-Api-User string is a leftover from the upstream project. Send Buzz-User.

Example request

curl -s 'https://buzzai.cc/api/user/self' \
  -H "Authorization: Bearer $BUZZ_ACCESS_TOKEN" \
  -H "Buzz-User: 1"
import os, requests

resp = requests.get(
    "https://buzzai.cc/api/user/self",
    headers={
        "Authorization": f"Bearer {os.environ['BUZZ_ACCESS_TOKEN']}",
        "Buzz-User": "1",
    },
    timeout=10,
)
resp.raise_for_status()
profile = resp.json()["data"]
print(profile["username"], profile["group"], profile["quota"])
const resp = await fetch("https://buzzai.cc/api/user/self", {
  headers: {
    Authorization: `Bearer ${process.env.BUZZ_ACCESS_TOKEN}`,
    "Buzz-User": "1",
  },
});
const { data } = await resp.json();
console.log(data.username, data.group, data.quota);

Response (live, redacted)

{
  "success": true,
  "message": "",
  "data": {
    "id": 1,
    "username": "buzz666",
    "display_name": "buzz666",
    "role": 100,
    "status": 1,
    "email": "",
    "github_id": "<REDACTED_NUMERIC_ID>",
    "discord_id": "",
    "oidc_id": "",
    "wechat_id": "",
    "telegram_id": "",
    "linux_do_id": "",
    "group": "enterprise",
    "quota": 29214128,
    "used_quota": 588097249,
    "request_count": 398916,
    "aff_code": "tYxh",
    "aff_count": 0,
    "aff_quota": 0,
    "aff_history_quota": 0,
    "inviter_id": 0,
    "setting": "{\"notify_type\":\"email\",\"quota_warning_threshold\":100000,\"gotify_priority\":0,\"record_ip_log\":true}",
    "stripe_customer": "",
    "sidebar_modules": "",
    "permissions": {
      "sidebar_modules": {},
      "sidebar_settings": false
    }
  }
}

Verified live against buzzai.cc on 2026-05-26.

Response envelope

FieldTypeDescription
successbooleanAlways true on a 200. Errors flip this to false and populate message.
messagestringEmpty on success; human-readable error string otherwise.
dataobjectThe user-profile projection (see below).

data fields

The response is a hand-crafted whitelist, not a serialised user row. Sensitive columns such as password, access_token, verification_code, and admin-only remark are deliberately stripped before serialisation.

FieldTypeDescription
idintegerUser numeric id. Must match the Buzz-User header.
usernamestringLogin name.
display_namestringDisplay name shown in the console.
roleinteger1 = common user · 10 = admin · 100 = root.
statusinteger1 = enabled · 2 = disabled.
emailstringEmail address. Empty when not bound.
github_idstringGitHub numeric id. Empty when not bound.
discord_idstringDiscord id. Empty when not bound.
oidc_idstringGeneric OIDC subject. Empty when not bound.
wechat_idstringWeChat openid. Empty when not bound.
telegram_idstringTelegram numeric id. Empty when not bound.
linux_do_idstringLinux.Do forum id. Empty when not bound.
groupstringPricing/permission group name (e.g. default, enterprise). Determines which channels and prices apply.
quotaintegerRemaining quota in raw billing units. Convert to currency via the site's quota-display setting (see the Billing endpoints).
used_quotaintegerLifetime consumed quota in raw units.
request_countintegerLifetime number of API requests this user has made.
aff_codestringAffiliate / referral code unique to this user.
aff_countintegerNumber of users who signed up using this affiliate code.
aff_quotaintegerAffiliate quota currently available to redeem.
aff_history_quotaintegerLifetime affiliate quota earned (already redeemed plus pending).
inviter_idintegerUser id of whoever invited this account, or 0 if direct signup.
settingstringJSON-encoded user preferences. Parse it client-side; common keys include notify_type, quota_warning_threshold, record_ip_log.
stripe_customerstringStripe customer id when the account has used Stripe checkout, otherwise empty.
sidebar_modulesstringPer-user sidebar override extracted from setting.sidebar_modules. Empty means use the site default.
permissionsobject{ sidebar_settings: bool, sidebar_modules: object }. Drives which modules render in the console UI.

Fields deliberately excluded

The handler explicitly enumerates the fields above instead of serialising the user row, so the following columns are never included in the response, even for the root account:

Errors

HTTPBodyCause
401{"success":false,"message":"Unauthorized, ..."}Missing or invalid Authorization; missing or mismatched Buzz-User header; account disabled.
429Rate-limit envelopeGlobal API rate limit hit. Respect retry-after.
500{"success":false,"message":"..."}Internal error fetching the user record. Retry with backoff.

See also