Read verification and plays
List plays, read their evidence and reconcile your totals.
You need the plays:read scope, plus stats:read for evidence composition. Webhooks tell you about plays as they happen; these endpoints are for detail and for reconciling. Plays and verification scores explains what the fields mean.
List plays
curl "https://api.vojo-media.com/v1/plays?external_id=creative-77&source=YOUR_CMS&band=high&from=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer $VOJO_KEY"for await (const play of listAll((cursor) =>
api.GET("/v1/plays", {
params: {
query: {
cursor,
limit: 100,
external_id: "creative-77",
source: "YOUR_CMS",
band: "high",
from: "2026-10-01T00:00:00Z",
},
},
}),
)) {
console.log(play.id, play.verification);
}{
"data": [{
"id": "vp_cm1vpl4k8s0001d2f6g9h3j5kq",
"screen_id": "cm1scr2w6n0001h8d4k9t3m7ve",
"screen": { "id": "cm1scr2w6n0001h8d4k9t3m7ve", "name": "Lobby North" },
"advertisement_id": null,
"advertisement": null,
"external_play_id": null,
"channel": null,
"started_at": "2026-10-07T09:00:00Z",
"tracks": { "passport": "matched", "harvester": "absent" },
"verification": { "score": 70, "band": "high", "phase": "final", "scored_at": "2026-10-07T09:15:02Z" },
"created_at": "2026-10-07T09:00:01Z",
"updated_at": "2026-10-07T09:15:02Z"
}],
"meta": { "next_cursor": null, "has_more": false }
}Plays are listed newest first. You can filter by:
screen_id,advertisement_idandcampaign_idexternal_id, with an optionalsourceband, which means "at least", soband=highreturnshighandmaxplaysphasefrom(inclusive) andto(exclusive)
A filter id that belongs to another organisation returns 404.
Wait for the final score
A score can still change while phase is preliminary. It becomes final at most about 15 minutes after the play starts, sooner if no Harvester is expected, and then never changes. If you bill or report on scores, use final scores only: filter with phase=final, or subscribe to verification.score.
Read a play's evidence
GET /v1/plays/{play_id} returns one play. GET /v1/plays/{play_id}/events returns its Passport and Harvester events, oldest first:
| Field | What it is |
|---|---|
source |
Where the evidence came from. |
event_type |
For Passport: content_started, fingerprint_sequence_finished or content_finished. |
occurred_at |
When it happened. |
fingerprint |
The fingerprint involved, if any. |
match_status |
How the event was matched to the play. |
See the whole estate
GET /v1/stats/evidence-composition?months=12 counts your plays per UTC month: corroborated, passport_only, harvester_only and unproven. You can filter it by screen_id or advertisement_id. Months with no plays come back as zeros.