Skip to content

Content Manifest API

The Content Manifest API exposes what happened on screen during an event as a searchable, timestamped timeline. It turns the actions your operators took live — speaker lower thirds, Bible verses, songs, and info banners — into structured, machine-readable metadata you can pull into a Media Asset Management (MAM) system or a post-production workflow.

Typical uses:

  • Automated chaptering — generate video chapters from speaker changes.
  • Deep content search — make your video library searchable by the exact Bible verse or song shown during a meeting.
  • Post-production speed — hand editors the precise offset of each segment (e.g. "the sermon started at 00:14:05").
  • Asset enrichment — auto-tag media files with metadata extracted from the live session.

Endpoint

GET /manifest/:tenant/:event
ParameterInDescription
tenantpathYour tenant id.
eventpathThe event id to build the manifest for.
typequeryOptional. Comma-separated content-type filter (see Types). Case-insensitive.

Authentication

Two schemes are accepted; the tenant API key is the intended one for integrations.

Tenant API key (recommended for MAM systems and scripts) — generate it in Settings → General → API Key. The key is shown once at generation; store it in your integration's secret store. Send it in a header — either works:

X-Api-Key: <api-key>
Authorization: Bearer <api-key>

The key is scoped to your tenant: it can only read events under the tenant it belongs to. Regenerating the key invalidates the previous one immediately. API keys are never accepted in the URL or query string.

Firebase ID token (for interactive testing) — a signed-in tenant administrator's token also works:

Authorization: Bearer <firebase-id-token>

Requests are rate limited per tenant (60 requests/minute); exceeding the limit returns 429.

Example

bash
curl -H "X-Api-Key: $API_KEY" \
  "https://<host>/manifest/my-church/sunday-service-2026-06-24?type=SPEAKER,SCRIPTURE"

Response

json
{
  "eventId": "sunday-service-2026-06-24",
  "eventStart": "2026-06-24T10:00:00.000Z",
  "eventStartSource": "scheduled",
  "manifest": [
    {
      "offsetSec": 342,
      "type": "SPEAKER",
      "label": "John Doe",
      "timestamp": "2026-06-24T10:05:42.000Z",
      "data": {
        "personId": "p-123",
        "uid": "uuid-john-doe",
        "name": "John Doe"
      }
    },
    {
      "offsetSec": 1205,
      "type": "SCRIPTURE",
      "label": "Psalm 23:1",
      "timestamp": "2026-06-24T10:20:05.000Z",
      "data": {
        "book": "Psalm",
        "chapter": 23,
        "verseFrom": 1,
        "verseTo": 1,
        "label": "Psalm 23:1"
      }
    }
  ]
}

Envelope fields

FieldTypeDescription
eventIdstringThe event id.
eventStartstring | nullISO 8601 instant that offsetSec is measured from.
eventStartSourcestring | nullHow the start was anchored: scheduled (from the event's date + start time, in UTC) or firstAction (the first content action, used when no scheduled start is set).
manifestarrayThe content events, oldest first.

Entry fields

FieldTypeDescription
offsetSecnumberWhole seconds from eventStart. Never negative.
typestringOne of the content types.
labelstringA human-readable label, always present.
timestampstringWall-clock time of the action, ISO 8601.
dataobjectType-specific structured metadata (see below).

Only content-bearing actions appear. Show/hide toggles, blackouts, and timer actions are operational state changes, not content, and are omitted.

Legacy events

Events recorded before structured metadata was captured still export: their entries carry the correct type, label, timestamp, and offsetSec, with a data object containing at least { "label": "…" }.

Content types

Filter with ?type= using any combination of the following.

SPEAKER — person lower third

json
{ "personId": "p-123", "uid": "uuid-john-doe", "name": "John Doe" }

SONG — song lower third

json
{
  "uid": "song-abc",
  "key": "HV 123",
  "metadata": {
    "author": "John Newton",
    "composer": null,
    "arranger": null,
    "soloist": null
  }
}

SCRIPTURE — Bible verse

json
{ "book": "Psalm", "chapter": 23, "verseFrom": 1, "verseTo": 1, "label": "Psalm 23:1" }

TWOLINES — info / two-line text lower third

json
{ "text": "Welcome to the service" }

SLIDE

Reserved for screen/slide changes. Accepted by the type filter but not emitted yet, as screen changes are not currently recorded in the event's content trail.

Errors

StatusMeaning
400An unknown value was passed to type.
401Missing/invalid API key or token, or not a tenant administrator.
404The event does not exist for that tenant.
429Rate limit exceeded (60 requests/minute per tenant).
500The manifest could not be built.

All rights reserved.