> ## 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.

# Compress Application Identifiers into a GS1 Digital Link path segment

> Bit-pack a primary key plus optional qualifiers/attributes into the single opaque base64url path segment defined by GS1's Digital Link compression scheme — the exact inverse of `/decompress`.

Takes the same `primary_ai` / `primary_value` / repeated `qualifier=code:value` / `attribute=code:value` shape as `/build`, so the same query string composes both the uncompressed and compressed forms of an identifier set.

An AI set that cannot be compressed (unknown AI code, malformed value, no primary identifier) is a `200` with `is_valid: false` and the reason — the same triage contract as `/validate` and `/decompress`.

**Keyless** — no API key, no signup. IP-throttled at 300 requests/minute and cached at the edge for 24h, so repeat calls for the same input do not reach origin. Over-rate callers get a `429` with a `Retry-After` header and a `retry_after` field — it never silently degrades or returns a wrong answer under load.



## OpenAPI

````yaml /openapi/openapi-resolver.json get /resolver/api/v1/public/gs1/compress
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: 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/public/gs1/compress:
    get:
      tags:
        - GS1 Primitives (Public)
      summary: Compress Application Identifiers into a GS1 Digital Link path segment
      description: >-
        Bit-pack a primary key plus optional qualifiers/attributes into the
        single opaque base64url path segment defined by GS1's Digital Link
        compression scheme — the exact inverse of `/decompress`.


        Takes the same `primary_ai` / `primary_value` / repeated
        `qualifier=code:value` / `attribute=code:value` shape as `/build`, so
        the same query string composes both the uncompressed and compressed
        forms of an identifier set.


        An AI set that cannot be compressed (unknown AI code, malformed value,
        no primary identifier) is a `200` with `is_valid: false` and the reason
        — the same triage contract as `/validate` and `/decompress`.


        **Keyless** — no API key, no signup. IP-throttled at 300 requests/minute
        and cached at the edge for 24h, so repeat calls for the same input do
        not reach origin. Over-rate callers get a `429` with a `Retry-After`
        header and a `retry_after` field — it never silently degrades or returns
        a wrong answer under load.
      operationId: apps_resolver_api_public_gs1_compress_digital_link_public
      parameters:
        - in: query
          name: primary_ai
          schema:
            description: The primary identifier AI code, e.g. `01` for GTIN.
            maxLength: 4
            minLength: 2
            title: Primary Ai
            type: string
          required: true
          description: The primary identifier AI code, e.g. `01` for GTIN.
        - in: query
          name: primary_value
          schema:
            description: The primary identifier's value, e.g. `09506000164908`.
            maxLength: 256
            minLength: 1
            title: Primary Value
            type: string
          required: true
          description: The primary identifier's value, e.g. `09506000164908`.
        - in: query
          name: qualifier
          schema:
            default: []
            description: Repeatable qualifier AI in `code:value` form, e.g. `10:LOT1`.
            items:
              type: string
            title: Qualifier
            type: array
          required: false
          description: Repeatable qualifier AI in `code:value` form, e.g. `10:LOT1`.
        - in: query
          name: attribute
          schema:
            default: []
            description: >-
              Repeatable data-attribute AI in `code:value` form, e.g.
              `17:261231`.
            items:
              type: string
            title: Attribute
            type: array
          required: false
          description: Repeatable data-attribute AI in `code:value` form, e.g. `17:261231`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DigitalLinkCompressOut'
        '400':
          description: Bad Request
          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'
components:
  schemas:
    DigitalLinkCompressOut:
      description: A GS1-compressed Digital Link path segment plus how it graded.
      examples:
        - ai_map:
            '01': '09506000164908'
          compressed_path: /ARFKk4awWA
          compressed_segment: ARFKk4awWA
          is_valid: true
      properties:
        ai_map:
          additionalProperties:
            type: string
          description: >-
            The `{ai_code: value}` map that was compressed, echoed back for
            confirmation.
          title: Ai Map
          type: object
        is_valid:
          description: True when the AI map compressed successfully.
          title: Is Valid
          type: boolean
        error:
          anyOf:
            - type: string
            - type: 'null'
          description: Why compression failed, or `null` on success.
          title: Error
        compressed_segment:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The opaque base64url path segment, or `null` when compression
            failed.
          examples:
            - ARFKk4awWA
          title: Compressed Segment
        compressed_path:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The GS1-canonical root-relative compressed path
            (`/<compressed_segment>`), as served at `id.gs1.org`, or `null` when
            compression failed. Closient's own resolver serves compressed
            Digital Links under a `/c/<segment>` prefix instead — see
            `docs.closient.com` for why.
          examples:
            - /ARFKk4awWA
          title: Compressed Path
      required:
        - ai_map
        - is_valid
      title: DigitalLinkCompressOut
      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

````