Enrichment States
Examples of resources at different stages of the enrichment lifecycle. These patterns are validated by the progressive enrichment and enrichment sync test suites.
Partial Enrichment — Video (FAST)
Initial request for heavy media. Core stages completed, preview stages pending.
{
"processing": {
"status": "partial",
"completion": 0.33,
"enrichmentsPending": true,
"completedStages": ["semantic", "mediaFormat"],
"pendingStages": ["metadata:video", "preview:thumbnail", "preview:blurhash", "preview:palette"]
},
"data": {
"identity": { "url": "https://download.blender.org/.../BigBuckBunny_320x180.mp4", "mime": "video/mp4" },
"semantic": { "kind": "direct-media", "semanticType": "video" },
"playback": { "strategy": "native", "component": "video", "streamable": true, "downloadable": true },
"metadata": { "filename": "BigBuckBunny_320x180.mp4", "size": { "bytes": 56733664, "formatted": "54.1 MB" } }
}
}Partial Enrichment — Image (STANDARD)
Image with metadata completed but preview generation still pending. Progressive null semantics show supported-but-pending enrichments.
{
"processing": {
"status": "partial",
"completion": 0.5,
"enrichmentsPending": true,
"completedStages": ["semantic", "mediaFormat", "metadata:image"],
"pendingStages": ["preview:thumbnail", "preview:blurhash", "preview:palette"]
},
"data": {
"metadata": {
"filename": "image.jpg",
"size": { "bytes": 2048, "formatted": "2 KB" },
"image": { "colorSpace": "srgb", "hasAlpha": false }
},
"preview": {
"thumbnail": null, // ← supported, pending
"placeholder": null, // ← supported, pending
"palette": null // ← supported, pending
}
}
}Null Semantics
null means the enrichment is supported for this media category and is registered in the lifecycle, but the worker hasn't completed yet. This is distinct from omission (unsupported).
Complete Enrichment — Image (FULL)
All enrichment stages finished. completion: 1, no pending stages.
{
"processing": {
"status": "complete",
"completion": 1,
"enrichmentsPending": false,
"completedStages": [
"semantic", "mediaFormat", "metadata:image",
"preview:thumbnail", "preview:blurhash", "preview:palette"
],
"pendingStages": []
},
"data": {
"metadata": {
"filename": "god_16.jpg",
"size": { "bytes": 204800, "formatted": "200 KB" },
"image": { "colorSpace": "srgb", "hasAlpha": false }
},
"preview": {
"thumbnail": { "url": "/public/thumbnails/generated.jpg", "dimensions": "320x180" },
"placeholder": { "type": "blurhash", "value": "LEHV6nWB2yk8pyo0adR*.7kCMdnj" },
"palette": { "dominant": "#112233" },
"dominantColor": "#112233"
}
}
}Complete Enrichment — YouTube (Provider-Native)
Provider resources complete immediately — no background workers needed.
{
"processing": {
"status": "complete",
"completion": 1,
"enrichmentsPending": false,
"completedStages": ["semantic", "mediaFormat", "oembed"],
"pendingStages": []
},
"data": {
"provider": { "name": "youtube", "confidence": 1, "detectionMethod": "url-parser" },
"preview": { "thumbnail": { "url": "https://i.ytimg.com/vi/GLTTI1NFHus/hqdefault.jpg" } }
},
"enrichmentSources": { "semantic": "fresh", "mediaFormat": "fresh", "oembed": "fresh" }
}Lifecycle Progression
The same resource evolves over multiple requests:
Step 1 — FAST (Partial)
{ "processing": { "status": "partial", "completion": 0.33, "completedStages": ["semantic", "mediaFormat"] } }Step 2 — Wait (Background Workers)
Workers generate thumbnail, compute blurhash, extract palette.
Step 3 — FULL (Complete)
{ "processing": { "status": "complete", "completion": 1, "completedStages": ["semantic", "mediaFormat", "metadata:video", "preview:thumbnail", "preview:blurhash", "preview:palette"] } }Non-Regression Guarantee
Step 3 completion is always ≥ Step 1 completion. Enrichments never regress.
Async Orchestration (202 Accepted)
STANDARD profile on heavy media returns partial data with a job reference:
// HTTP 202 Accepted
{
"success": true,
"responseSource": "fresh",
"processing": { "status": "partial", "enrichmentsPending": true },
"job": { "id": "job_abc123", "status": "processing" },
"data": {
"identity": { /* always available */ },
"semantic": { /* always available */ }
}
}Even 202 responses include partial data (identity + semantic) — they are never just a job reference.