page-api schema  [ test ui ]

POST /v1/render/page

Request

{
  "userId":        "u_abc123",          // required
  "pageType":      "home",             // "home" | "ministry" | "series" | "card-page"
  "pageContext":   { "slug": null },      // slug for ministry/series pages
  "clientContext": {
    "platform": "web",              // "web" | "ios" | "android" | "firetv" | "roku"
    "tier":     "vine",             // "new" | "vine" | "plus"
    "locale":   "en-US"
  }
}

Response

{
  "templateVersion": "1.0",
  "generatedAt":     "2026-05-13T20:00:00Z",
  "page": {
    "type": "home",
    "hero": {
      "items": [                       // featured content items
        {
          "id":             "101",
          "title":          "The God Who Sees You",
          "speakerName":    "Tony Evans",
          "ministryName":   "Oak Cliff Bible Fellowship",
          "thumbnailUrl":   "https://...",
          "durationDisplay":"32:15"
        }
      ]
    },
    "rails": [
      {
        "id":        "rail_recommended",
        "title":     "Recommended for You",
        "type":      "content",          // "content" | "card"
        "owner":     "trueviAI",         // "trueviAI" | "revidd"
        "order":     1,
        "visibleTo": ["vine", "plus"],
        "items":     [ ... ]            // null when owner="revidd" (Revidd fills at render time)
      }
    ]
  }
}

Rail item shapes

Rail typeowneritems shape
contenttrueviAI{ id, title, speakerName, ministryName, thumbnailUrl, durationDisplay }
contentreviddnull — Revidd populates at render time
cardtrueviAI{ id, title, thumbnailUrl, targetPageSlug }

POST /v1/activity

Request

{
  "userId":    "u_abc123",
  "sessionId": "s_xyz",
  "eventType": "video_progress",   // see table below
  "eventData": { /* event-specific payload */ }
}

Accepted eventType values

eventTypetypical eventData fields
content_viewedcontentId
video_progresscontentId, percentWatched, positionSec
video_completedcontentId
video_abandonedcontentId, positionSec
video_savedcontentId
session_started
session_endeddurationSec

Response

200  { "status": "ok" }
400  { "error": "Unknown eventType: ..." }
401  { "error": "Unauthorized" }

Auth

All endpoints require: Authorization: Bearer <API_TOKEN>