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

# Enrich known entities

> Given identifiers, returns the full normalized record for each one — resolution and
retrieval in a single call. Request only the `fields` you need to spend fewer credits.

Handles up to 100 inputs synchronously. For more, create an
[enrichment job](/docs/workflows/jobs).




## OpenAPI

````yaml /api-reference/openapi.yaml post /enrich
openapi: 3.1.0
info:
  title: Unif API
  version: '2026-09-01'
  summary: One schema for commerce data across every channel.
  description: >
    The Unif API returns normalized commerce data — shops, products, creators,
    videos,

    livestreams and categories — through a single schema that does not change
    when the

    underlying data source does.


    Each request runs a cascade across the sources behind a channel, in cost
    order, stopping at

    the first result that verifies. You are charged for the hit, not for the
    attempts. See

    [the waterfall](/docs/concepts/waterfall).


    Every response is denominated in the currency you ask for, scoped to a
    market, and

    measured over a period you control, whichever source answered.


    **Base URL**


    ```

    https://api.unif.dev/v1

    ```


    All requests require a bearer token. See
    [Authentication](/docs/authentication).


    **Conventions**


    - Success and failure are carried by the HTTP status code. There is no
    envelope to unwrap:
      a `200` body is the object itself, and any `4xx` or `5xx` body is an
      [error object](/docs/platform/errors).
    - Lists are cursor-paginated. Read `next_cursor` and stop when `has_more` is
    false.

    - Every response carries `X-Request-Id`. Billable responses also carry
      `X-Unif-Credits-Charged` and `X-Unif-Credits-Remaining`.
    - Monetary fields are converted to the `currency` you request, and every
    object repeats
      the `currency` and `period` it was measured under.
  contact:
    name: Unif Support
    email: support@unif.dev
    url: https://unif.dev/docs
  license:
    name: Proprietary
    url: https://unif.dev/legal/terms
servers:
  - url: https://api.unif.dev/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Meta
    description: Workspace, channel availability and field coverage.
  - name: Shops
    description: Storefronts and sellers.
  - name: Products
    description: Listings, pricing and sales performance.
  - name: Creators
    description: Affiliates and influencers who sell.
  - name: Videos
    description: Short-form video attributed to sales.
  - name: Livestreams
    description: Live selling sessions.
  - name: Categories
    description: The normalized category tree and category-level market data.
  - name: Resolution
    description: Turn a URL, handle or external ID into a Unif entity.
  - name: Jobs
    description: Asynchronous work for large searches, enrichments and exports.
  - name: Lists
    description: Saved sets of entities.
  - name: Trackers
    description: Scheduled re-checks that emit webhook events on change.
  - name: Webhooks
    description: Endpoint registration and delivery settings.
  - name: Usage
    description: Credit balance and per-request consumption.
paths:
  /enrich:
    post:
      tags:
        - Resolution
      summary: Enrich known entities
      description: >
        Given identifiers, returns the full normalized record for each one —
        resolution and

        retrieval in a single call. Request only the `fields` you need to spend
        fewer credits.


        Handles up to 100 inputs synchronously. For more, create an

        [enrichment job](/docs/workflows/jobs).
      operationId: enrichEntities
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnrichRequest'
            examples:
              enrichShopList:
                summary: Enrich a list of storefront URLs
                value:
                  currency: USD
                  period:
                    preset: last_30d
                  fields:
                    - name
                    - categories
                    - metrics.revenue
                    - metrics.units_sold
                    - metrics.revenue_growth_rate
                  inputs:
                    - type: shop
                      url: https://www.tiktok.com/shop/glowlab
                    - type: shop
                      url: https://www.tiktok.com/shop/northpeak
      responses:
        '200':
          description: Enrichment results, in the order the inputs were sent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnrichResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      description: >
        A unique key, at most 255 characters. Retrying with the same key returns
        the original

        response instead of doing the work twice. Keys are retained for 24
        hours.
      schema:
        type: string
  schemas:
    EnrichRequest:
      type: object
      required:
        - inputs
      properties:
        inputs:
          type: array
          minItems: 1
          maxItems: 100
          items:
            $ref: '#/components/schemas/ResolveInput'
        fields:
          type: array
          items:
            type: string
          description: >
            Dot-paths to return, for example `metrics.revenue`. Omit to return
            the full record.

            Narrowing the field set lowers the credit cost.
        period:
          $ref: '#/components/schemas/Period'
        currency:
          type: string
          default: USD
    EnrichResponse:
      type: object
      properties:
        object:
          type: string
          const: enrich_response
        data:
          type: array
          items:
            $ref: '#/components/schemas/EnrichResult'
        period:
          $ref: '#/components/schemas/ResolvedPeriod'
        currency:
          type: string
        credits_charged:
          type: integer
    ResolveInput:
      type: object
      description: >
        One identifier to resolve. Supply exactly one of `url`, `handle` or
        `external_id`.

        `handle` and `external_id` need `market` and `channel` respectively to
        be unambiguous.
      required:
        - type
      properties:
        type:
          $ref: '#/components/schemas/EntityType'
        url:
          type: string
          format: uri
          description: A channel URL for the entity.
        handle:
          type: string
          description: The channel handle
          with or without a leading `@`.: null
        external_id:
          type: string
          description: The entity's native ID on the channel.
        channel:
          $ref: '#/components/schemas/Channel'
        market:
          $ref: '#/components/schemas/Market'
        ref:
          type: string
          description: Your own identifier
          echoed back on the result so you can join rows.: null
    Period:
      type: object
      description: >
        The window a metric is measured over. Supply either `preset`, or both
        `start` and

        `end`. Periods are whole days in the market's local time zone.
      properties:
        preset:
          $ref: '#/components/schemas/PeriodPreset'
        start:
          type: string
          format: date
          description: First day
          inclusive.: null
        end:
          type: string
          format: date
          description: Last day
          inclusive.: null
      examples:
        - preset: last_30d
        - start: '2026-08-01'
          end: '2026-08-31'
    EnrichResult:
      type: object
      properties:
        ref:
          type:
            - string
            - 'null'
        status:
          type: string
          enum:
            - enriched
            - not_found
            - ambiguous
            - unsupported
            - partial
        type:
          $ref: '#/components/schemas/EntityType'
        data:
          description: >-
            The normalized entity, shaped by `fields`. Null unless `status` is
            `enriched` or `partial`.
          oneOf:
            - $ref: '#/components/schemas/Shop'
            - $ref: '#/components/schemas/Product'
            - $ref: '#/components/schemas/Creator'
            - $ref: '#/components/schemas/Video'
            - $ref: '#/components/schemas/Livestream'
            - type: 'null'
        meta:
          $ref: '#/components/schemas/DataMeta'
    ResolvedPeriod:
      type: object
      description: >
        The concrete window a request was measured over, after any preset was
        expanded and any

        channel-specific snapping was applied. Always read this rather than
        assuming you got

        back exactly the dates you asked for.
      required:
        - start
        - end
      properties:
        start:
          type: string
          format: date
        end:
          type: string
          format: date
        granularity:
          type: string
          enum:
            - day
            - week
            - month
          description: The smallest bucket the channel reports for this market.
        adjusted:
          type: boolean
          description: >
            True when the requested dates were snapped to the nearest boundary
            the channel

            supports. See [Periods and currency](/docs/concepts/periods).
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    EntityType:
      type: string
      enum:
        - shop
        - product
        - creator
        - video
        - livestream
        - category
    Channel:
      type: string
      description: >
        A sales channel — the commerce surface a request is about. Behind each
        channel is a

        cascade of data sources, tried in cost order until one verifies; the
        roster is published,

        but which source answered a given row is not carried in the response, so
        the cascade can

        be re-tuned without breaking your code.
      enum:
        - tiktok_shop
      examples:
        - tiktok_shop
    Market:
      type: string
      description: An ISO 3166-1 alpha-2 country code identifying a channel storefront.
      enum:
        - US
        - GB
        - IE
        - ES
        - FR
        - DE
        - IT
        - ID
        - TH
        - VN
        - MY
        - PH
        - SG
        - JP
        - BR
        - MX
      examples:
        - US
    PeriodPreset:
      type: string
      enum:
        - last_7d
        - last_30d
        - last_90d
        - last_180d
        - month_to_date
        - previous_month
      default: last_30d
    Shop:
      type: object
      description: A storefront on a channel.
      properties:
        id:
          type: string
          examples:
            - shp_01k3m9x7v2q8r4t6y0b1n5d7fa
        object:
          type: string
          const: shop
        channel:
          $ref: '#/components/schemas/Channel'
        market:
          $ref: '#/components/schemas/Market'
        name:
          type: string
          examples:
            - GlowLab
        handle:
          type: string
          examples:
            - glowlab
        url:
          type: string
          format: uri
        logo_url:
          type: string
          format: uri
        seller_type:
          type: string
          enum:
            - brand
            - reseller
            - cross_border
            - local
            - unknown
          description: Normalized seller classification.
        categories:
          type: array
          items:
            $ref: '#/components/schemas/CategoryRef'
        rating:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 5
        reviews_count:
          type:
            - integer
            - 'null'
        products_count:
          type:
            - integer
            - 'null'
        opened_at:
          type:
            - string
            - 'null'
          format: date
        metrics:
          $ref: '#/components/schemas/ShopMetrics'
        period:
          $ref: '#/components/schemas/ResolvedPeriod'
        currency:
          type: string
        meta:
          $ref: '#/components/schemas/DataMeta'
    Product:
      type: object
      description: A listing sold through a shop on a channel.
      properties:
        id:
          type: string
          examples:
            - prd_01k3m9x7v2q8r4t6y0b1n5d7fa
        object:
          type: string
          const: product
        channel:
          $ref: '#/components/schemas/Channel'
        market:
          $ref: '#/components/schemas/Market'
        title:
          type: string
          examples:
            - Ceramide Barrier Repair Serum 30ml
        url:
          type: string
          format: uri
        image_url:
          type: string
          format: uri
        brand:
          type:
            - string
            - 'null'
        shop:
          $ref: '#/components/schemas/ShopRef'
        category:
          $ref: '#/components/schemas/CategoryRef'
        price:
          $ref: '#/components/schemas/Price'
        commission_rate:
          type:
            - number
            - 'null'
          description: Affiliate commission offered to creators, as a ratio.
        rating:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 5
        reviews_count:
          type:
            - integer
            - 'null'
        listed_at:
          type:
            - string
            - 'null'
          format: date
        metrics:
          $ref: '#/components/schemas/ProductMetrics'
        period:
          $ref: '#/components/schemas/ResolvedPeriod'
        currency:
          type: string
        meta:
          $ref: '#/components/schemas/DataMeta'
    Creator:
      type: object
      description: A person who drives attributed sales on a channel.
      properties:
        id:
          type: string
          examples:
            - crt_01k3m9x7v2q8r4t6y0b1n5d7fa
        object:
          type: string
          const: creator
        channel:
          $ref: '#/components/schemas/Channel'
        market:
          $ref: '#/components/schemas/Market'
        name:
          type: string
          examples:
            - June
        handle:
          type: string
          examples:
            - '@glowbyjune'
        url:
          type: string
          format: uri
        avatar_url:
          type: string
          format: uri
        bio:
          type:
            - string
            - 'null'
        followers:
          type:
            - integer
            - 'null'
        categories:
          type: array
          items:
            $ref: '#/components/schemas/CategoryRef'
          description: Categories the creator actually sells in, ranked by revenue share.
        agency:
          type:
            - string
            - 'null'
          description: Talent network or MCN, where the channel discloses one.
        metrics:
          $ref: '#/components/schemas/CreatorMetrics'
        period:
          $ref: '#/components/schemas/ResolvedPeriod'
        currency:
          type: string
        meta:
          $ref: '#/components/schemas/DataMeta'
    Video:
      type: object
      description: A short-form video with products attached.
      properties:
        id:
          type: string
          examples:
            - vid_01k3m9x7v2q8r4t6y0b1n5d7fa
        object:
          type: string
          const: video
        channel:
          $ref: '#/components/schemas/Channel'
        market:
          $ref: '#/components/schemas/Market'
        caption:
          type:
            - string
            - 'null'
        url:
          type: string
          format: uri
        cover_url:
          type: string
          format: uri
        duration_seconds:
          type:
            - integer
            - 'null'
        published_at:
          type: string
          format: date-time
        creator:
          $ref: '#/components/schemas/CreatorRef'
        products:
          type: array
          items:
            $ref: '#/components/schemas/ProductRef'
        metrics:
          $ref: '#/components/schemas/VideoMetrics'
        currency:
          type: string
        meta:
          $ref: '#/components/schemas/DataMeta'
    Livestream:
      type: object
      description: A live selling session.
      properties:
        id:
          type: string
          examples:
            - liv_01k3m9x7v2q8r4t6y0b1n5d7fa
        object:
          type: string
          const: livestream
        channel:
          $ref: '#/components/schemas/Channel'
        market:
          $ref: '#/components/schemas/Market'
        title:
          type:
            - string
            - 'null'
        url:
          type: string
          format: uri
        cover_url:
          type: string
          format: uri
        started_at:
          type: string
          format: date-time
        ended_at:
          type:
            - string
            - 'null'
          format: date-time
        duration_seconds:
          type:
            - integer
            - 'null'
        creator:
          $ref: '#/components/schemas/CreatorRef'
        shop:
          $ref: '#/components/schemas/ShopRef'
        products:
          type: array
          items:
            $ref: '#/components/schemas/ProductRef'
        metrics:
          $ref: '#/components/schemas/LivestreamMetrics'
        currency:
          type: string
        meta:
          $ref: '#/components/schemas/DataMeta'
    DataMeta:
      type: object
      description: How current and how complete this record is.
      properties:
        refreshed_at:
          type: string
          format: date-time
          description: When Unif last refreshed this record.
        completeness:
          type: number
          minimum: 0
          maximum: 1
          description: Share of the requested fields that were populated.
        missing_fields:
          type: array
          items:
            type: string
          description: Fields that are not covered for this channel and market.
    Error:
      type: object
      properties:
        type:
          type: string
          enum:
            - invalid_request_error
            - authentication_error
            - permission_error
            - not_found_error
            - rate_limit_error
            - billing_error
            - coverage_error
            - api_error
        code:
          type: string
          examples:
            - parameter_invalid
        message:
          type: string
        param:
          type:
            - string
            - 'null'
          description: The offending field
          as a dot-path.: null
        doc_url:
          type: string
          format: uri
        request_id:
          type: string
    CategoryRef:
      type: object
      properties:
        id:
          type: string
          examples:
            - cat_beauty_personal_care
        name:
          type: string
          examples:
            - Beauty & Personal Care
        path:
          type: array
          items:
            type: string
          description: Names from the root down to this category.
    ShopMetrics:
      type: object
      description: Shop performance over the requested period, in the requested currency.
      properties:
        revenue:
          type: number
          description: Gross merchandise value attributed to the shop.
        units_sold:
          type: integer
        avg_unit_price:
          type: number
        revenue_growth_rate:
          type: number
          description: >-
            Change in revenue against the immediately preceding period of equal
            length, as a ratio. `0.25` is +25%.
        revenue_by_source:
          type: object
          description: Share of revenue by selling surface. Values sum to 1.
          properties:
            video:
              type: number
            live:
              type: number
            mall:
              type: number
            search:
              type: number
        products_sold_count:
          type: integer
          description: Distinct products with at least one sale.
        creators_count:
          type: integer
          description: Distinct creators who drove attributed sales.
        videos_count:
          type: integer
        livestreams_count:
          type: integer
    ShopRef:
      type: object
      properties:
        id:
          type: string
          examples:
            - shp_01k3m9x7v2q8r4t6y0b1n5d7fa
        name:
          type: string
          examples:
            - GlowLab
        url:
          type: string
          format: uri
    Price:
      type: object
      properties:
        current:
          type: number
        min:
          type: number
          description: Lowest observed price in the period.
        max:
          type: number
          description: Highest observed price in the period.
    ProductMetrics:
      type: object
      properties:
        revenue:
          type: number
        units_sold:
          type: integer
        avg_sale_price:
          type: number
          description: Revenue divided by units sold
          which can differ from list price.: null
        revenue_growth_rate:
          type: number
        revenue_by_source:
          type: object
          properties:
            video:
              type: number
            live:
              type: number
            mall:
              type: number
            search:
              type: number
        creators_count:
          type: integer
        videos_count:
          type: integer
        livestreams_count:
          type: integer
        gpm:
          type: number
          description: Gross revenue per thousand views across attributed content.
    CreatorMetrics:
      type: object
      properties:
        revenue:
          type: number
          description: Revenue attributed to the creator's content.
        units_sold:
          type: integer
        gpm:
          type: number
          description: Gross revenue per thousand views.
        avg_commission_rate:
          type: number
        products_count:
          type: integer
          description: Distinct products the creator sold.
        shops_count:
          type: integer
        videos_count:
          type: integer
        livestreams_count:
          type: integer
        avg_views_per_video:
          type: number
        engagement_rate:
          type: number
          description: Likes
          comments and shares divided by views.: null
        follower_growth:
          type: integer
          description: Net followers gained over the period.
    CreatorRef:
      type: object
      properties:
        id:
          type: string
          examples:
            - crt_01k3m9x7v2q8r4t6y0b1n5d7fa
        name:
          type: string
          examples:
            - June
        handle:
          type: string
          examples:
            - '@glowbyjune'
    ProductRef:
      type: object
      properties:
        id:
          type: string
          examples:
            - prd_01k3m9x7v2q8r4t6y0b1n5d7fa
        title:
          type: string
          examples:
            - Ceramide Barrier Repair Serum 30ml
        url:
          type: string
          format: uri
    VideoMetrics:
      type: object
      properties:
        views:
          type: integer
        likes:
          type: integer
        comments:
          type: integer
        shares:
          type: integer
        engagement_rate:
          type: number
        revenue:
          type: number
        units_sold:
          type: integer
        gpm:
          type: number
    LivestreamMetrics:
      type: object
      properties:
        revenue:
          type: number
        units_sold:
          type: integer
        viewers:
          type: integer
          description: Unique viewers over the session.
        peak_concurrent_viewers:
          type: integer
        avg_watch_seconds:
          type: number
        likes:
          type: integer
        comments:
          type: integer
        gpm:
          type: number
  responses:
    BadRequest:
      description: The request was malformed or a parameter was invalid.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: invalid_request_error
              code: parameter_invalid
              message: filters.revenue.gte must be a non-negative number.
              param: filters.revenue.gte
              doc_url: https://unif.dev/docs/platform/errors#parameter_invalid
              request_id: req_01k3m9x7v2q8r4t6y0b1n5d7fa
    InsufficientCredits:
      description: The workspace has no credits left for this billing period.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: billing_error
              code: insufficient_credits
              message: >-
                This request costs 25 credits and 4 remain in the current
                period.
              doc_url: https://unif.dev/docs/platform/credits
              request_id: req_01k3m9x7v2q8r4t6y0b1n5d7fa
    RateLimited:
      description: Too many requests.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  headers:
    RequestId:
      description: Unique ID for this request. Include it in support conversations.
      schema:
        type: string
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
    RateLimitLimit:
      description: Requests allowed in the current window.
      schema:
        type: integer
    RateLimitRemaining:
      description: Requests left in the current window.
      schema:
        type: integer
    RateLimitReset:
      description: Unix timestamp when the window resets.
      schema:
        type: integer
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Send your workspace API key as a bearer token:


        ```

        Authorization: Bearer unif_sk_live_...

        ```


        Keys are scoped to a single workspace. See
        [Authentication](/docs/authentication).

````