Add a member
/v1/collections/{id}/membersPuts a Tracker in the Collection: by tracker_id, or by platform and target. A Tracker you already have is attached as it is (a paused one stays paused, and the response shows it). A target you do not track yet gets a new Tracker whose first cycle runs now. A Tracker of another kind is refused. Adding a member twice is not an error. Video is no longer a trackable kind, so a video Collection takes only Video Trackers you already have, by tracker_id: a target is refused with 400 kind_deprecated. In an advertiser Collection, target is a Facebook Page id, Page URL or name (409 advertiser_ambiguous when several Pages carry it) and platform is omitted or meta.
Price
Free, except a target not tracked yet: its first cycle, 6 credits for a creator, 3 credits for a hashtag, 6 credits for a sound, 30 credits for an advertiser.
Supports estimate=true: the reply is the price in Credits and whether it would be cached, with no Run created and nothing charged.
Parameters
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
id | path | string | Required | — | Collection id. |
estimate | query | boolean | Optional | — | Return { estimate_credits, cached, already_tracking, tracker_id, per_cycle } and change nothing: zero when the target is already tracked, else one cycle, the first. Nothing is created or charged. |
Request body
application/json
object
tracker_idstringA Tracker you already have. Or, instead,platformandtarget(plus optionalintelligence) for a target of the Collection's kind; an explicitkindmust match it.platformstringone oftiktok,instagram,youtubetargetstringkindstringone ofcreator,hashtag,sound,advertiser,videoMust match the Collection's kind. A new Video Tracker is refused with 400kind_deprecated.intelligenceboolean
Responses
200 OK
Already a member: the same body with added: false. With estimate=true, { estimate_credits, cached, already_tracking, tracker_id, per_cycle } instead.
any of 2 shapes
Option 1object
collectionobjectAbsent only withcollection_error.idstringrequirednamestringrequiredUnique per Customer, regardless of case.kindstringrequiredone ofcreator,hashtag,sound,advertiser,videoWhat every member is. Fixed at creation.videois deprecated: existing Video Collections keep working, new ones are refused with 400kind_deprecated.member_countintegerrequiredLive (active or paused) member Trackers.created_atstringrequiredupdated_atstringrequired
trackerobjectrequiredThe member, as it now is, state included.idstringrequiredkindstringrequiredone ofcreator,hashtag,sound,advertiser,videovideois deprecated (ADR 0024): existing Video Trackers keep working, new ones are refused with 400kind_deprecated.platformstringrequiredmetafor an advertiser Tracker.targetstringrequiredintelligencebooleanrequiredWhether each new video (or Ad) the cycle finds is analysed.statestringrequiredone ofactive,paused,deletedlast_cycle_atstringrequirednullablelast_run_idstringrequirednullablecreated_atstringrequiredupdated_atstringrequired
addedbooleanrequiredFalse when the Tracker was already a member (200), or, withcollection_error, when the Collection was deleted before the new Tracker could join (201).createdbooleanrequiredTrue when this call started tracking the target.runobjectrequirednullableThe new Tracker's first cycle; null when nothing was created.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
intelligence_runobjectrequirednullableThe Run analysing the first cycle's new Ads (an advertiser Tracker withintelligence: true); null otherwise.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
collection_errorobjectOnly when the Collection was deleted while the new Tracker's first cycle ran: the Tracker stands, paid for, in no Collection.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,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
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 · Already a member: the same body with `added: false`. With `estimate=true`, `{ estimate_credits, cached, already_tracking, tracker_id, per_cycle }` instead.
{
"collection": {
"id": "col_7d20e1b5c4",
"name": "Competitors",
"kind": "creator",
"member_count": 4,
"created_at": "2026-09-02T09:14:40.221Z",
"updated_at": "2026-09-02T09:14:40.221Z"
},
"tracker": {
"id": "trk_4b1e90c7aa",
"kind": "creator",
"platform": "tiktok",
"target": "someone",
"intelligence": true,
"state": "active",
"last_cycle_at": "2026-09-08T04:00:11.402Z",
"last_run_id": "run_c07a41bb92",
"created_at": "2026-09-01T11:20:03.118Z",
"updated_at": "2026-09-08T04:00:11.402Z"
},
"added": false,
"created": false,
"run": null,
"intelligence_run": null
}200 · With `estimate=true`: the price of the first cycle, nothing created or charged.
{
"estimate_credits": 6,
"cached": false,
"already_tracking": false,
"tracker_id": null,
"per_cycle": true
}201 Created
{ collection, tracker, added: true, created, run, intelligence_run } — run is the first cycle when this call started tracking the target; intelligence_run the Run analysing an opted-in advertiser's new Ads, or null. If the Collection was deleted while that first cycle ran, the paid Tracker still stands: { tracker, added: false, created: true, run, collection_error }.
object
collectionobjectAbsent only withcollection_error.idstringrequirednamestringrequiredUnique per Customer, regardless of case.kindstringrequiredone ofcreator,hashtag,sound,advertiser,videoWhat every member is. Fixed at creation.videois deprecated: existing Video Collections keep working, new ones are refused with 400kind_deprecated.member_countintegerrequiredLive (active or paused) member Trackers.created_atstringrequiredupdated_atstringrequired
trackerobjectrequiredThe member, as it now is, state included.idstringrequiredkindstringrequiredone ofcreator,hashtag,sound,advertiser,videovideois deprecated (ADR 0024): existing Video Trackers keep working, new ones are refused with 400kind_deprecated.platformstringrequiredmetafor an advertiser Tracker.targetstringrequiredintelligencebooleanrequiredWhether each new video (or Ad) the cycle finds is analysed.statestringrequiredone ofactive,paused,deletedlast_cycle_atstringrequirednullablelast_run_idstringrequirednullablecreated_atstringrequiredupdated_atstringrequired
addedbooleanrequiredFalse when the Tracker was already a member (200), or, withcollection_error, when the Collection was deleted before the new Tracker could join (201).createdbooleanrequiredTrue when this call started tracking the target.runobjectrequirednullableThe new Tracker's first cycle; null when nothing was created.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
intelligence_runobjectrequirednullableThe Run analysing the first cycle's new Ads (an advertiser Tracker withintelligence: true); null otherwise.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
collection_errorobjectOnly when the Collection was deleted while the new Tracker's first cycle ran: the Tracker stands, paid for, in no Collection.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,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
201 · Example
{
"collection": {
"id": "col_7d20e1b5c4",
"name": "Competitors",
"kind": "creator",
"member_count": 4,
"created_at": "2026-09-02T09:14:40.221Z",
"updated_at": "2026-09-02T09:14:40.221Z"
},
"tracker": {
"id": "trk_4b1e90c7aa",
"kind": "creator",
"platform": "tiktok",
"target": "someone",
"intelligence": true,
"state": "paused",
"last_cycle_at": "2026-09-08T04:00:11.402Z",
"last_run_id": "run_c07a41bb92",
"created_at": "2026-09-01T11:20:03.118Z",
"updated_at": "2026-09-08T04:00:11.402Z"
},
"added": true,
"created": false,
"run": null,
"intelligence_run": null
}400 Bad Request
invalid_request — a malformed body. Or unsupported_platform: an unknown platform, or a creator on YouTube (creator Trackers cycle on TikTok, Instagram and Facebook). Nothing is created or charged. Or: kind_deprecated — a target in a video Collection: no new Video Trackers. Add a Video Tracker you already have by tracker_id. Track the Creator, a Hashtag or a Sound instead. Nothing is created or charged.
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,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
400 · unsupported_platform
{
"type": "https://www.shortsintel.com/docs/reference/errors/unsupported_platform",
"title": "Unsupported platform",
"status": 400,
"code": "unsupported_platform",
"detail": "Tracking a creator on youtube is not available yet. Creator Trackers are supported on: tiktok, instagram, facebook."
}400 · kind_deprecated
{
"type": "https://www.shortsintel.com/docs/reference/errors/kind_deprecated",
"title": "Kind deprecated",
"status": 400,
"code": "kind_deprecated",
"detail": "Video Trackers and Collections can no longer be created. Track the Creator, a Hashtag or a Sound instead: their cycles re-snapshot the Videos they find every day.",
"supported_kinds": [
"creator",
"hashtag",
"sound",
"advertiser"
]
}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,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 — a new Tracker's first cycle is not covered. Nothing is created.
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,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 does not cover this operation. Top up in the console.",
"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,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 Collection, or no Tracker, with that id for this Customer; or the vendor has no such creator. Nothing is created or charged."
}409 Conflict
collection_kind_mismatch — the Tracker is not of the Collection's kind. Or: tracker_limit_exceeded at 100 active Trackers. Paused Trackers do not count.
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,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 · collection_kind_mismatch
{
"type": "https://www.shortsintel.com/docs/reference/errors/collection_kind_mismatch",
"title": "Collection kind mismatch",
"status": 409,
"code": "collection_kind_mismatch",
"detail": "\"Competitors\" is a Collection of creator Trackers and cannot hold a video.",
"collection_kind": "creator",
"kind": "video"
}409 · tracker_limit_exceeded
{
"type": "https://www.shortsintel.com/docs/reference/errors/tracker_limit_exceeded",
"title": "Tracker limit exceeded",
"status": 409,
"code": "tracker_limit_exceeded",
"detail": "You already have 100 active Trackers. Pause one before starting another.",
"limit": 100,
"active": 100
}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,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
curl -X POST "https://www.shortsintel.com/v1/collections/col_7d20e1b5c4/members" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"tracker_id":"trk_4b1e90c7aa","kind":"creator"}'const response = await fetch(
"https://www.shortsintel.com/v1/collections/col_7d20e1b5c4/members",
{
method: "POST",
headers: {
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"tracker_id": "trk_4b1e90c7aa",
"kind": "creator"
}),
},
);
if (!response.ok) {
throw new Error(`ShortsIntel ${response.status}`);
}
const data = await response.json();import requests
response = requests.post(
"https://www.shortsintel.com/v1/collections/col_7d20e1b5c4/members",
headers={
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json",
},
json={
"tracker_id": "trk_4b1e90c7aa",
"kind": "creator",
},
)
response.raise_for_status()
data = response.json()