Skip to content

API referenceCollections

Act on every member

POST/v1/collections/{id}/actions

Pause, resume, refresh or switch analysis for every live member Tracker at once. A Collection holds no state, so the action writes through to each Tracker, and a Tracker in several Collections is changed for all of them: pausing "Competitors" also pauses a creator you track for "Influencers". Every answer lists those shared members in trackers_in_other_collections (in the Run result, and the estimate, for refresh). pause, resume and intelligence are free, answer at once and are not Runs; resume resumes nothing when the batch would pass the active-Tracker limit. refresh runs every member's cycle now, paused members included, as one Run with one item per member: members that fail are not charged, some failing makes the Run partial, all failing makes it failed and free.

Price

Free, except refresh: one cycle per member refreshed, 6 credits for a creator, 30 credits for an advertiser, plus 20 credits per new video on members with analysis on.

Supports estimate=true: the reply is the price in Credits and whether it would be cached, with no Run created and nothing charged.

Parameters

NameInTypeRequiredDefaultDescription
idpathstringRequired—Collection id.
waitqueryintegermin 0; max 120Optional30Seconds to hold the response open before handing back a running Run to poll. Default 30, max 120. A POST may send it in the body instead; given in both places with different values it is a 400. Only refresh waits; the other actions answer at once.
estimatequerybooleanOptional—true returns { estimate_credits, cached } computed from what is already stored, and creates no Run. Nothing is charged. Only true or false; anything else is a 400. A POST may send it in the body instead; given in both places with different values it is a 400.
Idempotency-KeyheaderstringOptional—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.

Request body

application/json

object

  • actionstringrequiredone of pause, resume, refresh, intelligencepause or resume every member; refresh runs every member's cycle now (a paid Run); intelligence switches analysis of new videos on or off for every member.
  • intelligencebooleanRequired with intelligence: true switches analysis on, false off.

Responses

200 OK

pause, resume, intelligence: { action, collection, trackers, changed_tracker_ids, trackers_in_other_collections }. refresh: the Run envelope { run, result, trackers_in_other_collections }; with estimate=true, { estimate_credits, trackers, per_tracker_credits, trackers_in_other_collections }. With estimate=true the free actions answer { estimate_credits: 0, cached, trackers_in_other_collections } and change nothing: the way to see what a pause would reach before making it.

any of 3 shapes

  • Option 1object
    • actionstringrequiredone of pause, resume, intelligence
    • collectionobjectrequiredA named set of Trackers of one kind. Holds no state: pausing, analysis and cycles belong to each Tracker.
      • idstringrequired
      • namestringrequiredUnique per Customer, regardless of case.
      • kindstringrequiredone of creator, hashtag, sound, advertiser, videoWhat every member is. Fixed at creation. video is deprecated: existing Video Collections keep working, new ones are refused with 400 kind_deprecated.
      • member_countintegerrequiredLive (active or paused) member Trackers.
      • created_atstringrequired
      • updated_atstringrequired
    • trackersarray of objectrequiredEvery live member, as it now is.
      • idstringrequired
      • kindstringrequiredone of creator, hashtag, sound, advertiser, videovideo is deprecated (ADR 0024): existing Video Trackers keep working, new ones are refused with 400 kind_deprecated.
      • platformstringrequiredmeta for an advertiser Tracker.
      • targetstringrequired
      • intelligencebooleanrequiredWhether each new video (or Ad) the cycle finds is analysed.
      • statestringrequiredone of active, paused, deleted
      • last_cycle_atstringrequirednullable
      • last_run_idstringrequirednullable
      • created_atstringrequired
      • updated_atstringrequired
    • changed_tracker_idsarray of stringrequiredMembers this call changed. One already in the asked-for state is left alone.
    • trackers_in_other_collectionsarray of objectrequired
      • tracker_idstringrequired
      • platformstringrequired
      • targetstringrequired
      • statestringrequiredone of active, paused
      • collectionsarray of objectrequiredThe other Collections it sits in. This one is left out.
        • idstringrequired
        • namestringrequired
  • Option 2object
    • runobjectrequiredEvery charged operation creates a Run. The envelope is identical whether the result came back inline or was polled.
      • idstringrequired
      • kindstringrequiredWhat was run, e.g. video_lookup.
      • statusstringrequiredone of running, completed, partial, failedpartial keeps the completed items and charges for them, up to what the Balance covers; failed charges 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 to charge_credits unless 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, and analysed of shortlisted. A count is absent until its stage produced it. Absent once the Run settles, and on every other kind.
        • stagestringrequiredone of keywords, searching, filtering, analysing, writing_digest
        • keywordsintegervalue at least 0
        • searchesintegervalue at least 0
        • foundintegervalue at least 0
        • judgedintegervalue at least 0
        • keptintegervalue at least 0
        • dropped_off_topicintegervalue at least 0
        • dropped_unsureintegervalue at least 0
        • shortlistedintegervalue at least 0
        • analysedintegervalue at least 0
        • updated_atstringrequired
    • resultobjectrequiredWhat a Collection refresh did. One item per member at GET /v1/runs/{id}/items.
      • collection_idstringrequired
      • collection_namestringrequired
      • requestedintegerrequiredLive members when the refresh started.
      • refreshedintegerrequiredMembers whose cycle completed, and the only ones charged.
      • failedintegerrequired
      • change_reportsintegerrequiredChange Reports the refresh produced; read them per Tracker.
      • trackers_in_other_collectionsarray of objectrequired
        • tracker_idstringrequired
        • platformstringrequired
        • targetstringrequired
        • statestringrequiredone of active, paused
        • collectionsarray of objectrequiredThe other Collections it sits in. This one is left out.
          • idstringrequired
          • namestringrequired
      • waived_creditsnumberOnly when analysis surcharges passed the Balance: the part not charged. The charge stops at the Balance.
    • trackers_in_other_collectionsarray of objectrequired
      • tracker_idstringrequired
      • platformstringrequired
      • targetstringrequired
      • statestringrequiredone of active, paused
      • collectionsarray of objectrequiredThe other Collections it sits in. This one is left out.
        • idstringrequired
        • namestringrequired
  • Option 3objectReturned 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 · `pause`, `resume`, `intelligence`: `{ action, collection, trackers, changed_tracker_ids, trackers_in_other_collections }`. `refresh`: the Run envelope `{ run, result, trackers_in_other_collections }`; with `estimate=true`, `{ estimate_credits, trackers, per_tracker_credits, trackers_in_other_collections }`. With `estimate=true` the free actions answer `{ estimate_credits: 0, cached, trackers_in_other_collections }` and change nothing: the way to see what a pause would reach before making it.

{
  "action": "pause",
  "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"
  },
  "trackers": [
    {
      "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"
    }
  ],
  "changed_tracker_ids": [
    "trk_4b1e90c7aa"
  ],
  "trackers_in_other_collections": [
    {
      "tracker_id": "trk_4b1e90c7aa",
      "platform": "tiktok",
      "target": "someone",
      "state": "paused",
      "collections": [
        {
          "id": "col_51b0a9e2f7",
          "name": "Influencers"
        }
      ]
    }
  ]
}

200 · `refresh`, finished inside the wait budget. Partial: one of four members could not be fetched and was not charged.

{
  "run": {
    "id": "run_8f2c1ad04b",
    "kind": "collection_refresh",
    "status": "partial",
    "created_at": "2026-09-08T09:14:02.418Z",
    "completed_at": "2026-09-08T09:14:04.930Z",
    "charge_credits": 150,
    "list_price_credits": 150,
    "cached": false
  },
  "result": {
    "collection_id": "col_7d20e1b5c4",
    "collection_name": "Competitors",
    "requested": 4,
    "refreshed": 3,
    "failed": 1,
    "change_reports": 1,
    "trackers_in_other_collections": [
      {
        "tracker_id": "trk_4b1e90c7aa",
        "platform": "tiktok",
        "target": "someone",
        "state": "active",
        "collections": [
          {
            "id": "col_51b0a9e2f7",
            "name": "Influencers"
          }
        ]
      }
    ]
  },
  "trackers_in_other_collections": [
    {
      "tracker_id": "trk_4b1e90c7aa",
      "platform": "tiktok",
      "target": "someone",
      "state": "active",
      "collections": [
        {
          "id": "col_51b0a9e2f7",
          "name": "Influencers"
        }
      ]
    }
  ]
}

200 · `refresh` with `estimate=true`: the price, no Run, no charge.

{
  "estimate_credits": 24,
  "cached": false,
  "trackers": 4,
  "per_tracker_credits": 6,
  "trackers_with_analysis": 0,
  "note": "A member that cannot be refreshed is not charged, so the final charge is at or below this quote.",
  "trackers_in_other_collections": [
    {
      "tracker_id": "trk_4b1e90c7aa",
      "platform": "tiktok",
      "target": "someone",
      "state": "active",
      "collections": [
        {
          "id": "col_51b0a9e2f7",
          "name": "Influencers"
        }
      ]
    }
  ]
}

202 Accepted

refresh still running: { run, trackers_in_other_collections }. Poll GET /v1/runs/{id}.

object

Still running. Poll GET /v1/runs/{id}.

  • runobjectrequiredEvery charged operation creates a Run. The envelope is identical whether the result came back inline or was polled.
    • idstringrequired
    • kindstringrequiredWhat was run, e.g. video_lookup.
    • statusstringrequiredone of running, completed, partial, failedpartial keeps the completed items and charges for them, up to what the Balance covers; failed charges 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 to charge_credits unless 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, and analysed of shortlisted. A count is absent until its stage produced it. Absent once the Run settles, and on every other kind.
      • stagestringrequiredone of keywords, searching, filtering, analysing, writing_digest
      • keywordsintegervalue at least 0
      • searchesintegervalue at least 0
      • foundintegervalue at least 0
      • judgedintegervalue at least 0
      • keptintegervalue at least 0
      • dropped_off_topicintegervalue at least 0
      • dropped_unsureintegervalue at least 0
      • shortlistedintegervalue at least 0
      • analysedintegervalue at least 0
      • updated_atstringrequired
  • trackers_in_other_collectionsarray of objectrequired
    • tracker_idstringrequired
    • platformstringrequired
    • targetstringrequired
    • statestringrequiredone of active, paused
    • collectionsarray of objectrequiredThe other Collections it sits in. This one is left out.
      • idstringrequired
      • namestringrequired

202 · Example

{
  "run": {
    "id": "run_8f2c1ad04b",
    "kind": "collection_refresh",
    "status": "running",
    "created_at": "2026-09-08T09:14:02.418Z",
    "completed_at": null,
    "charge_credits": 0,
    "list_price_credits": 0,
    "cached": false
  },
  "trackers_in_other_collections": [
    {
      "tracker_id": "trk_4b1e90c7aa",
      "platform": "tiktok",
      "target": "someone",
      "state": "active",
      "collections": [
        {
          "id": "col_51b0a9e2f7",
          "name": "Influencers"
        }
      ]
    }
  ]
}

400 Bad Request

invalid_request — an unknown action, intelligence without intelligence: true|false, or refresh on a Collection with no members.

object

RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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 · Example

{
  "type": "https://www.shortsintel.com/docs/reference/errors/invalid_request",
  "title": "Invalid request",
  "status": 400,
  "code": "invalid_request",
  "detail": "The Collection \"Competitors\" has no members to refresh."
}

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.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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 — refresh only, checked against one cycle per member before any work starts.

object

RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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": 24
}

404 Not Found

not_found.

object

RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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 with that id for this Customer."
}

409 Conflict

tracker_limit_exceeded — resume would pass the active-Tracker limit. Nothing is resumed. Or: 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.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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 · 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": "Resuming 4 Trackers would take this Customer to 102 active, the limit is 100. Nothing was resumed. Pause or delete some first.",
  "limit": 100,
  "active": 98,
  "requested": 4
}

409 · idempotency_conflict

{
  "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"
}

422 Unprocessable Content

unsupported_kind — refresh on a Collection of a kind with no cycle yet (video). Nothing is run or charged.

object

RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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

422 · Example

{
  "type": "https://www.shortsintel.com/docs/reference/errors/unsupported_kind",
  "title": "Unsupported kind",
  "status": 422,
  "code": "unsupported_kind",
  "detail": "Tracking video targets is not available yet. Creator tracking is supported today.",
  "supported_kinds": [
    "creator"
  ]
}

429 Too Many Requests

rate_limit_exceeded or concurrency_limit_exceeded, with Retry-After.

object

RFC 9457 problem document, served as application/problem+json. Branch on code, never on the prose.

  • typestringrequired
  • titlestringrequired
  • statusintegerrequired
  • codestringrequiredone of missing_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/actions?wait=30" \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"pause"}'

This call creates a Run. With wait it holds the response open until the Run finishes or the wait runs out, then answers with the finished result or 202 and the running Run. Poll GET /v1/runs/{id} until it settles; re-reading a Run is free.

  • Runs: How a call becomes a Run, waiting inline, polling and free re-reads.