> ## Documentation Index
> Fetch the complete documentation index at: https://docs.creatoraudit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Track a video

> Track an individual Instagram post or TikTok video.

Set ``platform`` to ``"instagram"`` or ``"tiktok"``. The item is
registered immediately and, when added as active, its metrics are
fetched in the background so they begin populating within seconds
instead of waiting for the next refresh cycle. Subsequent refreshes
then occur automatically at the configured interval.

To track **every** post/video from an account automatically, add the
account via ``POST /accounts`` instead.



## OpenAPI

````yaml /api-reference/openapi.json post /videos
openapi: 3.1.0
info:
  title: CreatorAudit API v2
  summary: Public REST API for tracking creators, accounts, videos, and analytics.
  description: >
    The **CreatorAudit v2 API** tracks Instagram and TikTok creators, accounts,
    and

    their content, and serves the engagement analytics computed from them.


    ### Authentication & scopes


    Send your organization API key as a bearer token on every request:


    ```

    Authorization: Bearer <YOUR_API_KEY>

    ```


    Keys are scoped to a single organization; every response is limited to the
    data

    that organization owns. Missing or invalid credentials return `401`; an
    inactive

    key or subscription returns `403`.


    Each key carries a set of **scopes** — `read`, `write`, and `admin` — and
    keys

    are issued with all three by default. Read endpoints (`GET`) require no
    special

    scope; mutating endpoints (`POST`/`PATCH`/`PUT`/`DELETE`) require the
    `write`

    scope (`admin` implies `write` implies `read`). A key lacking the required
    scope

    gets `403` with `code: INSUFFICIENT_SCOPE`.


    ### Response envelope


    Successful responses are wrapped in a consistent envelope:


    - **Single resource** — `{ "data": { ... } }`

    - **Collection** — `{ "data": [ ... ], "pagination": { ... }, "filters": {
    ... } }`

    - **Collection with metadata** — `{ "data": ..., "meta": { ... } }`


    `pagination` carries `next_cursor`, `has_next`, `limit`, and (when
    requested)

    `total_count`. `filters` echoes the filter/sort that produced the page.


    ### Pagination


    List endpoints use opaque **cursor** pagination. Pass `limit` (1–200) and
    the

    `pagination.next_cursor` from the previous page as `cursor` to fetch the
    next

    page. `pagination.has_next` is `false` on the final page. A cursor is bound
    to

    the exact filter and sort combination it was issued for — reusing it under a

    different filter/sort returns `422`. Pass `include_total=true` to also
    receive

    `pagination.total_count` (adds one COUNT query). List responses also carry
    an

    RFC 8288 `Link` header with `rel="first"` and (when more pages exist)

    `rel="next"`.


    ### Caching


    `GET` responses carry a strong `ETag` and `Cache-Control: private,
    no-cache`.

    Send the value back as `If-None-Match` on a follow-up request; if the

    representation is unchanged the API replies `304 Not Modified` with an empty

    body, saving the re-download.


    ### Rate limits


    Requests are rate limited per API key. Every **authenticated** response
    includes

    `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (a
    Unix

    timestamp); the unauthenticated `GET /health` and `GET /meta` are not
    limited

    and omit them. Exceeding the limit returns `429` with `code: RATE_LIMITED`
    and a

    `Retry-After` header (seconds to wait).


    ### Account quota


    An organization may set an optional cap on the number of accounts it tracks.
    By

    default there is **no cap** (unlimited). When a cap is set and reached,

    `POST /accounts` returns `403` with `code: QUOTA_EXCEEDED`.


    ### Content negotiation


    The API only produces JSON. A request whose `Accept` header cannot be
    satisfied

    with JSON returns `406` (`code: NOT_ACCEPTABLE`). A write request whose body
    is

    not `application/json` returns `415` (`code: UNSUPPORTED_MEDIA_TYPE`).


    ### Errors


    Errors follow **RFC 9457 Problem Details** (`application/problem+json`):


    ```json

    {
      "type": "urn:creatoraudit:error:not-found",
      "title": "Not Found",
      "status": 404,
      "detail": "Account not found.",
      "code": "NOT_FOUND",
      "instance": "/v2/accounts/{id}",
      "request_id": "8f1c…"
    }

    ```


    The `code` is the stable machine identifier; `type` is an RFC 9457 URN.

    Validation failures (`422`) additionally carry an `errors` array of

    `{ field, message }` entries. The full set of machine `code`s:


    | HTTP | `code` | Meaning |

    | ---- | ------ | ------- |

    | 400 | `BAD_REQUEST` | Malformed request. |

    | 401 | `UNAUTHORIZED` | Missing or invalid API key. |

    | 403 | `FORBIDDEN` | Inactive key/subscription. |

    | 403 | `INSUFFICIENT_SCOPE` | Key lacks the required scope. |

    | 403 | `QUOTA_EXCEEDED` | Account quota reached. |

    | 404 | `NOT_FOUND` | Resource not found in your org. |

    | 406 | `NOT_ACCEPTABLE` | `Accept` not satisfiable as JSON. |

    | 409 | `CONFLICT` | State conflict (e.g. duplicate). |

    | 415 | `UNSUPPORTED_MEDIA_TYPE` | Write body is not JSON. |

    | 422 | `VALIDATION_ERROR` | Request failed validation. |

    | 429 | `RATE_LIMITED` | Rate limit exceeded. |

    | 500 | `INTERNAL_ERROR` | Unexpected server error. |

    | 502 | `UPSTREAM_ERROR` | Upstream provider error. |

    | 503 | `SERVICE_UNAVAILABLE` | Temporarily unavailable; retry. |


    ### Idempotency


    `POST` create endpoints accept an optional `Idempotency-Key` header so a
    retried

    request returns the original result instead of creating a duplicate. On
    success

    a `201` carries a `Location` header pointing at the new resource.


    ### Response headers


    Every response echoes `X-Request-ID` (also surfaced as `request_id` in error

    bodies) so a call can be correlated with its server-side event. Collections
    add

    `Link`; `GET`s add `ETag`/`Cache-Control`; authenticated responses add

    `X-RateLimit-*`; `429`/`503` add `Retry-After`; `201` creates add
    `Location`.
  contact:
    name: CreatorAudit Support
    url: https://creatoraudit.com/
    email: support@creatoraudit.com
  license:
    name: Proprietary — © CreatorAudit
  version: 2.0.0
  x-api-stability: current
servers:
  - url: https://api.creatoraudit.com/v2
    description: Production
security: []
tags:
  - name: Accounts
    description: >-
      Track and manage Instagram/TikTok accounts. Listing, retrieval, creation
      (which begins automated tracking), updates, and removal.
  - name: Videos
    description: >-
      Individually tracked posts/videos, account-discovered videos, and batch
      engagement deltas.
  - name: Creators
    description: >-
      Creators group one or more accounts under a single entity for roll-up
      analytics. Includes account linking and the top-creators leaderboard.
  - name: Analytics
    description: >-
      Daily engagement series for the org, accounts, creators, and individual
      videos, plus per-metric daily breakdowns for accounts, creators, and
      videos.
  - name: Overview
    description: Org-wide headline stats with period-over-period changes.
  - name: Search
    description: Cross-entity search over accounts, creators, and videos.
  - name: System
    description: Unauthenticated liveness and service-health checks.
paths:
  /videos:
    post:
      tags:
        - Videos
      summary: Track a video
      description: |-
        Track an individual Instagram post or TikTok video.

        Set ``platform`` to ``"instagram"`` or ``"tiktok"``. The item is
        registered immediately and, when added as active, its metrics are
        fetched in the background so they begin populating within seconds
        instead of waiting for the next refresh cycle. Subsequent refreshes
        then occur automatically at the configured interval.

        To track **every** post/video from an account automatically, add the
        account via ``POST /accounts`` instead.
      operationId: track_video
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Optional client-supplied unique key for retry-safe POSTs.
              Best-effort in-process dedup over a 10-minute window.
              Multi-replica deployments will need a shared store before this is
              load-bearing across all writes.
            title: Idempotency-Key
          description: >-
            Optional client-supplied unique key for retry-safe POSTs.
            Best-effort in-process dedup over a 10-minute window. Multi-replica
            deployments will need a shared store before this is load-bearing
            across all writes.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TrackVideoRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Single_VideoResponse_'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
            Location:
              schema:
                type: string
              description: URI of the created resource.
        '401':
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '403':
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '404':
          description: Not Found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '409':
          description: Conflict
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '422':
          description: Validation Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '429':
          description: Too Many Requests
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
        '500':
          description: Internal Server Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '503':
          description: Service Unavailable
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
      security:
        - HTTPBearer: []
components:
  schemas:
    TrackVideoRequest:
      properties:
        platform:
          type: string
          enum:
            - instagram
            - tiktok
          title: Platform
          description: 'Platform to track: instagram or tiktok.'
        identifier:
          type: string
          maxLength: 512
          minLength: 1
          title: Identifier
          description: >-
            The post/video to track. Accepts a full URL
            (instagram.com/p/{shortcode}, tiktok.com/@user/video/{id}), a
            numeric id, or — for Instagram only — a bare shortcode. The server
            resolves and normalizes it.
        metadata:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Metadata
          description: Optional key/value tags (≤20 keys, ≤255 chars each).
        is_active:
          type: boolean
          title: Is Active
          description: Track as active (default true).
          default: true
        scrape_interval_hours:
          type: integer
          maximum: 720
          minimum: 6
          title: Scrape Interval Hours
          description: Refresh cadence in hours (6–720). Defaults to 24.
          default: 24
      type: object
      required:
        - platform
        - identifier
      title: TrackVideoRequest
      examples:
        - identifier: https://www.tiktok.com/@user/video/712345
          is_active: true
          platform: tiktok
    Single_VideoResponse_:
      properties:
        data:
          $ref: '#/components/schemas/VideoResponse'
      type: object
      required:
        - data
      title: Single[VideoResponse]
    ProblemDetail:
      additionalProperties: true
      properties:
        type:
          title: Type
          type: string
        title:
          title: Title
          type: string
        status:
          title: Status
          type: integer
        detail:
          title: Detail
          type: string
        code:
          title: Code
          type: string
          enum:
            - BAD_REQUEST
            - CONFLICT
            - FORBIDDEN
            - INSUFFICIENT_SCOPE
            - INTERNAL_ERROR
            - NOT_ACCEPTABLE
            - NOT_FOUND
            - QUOTA_EXCEEDED
            - RATE_LIMITED
            - SERVICE_UNAVAILABLE
            - UNAUTHORIZED
            - UNSUPPORTED_MEDIA_TYPE
            - UPSTREAM_ERROR
            - VALIDATION_ERROR
        instance:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Instance
        errors:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          default: null
          title: Errors
      required:
        - type
        - title
        - status
        - detail
        - code
      title: ProblemDetail
      type: object
    VideoResponse:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: Org-scoped video id; use it on all video routes.
        type:
          type: string
          title: Type
          description: Resource type discriminator.
          default: video
        platform:
          type: string
          enum:
            - instagram
            - tiktok
          title: Platform
          description: 'Source platform: instagram or tiktok.'
        external_id:
          type: string
          title: External Id
          description: Platform-native post/video id.
        shortcode:
          anyOf:
            - type: string
            - type: 'null'
          title: Shortcode
          description: Instagram shortcode for the post URL (null for TikTok).
        is_active:
          type: boolean
          title: Is Active
          description: Whether tracking is active (vs. paused).
          default: true
        scrape_interval_hours:
          type: integer
          title: Scrape Interval Hours
          description: How often the video is refreshed, in hours.
          default: 24
        metadata:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Metadata
          description: Caller-supplied key/value tags.
        added_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Added At
          description: When tracking of this video began.
        updated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Updated At
          description: Last time the tracking record changed.
        first_scrape_time:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: First Scrape Time
          description: First successful refresh timestamp.
        last_scrape_time:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Last Scrape Time
          description: Most recent successful refresh timestamp.
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: Caption / description text.
        create_time:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Create Time
          description: When the post was published on the platform.
        media_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Media Type
          description: Media kind (e.g. VIDEO, IMAGE, CAROUSEL).
        duration:
          anyOf:
            - type: number
            - type: 'null'
          title: Duration
          description: Duration in seconds, if a video.
        is_unavailable:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Unavailable
          description: True if the post is private/removed/unreachable.
        cover_image_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Cover Image Url
          description: CDN-hosted cover/thumbnail URL.
        cover_image_url_original:
          anyOf:
            - type: string
            - type: 'null'
          title: Cover Image Url Original
          description: Original platform cover/thumbnail URL.
        video_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Video Url
          description: CDN-hosted video URL, if a video.
        video_url_original:
          anyOf:
            - type: string
            - type: 'null'
          title: Video Url Original
          description: Original platform video URL, if a video.
        view_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: View Count
          description: Latest view count.
        like_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Like Count
          description: Latest like count.
        comment_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Comment Count
          description: Latest comment count.
        share_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Share Count
          description: Latest share count.
        play_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Play Count
          description: Latest play count.
        saved_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Saved Count
          description: Latest save count (Instagram only).
        total_views:
          anyOf:
            - type: integer
            - type: 'null'
          title: Total Views
          description: Cumulative views to date.
        total_plays:
          anyOf:
            - type: integer
            - type: 'null'
          title: Total Plays
          description: Cumulative plays to date.
        account_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Account Id
          description: >-
            Org-scoped author account id; null when your org doesn't track the
            author (open the platform profile instead).
        account_username:
          anyOf:
            - type: string
            - type: 'null'
          title: Account Username
          description: Author's username, once the profile is scraped.
        platform_account_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Platform Account Id
          description: >-
            Global platform-account id (string), stable even when your org
            doesn't track the author.
        platform_data:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Platform Data
          description: Raw platform-specific extras.
      type: object
      required:
        - id
        - platform
        - external_id
      title: VideoResponse
      description: A tracked post/video with its content fields and latest metrics.
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````