---
title: "Get keyword search status and results"
method: GET
path: "/v1/orbit/{orbit_id}"
tags: ["Orbit"]
---

# Get keyword search status and results

`GET /v1/orbit/{orbit_id}`

## Request

- Base URL: `https://api.virlo.ai`
- URL: `https://api.virlo.ai/v1/orbit/{orbit_id}`
- Auth: HTTP bearer

Polls the status of a keyword search job and retrieves results once complete.

## Path parameters

- `orbit_id` string, required

## Query parameters

- `order_by` 'views' | 'likes' | 'shares' | 'comments' | 'bookmarks' | 'publish_date' | 'author.followers'
- `sort` 'asc' | 'desc'

## Response `200`

Successfully retrieved search results

- OrbitDetailResponseDto
  - `data` OrbitDetailDataDto, required
    - `id` string, required
    - `status` string, required: pending | processing | completed | partial_failure | failed
    - `finalized` boolean: True when this resource will not change anymore: its main job is in a terminal state AND `pending_jobs` is empty. Optional for backwards compatibility; absent on responses where the field was not yet emitted.
    - `pending_jobs` PendingJobDto[]: Secondary jobs (e.g. viral analysis, trends) still running after the main scrape completed. Always an array, never null. Empty when nothing is pending. Each entry tells you where the result will land (`result_path`), how to poll (`poll_url`), and which webhook fires (`webhook_event`).
      - `type` 'viral_analysis' | 'audience_demographics' | 'audience_geography' | 'tracking_report', required: Stable identifier for the kind of secondary job. Use this to switch on the field where the result will appear (see `result_path`).
      - `status` 'pending' | 'processing', required: Current non-terminal state of the job. Once the job reaches a terminal state (ready / failed / skipped) the entry is removed from `pending_jobs[]`.
      - `job_id` string: Optional opaque identifier for the underlying job, when one exists. Useful with `poll_url` to fetch the result directly.
      - `poll_url` string: Path (relative to api.virlo.ai) you can GET to fetch the result of this job once it is ready. Free to call.
      - `result_path` string: Dot-path inside the parent resource's response body where the completed result will appear. Useful for clients that re-fetch the resource instead of using `poll_url`.
      - `webhook_event` string: Name of an event from the existing `SUPPORTED_EVENTS` list that fires when this job reaches a terminal state. Subscribe to it via POST /v1/webhooks to avoid polling. Guaranteed to be one of the already-supported event names so existing webhook subscriptions keep working — no new event types were introduced.
      - `started_at` string: When the job entered its current state (ISO 8601 UTC).
      - `retry_after_seconds` number: Suggested minimum delay (seconds) before polling again. Respect this to avoid hitting rate limits.
    - `name` string, nullable
    - `keywords` string[], required
    - `intent` string, nullable
    - `data_intelligence_enabled` boolean, required: Whether per-video AI intelligence is enabled. When true, each run costs $1.50 (base $0.50 + intelligence $1.00).
    - `analysis` string, nullable: Short human-readable highlight from the latest AI analysis, sourced from analysis_data.key_highlight. null until the analysis pipeline completes. For the full structured object use `analysis_data` or GET /v1/orbit/:orbit_id/analysis.
    - `analysis_data` object, nullable: Full structured AI analysis object (themes, connecting_thread, viral_tactics, timing_analysis, top_10_breakdown, …). null until the analysis pipeline completes.
    - `analysis_batch_start` string, nullable: Start of the batch window for the latest analysis (ISO-8601)
    - `analysis_batch_end` string, nullable: End of the batch window for the latest analysis (ISO-8601)
    - `started_at` string, required
    - `order_by` string
    - `sort` string
    - `results` OrbitResultsDto
      - `total_videos` number, required
      - `total_slideshows` number, required
      - `youtube_count` number, required
      - `tiktok_count` number, required
      - `instagram_count` number, required
      - `trends` OrbitTrendItemDto[], required: AI-identified narrative trends (may be empty)
        - `name` string, required
        - `description` string, required
        - `videoCount` number, required
        - `confidence` number, required
      - `videos` OrbitVideoItemDto[], required
        - `url` string, required
        - `description` string, nullable
        - `platform` string, required
        - `views` number, required
        - `likes` number, required
        - `shares` number, required
        - `comments` number, required
        - `bookmarks` number, nullable
        - `publish_date` string, nullable
        - `hashtags` string[], required
        - `thumbnail_url` string, nullable
        - `author` V1AuthorDto
          - `username` string, required
          - `avatar_url` string, nullable, required: Creator avatar URL. Always an absolute URL (or null). Images Virlo stores are served from https://auth.virlo.ai/storage/v1/object/public/<bucket>/; platform CDN links are passed through. Some files are HEIC, which most non-Safari browsers cannot render, so convert before display if you need to.
          - `followers` number, required
          - `verified` boolean, required
          - `country` string, nullable: Creator's country (ISO-3166-1 alpha-2), when the platform exposes it. Distinct from a video's `upload_region`.
        - `keyword_found_by` string
        - `sound` V1SoundDto
          - `id` string, required: Virlo's internal sound ID (UUID). Use this for the /v1/sounds/:sound_id family (details, videos, usage-history, resolve). For the satellite sound lookup prefer `external_id`, though passing this UUID also works — it is auto-resolved to the sound's platform + external_id.
          - `external_id` string, nullable: Platform-native sound identifier (TikTok music/clip id, or Instagram audio id). This is the `music_id` accepted by the satellite sound lookup — call GET /v1/satellite/sounds/{platform}/{external_id} for TikTok or Instagram sounds. YouTube sounds are not supported (you'll get a 400). Null for sounds without a platform id.
          - `title` string, required
          - `platform` 'tiktok' | 'youtube' | 'instagram', required
          - `duration` number, nullable: Duration in seconds. Available on TikTok only.
          - `cover_url` string, nullable: Sound cover image URL. Available on TikTok and YouTube. Always an absolute URL (or null). Images Virlo stores are served from https://auth.virlo.ai/storage/v1/object/public/<bucket>/; platform CDN links are passed through. Some files are HEIC, which most non-Safari browsers cannot render, so convert before display if you need to.
          - `owner_handle` string, nullable: Sound owner handle. Partially available on TikTok (~12%).
          - `owner_nickname` string, nullable: Sound owner display name. Available on TikTok, YouTube, Instagram.
          - `is_original` boolean, nullable: Whether the sound is an original creation. TikTok only.
          - `is_commerce_music` boolean, nullable: Whether the sound is cleared for commercial use. TikTok only.
          - `usage_count` number, nullable: Platform-wide usage count. TikTok only.
        - `intelligence` object, nullable: Per-video AI intelligence payload (themes, hook analysis, etc.). null when not ready or not requested — see `intelligence_status` for why.
        - `intelligence_status` 'ready' | 'pending' | 'disabled' | 'failed' | 'skipped': Disambiguates a null `intelligence` field: `ready` (use it), `pending` (still being generated — poll later or wait for webhook), `disabled` (parent orbit didn't enable data_intelligence_enabled, so it will never arrive), `skipped` (deliberately not analyzed, so it will never arrive; see `intelligence_skip_reason`), `failed` (reserved for future use). Optional for backwards compatibility.
        - `intelligence_skip_reason` 'intent_mismatch' | 'too_old' | 'under_followers', nullable: Set only when `intelligence_status` is `skipped`: why Data Intelligence deliberately did not analyze this item, so its `intelligence` will never arrive. `intent_mismatch` (it does not match the agent's intent), `too_old` (published more than a year ago and not among the run's top performers), `under_followers` (more than two days old with no more views than its creator has followers). null otherwise.
      - `slideshows` OrbitSlideshowItemDto[], required
        - `url` string, required
        - `description` string, nullable
        - `platform` string, required
        - `views` number, required
        - `likes` number, required
        - `shares` number, required
        - `comments` number, required
        - `bookmarks` number, nullable
        - `publish_date` string, nullable
        - `hashtags` string[], required
        - `thumbnail_url` string, nullable
        - `images` SlideshowImageDto[], required
          - `image_url` string, required
          - `position` number, required
        - `author` V1AuthorDto
          - `username` string, required
          - `avatar_url` string, nullable, required: Creator avatar URL. Always an absolute URL (or null). Images Virlo stores are served from https://auth.virlo.ai/storage/v1/object/public/<bucket>/; platform CDN links are passed through. Some files are HEIC, which most non-Safari browsers cannot render, so convert before display if you need to.
          - `followers` number, required
          - `verified` boolean, required
          - `country` string, nullable: Creator's country (ISO-3166-1 alpha-2), when the platform exposes it. Distinct from a video's `upload_region`.
        - `keyword_found_by` string
        - `is_eligible_for_commission` boolean
        - `region` string, nullable
        - `intelligence` object, nullable: Per-slideshow AI intelligence payload (panel-text analysis, hook, brand safety, etc.). Slideshow intelligence is a separate schema from video intelligence — see the Data Intelligence docs. null when not ready or not requested — see `intelligence_status` for why.
        - `intelligence_status` 'ready' | 'pending' | 'disabled' | 'failed' | 'skipped': Disambiguates a null `intelligence` field: `ready` (use it), `pending` (still being generated — poll later or wait for webhook), `disabled` (parent orbit didn't enable data_intelligence_enabled, so it will never arrive), `skipped` (deliberately not analyzed, so it will never arrive; see `intelligence_skip_reason`), `failed` (reserved for future use). Optional for backwards compatibility.
        - `intelligence_skip_reason` 'intent_mismatch' | 'too_old' | 'under_followers', nullable: Set only when `intelligence_status` is `skipped`: why Data Intelligence deliberately did not analyze this item, so its `intelligence` will never arrive. `intent_mismatch` (it does not match the agent's intent), `too_old` (published more than a year ago and not among the run's top performers), `under_followers` (more than two days old with no more views than its creator has followers). null otherwise.
      - `ads` V1MetaAdDto[], required
        - `id` number, required
        - `ad_archive_id` string, nullable, required
        - `page_id` string, nullable, required
        - `page_profile_url` string, nullable
        - `page_profile_picture_url` string, nullable
        - `is_active` boolean, nullable
        - `start_date` string, nullable
        - `end_date` string, nullable
        - `url` string, nullable
        - `caption` string, nullable
        - `body` string, nullable
        - `cta_type` string, nullable
        - `page_like_count` number, nullable
        - `title` string, nullable
        - `video_url` string, nullable
        - `created_at` string, required
      - `execution_time_ms` number, nullable
      - `keyword_breakdown` KeywordBreakdownItemDto[]: Keyword breakdown data
        - `keyword` string, required
        - `video_count` number, required

## Other responses

- `401`: Unauthorized - missing or invalid API key
- `404`: Keyword search not found
- `429`: Too many requests - rate limit exceeded

---

[API](https://skmtc.dev/virlo/apis/virlo-public-api.md) · [All operations](https://skmtc.dev/virlo/apis/virlo-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/virlo/apis/virlo-public-api/revisions/3b69c6145087?raw)
