Appearance
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| Parameter | In | Description |
|---|---|---|
tenant | path | Your tenant id. |
event | path | The event id to build the manifest for. |
type | query | Optional. 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
| Field | Type | Description |
|---|---|---|
eventId | string | The event id. |
eventStart | string | null | ISO 8601 instant that offsetSec is measured from. |
eventStartSource | string | null | How 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). |
manifest | array | The content events, oldest first. |
Entry fields
| Field | Type | Description |
|---|---|---|
offsetSec | number | Whole seconds from eventStart. Never negative. |
type | string | One of the content types. |
label | string | A human-readable label, always present. |
timestamp | string | Wall-clock time of the action, ISO 8601. |
data | object | Type-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
| Status | Meaning |
|---|---|
400 | An unknown value was passed to type. |
401 | Missing/invalid API key or token, or not a tenant administrator. |
404 | The event does not exist for that tenant. |
429 | Rate limit exceeded (60 requests/minute per tenant). |
500 | The manifest could not be built. |