Overview
The Vidmob Public API exposes two product areas:
- Scoring API — Submit external media assets for evaluation against a workspace's configured guidelines. Results are returned per advertising channel and per guideline.
- Creative Tags API (Aperture) — Submit media assets for AI-powered attribute analysis. Returns structured tags describing visual/audio elements. Tagging is a prerequisite for many scoring rules.
Both share the same base URL, authentication model, and core data model.
Key Concepts and Terminology
Organization and Workspace
An Organization is the top-level account entity — typically a brand or agency. An organization contains one or more Workspaces (logical containers for scorecards, criteria, and media scoped to a team/brand/product line).
Most API calls accept a numeric workspaceId. Use GET /v1/workspaces to enumerate the workspaces your key can access; it returns {id, name} per workspace and is paginated (73 workspaces on the test org).
GET /v1/organization returns only {id, name} for the organization itself. It does not enumerate workspaces. If a guide tells you to get workspaceId from /v1/organization, that guide is wrong.
Scorecard
A Scorecard is a named collection of scored media within a workspace, configured against a set of channels and guidelines. The type field distinguishes them, and the API accepts five values:
type | Meaning |
|---|---|
IN_FLIGHT | Ongoing/active campaigns whose performance is being tracked. Stores a single platform |
PRE_FLIGHT | Pre-launch checks against a creative before it ships. May store a comma-separated list of intended platforms |
AD_ACCOUNT | Ad-account-scoped batch |
PLUGIN_MEDIA | Media submitted through a Vidmob plugin |
API_MEDIA | Media submitted through this API with a workspaceId. One batch per asset, shown in ACS under Pre-test → API Submissions. Not listable via this endpoint and not served by media-metadata — retrieve API-submitted media per asset via /scores (see the integration pattern section) |
Scorecards are configured inside the Vidmob platform; the API exposes them as read-only references.
A PRE_FLIGHT scorecard may be configured against several channels at once. This affects which scorecards the media-metadata endpoint can return results for.
Channel
A Channel is an advertising platform (Meta, Google Ads, TikTok, etc.). Guidelines are channel-specific. One asset can be scored against multiple channels in a single submission.
The API is not internally consistent about channel names. See Channel Identifiers — read that section before writing any channel-handling code.
Guideline (Criterion)
A Guideline (called a Criterion in the API) is a single evaluable rule. Each guideline targets a specific channel and creative type. When a media asset is scored, each applicable guideline returns PASS, FAIL, NOT_APPLICABLE, or a NO_DATA_* code.
The endpoint path uses criteria (/v1/scoring/criteria/metadata); field names and UI language use "guideline." They are the same thing.
Note that the criterion id is returned as a JSON string ("id": "111"), not a number.
Guideline Group (Criterion Group)
A Criterion Group is a named collection of guidelines within a workspace, used to organize/filter results.
Groups are metadata — they do not change scoring, only its organization. A guideline can belong to multiple groups or none.
The criteriaGroups field is only returned by POST /v1/scoring/criteria/metadata. It is not returned by the scores endpoint.
Score vs. Adherence
The scores endpoint returns two metrics per channel:
- score — Weighted aggregate across scored guidelines, where each guideline's
weightdetermines its contribution. Range 0.0–1.0, ornull. - adherencePercent — Unweighted pass rate. Range 0.0–1.0, or
null.
The denominator for adherencePercent is passCount + failCount, not applicableCount.
Worked example from a live response:
{ "score": 0.5789473684210527, "adherencePercent": 0.5789473684210527,
"passCount": 11, "failCount": 8, "applicableCount": 20,
"notApplicableCount": 2, "notAvailableCount": 1 }11 / (11 + 8) = 0.5789473684210527 matches. 11 / 20 = 0.55 does not. Guidelines that returned a NO_DATA_* code are excluded from the ratio even though they are counted in applicableCount.
Both metrics are null when nothing was scored for that channel:
{ "score": null, "adherencePercent": null, "passCount": 0, "failCount": 0,
"applicableCount": 0, "notApplicableCount": 0, "notAvailableCount": 0 }Every channel key is present in the summary object whether or not it was scored, so treat null as "not scored for this channel" and guard against it before doing arithmetic.
In the sample above score and adherencePercent are identical because every guideline carried the same weight.
Weights do vary in practice (values as low as 0.01 appear in the criteria catalog), so do not assume the two metrics are interchangeable. When guideline weights differ, score and adherencePercent diverge.
Media identifiers
When you submit an asset via POST /v1/media, Vidmob assigns a uniqueId (UUID) that permanently identifies the asset.
Subsequent endpoints accept either:
- The
uniqueId, or - Your client-side
idplussourceandversionquery parameters.
Use one approach or the other — not both.
Submitting the same (id, version, source) again is idempotent: the API returns HTTP 201 with the existing uniqueId and does not re-ingest the media. It does not return 409. Verified by submitting an identical body three times and receiving the same uniqueId each time.
Aperture
Aperture is Vidmob's name for the Creative Tags engine. The endpoints live under /v1/media/aperture. The API key scope is aperture.
Guideline weights vs. Consideration
Each guideline carries a numeric weight that drives the rolled-up channel score.
A separate consideration field (MANDATORY or OPTIONAL) exists for backward compatibility.
New integrations should rely on weight rather than filtering or branching on consideration.
A separate boolean bestPractice field flags whether a guideline is a best-practice rule. consideration and bestPractice are independent — do not conflate them.
Be aware that the consideration filter on criteria metadata is not validated: passing {"consideration":"BOGUS"} returns HTTP 201 and the full unfiltered result set rather than a 400.
Verify your filter actually narrowed the result by comparing pagination.totalSize against an unfiltered call.
Updated about 1 month ago