Media Scoring API Guide
A step-by-step guide on usage of Scoring API to score media.
The Creative Scoring API lets you evaluate media assets against your organization's configured guidelines and receive structured pass/fail results per advertising channel. This guide walks through the full integration end to end.
PrerequisitesYou'll need an API key with
scoring:read_writescope, and at least one Workspace configured in your Vidmob organization. CallGET /v1/organizationto retrieve yourworkspaceIdvalues before you start.
How Scoring Works
Scoring is asynchronous. You submit a media asset, Vidmob queues it through a multi-stage AI pipeline, and results become available when processing completes — typically within 30–60 minutes depending on asset complexity and queue depth.
The workflow is always three steps:
- Submit — Register the asset and receive a
uniqueId - Poll — Check status every 10–15 minutes until
COMPLETE - Fetch — Retrieve the score results
Step 1 — Submit Media
Register your asset with POST /v1/media. At minimum you need a client-side id and a publicly accessible url.
curl -X POST https://public-api.vidmob.com/v1/media \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "spring-campaign-15s-v1",
"version": "1.0",
"url": "https://your-cdn.com/creative.mp4",
"workspaceId": 45914,
"channels": ["META", "TIKTOK"]
}'The response returns a uniqueId — a UUID that permanently identifies this asset in Vidmob. Store it.
{
"status": "OK",
"result": {
"uniqueId": "8576725c-dc61-42c6-bf56-3898ea2523cf"
}
}Key parameters:
| Parameter | Required | Notes |
|---|---|---|
id | Yes | Your client-side identifier |
url | Yes | Direct download URL — must be publicly accessible. Presigned S3 URLs and CDN links work reliably. Auth-gated or redirect URLs can cause silent failures. |
version | No | Part of the deduplication key with id. Use if you track multiple versions of the same asset. |
workspaceId | No | Makes the asset visible in the Vidmob platform UI and applies workspace-specific guidelines. Strongly recommended. |
channels | No | Channels to score against (e.g. META, TIKTOK, DV360). Defaults to channels configured on the workspace scorecard. |
Deduplication: Submitting the same id + version + source combination twice does not re-ingest the asset — Vidmob returns the existing uniqueId with a 409 response. You can use that uniqueId directly.
Step 2 — Poll for Completion
Check processing status with GET /v1/media/{uniqueId}/status. Poll every 10–15 minutes — more frequent polling does not speed up processing.
curl -H "Authorization: Bearer $API_KEY" \
https://public-api.vidmob.com/v1/media/8576725c-dc61-42c6-bf56-3898ea2523cf/status{
"status": "OK",
"result": {
"uniqueId": "8576725c-dc61-42c6-bf56-3898ea2523cf",
"status": "PROCESSING"
}
}Status values:
| Status | Meaning | Action |
|---|---|---|
PROCESSING | In progress | Continue polling |
COMPLETE | Done | Fetch scores |
ERROR | Non-terminal error | Retry after a delay |
UNSUPPORTED | Format not supported | Terminal — do not retry |
FAILED | Processing failed | Terminal — do not retry |
You can also look up by your client-side id instead of uniqueId by appending ?source=<source>&version=<version> query params.
Step 3 — Fetch Scores
Once status is COMPLETE, retrieve results with GET /v1/scoring/media/{uniqueId}/scores.
# Summary only (default)
curl -H "Authorization: Bearer $API_KEY" \
"https://public-api.vidmob.com/v1/scoring/media/8576725c-.../scores"
# Per-guideline detail
curl -H "Authorization: Bearer $API_KEY" \
"https://public-api.vidmob.com/v1/scoring/media/8576725c-.../scores?format=detail&channel=META"The format parameter controls response depth:
| Value | Returns |
|---|---|
summary (default) | Per-channel rollup: score, adherencePercent, pass/fail counts |
detail | Summary + per-guideline breakdown (name, rule, result, weight) |
summary,detail | Both |
Understanding Score Results
score vs adherencePercent — these are two different ways of measuring the same underlying data:
scoreis a weighted aggregate:SUM(passed guideline points) / SUM(total guideline points). Guidelines with higher weight contribute more.adherencePercentis a simple pass rate:passCount / applicableCount. Every guideline counts equally. This is usually the easier number to communicate to stakeholders.
Both range from 0.0 to 1.0.
Per-guideline result values:
| Value | Meaning |
|---|---|
PASS | Guideline met |
FAIL | Guideline not met |
NOT_APPLICABLE | Guideline does not apply to this asset type |
NO_DATA | Could not evaluate — data missing |
NO_DATA_* | Specific data gap, e.g. NO_DATA_MEDIA_NOT_TAGGED |
Only PASS and FAIL results are counted in the score and adherencePercent calculations. NOT_APPLICABLE and NO_DATA results are excluded.
Staying in Sync — Updated Scores
Scores can change after initial processing if a workspace admin overrides a result in the Vidmob platform, or if an asset is rescored against updated guidelines. Use GET /v1/media/updated-scores to poll for assets whose scores have changed since a given timestamp:
curl -H "Authorization: Bearer $API_KEY" \
"https://public-api.vidmob.com/v1/media/updated-scores?workspaceId=45914&updatedSince=2026-04-01T00:00:00Z"The response returns a paginated list of uniqueId values. Re-fetch scores for each using the scores endpoint.
Scorecards and Guidelines
Your workspace's scoring rules are organized into Scorecards — named collections of guidelines associated with specific channels and campaigns. Call GET /v1/scoring/workspace/{workspaceId}/scorecards to see what's configured.
To inspect the full catalog of guidelines (criteria) available to your organization, use POST /v1/scoring/criteria/metadata. This endpoint supports filtering by channel, scorecard, and other dimensions.
Common Integration Patterns
Simple polling loop
import time, requests
headers = {'Authorization': f'Bearer {API_KEY}'}
base = 'https://public-api.vidmob.com/v1'
# 1. Submit
res = requests.post(f'{base}/media', headers=headers, json={
'id': 'my-asset-001', 'url': 'https://cdn.example.com/ad.mp4', 'workspaceId': 45914
})
unique_id = res.json()['result']['uniqueId']
# 2. Poll
while True:
status = requests.get(f'{base}/media/{unique_id}/status', headers=headers).json()['result']['status']
if status == 'COMPLETE':
break
if status in ('FAILED', 'UNSUPPORTED'):
raise Exception(f'Terminal status: {status}')
time.sleep(600) # 10 minutes
# 3. Fetch
scores = requests.get(f'{base}/scoring/media/{unique_id}/scores', headers=headers, params={'format': 'detail'}).json()Tips:
- Store
uniqueIdvalues persistently — they are stable identifiers and you will need them for re-fetching scores. - Use
workspaceIdon every submission unless you intentionally want org-global guidelines only. - If you receive a
409 Conflict, extract the existinguniqueIdfrom the error context and use it directly. - For large-scale integrations, use
GET /v1/media/updated-scoresrather than polling every individual asset.