Guide

User Accounts REST API

Authenticated routes for external (Firebase) users. There is no server-side password registration route.

Base path: /wp-json/prc-api/v3/user-accounts/

Auth summary

Most routes use external_user_permissions_check, which validates Firebase identity from headers:

HeaderPurpose
X-PRC-User-IdFirebase user ID
X-PRC-User-TokenFirebase ID token

POST /get-user also requires JSON body nonce verified against prc-user-accounts.

Routes

MethodPathPurpose
POST/get-userReturn user data (nonce + auth headers)
POST/complete-profilePersist profile fields after sign-in
GET / POST/saved-articlesList or save articles
DELETE/saved-articles/{post_id}Remove a saved article
GET / POST/starred-filesList or star protected files
DELETE/starred-files/{attachment_id}Remove a starred file
GET / POST / DELETE/listening-historyList, log, or clear listening history
DELETE/delete-userDelete the external account (email required)
POST/protected-files/downloadGrant a protected attachment URL and log it on the user
POST/protected-files/zipZip granted attachments and stream application/zip
GET/private-files/download-statsPer-block download totals and month/day log (edit_post)
POST/protected-files/protectMark an attachment as DRM protected (upload_files)
POST/protected-files/unprotectClear protection (409 if a dataset still uses the file)

Protected files

Reference

POST /protected-files/download body

Typed options, defaults, and constraints in one scannable reference.
3 fields
attachment_id number required
Media library attachment ID.
post_id number
Host post that contains the Private Files block.
instance_id string
Private Files block instance UUID. When set with post_id, a successful grant increments that block’s download ledger.

The token is verified before a file URL is returned. Frontend markup never includes the URL. Extra gates (dataset ATP) hook prc_user_accounts_can_grant_protected_file. The Private Files view calls this route with native fetch and Firebase headers only. Pass post_id and instance_id so WordPress can record totals, per-file counts, and month/day buckets on that block.

Reference

POST /protected-files/zip body

Typed options, defaults, and constraints in one scannable reference.
3 fields
attachment_ids number required
Media library attachment IDs. Capped at 50 unique IDs.
post_id number
Host post that contains the Private Files block.
instance_id string
Private Files block instance UUID. When set with post_id, a successful zip increments that block once per unique listed file.

Zip uses the same header auth as download. Every ID must pass grant_for_user() with source private-files-zip. Any denial returns JSON zip_blocked (403) with data.blocked and a server-composed message. Success is a zip stream. File URLs are never included in zip JSON errors. Pass post_id and instance_id so WordPress can record each unique listed file on that block.

Private Files download stats

GET /private-files/download-stats?post_id=&instance_id= requires edit_post on that post. The response is { total, files, log, daily } for that block instance only. files is all-time per-attachment counts. log and daily are yearly month and day maps, the same shape the dataset heatmap reads.

Starred files

Reference

POST /starred-files body

Typed options, defaults, and constraints in one scannable reference.
1 field
attachment_id number required
Protected media library attachment ID. Title and mime are derived on the server.

GET /starred-files returns the starredFiles map. Starring requires a protected attachment and does not run the download grant filter. Entries are { starredAt, title, mime } at users/{uid}/starredFiles/{id}.

Complete profile

Reference

POST /complete-profile body

Typed options, defaults, and constraints in one scannable reference.
6 fields
firstName string required
Given name.
lastName string required
Family name.
captchaToken string
Turnstile token when captcha is enabled.
country string
Stored as profile location.
industry string
Industry field.
organization string
Organization field.

Handler writes Firebase RTDB profile data and updates Firebase Auth displayName.

Saved articles

Reference

POST /saved-articles body

Typed options, defaults, and constraints in one scannable reference.
3 fields
postId number required
WordPress post ID.
postTitle string
Optional title snapshot.
postUrl url
Optional URL snapshot.

Listening history

POST /listening-history accepts postId (required) plus optional postTitle, audioUrl, postUrl, duration, and playProgress.

Delete user

Request DELETE /wp-json/prc-api/v3/user-accounts/delete-user
HeadersKey: value
X-PRC-User-Id firebase-uidX-PRC-User-Token firebase-id-tokenContent-Type application/json
Request bodyJSON
{
  "email": "user@example.com"
}
Response 200 OK
BodyJSON
{
  "success": true
}

Was this helpful?