Skip to content
For AI agents: a documentation index is available at /llms.txt. Every docs page is also available as markdown: add .md to its URL. To connect, read /agents.md.

API referenceVideos

Look up many videos by URL

POST /v1/videos/lookup/batch

Up to 100 video URLs, any mix of TikTok, Instagram, YouTube and Facebook, in one Run. Each distinct URL is looked up exactly as POST /v1/videos/lookup would.

  • Validation: every URL is checked before anything runs. One bad URL refuses the whole call with 400 invalid_request naming it (urls[3]), uncharged.
  • Duplicates: the same video however spelled is looked up and charged once, under the first URL that named it.
  • Results: result.items lists each input with its video (the single lookup's shape) or its error. The same outcomes are the Run's items at GET /v1/runs/{id}/items, free to read again.
  • Partial Runs: the Run is completed when every URL succeeded, partial when some did, failed when none did. A URL that is not found, unavailable or whose Source is down is not charged.
  • Long batches: over 10 distinct URLs answer 202 with the Run to poll at once unless wait is passed; any batch answers 202 past wait.

Price

3 credits per video, charged only for the distinct URLs that succeed. estimate=true quotes them all.

Supports "estimate": true in the body: 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

NameInTypeRequiredDefaultDescription
Idempotency-Keyheaderstring Optional—1-255 printable ASCII characters. The same key and payload returns the original Run (202 while running); a different payload or operation is a 409 idempotency_conflict.

Request body

application/json

object

  • urls array of string required items 1 to 100 1 to 100 video URLs, any mix of platforms, each one POST /v1/videos/lookup accepts. Duplicates (the same video however spelled) are looked up once.
  • wait number value 0 to 120 Default 30 Seconds to hold the response open before returning a running Run to poll. Default 30, max 120.
  • max_credits integer value at least 0 As in the query.
  • estimate boolean If a source the call would read is unavailable and the cache cannot answer, the estimate adds unavailable (the { platform, capability } parts it cannot reach), or is a 503 source_unavailable when it can reach none.

Responses

200 OK

The Run finished inside the wait budget: { run, result }. The example found one of its two URLs, so the Run is partial and charged for one lookup. With estimate=true, { estimate_credits, cached, items, credits_per_item } instead.

any of 2 shapes

  • Option 1 object The envelope every charged operation answers with: { run } while the Run is running (plus poll_url on the 202), joined by result once it completes or error once it fails.
    • run object required Every charged operation creates a Run; the envelope is the same inline or polled.
      • id string required
      • kind string required What was run, e.g. video_lookup.
      • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
      • created_at string required RFC 3339.
      • completed_at string required nullable Null while the Run is still running.
      • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
      • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
      • cached boolean required True when a stored result answered without a fresh fetch.
      • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
        • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
        • keywords integer value at least 0
        • creators integer value at least 0
        • creators_read integer value at least 0
        • searches integer value at least 0
        • found integer value at least 0
        • judged integer value at least 0
        • kept integer value at least 0
        • dropped_off_topic integer value at least 0
        • dropped_unsure integer value at least 0
        • shortlisted integer value at least 0
        • analysed integer value at least 0
        • updated_at string required
    • result object required
      • requested integer required Distinct inputs looked up.
      • completed integer required Inputs answered, and charged.
      • failed integer required Inputs that failed, uncharged.
      • items array of object required
        • input any The input this item answers, as you sent it.
        • status string required one of completed, failed
        • video object On a completed item: the same object the single lookup returns.
          • platform string required
          • id string required
          • url string required nullable
          • description string required nullable Null when the read fetched no caption.
          • posted_at string required nullable
          • duration_seconds number required nullable
          • thumbnail_url string required nullable
          • hashtags array of string required
          • sound object required nullable
            • id string required
            • title string required nullable
            • author string required nullable Who made the sound, as the platform names them. Null when the platform did not say (Facebook never does).
            • is_original boolean required nullable True for the creator's own audio, false for a catalogue track. Null when not reported.
          • creator object required nullable
            • id string required
            • handle string required nullable
            • name string required
            • follower_count number required nullable
            • avatar_url string required nullable Our archived copy, else the platform's URL, which may expire: download it rather than store the link.
            • verified boolean required nullable The verified badge, from the latest profile read, else this video's. Null when unreported.
          • region string required nullable Where the video was posted, as the platform reports it (a country code on TikTok). Null when not reported.
          • language string required nullable Platform-declared caption language, e.g. en (TikTok). Null when not reported.
          • title string required nullable The video's own title (YouTube, Facebook). Null when none or not reported.
          • commerce object required nullable What the Platform declares, never inferred from the content. A flag is null when not reported, never false; the object is null when nothing was.
            • is_ad boolean required nullable The Platform marks the video as an ad (TikTok, Instagram).
            • paid_partnership boolean required nullable The Platform marks a paid partnership (TikTok, Instagram; on YouTube, its "Includes paid promotion" label).
            • affiliate boolean required nullable The Platform marks affiliate content (Instagram).
            • shop_url string required nullable The product link the video carries (TikTok Shop).
            • anchors array of object required The links the video carries under its caption (an editing template, a product, a place). Empty when none were reported.
              • kind string required The Platform's own anchor type id, e.g. 54.
              • label string required What the anchor shows, e.g. CapCut · Editing made easy.
          • people object required nullable Accounts the Video mentions or names (on Instagram, tagged users first). Null when none.
            • mentions array of string required Handles the caption mentions (lowercased).
            • collaborators array of object required Co-authors the Platform names on the Video (an Instagram collab, a Facebook collaborator).
              • handle string required nullable
              • name string required nullable
          • location object required nullable The place the Video names (Instagram). Null when it named none or the read did not say.
            • id string required nullable The Platform's own place id. Null when not sent.
            • name string required The place, e.g. Central Park, New York.
          • topics object required nullable Platform-declared topics. Null when the Platform reported none.
            • keywords array of string required The creator's own tags (YouTube).
            • genre string required nullable The Platform's category, e.g. Education (YouTube).
            • labels array of string required The Platform's own category labels (TikTok).
          • chapters array of object required nullable The description's chapters, in order (YouTube). Null when the video has none or they were not reported.
            • title string required
            • start_seconds number required Where the chapter starts, in seconds from the start.
          • ai_generated boolean required nullable The Platform labels the video AI-generated (TikTok). Null when not reported.
          • is_pinned boolean required nullable Pinned to the top of the creator's feed (Instagram). Null when not reported.
          • is_sponsored boolean required nullable Ad flag, #ad or #…partner tag, or a brand collaborator. Null: unchecked.
          • sponsor string required nullable The sponsoring brand's handle when is_sponsored.
          • snapshot object required nullable Deprecated: use engagement.
            • at string required
            • views number required nullable
            • likes number required nullable
            • comments number required nullable
            • shares number required nullable
            • saves number required nullable
          • engagement object required nullable A count the platform did not report is null, never 0.
            • views number required nullable
            • likes number required nullable
            • comments number required nullable
            • shares number required nullable
            • saves number required nullable
            • at string required
          • scores object required nullable Null when the creator has no baseline yet.
            • outlier number required nullable Views over the creator's median views.
            • outlier_p90 number required nullable
            • percentile number required nullable Where this video sits in the creator's own sample, 0-100.
            • velocity object required nullable
              • views_per_hour number required
              • window string required
              • since string required nullable When the window starts.
            • engagement_rate number required nullable This video's reported interactions (likes, comments, shares, saves) over its views. Null when unknown.
            • anomaly boolean required nullable True when engagement_rate is under 20% of the baseline's, as paid or boosted views read. Null when unknown.
            • reason string required nullable always aged_out aged_out when the video is over 30 days old and the view Scores are null.
            • baseline object required The yardstick every Score on this creator is measured against.
              • median_views number required
              • p90_views number required
              • engagement_rate number required nullable
              • posts_per_week number required nullable
              • sample integer required
              • confidence string required one of high, low
              • source string required one of videos, follower_tier
              • computed_at string required nullable
              • stale boolean required True past 7 days; the next lookup refreshes it.
          • coverage string always partial Present only where the platform's index is best-effort.
        • error object On a failed item: why, e.g. not_found or source_unavailable. Not charged. Its fields are on Errors.
  • Option 2 object Returned instead of a Run when estimate=true. Nothing is charged; some operations add members.
    • estimate_credits integer required What the call would be charged, in Credits.
    • cached boolean required Whether a stored result can already answer. It does not change the price.

202 Accepted

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

object

Still running. Poll poll_url (GET /v1/runs/{id}), waiting the 202's Retry-After seconds between polls.

  • run object required Every charged operation creates a Run; the envelope is the same inline or polled. Its fields are on Poll or re-read a run.
  • poll_url string required format uri Absolute URL of GET /v1/runs/{id}, the body's copy of the Location header (for MCP). Present only while running.

202 · Example

{
  "run": {
    "id": "run_8f2c1ad04b",
    "kind": "video_lookup_batch",
    "status": "running",
    "created_at": "2026-09-08T09:14:02.418Z",
    "completed_at": null,
    "charge_credits": 0,
    "list_price_credits": 0,
    "cached": false
  },
  "poll_url": "https://www.shortsintel.com/v1/runs/run_8f2c1ad04b"
}

400 Bad Request

invalid_request (a malformed id, wait, estimate or Idempotency-Key) or unsupported_platform, refused before any Run opens. Nothing is charged.

Codes: invalid_request, unsupported_platform. 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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object 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": "`estimate` must be `true` or `false`.",
  "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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object 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."
}

402 Payment Required

insufficient_balance: the Balance cannot cover the quoted price (the worst case for Research and enriched search). No Run opens and nothing is charged; a multi-item Run that runs short later charges its completed items up to the Balance and ends partial.

Code: insufficient_balance. 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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object The same problem, nested, on a failed Run's body.

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.",
  "retryable": false,
  "action": "Tell the Customer to top up the Balance, then repeat the same request.",
  "balance_credits": 0,
  "required_credits": 6
}

409 Conflict

idempotency_conflict — the same Idempotency-Key with a different payload.

Code: idempotency_conflict. 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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object The same problem, nested, on a failed Run's body.

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.",
  "retryable": false,
  "action": "Resend the original payload with this key, or use a new key for the new payload.",
  "run_id": "run_8f2c1ad04b"
}

429 Too Many Requests

rate_limit_exceeded or concurrency_limit_exceeded, with Retry-After.

Codes: rate_limit_exceeded, concurrency_limit_exceeded. 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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object The same problem, nested, on a failed Run's body.

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`.",
  "retryable": true,
  "action": "Wait `retry_after_seconds`, then retry the same request.",
  "limit": 60,
  "retry_after_seconds": 12,
  "resets_at": "2026-09-08T09:15:00.000Z"
}

502 Bad Gateway

A Run that opened and then failed answers application/problem+json with its problem's status (vendor_error here, not_found as 404) and the Run envelope, keeping the Run id. Never charged. The example is a Video lookup's.

Code: vendor_error. 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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object The same problem, nested, on a failed Run's body.

502 · Example

{
  "type": "https://www.shortsintel.com/docs/reference/errors/vendor_error",
  "title": "Vendor error",
  "status": 502,
  "code": "vendor_error",
  "detail": "The upstream data provider could not be reached.",
  "retryable": true,
  "action": "Retry with a backoff; nothing was charged.",
  "run": {
    "id": "run_8f2c1ad04b",
    "kind": "video_lookup",
    "status": "failed",
    "created_at": "2026-09-08T09:14:02.418Z",
    "completed_at": "2026-09-08T09:14:04.930Z",
    "charge_credits": 0,
    "list_price_credits": 0,
    "cached": false
  }
}

503 Service Unavailable

source_unavailable: every source this Run reads failed or is switched off. The Run fails uncharged, envelope alongside; endpoints names the source. Retry after retry_after_seconds (also Retry-After); it does not mean empty. The example is a Video lookup's.

Code: source_unavailable. 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.

  • type string required
  • title string required
  • status integer required
  • code string required one of missing_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, feature_unavailable, 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_error Stable machine-readable code.
  • detail string
  • errors array of object On invalid_request from a field that failed validation: one entry per problem, so you can find the field without parsing detail. Absent when no single field is at fault, e.g. a body that is not JSON.
    • path string required Dotted path of the field to fix, e.g. collection_ids.1 or cursor. Empty for an issue with the request body as a whole.
    • message string required What is wrong with that field.
  • request_id string The request this problem answers, the same as its X-Request-Id header. Quote it to support.
  • retryable boolean required Whether sending the same request again, after any wait named here, can succeed: true for a rate or concurrency limit, an upstream outage, an internal error or a Run not yet settled; false when the request must change or a person must act. Fixed per code.
  • action string required The next step, in one sentence.
  • remedy string What to do next, as the code's error reference page says it; fuller than action. On every problem a request answers with; a per-item error inside a result may omit it.
  • retry_after_seconds integer value at least 0 Seconds to wait before retrying; the same as the Retry-After header. On rate_limit_exceeded, concurrency_limit_exceeded, source_unavailable and service_unavailable.
  • expired_at string When the key expired. On key_expired.
  • resets_at string When the request window (rate_limit_exceeded) or the key's month (key_spend_cap_exceeded) resets.
  • limit integer The limit that was hit, on the *_limit_exceeded codes.
  • running integer Runs in flight. On concurrency_limit_exceeded.
  • active integer Active Trackers or webhook endpoints. On tracker_limit_exceeded and webhook_limit_exceeded.
  • requested integer Trackers the request would resume. On tracker_limit_exceeded from a Collection action.
  • count integer Collections held. On collection_limit_exceeded.
  • balance_credits integer The Balance, in Credits. On insufficient_balance.
  • required_credits integer What the call needs, in Credits (the worst case where quoted). On insufficient_balance.
  • max_credits integer The cap the call sent. On max_credits_exceeded.
  • estimate_credits integer The call's worst-case quote, in Credits. On max_credits_exceeded and key_spend_cap_exceeded.
  • cap_credits integer The key's monthly cap. On key_spend_cap_exceeded.
  • spent_credits integer The key's Charges this UTC month. On key_spend_cap_exceeded.
  • reserved_credits integer What the key's Runs in flight hold. On key_spend_cap_exceeded.
  • endpoints array of string The sources that could not answer. On source_unavailable.
  • endpoint string The source that could not answer. On source_unavailable.
  • candidates array of object The advertisers that carry the name, to ask again with. On advertiser_ambiguous.
  • supported_kinds array of string The kinds that are accepted. On kind_deprecated and focus_unsupported_kind.
  • feature string The switched-off option, e.g. download. On feature_unavailable.
  • duration_seconds number The video's length. On video_too_long.
  • max_duration_seconds number The longest video accepted. On video_too_long.
  • overlap_expires_at string When the previous secret stops working. On webhook_rotation_in_progress.
  • scope string always read_only The key's scope. On key_scope_insufficient.
  • required string always full The scope the call needs. On key_scope_insufficient.
  • collection_id string The Collection that already has the name. On collection_name_taken.
  • collection_kind string The Collection's kind. On collection_kind_mismatch.
  • kind string The kind that was offered. On collection_kind_mismatch.
  • run_id string The Run the Idempotency-Key already belongs to. On idempotency_conflict.
  • reason string A short machine-readable reason, where a code has several.
  • reference_id string Our reference for an unexpected failure, the same as request_id; quote it when reporting it.
  • run object The Run, on a failed Run's body, so its id is kept.
    • id string required
    • kind string required What was run, e.g. video_lookup.
    • status string required one of running, completed, partial, failed partial keeps the completed items and charges for them, up to what the Balance covers; failed charges nothing.
    • created_at string required RFC 3339.
    • completed_at string required nullable Null while the Run is still running.
    • charge_credits integer required What this Run actually cost, in Credits. A stored answer costs the same as a fresh one.
    • list_price_credits integer required The full price of the work asked for, in Credits. Equal to charge_credits unless the Run charged for only part of it.
    • cached boolean required True when a stored result answered without a fresh fetch.
    • progress object A running Research's stage and counts so far, such as analysed of shortlisted; a count is absent until known. Absent once the Run settles and on other kinds.
      • stage string required one of keywords, searching, reading_creators, filtering, analysing, writing_digest
      • keywords integer value at least 0
      • creators integer value at least 0
      • creators_read integer value at least 0
      • searches integer value at least 0
      • found integer value at least 0
      • judged integer value at least 0
      • kept integer value at least 0
      • dropped_off_topic integer value at least 0
      • dropped_unsure integer value at least 0
      • shortlisted integer value at least 0
      • analysed integer value at least 0
      • updated_at string required
  • error object The same problem, nested, on a failed Run's body.

503 · Example

{
  "type": "https://www.shortsintel.com/docs/reference/errors/source_unavailable",
  "title": "Source unavailable",
  "status": 503,
  "code": "source_unavailable",
  "detail": "The tiktok/video source is unavailable right now.",
  "retryable": true,
  "action": "Wait `retry_after_seconds`, then retry; do not treat this as an empty result.",
  "endpoints": [
    "tiktok/video"
  ],
  "run": {
    "id": "run_8f2c1ad04b",
    "kind": "video_lookup",
    "status": "failed",
    "created_at": "2026-09-08T09:14:02.418Z",
    "completed_at": "2026-09-08T09:14:04.930Z",
    "charge_credits": 0,
    "list_price_credits": 0,
    "cached": false
  },
  "retry_after_seconds": 60
}

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.
  • Pricing and estimates: Credits, estimates and why a cached result costs the same as a fresh one.
  • 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.

Request samples

Use ShortsIntel to look up many videos by URL.

- urls: https://www.tiktok.com/@someone/video/7300000000000000000, https://www.instagram.com/reel/DAbCdEfGhIj/

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.

200 · The Run finished inside the wait budget: `{ run, result }`. The example found one of its two URLs, so the Run is `partial` and charged for one lookup. With `estimate=true`, `{ estimate_credits, cached, items, credits_per_item }` instead.

{
  "run": {
    "id": "run_8f2c1ad04b",
    "kind": "video_lookup_batch",
    "status": "partial",
    "created_at": "2026-09-08T09:14:02.418Z",
    "completed_at": "2026-09-08T09:14:04.930Z",
    "charge_credits": 3,
    "list_price_credits": 6,
    "cached": false
  },
  "result": {
    "requested": 2,
    "completed": 1,
    "failed": 1,
    "items": [
      {
        "input": "https://www.tiktok.com/@someone/video/7300000000000000000",
        "status": "completed",
        "video": {
          "platform": "tiktok",
          "id": "7300000000000000000",
          "url": "https://www.tiktok.com/@someone/video/7300000000000000000",
          "description": "3 minutes at 4°C every morning for 30 days. Here is what actually changed. #coldplunge #recovery",
          "posted_at": "2026-09-05T06:32:11.000Z",
          "duration_seconds": 41,
          "thumbnail_url": "https://p16-sign.tiktokcdn.com/obj/tos-cover-7300000000000000000.jpeg",
          "hashtags": [
            "coldplunge",
            "recovery",
            "morningroutine"
          ],
          "sound": {
            "id": "7180000000000000000",
            "title": "original sound - someone",
            "author": "someone",
            "is_original": true
          },
          "creator": {
            "id": "cre_9d4b2a7f1c",
            "handle": "someone",
            "name": "Someone",
            "follower_count": 184300,
            "avatar_url": "https://p16-sign.tiktokcdn.com/obj/tos-avatar-someone.jpeg",
            "verified": false
          },
          "region": "US",
          "language": "en",
          "title": null,
          "commerce": {
            "is_ad": false,
            "paid_partnership": null,
            "affiliate": null,
            "shop_url": null,
            "anchors": [
              {
                "kind": "54",
                "label": "CapCut · Editing made easy"
              }
            ]
          },
          "people": {
            "mentions": [
              "coldplungeco"
            ],
            "collaborators": []
          },
          "location": null,
          "topics": {
            "keywords": [],
            "genre": null,
            "labels": [
              "Fitness",
              "Health"
            ]
          },
          "chapters": null,
          "ai_generated": false,
          "is_pinned": null,
          "is_sponsored": null,
          "sponsor": null,
          "snapshot": {
            "at": "2026-09-08T09:14:04.219Z",
            "views": 1284000,
            "likes": 143200,
            "comments": 2810,
            "shares": 9040,
            "saves": 21600
          },
          "engagement": {
            "at": "2026-09-08T09:14:04.219Z",
            "views": 1284000,
            "likes": 143200,
            "comments": 2810,
            "shares": 9040,
            "saves": 21600
          },
          "scores": {
            "outlier": 4.21,
            "outlier_p90": 1.6,
            "percentile": 95,
            "velocity": {
              "views_per_hour": 6698.6,
              "window": "snapshot",
              "since": "2026-10-03T08:00:00.000Z"
            },
            "engagement_rate": 0.1376,
            "anomaly": false,
            "reason": null,
            "baseline": {
              "median_views": 305000,
              "p90_views": 802000,
              "engagement_rate": 0.1342,
              "posts_per_week": 4.1,
              "sample": 20,
              "confidence": "high",
              "source": "videos",
              "computed_at": "2026-09-08T09:14:03.902Z",
              "stale": false
            }
          }
        }
      },
      {
        "input": "https://www.instagram.com/reel/DAbCdEfGhIj/",
        "status": "failed",
        "error": {
          "type": "https://www.shortsintel.com/docs/reference/errors/not_found",
          "title": "Not found",
          "status": 404,
          "code": "not_found",
          "detail": "No video with that id exists on this platform.",
          "retryable": false,
          "action": "Check the id or handle; list your resources to find the right one."
        }
      }
    ]
  }
}

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

{
  "estimate_credits": 6,
  "cached": false,
  "items": 2,
  "credits_per_item": 3
}