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

# Sample funnel

> Returns the sample funnel for a cohort of sample requests: counts per stage, conversion rates and time in stage. The cohort is every sample row (one per application and product) first seen as requested between `start_date` and `end_date` (YYYY-MM-DD, UTC, inclusive, at most 365 days apart). Later stages count for that cohort whenever they happened.

Stages run `sample_requested`, `awaiting_shipment`, `sample_shipped`, `content_pending`, `content_fulfilled`. Each has `count`, `rateFromPrevious` and `rateFromRequested` (fractions, 0.6 = 60%, null when the denominator is 0) and `timeInStage` (median and p90 hours to the next stage). `exits` counts `content_warning` and `content_unfulfilled` (set by Growi's timers) and `cancelled` (set by TikTok). `byCollabType` splits open and target collabs, and `currentStates` counts rows by state. Filter with `productId` or `targetCollaborationId`.

Times are when Growi observed each change, not TikTok's event times. For a newly connected shop, its whole pending backlog lands on the day it connected.



## OpenAPI

````yaml api-reference/tik-tok-shop-openapi.json GET /tik_tok_shop/samples/funnel
openapi: 3.0.3
info:
  title: 'Growi API: TikTok Shop'
  version: 1.0.0
  description: >-
    Generated by scripts/gen_tik_tok_shop.rb from Growi's TikTok Shop route
    table.
servers:
  - url: https://api.growi.io/api/public/v1
security:
  - bearerAuth: []
paths:
  /tik_tok_shop/samples/funnel:
    get:
      summary: Sample funnel
      description: >-
        Returns the sample funnel for a cohort of sample requests: counts per
        stage, conversion rates and time in stage. The cohort is every sample
        row (one per application and product) first seen as requested between
        `start_date` and `end_date` (YYYY-MM-DD, UTC, inclusive, at most 365
        days apart). Later stages count for that cohort whenever they happened.


        Stages run `sample_requested`, `awaiting_shipment`, `sample_shipped`,
        `content_pending`, `content_fulfilled`. Each has `count`,
        `rateFromPrevious` and `rateFromRequested` (fractions, 0.6 = 60%, null
        when the denominator is 0) and `timeInStage` (median and p90 hours to
        the next stage). `exits` counts `content_warning` and
        `content_unfulfilled` (set by Growi's timers) and `cancelled` (set by
        TikTok). `byCollabType` splits open and target collabs, and
        `currentStates` counts rows by state. Filter with `productId` or
        `targetCollaborationId`.


        Times are when Growi observed each change, not TikTok's event times. For
        a newly connected shop, its whole pending backlog lands on the day it
        connected.
      parameters:
        - name: start_date
          in: query
          required: true
          schema:
            type: string
          description: Cohort window start, YYYY-MM-DD (UTC) INCLUSIVE.
        - name: end_date
          in: query
          required: true
          schema:
            type: string
          description: >-
            Cohort window end, YYYY-MM-DD (UTC) INCLUSIVE. At most 365 days
            after start_date.
        - name: productId
          in: query
          required: false
          schema:
            type: string
          description: Only this product's sample rows.
        - name: targetCollaborationId
          in: query
          required: false
          schema:
            type: string
          description: Only samples attributed to this target collaboration.
        - name: organization_id
          in: query
          required: false
          schema:
            type: integer
          description: >-
            Use the TikTok Shop of this child brand (organization id) of your
            API key's organization
      responses:
        '200':
          description: >-
            { shopId, window {startDate, endDate}, filters {productId,
            targetCollaborationId}, cohort, stages: [{ key, count, source:
            "tts_native", rateFromPrevious, rateFromRequested, timeInStage: {
            medianHours, p90Hours, rows } | null }], exits: [{ key, count,
            source: "timer" | "tts_native", rateFromRequested }], byCollabType:
            { open, target } each { requested, approved, shipped,
            contentFulfilled }, currentStates: { state: count } }. Rates are
            fractions (0.6 = 60%) to 4 dp, null when the denominator is 0.
          content:
            application/json:
              example:
                shopId: '7494000000000000900'
                window:
                  startDate: '2026-01-01'
                  endDate: '2026-01-31'
                filters:
                  productId: null
                  targetCollaborationId: null
                cohort: 200
                stages:
                  - key: sample_requested
                    count: 200
                    source: tts_native
                    rateFromPrevious: null
                    rateFromRequested: 1
                    timeInStage:
                      medianHours: 20.5
                      p90Hours: 70.1
                      rows: 150
                  - key: awaiting_shipment
                    count: 150
                    source: tts_native
                    rateFromPrevious: 0.75
                    rateFromRequested: 0.75
                    timeInStage:
                      medianHours: 30
                      p90Hours: 96
                      rows: 120
                  - key: sample_shipped
                    count: 120
                    source: tts_native
                    rateFromPrevious: 0.8
                    rateFromRequested: 0.6
                    timeInStage:
                      medianHours: 72
                      p90Hours: 150
                      rows: 100
                  - key: content_pending
                    count: 100
                    source: tts_native
                    rateFromPrevious: 0.8333
                    rateFromRequested: 0.5
                    timeInStage:
                      medianHours: 120
                      p90Hours: 300
                      rows: 60
                  - key: content_fulfilled
                    count: 60
                    source: tts_native
                    rateFromPrevious: 0.6
                    rateFromRequested: 0.3
                    timeInStage: null
                exits:
                  - key: content_warning
                    count: 12
                    source: timer
                    rateFromRequested: 0.06
                  - key: content_unfulfilled
                    count: 8
                    source: timer
                    rateFromRequested: 0.04
                  - key: cancelled
                    count: 30
                    source: tts_native
                    rateFromRequested: 0.15
                byCollabType:
                  open:
                    requested: 150
                    approved: 110
                    shipped: 90
                    contentFulfilled: 40
                  target:
                    requested: 50
                    approved: 40
                    shipped: 30
                    contentFulfilled: 20
                currentStates:
                  content_fulfilled: 60
                  content_pending: 32
                  cancelled: 30
                  sample_requested: 50
                  awaiting_shipment: 20
                  content_unfulfilled: 8
        '400':
          description: >-
            Invalid params: missing or malformed dates, a reversed window, or a
            span over 365 days
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TikTokShopError'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TikTokShopError'
        '404':
          description: >-
            `organization_id` isn't an active child brand of your organization,
            or the record you asked for doesn't exist
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TikTokShopError'
        '422':
          description: >-
            No TikTok Shop is connected for this organization. A parent
            organization whose shops sit on its child brands has to pass
            `organization_id`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TikTokShopError'
        '429':
          description: >-
            Rate limited: one call every 2 seconds and an hourly cap per API
            key. See `Retry-After` and the `X-RateLimit-*` headers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TikTokShopError'
        '502':
          description: >-
            TikTok refused or failed. `error` is a fixed message and `code`
            names the failure when there is one
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TikTokShopError'
components:
  schemas:
    TikTokShopError:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: What went wrong
        code:
          type: string
          description: Machine-readable reason, when there is one
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.