Roblox summary report
Everything measured to date, on one page. Both API routes have been run against live Sway-owned accounts — these findings are observed HTTP results, not estimates.
Measured Research opened 27 Jul 2026 · API probe 18 Aug · badge + cookie re-probe 3 Sep · report 16 Sep 2026
The cookie route is technically complete and the research verdict is do not build it: it needs the child's full session token, bypasses 2FA, breaches the Terms of Use and the 2026-04-15 human-only cookie rule, and presence — the most powerful field on the page — is expressly prohibited by the 2026-06-02 rich-presence clause. DECISION-1 is to record that it is dropped, or to record an explicit override with a name and date. Both prototypes exist, so this can now be decided on evidence rather than argument.
What each route returns — measured
Every row was tested. 200 means live data came back; 404 means the route does not exist; 403 means it exists and refused.
| Data point | Open Cloud API | Cookie | Device | Notes |
|---|---|---|---|---|
| Username, display name | 200 | 200 | — | id is a string and the only stable key; name and displayName are mutable |
| Account creation date | 200 | 200 | — | createTime, RFC 3339 |
| Locale | 200 | — | — | |
| Bio | 200 | 200 | — | Omitted when empty — not scope-gated |
| Premium status | 200 | — | — | Omitted when false. The first read of this was wrong |
| ID-verified flag | Unresolved | — | — | Not observed on any of five accounts; omitted-because-false vs scope-gated needs OAuth to settle |
| Inventory contents | 200 own only | — | — | Other users → 403. onlyCollectibles unlocks the call and returns nothing |
| Badges earned | 200 | — | — | Inventory rows with badgeDetails; a second shape the first capture never saw |
| Experiences played | Partial via badges | 200 current only | — | Badge → awardingUniverse → name + award time. Cookie presence gives the experience she is in now |
| Followed experiences | 403 | — | — | Needs legacy-universe.following:read — unproven pending an OAuth app |
| Friends list | 404 | 200 | — | 67 friends with id, username, display name. The "new unknown contact" signal is cookie-only |
| Followers | 404 | 200 | — | Count |
| Direct messages | — | 200 | — | Full bodies, sender, subject, timestamp, read state. Legacy web inbox only |
| Presence / current experience | 404 | 200 Prohibited | — | Resolves exact universeId. Named and forbidden by the 2026-06-02 clause |
| Robux balance | — | 200 | — | Transaction ledger not probed |
Moderation / isBanned | — | 200 | — | Not on the Open Cloud user object |
| Username history | — | 200 | — | Empty on the test account |
| Playtime / screen time | 404 | None | Android iOS | Android exact; iOS a threshold staircase; console and PC invisible |
| Sessions (start / end) | 404 | None | Android | Via queryEvents() |
| In-experience chat | — | None | — | No surface exists anywhere, including Roblox's own parent dashboard |
| Age bracket / under-13 flag | None | — | — | age scope not permitted to third parties; createTime is the only weak proxy |
| Privacy / parental-control settings | None | reachable | — | 83 endpoints, all cookie-only. Offer as a guided checklist instead |
Route A — Open Cloud API Sanctioned
Tested with an Open Cloud API key owned by test account DaFerG81
(11525168069, created 17 Aug 2026). No OAuth app has been registered — that is still
CRED-1, and OAuth is the only model that expresses guardian consent.
What comes back
GET /cloud/v2/users/{id} returns id, name, displayName,
createTime, locale, and — only when non-default — about,
premium, socialNetworkProfiles. An API key can read any user's basic
profile without that user's consent, verified against unrelated accounts. Whether it is
appropriate to read a child's profile without involving them is a product and legal question
that belongs with S4, not something to settle by what the API happens to allow.
GET /cloud/v2/users/{id}/inventory-items returns the key owner's inventory: 75 items on a
one-day-old account, all written within 0.81 seconds of signup — default body parts,
animations and starter clothing. Inventory is a poor activity signal and addTime must
not drive an activity chart.
By 3 September the inventory held 78 items, and the three new rows carried badgeDetails
instead of assetDetails. A badge resolves to the experience that awarded it via
awardingUniverse, and GET /cloud/v2/universes/{id} returns the display name — so
the whole chain stays on Open Cloud. Verified live: two badges resolved to Dress To Impress
(24 Aug 14:56) and Club Roblox RP (24 Aug 15:02).
This is the only sanctioned route to an experience name plus a timestamp. The research had called it impossible.
- Only experiences that award badges, only when one is actually earned. Many popular experiences award none.
- No duration, no session, no ordering beyond award time.
- Silence proves nothing. A child can play for hours and earn nothing.
A dashboard can honestly say "she earned a badge in Dress To Impress on Sunday afternoon". It cannot say how long she played, and must not imply the list is complete. Evidence of play, not a measure of it.
What is absent
/playtime, /friends, /sessions and /presence under
/cloud/v2/users/{id}/ all return 404 with an empty error body — absent, not
gated. There is no scope to apply for, no review to pass, no partnership to negotiate.
For whoever builds it
- Protobuf-style JSON: fields at their default value are omitted. Never branch on key presence; normalise every optional field on ingest.
- Two incompatible error envelopes from the same host —
{errors:[{code,message}]}and{code,message}— andmessagemay be empty. - Inventory rows come in two mutually exclusive shapes; assuming
assetDetailsthrows on badge rows. - OAuth access tokens live 15 minutes against a 12-hour analysis cycle, so every run refreshes first. Refresh tokens are 90-day, single-use and rotating — persist the new one before using the access token.
- Rate limits are per-authorisation (10/min user, 20/min inventory). Not a constraint — there is nothing worth polling.
- Unreviewed OAuth apps are capped at 10 test users; 2026 reports of opaque automated rejections. Treat "passes review" as a risk.
- Only four consumer scopes exist. There is no safety or parental app category; Sway would file as "User Tools".
Route B — Cookie (.ROBLOSECURITY) Do not build
Tested on 3 Sep 2026 with the session cookie of test account thmainaccount2 against the
internal *.roblox.com web endpoints. Shapes were captured; no field values, friend names or
message bodies were retained.
| Region | Endpoint | Returned |
|---|---|---|
| Friends | friends.roblox.com/v1/users/{id}/friends | Array of 67 — userId, username, display name |
| Followers | …/followers/count | Count |
| Direct messages | privatemessages.roblox.com/v1/messages | 4 messages — sender, recipient, subject, body, timestamp, read state |
| Presence | presence.roblox.com/v1/presence/users | userPresenceType, lastLocation, universeId, rootPlaceId, gameId |
| Robux balance | economy.roblox.com | { robux } |
| Account & moderation | users.roblox.com/v1/users/{id} | isBanned, created, description |
| Username history | — | 200, empty for this account |
| Ban state | as above | isBanned |
Even with the cookie, two things stay dark: in-experience chat and playtime / session duration. The cookie fills the social and economic gaps; it does not fill those two.
- It needs the child's full session token — which Roblox's own cookie value prefixes with a do-not-share account-theft warning — and it bypasses 2FA.
- It breaches the Terms clause "Only access an API by the means described in the documentation of that API" and the 2026-04-15 human-only cookie rule. Every one of these endpoints is documented as "Auth: Cookie — not recommended, do not use in production." None accept OAuth.
- Presence is named and prohibited by the 2026-06-02 rich-presence clause. It returns, and surfacing it is forbidden.
- Storing children's session tokens is a breach liability and an App Store / Play review exposure.
The cookie prototype exists to show feasibility, not to endorse it. Once DECISION-1 is recorded it should be retired from this site so it is not mistaken for a plan (DECISION-2).
Route C — Device / OS usage Not yet probed
The only source of actual playtime, and entirely independent of Roblox. Needs a handset and, on iOS, an Apple entitlement.
Android Exact
UsageStatsManager keyed on com.roblox.client, sessions via
queryEvents(). Play permits it as the explicit stalkerware exception, conditional on
IsMonitoringTool, a persistent notification while running, and listing disclosure.
iOS Staircase
DeviceActivityReport is sandboxed from the network. Only threshold event names cross,
so time is encoded in them. Needs family-controls, which gates dev clients — request on
day one. EU-only iOS 26.4 exports exact data.
Console & PC Invisible
Not covered by any mobile approach. Roblox does not disclose DAU by platform. We will undercount and cannot measure by how much — the dashboard must say so.
apps/mobile is on managed Expo 53; this route requires prebuild/bare (DECISION-3).
Route D — Guardian-mediated checklist Shippable now
Surface Roblox's own parental dashboard as a guided in-app checklist: link a parent account, maturity ceiling, spend limit and threshold notifications, review connections, chat settings. Zero API risk, zero automation, honest — and the only thing on this page that could ship this month.
What the prototype can honestly show
| Region | Sanctioned route | Cookie route |
|---|---|---|
| Account & settings | Live partial — no ID-verified, no privacy settings | Live |
| Experiences played | Partial badge-derived, no duration | Current experience only |
| When she played | No | No |
| Device screen time | Pending handset | — |
| Friends | 404 | Live |
| Direct messages | No | Live, full bodies |
| Robux spent | No | Balance live; ledger not probed |
| Privacy & chat | No | Reachable |
| Followers, username history, moderation, ban state | No | Live |
An account-identity panel, a badge-derived "evidence of play" list, a device screen-time panel with its coverage gap stated, and a guided checklist to Roblox's own controls. Real, but much narrower than the page as originally drawn.
Open decisions and blockers
| ID | Item | Status |
|---|---|---|
| DECISION-1 | Cookie route: confirm dropped, or record an explicit override with a name and date | Now decidable both prototypes are live |
| DECISION-2 | If dropped, retire the cookie prototype from this site | Open |
| DECISION-3 | Move apps/mobile off managed Expo for the device route | Open |
| CRED-1 | Open Cloud OAuth app — only an API key was supplied; OAuth is the only model that expresses guardian consent | Outstanding |
| CRED-3 | Apple Developer access to request family-controls | Open |
| CRED-4 | Android device or emulator for usage-access testing | Open |
| S1 | Can an under-13 account complete OAuth consent at all? If not, Route A serves teenagers only | Unverified half-day spike, do before code |
| S4 | Written ruling from Roblox on "Creators may not build or release tools that expose one user's individual data to another user", via the Trusted Flagger programme | Not requested longest lead time — open now |
Both test credentials passed through chat and must be treated as compromised. The Open Cloud API
key ("Swayly") — rotate at the Roblox credentials dashboard; still live as of 3 Sep. The
thmainaccount2 cookie — sign the account out to invalidate it. Do not infer key validity
from the embedded JWT's one-hour expiry; the key authenticated well beyond it.