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

# Get product resolver behavior

> Return whether the product is enrolled in the resolver and its per-GTIN behavior controls. Requires VIEW permission; 404 if the product does not belong to one of the organization's brands.



## OpenAPI

````yaml /openapi/openapi-resolver.json get /resolver/api/v1/organizations/{organization_id}/products/{gtin}/resolver-behavior
openapi: 3.1.0
info:
  title: Resolver API
  version: 1.0.0
  description: >
    GS1 Digital Link resolution with content negotiation and linkset support.


    ## Authentication


    All endpoints require an API key passed via the `X-API-Key` HTTP header,
    unless otherwise noted.


    ```

    X-API-Key: csb_<body>_<checksum>

    ```


    Generate API keys in **Settings > API Keys** in your dashboard, or via the
    Account API.

    Session-based (cookie) authentication is also accepted for browser-based
    access.


    ## Rate Limits


    | Tier        | Requests / minute | Requests / day |

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

    | Default     | 300               | 10,000         |

    | Custom      | Contact us        | Contact us     |


    Rate-limit headers are included on every response so callers can
    self-throttle without

    hitting our 429s ("informed governor"):


    - `RateLimit-Policy` — every active window, e.g. `300;w=60, 10000;w=86400`

    - `RateLimit-Limit` — quota for the **most-restrictive** currently-active
    window

    - `RateLimit-Remaining` — requests left in that window

    - `RateLimit-Reset` — seconds until that window resets (relative; clock-skew
    safe)


    Legacy `X-RateLimit-*` aliases are also emitted for back-compat.
    `X-RateLimit-Reset`

    keeps the absolute Unix-timestamp shape to avoid breaking existing
    consumers.


    When rate-limited, you receive `429 Too Many Requests` with a
    `retry_after_seconds` field

    in the error envelope and a `Retry-After` header.


    ## Pagination


    List endpoints return paginated results in this envelope:


    ```json

    {
      "data": [...],
      "pagination": {
        "page": 1,
        "page_size": 25,
        "total_count": 342,
        "total_pages": 14,
        "has_next": true,
        "has_previous": false
      }
    }

    ```


    Use `?page=2&page_size=50` query parameters. Maximum page size is 100.


    ## Error Responses


    All errors conform to [RFC 9457 Problem
    Details](https://www.rfc-editor.org/rfc/rfc9457)

    with `Content-Type: application/problem+json`:


    ```json

    {
      "type": "https://closient.com/docs/errors/not_found",
      "title": "Not Found",
      "status": 404,
      "detail": "The requested resource was not found.",
      "error_code": "not_found",
      "retryable": false,
      "timestamp": "2026-03-31T12:00:00+00:00"
    }

    ```


    Common error codes: `unauthorized` (401), `forbidden` (403), `not_found`
    (404),

    `validation_error` (422), `rate_limited` (429), `internal_error` (500).
  termsOfService: https://www.closient.com/terms/
servers:
  - url: https://www.closient.com
security: []
tags:
  - name: Resolver
    description: GS1 Digital Link resolution with content negotiation and linkset support.
  - name: Custom URLs
    description: >-
      Reusable custom-URL catalog (C-3339) — create, list, edit, and delete the
      custom redirect destinations that resolution rules point at.
  - name: Resolver Configuration
    description: >-
      Organization resolver settings and per-product resolver state (C-6273) —
      the routing timezone, whether the resolver serves a product, and its
      per-GTIN behavior controls (enhanced resolution, expiry, serial policy,
      shelf-life offset, age gate). The same audited writes the dashboard pages
      make.
  - name: Verification
    description: >-
      Serial verification (`gs1:verificationService`) — tiered, rate-limited
      responses for serialized GTIN scans. Experimental v1; see the
      verification-service guide.
  - name: GS1 Primitives (Public)
    description: >-
      Keyless GS1 Digital Link primitives (C-4295) — parse, validate, build,
      decompress, and check-digit analysis. **No API key, no signup.** Pure
      functions over strings: no database, no network, no catalog data.
      IP-throttled and edge-cached so repeat calls cost nothing. This is the
      reference implementation the resolver itself runs on.
  - name: Resolver Custom Hostnames
    description: >-
      BYO domain (C-4058) — register a customer-owned hostname, publish the
      CNAME records, verify ownership, and serve an org's Digital Link QRs from
      its own DNS.
externalDocs:
  description: Closient Documentation
  url: https://docs.closient.com
paths:
  /resolver/api/v1/organizations/{organization_id}/products/{gtin}/resolver-behavior:
    get:
      tags:
        - Resolver Configuration
      summary: Get product resolver behavior
      description: >-
        Return whether the product is enrolled in the resolver and its per-GTIN
        behavior controls. Requires VIEW permission; 404 if the product does not
        belong to one of the organization's brands.
      operationId: apps_resolver_api_configuration_get_product_resolver_behavior
      parameters:
        - in: path
          name: organization_id
          schema:
            description: ID of the organization. Caller must have VIEW.
            format: shortuuid
            maxLength: 22
            minLength: 22
            pattern: ^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$
            title: Organization Id
            type: string
          required: true
          description: ID of the organization. Caller must have VIEW.
        - in: path
          name: gtin
          schema:
            description: >-
              GTIN-8, GTIN-12, GTIN-13, or GTIN-14 digits (no separators) with a
              valid GS1 check digit. Normalized to GTIN-14 for lookup; the
              product must belong to one of the organization's brands.
            maxLength: 14
            minLength: 8
            title: Gtin
            type: string
          required: true
          description: >-
            GTIN-8, GTIN-12, GTIN-13, or GTIN-14 digits (no separators) with a
            valid GS1 check digit. Normalized to GTIN-14 for lookup; the product
            must belong to one of the organization's brands.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductResolverBehaviorOut'
        '400':
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
        '401':
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
        '403':
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
        '404':
          description: Not Found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
        '405':
          description: Method Not Allowed
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
        '422':
          description: Unprocessable Content
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
        '429':
          description: Too Many Requests
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorOut'
      security:
        - APIKeyHeaderAuth: []
        - OAuthTokenAuth: []
        - CookieGatedSessionAuth: []
components:
  schemas:
    ProductResolverBehaviorOut:
      description: A product's resolver state and its per-GTIN resolver behavior.
      examples:
        - age_restricted: false
          enhanced_resolution_enabled: true
          expiry_behavior: REDIRECT
          expiry_redirect_url: https://acmesnacks.com/reorder
          gtin: '00012345678905'
          product_name: Acme Trail Mix 12oz
          resolver_enabled: true
          resolver_enabled_at: '2026-06-01T09:00:00Z'
          serial_policy: PERMISSIVE
          shelf_life_offset_ai: '15'
          shelf_life_offset_days: 180
      properties:
        gtin:
          description: Normalized GTIN-14 (zero-padded).
          title: Gtin
          type: string
        product_name:
          description: Product name, for display.
          title: Product Name
          type: string
        resolver_enabled:
          description: >-
            Whether the product is enrolled in the resolver (its billable unit).
            While false, its lots and serials are not billable either, whatever
            their own flags say, and enhanced resolution cannot be on. Scans of
            the product resolve either way.
          title: Resolver Enabled
          type: boolean
        resolver_enabled_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            When the resolver was last turned on for this product; null if
            never.
          title: Resolver Enabled At
        enhanced_resolution_enabled:
          description: >-
            Whether the product is on the paid enhanced tier, which unlocks
            expiry behavior and the strict serial policy. Requires the resolver
            to be on.
          title: Enhanced Resolution Enabled
          type: boolean
        expiry_behavior:
          $ref: '#/components/schemas/ProductExpiryBehaviorEnum'
          description: >-
            What a scan carrying a past use-by (AI 17) or best-before (AI 15)
            date gets: ``NONE`` forwards it unchanged, ``NOTICE`` shows a
            past-date notice, ``REDIRECT`` sends it to ``expiry_redirect_url``.
            Only acted on while enhanced resolution is on.
        expiry_redirect_url:
          description: >-
            Destination for an expired scan when ``expiry_behavior`` is
            ``REDIRECT``; empty otherwise.
          title: Expiry Redirect Url
          type: string
        serial_policy:
          $ref: '#/components/schemas/ProductSerialPolicyEnum'
          description: >-
            ``PERMISSIVE`` falls back to the deepest available page for an
            unknown serial; ``STRICT`` shows an unverified-unit page. Only acted
            on while enhanced resolution is on.
        shelf_life_offset_days:
          anyOf:
            - type: integer
            - type: 'null'
          description: Days from manufacture to the printed date; null when not configured.
          title: Shelf Life Offset Days
        shelf_life_offset_ai:
          anyOf:
            - $ref: '#/components/schemas/ProductShelfLifeDateAIEnum'
            - type: 'null'
          description: >-
            Which printed date the offset produces: ``15`` best-before or ``17``
            use-by; null when not set.
        age_restricted:
          description: Whether scans of this product pass an 18+ age gate first.
          title: Age Restricted
          type: boolean
      required:
        - gtin
        - product_name
        - resolver_enabled
        - enhanced_resolution_enabled
        - expiry_behavior
        - expiry_redirect_url
        - serial_policy
        - age_restricted
      title: ProductResolverBehaviorOut
      type: object
    ErrorOut:
      description: |-
        RFC 9457 Problem Details response.

        All API errors are returned in this format with Content-Type:
        application/problem+json.
      examples:
        - detail: The requested resource was not found.
          error_code: not_found
          retryable: false
          status: 404
          timestamp: '2026-03-31T12:00:00+00:00'
          title: Not Found
          type: https://closient.com/docs/errors/not_found
        - detail: Validation error.
          details:
            - loc:
                - body
                - name
              msg: Field required
              type: missing
          error_code: validation_error
          retryable: false
          status: 422
          timestamp: '2026-03-31T12:00:00+00:00'
          title: Validation Error
          type: https://closient.com/docs/errors/validation_error
        - detail: Rate limit exceeded. Please try again later.
          error_code: rate_limited
          retry_after: 31
          retryable: true
          status: 429
          timestamp: '2026-03-31T12:00:00+00:00'
          title: Rate Limited
          type: https://closient.com/docs/errors/rate_limited
      properties:
        type:
          description: URI reference identifying the error type.
          title: Type
          type: string
        title:
          description: Short human-readable summary of the error.
          title: Title
          type: string
        status:
          description: HTTP status code.
          title: Status
          type: integer
        detail:
          description: Human-readable explanation of this specific occurrence.
          title: Detail
          type: string
        error_code:
          description: Machine-readable error code (e.g. not_found, unauthorized).
          title: Error Code
          type: string
        retryable:
          default: false
          description: Whether retrying the same request can succeed.
          title: Retryable
          type: boolean
        timestamp:
          description: ISO 8601 timestamp of when the error occurred.
          title: Timestamp
          type: string
        retry_after:
          anyOf:
            - type: integer
            - type: 'null'
          description: Seconds to wait before retrying (when applicable).
          title: Retry After
        owner_action_required:
          anyOf:
            - type: boolean
            - type: 'null'
          description: Whether the error requires account owner intervention.
          title: Owner Action Required
        details:
          description: Additional context (validation errors, etc.).
          title: Details
      required:
        - type
        - title
        - status
        - detail
        - error_code
        - timestamp
      title: ErrorOut
      type: object
    ProductExpiryBehaviorEnum:
      description: >-
        What an expired scan does. Mirrors
        :class:`apps.products.models.ProductExpiryBehavior`.
      enum:
        - NONE
        - NOTICE
        - REDIRECT
      title: ProductExpiryBehaviorEnum
      type: string
    ProductSerialPolicyEnum:
      description: >-
        How an unknown serial resolves. Mirrors
        :class:`apps.products.models.ProductSerialPolicy`.
      enum:
        - PERMISSIVE
        - STRICT
      title: ProductSerialPolicyEnum
      type: string
    ProductShelfLifeDateAIEnum:
      description: >-
        Which printed date a shelf-life offset produces. Mirrors
        :class:`apps.products.models.ProductShelfLifeDateAI`.
      enum:
        - '15'
        - '17'
      title: ProductShelfLifeDateAIEnum
      type: string
  securitySchemes:
    APIKeyHeaderAuth:
      type: apiKey
      in: header
      name: X-API-Key
    OAuthTokenAuth:
      type: http
      scheme: bearer
    CookieGatedSessionAuth:
      type: apiKey
      in: cookie
      name: sessionid

````

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