Preview a focus on a tracker
/v1/trackers/{id}/focus/previewJudges a proposed Focus on the Tracker's latest Sample without saving it: every Video with its verdict and reason, and how many would be hidden. Its verdicts are kept under that Focus, so setting it afterwards with PUT /v1/trackers/{id}/focus costs nothing more. A kind that cannot take a Focus is 422 focus_unsupported_kind, which lists the kinds that can.
Price
As setting the Focus: +3 credits per Video the model judges, +1 credit per Video must_mention rules out, nothing for a Video already judged under it.
Supports estimate=true: the reply is the price in Credits and whether it would be cached, with no Run created and nothing charged.
A cached result costs the same as a fresh one; cached says which you got.
Parameters
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
id | path | string | Required | — | Tracker id. |
Idempotency-Key | header | string | Optional | — | 1-255 printable ASCII characters. Replaying this key with the same payload returns the original Run (202 while it is still running); a different payload, or a different operation, is a 409 idempotency_conflict. |
estimate | query | boolean | Optional | — | Return { estimate_credits, cached, videos, to_judge } and judge nothing. |
Request body
application/json
object
focusobjectrequiredThe Focus to judge, not saved.textstringrequiredWhich Videos are relevant to you, in plain language, exclusions included, e.g.Apple Inc. and its products (iPhone, Mac, AirPods, iOS). Not the fruit, recipes or orchards.1 to 1000 characters.must_mentionarray of stringUp to 20 terms of at most 60 characters. A Video that has captions or an analysis transcript, and whose caption, hashtags, captions and transcript name none of them (any case, whole term), is off focus without a model call; one with neither goes to the model, so a term said aloud still counts; one naming any is still judged againsttext.
Responses
200 OK
{ run, focus, sample }; sample is null when the Tracker has no Sample yet. With estimate=true, the quote instead.
any of 2 shapes
Option 1object
runobjectrequiredThe Run judging the latest Sample, charged per judgment.idstringrequiredkindstringrequiredWhat was run, e.g.video_lookup.statusstringrequiredone ofrunning,completed,partial,failedpartialkeeps the completed items and charges for them, up to what the Balance covers;failedcharges nothing.created_atstringrequiredRFC 3339.completed_atstringrequirednullableNull while the Run is still running.charge_creditsintegerrequiredWhat this Run actually cost, in Credits. A stored answer costs the same as a fresh one.list_price_creditsintegerrequiredThe full price of the work asked for, in Credits. Equal tocharge_creditsunless the Run charged for only part of it.cachedbooleanrequiredTrue when a stored result answered without paying the vendor.progressobjectWhat a running Research has done so far, refreshed as it works:stage(keywords,searching,filtering,analysing,writing_digest) and the counts known by then —keywords,found,kept,dropped_off_topic, andanalysedofshortlisted. A count is absent until its stage produced it. Absent once the Run settles, and on every other kind.stagestringrequiredone ofkeywords,searching,filtering,analysing,writing_digestkeywordsintegervalue at least 0searchesintegervalue at least 0foundintegervalue at least 0judgedintegervalue at least 0keptintegervalue at least 0dropped_off_topicintegervalue at least 0dropped_unsureintegervalue at least 0shortlistedintegervalue at least 0analysedintegervalue at least 0updated_atstringrequired
focusobjectrequiredThe Focus previewed, as it would be stored.textstringrequiredmust_mentionarray of stringrequired
sampleobjectrequirednullableEvery Video of the latest Sample withfocus: { verdict, reason }. Null when the Tracker has no Sample yet (always on a Creator Tracker).atstringrequiredWhen the latest Sample's Snapshot was taken.statsobjectrequiredThe full Sample's stats, unchanged by the Focus.sampled_videosintegerrequiredviews_totalnumberrequiredviews_mediannumberrequirednullableviews_maxnumberrequirednullablelikes_totalnumberrequiredcomments_totalnumberrequiredengagement_ratenumberrequirednullable
videosarray of objectrequiredIn-focus and unjudged Videos; withinclude_off_focus=true(and on a preview) every Video, each withfocus.platformstringrequiredidstringrequiredurlstringrequirednullabledescriptionstringrequiredposted_atstringrequirednullableduration_secondsnumberrequirednullablethumbnail_urlstringrequirednullablesoundobjectrequirednullableidstringrequiredtitlestringrequirednullable
creatorobjectrequirednullableidstringrequiredhandlestringrequirednullablenamestringrequiredfollower_countnumberrequirednullable
snapshotobjectrequirednullableatstringrequiredviewsnumberrequiredlikesnumberrequiredcommentsnumberrequiredsavesnumberrequired
scoresobjectrequirednullableNull when the creator has no baseline yet.outliernumberrequirednullableViews over the creator's median views.outlier_p90numberrequirednullablepercentilenumberrequirednullableWhere this video sits in the creator's own sample, 0-100.velocityobjectrequirednullableviews_per_hournumberrequiredwindowstringrequired
reasonstringrequirednullablealwaysaged_outaged_outwhen the video is over 30 days old and Scores are null.baselineobjectrequiredThe yardstick every Score on this creator is measured against.median_viewsnumberrequiredp90_viewsnumberrequiredengagement_ratenumberrequirednullableposts_per_weeknumberrequirednullablesampleintegerrequiredconfidencestringrequiredone ofhigh,lowsourcestringrequiredone ofvideos,follower_tiercomputed_atstringrequirednullablestalebooleanrequiredTrue past 7 days; the next lookup refreshes it.
coveragestringalwayspartialPresent only where the platform's index is best-effort.focusobjectverdictstringrequiredone ofin_focus,off_focus,unjudgedunjudged: the Video could not be judged (or is not judged yet) and is shown.reasonstringrequired
off_focus_countintegerrequiredVideos hidden as off focus.focusobjectrequiredtotalintegerrequiredVideos read.in_focusintegerrequiredunjudgedintegerrequiredShown, but not counted in focus.summarystringrequired"N of M in focus".statsobjectrequiredStats over the in-focus Videos only.sampled_videosintegerrequiredviews_totalnumberrequiredviews_mediannumberrequirednullableviews_maxnumberrequirednullablelikes_totalnumberrequiredcomments_totalnumberrequiredengagement_ratenumberrequirednullable
recent_videosobjectOnly on a Creator Tracker: its newest Videos, every one withfocus: { verdict, reason }.videosarray of objectrequiredThe Creator's newest Videos, newest first: in-focus and unjudged ones; withinclude_off_focus=trueevery Video, each withfocus.platformstringrequiredidstringrequiredurlstringrequirednullabledescriptionstringrequiredposted_atstringrequirednullableduration_secondsnumberrequirednullablethumbnail_urlstringrequirednullablesoundobjectrequirednullableidstringrequiredtitlestringrequirednullable
creatorobjectrequirednullableidstringrequiredhandlestringrequirednullablenamestringrequiredfollower_countnumberrequirednullable
snapshotobjectrequirednullableatstringrequiredviewsnumberrequiredlikesnumberrequiredcommentsnumberrequiredsavesnumberrequired
scoresobjectrequirednullableNull when the creator has no baseline yet.outliernumberrequirednullableViews over the creator's median views.outlier_p90numberrequirednullablepercentilenumberrequirednullableWhere this video sits in the creator's own sample, 0-100.velocityobjectrequirednullableviews_per_hournumberrequiredwindowstringrequired
reasonstringrequirednullablealwaysaged_outaged_outwhen the video is over 30 days old and Scores are null.baselineobjectrequiredThe yardstick every Score on this creator is measured against.median_viewsnumberrequiredp90_viewsnumberrequiredengagement_ratenumberrequirednullableposts_per_weeknumberrequirednullablesampleintegerrequiredconfidencestringrequiredone ofhigh,lowsourcestringrequiredone ofvideos,follower_tiercomputed_atstringrequirednullablestalebooleanrequiredTrue past 7 days; the next lookup refreshes it.
coveragestringalwayspartialPresent only where the platform's index is best-effort.focusobjectverdictstringrequiredone ofin_focus,off_focus,unjudgedunjudged: the Video could not be judged (or is not judged yet) and is shown.reasonstringrequired
off_focus_countintegerrequiredVideos hidden as off focus.focusobjectrequiredtotalintegerrequiredVideos read.in_focusintegerrequiredunjudgedintegerrequiredShown, but not counted in focus.summarystringrequired"N of M in focus".statsobjectrequiredStats over the in-focus Videos only.sampled_videosintegerrequiredviews_totalnumberrequiredviews_mediannumberrequirednullableviews_maxnumberrequirednullablelikes_totalnumberrequiredcomments_totalnumberrequiredengagement_ratenumberrequirednullable
Option 2objectReturned instead of a Run when
estimate=true. Nothing is charged. Operations with more to say about a quote add members; the two above are always present.estimate_creditsintegerrequiredWhat the call would be charged, in Credits.cachedbooleanrequiredWhether a stored result can already answer. It does not change the price.
200 · `{ run, focus, sample }`; `sample` is null when the Tracker has no Sample yet. With `estimate=true`, the quote instead.
{
"run": {
"id": "run_8f2c1ad04b",
"kind": "focus_judgment",
"status": "completed",
"created_at": "2026-09-08T09:14:02.418Z",
"completed_at": "2026-09-08T09:14:04.930Z",
"charge_credits": 6,
"list_price_credits": 6,
"cached": false
},
"focus": {
"text": "Hands-on tips for AI video tools. Not product comparisons.",
"must_mention": []
},
"sample": null
}401 Unauthorized
missing_authorization, invalid_key, key_revoked or invalid_token.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.
typestringrequiredtitlestringrequiredstatusintegerrequiredcodestringrequiredone ofmissing_authorization,invalid_key,key_revoked,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,rate_limit_exceeded,concurrency_limit_exceeded,tracker_limit_exceeded,webhook_limit_exceeded,webhook_rotation_in_progress,collection_limit_exceeded,collection_name_taken,collection_kind_mismatch,media_unavailable,vendor_error,source_unavailable,service_unavailable,internal_errorStable machine-readable code.detailstring
401 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/invalid_key",
"title": "Invalid key",
"status": 401,
"code": "invalid_key",
"detail": "That API key does not exist. Keys look like `sk_live_...` and are created in the console."
}402 Payment Required
insufficient_balance — the Balance cannot cover the quote. Nothing is judged.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.
typestringrequiredtitlestringrequiredstatusintegerrequiredcodestringrequiredone ofmissing_authorization,invalid_key,key_revoked,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,rate_limit_exceeded,concurrency_limit_exceeded,tracker_limit_exceeded,webhook_limit_exceeded,webhook_rotation_in_progress,collection_limit_exceeded,collection_name_taken,collection_kind_mismatch,media_unavailable,vendor_error,source_unavailable,service_unavailable,internal_errorStable machine-readable code.detailstring
402 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/insufficient_balance",
"title": "Insufficient balance",
"status": 402,
"code": "insufficient_balance",
"detail": "Your balance is 0 Credits and this operation needs 6 Credits. Nothing was charged.",
"balance_credits": 0,
"required_credits": 6
}404 Not Found
not_found.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.
typestringrequiredtitlestringrequiredstatusintegerrequiredcodestringrequiredone ofmissing_authorization,invalid_key,key_revoked,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,rate_limit_exceeded,concurrency_limit_exceeded,tracker_limit_exceeded,webhook_limit_exceeded,webhook_rotation_in_progress,collection_limit_exceeded,collection_name_taken,collection_kind_mismatch,media_unavailable,vendor_error,source_unavailable,service_unavailable,internal_errorStable machine-readable code.detailstring
404 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/not_found",
"title": "Not found",
"status": 404,
"code": "not_found",
"detail": "No Tracker with that id for this Customer."
}409 Conflict
idempotency_conflict — the same Idempotency-Key with a different payload.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.
typestringrequiredtitlestringrequiredstatusintegerrequiredcodestringrequiredone ofmissing_authorization,invalid_key,key_revoked,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,rate_limit_exceeded,concurrency_limit_exceeded,tracker_limit_exceeded,webhook_limit_exceeded,webhook_rotation_in_progress,collection_limit_exceeded,collection_name_taken,collection_kind_mismatch,media_unavailable,vendor_error,source_unavailable,service_unavailable,internal_errorStable machine-readable code.detailstring
409 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/idempotency_conflict",
"title": "Idempotency conflict",
"status": 409,
"code": "idempotency_conflict",
"detail": "This Idempotency-Key was used with a different payload.",
"run_id": "run_8f2c1ad04b"
}429 Too Many Requests
rate_limit_exceeded, with Retry-After.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.
typestringrequiredtitlestringrequiredstatusintegerrequiredcodestringrequiredone ofmissing_authorization,invalid_key,key_revoked,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,rate_limit_exceeded,concurrency_limit_exceeded,tracker_limit_exceeded,webhook_limit_exceeded,webhook_rotation_in_progress,collection_limit_exceeded,collection_name_taken,collection_kind_mismatch,media_unavailable,vendor_error,source_unavailable,service_unavailable,internal_errorStable machine-readable code.detailstring
429 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/rate_limit_exceeded",
"title": "Rate limit exceeded",
"status": 429,
"code": "rate_limit_exceeded",
"detail": "60 requests per minute per key. Retry after the number of seconds in `Retry-After`.",
"limit": 60
}Request samples
Use ShortsIntel to preview a focus on a tracker.
- id: trk_4b1e90c7aa
Tell me what it will cost before you run it, then summarise what you find.
If you don't have ShortsIntel tools, don't guess: tell me to connect it first. Add the MCP server https://www.shortsintel.com/api/mcp (or install the ShortsIntel plugin), sign in, and retry. Setup guide: https://www.shortsintel.com/docs/mcpcurl -X POST "https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/focus/preview" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"focus":{"text":"text","must_mention":["must_mention"]}}'const response = await fetch(
"https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/focus/preview",
{
method: "POST",
headers: {
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"focus": {
"text": "text",
"must_mention": [
"must_mention"
]
}
}),
},
);
if (!response.ok) {
throw new Error(`ShortsIntel ${response.status}`);
}
const data = await response.json();import requests
response = requests.post(
"https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/focus/preview",
headers={
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json",
},
json={
"focus": {
"text": "text",
"must_mention": [
"must_mention",
],
},
},
)
response.raise_for_status()
data = response.json()Related guides
- Pricing and estimates: Credits, estimates and why a cached result costs the same as a fresh one.
- Trackers: Standing watches on a creator or a Meta or TikTok Advertiser: how a cycle runs, when it reports a change, and how to pause one.