Read a video's metric history
/v1/videos/{platform}/{id}/snapshotsViews and metrics over time, newest first. A metric is null where its Snapshot marks it unreported; one a Platform never reports can still read 0, such as Instagram and Facebook shares and saves. is_ad/paid_partnership appear where recorded. Shared and kept forever, so history predates your first lookup. A video gets Snapshots only while a lookup, search, Creator Tracker page or Keyword, Hashtag or Sound Sample reads it, so those histories have gaps: a missing day is not a drop. not_found until looked up with GET /v1/videos/{platform}/{id}.
Open in Playground (no API Key needed)
Price
Free.
Parameters
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
platform | path | string one of tiktok, instagram, youtube, facebook | Required | — | Platform the subject lives on. |
id | path | string | Required | — | Platform video id. |
limit | query | integer min 1; max 100 | Optional | 25 | Items per page. |
cursor | query | string | Optional | — | Opaque next_cursor from the previous page. |
Responses
200 OK
{ items, next_cursor }.
object
A page of a list. items holds the page; pass next_cursor back as cursor for the next one.
next_cursorstring required nullable Pass back ascursor. Null on the last page.itemsarray of object requiredatstring required When the metrics were read.viewsnumber required nullable Views atat. Null when the Snapshot marks them unreported.metricsobject required The public metrics recorded atat.viewsnumber required nullable Views. Null when the Snapshot marks it unreported.likesnumber required nullable Likes. Null when the Snapshot marks it unreported.commentsnumber required nullable Comments. Null when the Snapshot marks it unreported.savesnumber required nullable Saves. Null when the Snapshot marks it unreported.is_adboolean nullable The Platform marked the video as an ad atat. Present only when the read recorded ad flags.paid_partnershipboolean nullable The Platform marked a paid partnership atat. Present only when the read recorded ad flags.
sourcestring requiredvendororbackfill.
200 · `{ items, next_cursor }`.
{
"items": [
{
"at": "2026-09-08T09:14:04.219Z",
"views": 1284000,
"metrics": {
"views": 1284000,
"likes": 98200,
"comments": 1410,
"shares": 3020,
"saves": 7650,
"is_ad": false,
"paid_partnership": false
},
"source": "vendor"
},
{
"at": "2026-09-07T09:12:58.104Z",
"views": 912400,
"metrics": {
"views": 912400,
"likes": 70150,
"comments": 1022,
"shares": 2210,
"saves": null
},
"source": "vendor"
}
],
"next_cursor": "eyJpZCI6ImNsdjRxOHoifQ"
}400 Bad Request
invalid_request for a cursor that is not a next_cursor this API issued. Nothing is charged.
Code: invalid_request. The problem body and every code are on Errors.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose. retryable and action say whether to retry and what to do next.
typestring requiredtitlestring requiredstatusinteger requiredcodestring required one ofmissing_authorization,invalid_key,key_revoked,key_expired,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,key_scope_insufficient,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,comment_not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,max_credits_exceeded,key_spend_cap_exceeded,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.detailstringerrorsarray of object Oninvalid_requestfrom a field that failed validation: one entry per problem, so you can find the field without parsingdetail. Absent when no single field is at fault, e.g. a body that is not JSON.pathstring required Dotted path of the field to fix, e.g.collection_ids.1orcursor. Empty for an issue with the request body as a whole.messagestring required What is wrong with that field.
request_idstring The request this problem answers, the same as itsX-Request-Idheader. Quote it to support.retryableboolean required Whether sending the same request again, after any wait named here, can succeed:truefor a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled;falsewhen the request must change or a person must act. Fixed percode.actionstring required The next step, in one sentence.remedystring What to do next, as the code's error reference page says it; fuller thanaction. On every problem a request answers with; a per-itemerrorinside a result may omit it.retry_after_secondsinteger value at least 0 Seconds to wait before retrying; the same as theRetry-Afterheader. Onrate_limit_exceeded,concurrency_limit_exceeded,source_unavailableandservice_unavailable.expired_atstring When the key expired. Onkey_expired.resets_atstring When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.limitinteger The limit that was hit, on the*_limit_exceededcodes.runninginteger Runs in flight. Onconcurrency_limit_exceeded.activeinteger Active Trackers or webhook endpoints. Ontracker_limit_exceededandwebhook_limit_exceeded.requestedinteger Trackers the request would resume. Ontracker_limit_exceededfrom a Collection action.countinteger Collections held. Oncollection_limit_exceeded.balance_creditsinteger The Balance, in Credits. Oninsufficient_balance.required_creditsinteger What the call needs, in Credits (the worst case where quoted). Oninsufficient_balance.max_creditsinteger The cap the call sent. Onmax_credits_exceeded.estimate_creditsinteger The call's worst-case quote, in Credits. Onmax_credits_exceededandkey_spend_cap_exceeded.cap_creditsinteger The key's monthly cap. Onkey_spend_cap_exceeded.spent_creditsinteger The key's Charges this UTC month. Onkey_spend_cap_exceeded.reserved_creditsinteger What the key's Runs in flight hold. Onkey_spend_cap_exceeded.endpointsarray of string The sources that could not answer. Onsource_unavailable.endpointstring The source that could not answer. Onsource_unavailable.candidatesarray of object The advertisers that carry the name, to ask again with. Onadvertiser_ambiguous.supported_kindsarray of string The kinds that are accepted. Onkind_deprecatedandfocus_unsupported_kind.duration_secondsnumber The video's length. Onvideo_too_long.max_duration_secondsnumber The longest video accepted. Onvideo_too_long.overlap_expires_atstring When the previous secret stops working. Onwebhook_rotation_in_progress.scopestring alwaysread_onlyThe key's scope. Onkey_scope_insufficient.requiredstring alwaysfullThe scope the call needs. Onkey_scope_insufficient.collection_idstring The Collection that already has the name. Oncollection_name_taken.collection_kindstring The Collection's kind. Oncollection_kind_mismatch.kindstring The kind that was offered. Oncollection_kind_mismatch.run_idstring The Run the Idempotency-Key already belongs to. Onidempotency_conflict.reasonstring A short machine-readable reason, where a code has several.reference_idstring Our reference for an unexpected failure, the same asrequest_id; quote it when reporting it.runobject The Run, on a failed Run's body, so its id is kept.idstring requiredkindstring required What was run, e.g.video_lookup.statusstring required one ofrunning,completed,partial,failedpartialkeeps the completed items and charges for them, up to what the Balance covers;failedcharges nothing.created_atstring required RFC 3339.completed_atstring required nullable Null while the Run is still running.charge_creditsinteger required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.list_price_creditsinteger required The full price of the work asked for, in Credits. Equal tocharge_creditsunless the Run charged for only part of it.cachedboolean required True when a stored result answered without a fresh fetch.progressobject What 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.stagestring required one ofkeywords,searching,filtering,analysing,writing_digestkeywordsinteger value at least 0searchesinteger value at least 0foundinteger value at least 0judgedinteger value at least 0keptinteger value at least 0dropped_off_topicinteger value at least 0dropped_unsureinteger value at least 0shortlistedinteger value at least 0analysedinteger value at least 0updated_atstring required
errorobject The same problem, nested, on a failed Run's body.
400 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/invalid_request",
"title": "Invalid request",
"status": 400,
"code": "invalid_request",
"detail": "`cursor` is not a cursor this API issued. Pass back the `next_cursor` from the previous page.",
"retryable": false,
"action": "Fix the field named in `detail`, then send the corrected request."
}401 Unauthorized
missing_authorization, invalid_key, key_revoked, key_expired or invalid_token.
Codes: missing_authorization, invalid_key, key_revoked, key_expired, invalid_token. The problem body and every code are on Errors.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose. retryable and action say whether to retry and what to do next.
typestring requiredtitlestring requiredstatusinteger requiredcodestring required one ofmissing_authorization,invalid_key,key_revoked,key_expired,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,key_scope_insufficient,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,comment_not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,max_credits_exceeded,key_spend_cap_exceeded,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.detailstringerrorsarray of object Oninvalid_requestfrom a field that failed validation: one entry per problem, so you can find the field without parsingdetail. Absent when no single field is at fault, e.g. a body that is not JSON.pathstring required Dotted path of the field to fix, e.g.collection_ids.1orcursor. Empty for an issue with the request body as a whole.messagestring required What is wrong with that field.
request_idstring The request this problem answers, the same as itsX-Request-Idheader. Quote it to support.retryableboolean required Whether sending the same request again, after any wait named here, can succeed:truefor a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled;falsewhen the request must change or a person must act. Fixed percode.actionstring required The next step, in one sentence.remedystring What to do next, as the code's error reference page says it; fuller thanaction. On every problem a request answers with; a per-itemerrorinside a result may omit it.retry_after_secondsinteger value at least 0 Seconds to wait before retrying; the same as theRetry-Afterheader. Onrate_limit_exceeded,concurrency_limit_exceeded,source_unavailableandservice_unavailable.expired_atstring When the key expired. Onkey_expired.resets_atstring When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.limitinteger The limit that was hit, on the*_limit_exceededcodes.runninginteger Runs in flight. Onconcurrency_limit_exceeded.activeinteger Active Trackers or webhook endpoints. Ontracker_limit_exceededandwebhook_limit_exceeded.requestedinteger Trackers the request would resume. Ontracker_limit_exceededfrom a Collection action.countinteger Collections held. Oncollection_limit_exceeded.balance_creditsinteger The Balance, in Credits. Oninsufficient_balance.required_creditsinteger What the call needs, in Credits (the worst case where quoted). Oninsufficient_balance.max_creditsinteger The cap the call sent. Onmax_credits_exceeded.estimate_creditsinteger The call's worst-case quote, in Credits. Onmax_credits_exceededandkey_spend_cap_exceeded.cap_creditsinteger The key's monthly cap. Onkey_spend_cap_exceeded.spent_creditsinteger The key's Charges this UTC month. Onkey_spend_cap_exceeded.reserved_creditsinteger What the key's Runs in flight hold. Onkey_spend_cap_exceeded.endpointsarray of string The sources that could not answer. Onsource_unavailable.endpointstring The source that could not answer. Onsource_unavailable.candidatesarray of object The advertisers that carry the name, to ask again with. Onadvertiser_ambiguous.supported_kindsarray of string The kinds that are accepted. Onkind_deprecatedandfocus_unsupported_kind.duration_secondsnumber The video's length. Onvideo_too_long.max_duration_secondsnumber The longest video accepted. Onvideo_too_long.overlap_expires_atstring When the previous secret stops working. Onwebhook_rotation_in_progress.scopestring alwaysread_onlyThe key's scope. Onkey_scope_insufficient.requiredstring alwaysfullThe scope the call needs. Onkey_scope_insufficient.collection_idstring The Collection that already has the name. Oncollection_name_taken.collection_kindstring The Collection's kind. Oncollection_kind_mismatch.kindstring The kind that was offered. Oncollection_kind_mismatch.run_idstring The Run the Idempotency-Key already belongs to. Onidempotency_conflict.reasonstring A short machine-readable reason, where a code has several.reference_idstring Our reference for an unexpected failure, the same asrequest_id; quote it when reporting it.runobject The Run, on a failed Run's body, so its id is kept.idstring requiredkindstring required What was run, e.g.video_lookup.statusstring required one ofrunning,completed,partial,failedpartialkeeps the completed items and charges for them, up to what the Balance covers;failedcharges nothing.created_atstring required RFC 3339.completed_atstring required nullable Null while the Run is still running.charge_creditsinteger required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.list_price_creditsinteger required The full price of the work asked for, in Credits. Equal tocharge_creditsunless the Run charged for only part of it.cachedboolean required True when a stored result answered without a fresh fetch.progressobject What 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.stagestring required one ofkeywords,searching,filtering,analysing,writing_digestkeywordsinteger value at least 0searchesinteger value at least 0foundinteger value at least 0judgedinteger value at least 0keptinteger value at least 0dropped_off_topicinteger value at least 0dropped_unsureinteger value at least 0shortlistedinteger value at least 0analysedinteger value at least 0updated_atstring required
errorobject The same problem, nested, on a failed Run's body.
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.",
"retryable": false,
"action": "Check the whole key was copied, or create a new key in the console."
}404 Not Found
not_found — including anything belonging to another Customer.
Code: not_found. The problem body and every code are on Errors.
object
RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose. retryable and action say whether to retry and what to do next.
typestring requiredtitlestring requiredstatusinteger requiredcodestring required one ofmissing_authorization,invalid_key,key_revoked,key_expired,invalid_token,organization_not_selected,organization_access_revoked,connection_revoked,forbidden,key_scope_insufficient,invalid_request,unsupported_platform,unsupported_kind,kind_deprecated,focus_unsupported_kind,not_found,comment_not_found,video_too_long,idempotency_conflict,run_not_ready,advertiser_ambiguous,insufficient_balance,max_credits_exceeded,key_spend_cap_exceeded,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.detailstringerrorsarray of object Oninvalid_requestfrom a field that failed validation: one entry per problem, so you can find the field without parsingdetail. Absent when no single field is at fault, e.g. a body that is not JSON.pathstring required Dotted path of the field to fix, e.g.collection_ids.1orcursor. Empty for an issue with the request body as a whole.messagestring required What is wrong with that field.
request_idstring The request this problem answers, the same as itsX-Request-Idheader. Quote it to support.retryableboolean required Whether sending the same request again, after any wait named here, can succeed:truefor a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled;falsewhen the request must change or a person must act. Fixed percode.actionstring required The next step, in one sentence.remedystring What to do next, as the code's error reference page says it; fuller thanaction. On every problem a request answers with; a per-itemerrorinside a result may omit it.retry_after_secondsinteger value at least 0 Seconds to wait before retrying; the same as theRetry-Afterheader. Onrate_limit_exceeded,concurrency_limit_exceeded,source_unavailableandservice_unavailable.expired_atstring When the key expired. Onkey_expired.resets_atstring When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.limitinteger The limit that was hit, on the*_limit_exceededcodes.runninginteger Runs in flight. Onconcurrency_limit_exceeded.activeinteger Active Trackers or webhook endpoints. Ontracker_limit_exceededandwebhook_limit_exceeded.requestedinteger Trackers the request would resume. Ontracker_limit_exceededfrom a Collection action.countinteger Collections held. Oncollection_limit_exceeded.balance_creditsinteger The Balance, in Credits. Oninsufficient_balance.required_creditsinteger What the call needs, in Credits (the worst case where quoted). Oninsufficient_balance.max_creditsinteger The cap the call sent. Onmax_credits_exceeded.estimate_creditsinteger The call's worst-case quote, in Credits. Onmax_credits_exceededandkey_spend_cap_exceeded.cap_creditsinteger The key's monthly cap. Onkey_spend_cap_exceeded.spent_creditsinteger The key's Charges this UTC month. Onkey_spend_cap_exceeded.reserved_creditsinteger What the key's Runs in flight hold. Onkey_spend_cap_exceeded.endpointsarray of string The sources that could not answer. Onsource_unavailable.endpointstring The source that could not answer. Onsource_unavailable.candidatesarray of object The advertisers that carry the name, to ask again with. Onadvertiser_ambiguous.supported_kindsarray of string The kinds that are accepted. Onkind_deprecatedandfocus_unsupported_kind.duration_secondsnumber The video's length. Onvideo_too_long.max_duration_secondsnumber The longest video accepted. Onvideo_too_long.overlap_expires_atstring When the previous secret stops working. Onwebhook_rotation_in_progress.scopestring alwaysread_onlyThe key's scope. Onkey_scope_insufficient.requiredstring alwaysfullThe scope the call needs. Onkey_scope_insufficient.collection_idstring The Collection that already has the name. Oncollection_name_taken.collection_kindstring The Collection's kind. Oncollection_kind_mismatch.kindstring The kind that was offered. Oncollection_kind_mismatch.run_idstring The Run the Idempotency-Key already belongs to. Onidempotency_conflict.reasonstring A short machine-readable reason, where a code has several.reference_idstring Our reference for an unexpected failure, the same asrequest_id; quote it when reporting it.runobject The Run, on a failed Run's body, so its id is kept.idstring requiredkindstring required What was run, e.g.video_lookup.statusstring required one ofrunning,completed,partial,failedpartialkeeps the completed items and charges for them, up to what the Balance covers;failedcharges nothing.created_atstring required RFC 3339.completed_atstring required nullable Null while the Run is still running.charge_creditsinteger required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.list_price_creditsinteger required The full price of the work asked for, in Credits. Equal tocharge_creditsunless the Run charged for only part of it.cachedboolean required True when a stored result answered without a fresh fetch.progressobject What 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.stagestring required one ofkeywords,searching,filtering,analysing,writing_digestkeywordsinteger value at least 0searchesinteger value at least 0foundinteger value at least 0judgedinteger value at least 0keptinteger value at least 0dropped_off_topicinteger value at least 0dropped_unsureinteger value at least 0shortlistedinteger value at least 0analysedinteger value at least 0updated_atstring required
errorobject The same problem, nested, on a failed Run's body.
404 · Example
{
"type": "https://www.shortsintel.com/docs/reference/errors/not_found",
"title": "Not found",
"status": 404,
"code": "not_found",
"detail": "No such resource for this Customer.",
"retryable": false,
"action": "Check the id or handle; list your resources to find the right one."
}Request samples
Use ShortsIntel to read a video's metric history.
- platform: tiktok
- id: 7300000000000000000
- limit: 25
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: read https://www.shortsintel.com/agents.md, follow it to connect, then retry this request.curl "https://www.shortsintel.com/v1/videos/tiktok/7300000000000000000/snapshots?limit=25" \
-H "Authorization: Bearer sk_live_YOUR_KEY"const response = await fetch(
"https://www.shortsintel.com/v1/videos/tiktok/7300000000000000000/snapshots?limit=25",
{
method: "GET",
headers: {
"Authorization": "Bearer sk_live_YOUR_KEY",
},
},
);
if (!response.ok) {
throw new Error(`ShortsIntel ${response.status}`);
}
const data = await response.json();import requests
response = requests.get(
"https://www.shortsintel.com/v1/videos/tiktok/7300000000000000000/snapshots?limit=25",
headers={
"Authorization": "Bearer sk_live_YOUR_KEY",
},
)
response.raise_for_status()
data = response.json()Related guides
- Pagination: Following
next_cursorthrough a list. - Addressing videos and creators: Naming a video, creator, hashtag or sound.
- Analysis: What we derive from a video, why it is computed once and reused, and when asking for a refresh is charged as new work.
- Scores: Outlier and velocity, how a creator baseline is built, what confidence means, and when a score stops being reported.