# Closient

> Closient is a GS1 Digital Link resolver and product data platform for CPG brands, retailers, and consumers at closient.com. It provides Sunrise 2027-ready GS1-compliant product identity infrastructure — Digital Link resolution, QR code generation, EPCIS 2.0 traceability, and compliance tooling — and also helps consumers find products at nearby stores using conversational search.

## About

Closient is a GS1 Digital Link resolver and product data platform. Brands register their products, locations, and inventory, use GS1 Digital Link resolution for product packaging QR codes, and meet GS1 Sunrise 2027 readiness and regulatory requirements. As a secondary capability, consumers search for those products and find them at nearby stores ranked by distance.

Key capabilities:

- GS1 Digital Link URI resolution with full Application Identifier support (AI 01 GTIN, 21 Serial, 10 Batch/Lot, 17 Expiry, and more)
- Sunrise 2027 readiness: migrate barcodes to GS1 Digital Link QR codes carrying both retail-scan and web data
- Local product search ranked by geographic proximity with inventory confidence scoring
- Contextual routing: the same QR code resolves to different destinations based on link type, locale, or device
- Hosted product pages with ingredients, nutrition, allergens, recalls, and brand content
- QR code generation optimized for minimum module count and maximum scan reliability
- FSMA 204 food traceability with lot and serial tracking
- EU Digital Product Passport (DPP) concepts
- EPCIS 2.0 event capture and query for supply chain visibility
- Retail POS integrations (Shopify, Square, Clover, Lightspeed)

## Docs

- [Getting Started](https://docs.closient.com/quickstart): Account setup, API keys, product registration, and local search visibility
- [GS1 Resolution](https://docs.closient.com/guides/digital-link-resolution): URI structure, Application Identifiers, content negotiation, and linkset format
- [API Reference](https://docs.closient.com): REST API for catalog management, GTIN resolution, and local search
- [QR Codes and Barcodes](/learn/2d-barcodes/): Generation formats, parameters, and supported symbologies
- [Local Search](https://docs.closient.com/user-guides/searching-products): How proximity ranking, inventory signals, and conversational refinement work

## Pages

- [About Closient — Product Data Platform for CPG & Retail](/about.md): Closient is a local-first product search engine built on GS1 Digital Link standards. Learn about our mission, team, and how we connect consumers with nearby products.
- [Imprint](/legal/imprint.md): Legal disclosure and company information for Closient Search Inc., including registered address, contact details, and representative.
- [Deleting Your Organization — What Actually Happens to Your Data](/learn/deleting-your-organization.md): Deleting an organization on Closient is a reversible 90-day process, not an instant wipe. Here's exactly what happens to your products, billing, API keys, and traceability records — and how to undo it.
- [GS1 Glossary — Learn — Closient](/learn/glossary.md): A glossary of key GS1 terms and definitions including GTIN, GLN, EPCIS, Digital Link, Data Matrix, and more.
- [GS1 Sunrise 2027 for Wholesalers — Help Your Brand Partners Get Ready](/learn/sunrise-2027-for-wholesalers.md): An industry briefing for wholesalers and distributors: what GS1 Sunrise 2027, the EU Digital Product Passport, and FSMA 204 mean for the brand partners in your portfolio — and the 4-step path brands can run to be ready.
- [Learn with Closient — GS1, EPCIS, Digital Link, Sustainability](/learn.md): Learn about GS1 standards, EPCIS, Digital Link resolvers, sustainability, and the Digital Product Passport. Educational resources from Closient.
- [SMS Messaging Policy — Closient Recall & Safety Alerts](/messaging-policy.md): How Closient's product recall and safety alert text messages work: who sends them, how you opt in, message frequency and cost, and how to stop them at any time.
- [Press Kit — Closient Brand Assets, Logos & Media Resources](/press-kit.md): Download Closient logos, brand guidelines, color palette, and boilerplate copy. Press contact and company facts for journalists, analysts, and partners.
- [Subprocessors](/legal/subprocessors.md): The third-party and self-hosted infrastructure providers Closient Search Inc. uses to operate the Service, and what each one does.

## Consumer Tools

- [Scan a barcode or QR code](/scan/): Public, mobile-optimized camera-scan page. Point your phone at any product barcode or GS1 Digital Link QR code; redirects to the resolver for instant product information. No app, no login required.
- [Free tools index](/tools/): Public utilities for working with QR codes and GS1 Digital Link URLs.
- [QR Print Size Calculator](/tools/qr-print-size/): Paste a URL → get the QR version, module grid, and minimum + recommended print size in mm and inches per the GS1 X-dimension specification.
- [GS1 Digital Link Validator](/tools/gs1-validator/): Paste any URL → pass/fail conformance check against the GS1 Digital Link spec, with parsed primary AI + qualifiers and specific failure reasons.
- [GS1 Digital Link Builder](/tools/digital-link-builder/): Interactive composer — pick a primary key (GTIN, GLN, GSRN, GDTI, GCN, ...), add qualifier AIs (lot, expiry, serial, CPV), validate against the spec, copy the resulting URI.
- [Supported Application Identifiers](/tools/digital-link-ais/): Reference of every GS1 Application Identifier the resolver understands — 16 primary key AIs with per-key qualifier rules and data-attribute AIs, generated from the resolver's own validation tables. Honestly marks GINC (401) and GSIN (402) as not yet supported.
- [GS1 Conformance Report](/tools/gs1-conformance/): Daily run of the official GS1 Digital Link Resolver test suite (gs1/GS1DL-resolver-testsuite) against Closient — pass/fail counts per category, 30-day history, last-run timestamp, and the resolver release that produced the result.
- [Sunrise 2027 Readiness Tracker](/tools/sunrise-tracker/): Public dashboard of retailer, POS vendor, and wholesaler readiness for the GS1 Sunrise 2027 deadline (2D barcodes at point of sale). Curated, citation-backed list grouped by status — Ready / Piloting / Announced / Silent — with a countdown to 2027-01-01.

## Product

- [Pricing](/pricing): Every product resolves free and unlimited; pay only for enhanced products and stored records

## Resolution

Closient resolves GS1 Digital Link URIs following the GS1 specification:

- `/01/{gtin}` — Resolve a GTIN (Global Product Number) to product information
- `/01/{gtin}/10/{lot}` — Resolve with batch/lot number
- `/01/{gtin}/21/{serial}` — Resolve with serial number
- `/01/{gtin}/17/{expiry}` — Resolve with expiry date
- `?linkType=gs1:pip` — Request a specific link type (product information page)
- `?linkType=gs1:recallStatus` — Request recall status
- `?linkType=gs1:hasRetailers` — Request retailer information
- `/brands/{brand-slug}/{family-slug}/` — Public product family page: one page per family of variants (sizes, flavors, scents, colors, ...) with the default variant first and the siblings grouped by axis. Embeds a schema.org `ProductGroup` (`productGroupID`, `variesBy`, `hasVariant`); each variant's JSON-LD names it with `inProductGroupWithID` / `isVariantOf`. Its RFC 9264 linkset at `/brands/{brand-slug}/{family-slug}/linkset/` lists every variant's Digital Link as `item`, and a resolved variant's `Link` header points back with `rel="collection"`.
- `/pip/{gtin}/verification/` — Public claim-verification trust card for a product: the brand-ownership tier (Unverified / Prefix Matched / Verified / Disputed), the approved evidence behind it, last re-verification check, expiry, and an anonymized dispute history. Externally linkable; no login required.

Additional supported Application Identifiers:

- `/00/{sscc}` — Serial Shipping Container Code
- `/253/{gdti}` — Global Document Type Identifier
- `/255/{gcn}` — Global Coupon Number
- `/401/{ginc}` — Global Identification Number for Consignment
- `/402/{gsin}` — Global Shipment Identification Number
- `/414/{gln}` — Global Location Number (physical location)
- `/415/{gln}` — Global Location Number (invoicing party)
- `/417/{gln}` — Global Location Number (party)
- `/8003/{grai}` — Global Returnable Asset Identifier
- `/8004/{giai}` — Global Individual Asset Identifier
- `/8006/{itip}` — Identification of an Individual Product Piece
- `/8010/{cpid}` — Component/Part Identifier
- `/8013/{gmn}` — Global Model Number
- `/8017/{gsrn}` — Global Service Relation Number (provider)
- `/8018/{gsrn}` — Global Service Relation Number (recipient)

### Content Negotiation

The resolver supports content negotiation via the `Accept` header:

**`Accept: text/html`** (default) — 307 redirect to the product destination URL:

```
HTTP/1.1 307 Temporary Redirect
Location: https://example.com/product-page
Link: <https://closient.com/01/00012345678905?linkType=linkset>; rel="linkset"; type="application/linkset+json"
Vary: Accept, Accept-Language
Cache-Control: public, max-age=300
```

**`Accept: application/json`** — Structured product data:

```json
{
  "@context": "https://gs1.org/voc/",
  "type": "Product",
  "gtin": "00012345678905",
  "name": "Organic Whole Milk",
  "anchor": "https://closient.com/01/00012345678905",
  "brand": {
    "name": "Happy Valley Dairy"
  }
}
```

**`Accept: application/linkset+json`** — GS1 linkset format per RFC 9264:

```json
{
  "linkset": [
    {
      "anchor": "https://closient.com/01/00012345678905",
      "itemDescription": "Organic Whole Milk",
      "canonical": [
        {
          "href": "https://closient.com/01/00012345678905",
          "title": "Canonical URI"
        }
      ],
      "https://gs1.org/voc/pip": [
        {
          "href": "https://closient.com/product/00012345678905/",
          "title": "Organic Whole Milk"
        }
      ],
      "https://gs1.org/voc/defaultLink": [
        {
          "href": "https://example.com/product-page",
          "title": "Organic Whole Milk"
        }
      ]
    }
  ]
}
```

All resolution responses include CORS headers (`Access-Control-Allow-Origin: *`) and ETag support with `If-None-Match` for 304 Not Modified.

## Search

Closient's local search finds products at nearby stores using a conversational session-based model.

### Template View

- `GET /search?q={query}` — Search for products near the user's location

Query parameters:

| Parameter | Type | Description |
|-----------|------|-------------|
| `q` | string | Search query text |
| `gtin` | string | GTIN lookup (auto-redirects to resolver) |
| `lat` | float | Latitude for proximity ranking |
| `lon` | float | Longitude for proximity ranking |
| `radius` | float | Search radius |
| `in_stock` | boolean | Filter to in-stock items only |
| `sort` | string | Sort order |
| `page` | integer | Page number for pagination |

### Search Session API

The search API uses conversational sessions with natural language constraint extraction.

**`POST /search/api/v1/search/session`** — Start a search session:

Request:

```json
{
  "query": "organic milk near me",
  "latitude": 40.7128,
  "longitude": -74.0060
}
```

Response:

```json
{
  "session_id": "a3cg7kpw4x89",
  "base_query": "organic milk",
  "active_constraints": {
    "distance_km": 2.0
  },
  "search_history": ["organic milk near me"],
  "is_expired": false,
  "latitude": 40.7128,
  "longitude": -74.006
}
```

**`POST /search/api/v1/search/session/{session_id}/query`** — Refine or new query within a session:

Request:

```json
{
  "query": "under $5"
}
```

Response:

```json
{
  "session_id": "a3cg7kpw4x89",
  "is_refinement": true,
  "classification_reason": "refinement_language_detected",
  "active_constraints": {
    "distance_km": 2.0,
    "price_max": 5.0
  },
  "new_constraints": {
    "price_max": 5.0
  },
  "base_query": "organic milk",
  "query": "under $5",
  "search_history": ["organic milk near me", "under $5"]
}
```

**`DELETE /search/api/v1/search/session/{session_id}/constraints/{key}`** — Remove a specific constraint.

**`DELETE /search/api/v1/search/session/{session_id}`** — Clear session.

Extractable constraints from natural language:

| Constraint | Example phrases | Values |
|------------|----------------|--------|
| `price_max` | "under $50", "less than 100" | float |
| `price_min` | "over $50", "at least $20" | float |
| `distance_km` | "within 5 km", "nearby", "walking distance" | float (km) |
| `color` | "red shoes", "in blue" | string |
| `availability` | "in stock", "open now" | `"in_stock"` or `"open_now"` |
| `scope` | "online", "local", "in-store" | `"online"` or `"local"` |

Sessions expire after 30 minutes of inactivity. The system classifies follow-up queries as refinements (merge constraints) or new searches (reset constraints) using heuristic analysis.

## GS1 Digital Link Primitives (no API key required)

Closient's GS1 Digital Link engine — the same code that powers the production
resolver — is exposed as a **keyless** public API. No account, no API key, no
signup. These are pure functions over strings: no database, no network, no
product data. Use them as the reference implementation for GS1 Digital Link
parsing, validation, composition, and check digits.

All endpoints are `GET` (so responses cache at the edge) and IP-rate-limited
at 300 requests/minute. A non-conformant input is a `200` carrying the reasons,
not an error; only malformed *requests* return `4xx`.

**`GET /resolver/api/v1/public/gs1/validate?uri=...`** — Grade a URI for GS1
Digital Link conformance. Returns `is_conformant` plus every issue with a
stable `code`, a `severity` (`error` / `warning`), and a `message`.

```
curl "https://www.closient.com/resolver/api/v1/public/gs1/validate?uri=https://id.gs1.org/01/09506000164908/10/LOT1"
```

**`GET /resolver/api/v1/public/gs1/parse?uri=...`** — Decompose a URI into its
primary key, qualifiers, and data attributes, plus a flat `ai_map` of
`{ai_code: value}`.

**`GET /resolver/api/v1/public/gs1/build?primary_ai=01&primary_value=...`** —
Compose a spec-ordered Digital Link URI. Qualifiers and data attributes are
repeated query parameters in `code:value` form:
`&qualifier=10:LOT1&qualifier=21:SER99&attribute=17:261231`. Optional `scheme`
and `host`.

**`GET /resolver/api/v1/public/gs1/compress?primary_ai=01&primary_value=...`** —
Bit-pack Application Identifiers into the compressed base64url path segment
defined by GS1's Digital Link compression scheme — the exact inverse of
`/decompress`. Takes the same `primary_ai`/`primary_value`/`qualifier`/
`attribute` shape as `/build`.

**`GET /resolver/api/v1/public/gs1/decompress?value=...`** — Decode a
GS1-compressed Digital Link path segment back into its Application Identifiers
and the equivalent uncompressed path.

**`GET /resolver/api/v1/public/gs1/analyze?key=...`** — Verify the GS1 mod-10
check digit on any numeric GS1 key (GTIN-8/12/13/14, GLN, SSCC) and, for
GTIN-shaped keys, identify the GS1 prefix's issuing organization. Returns
`expected_check_digit` even when the supplied digit is wrong.

Anything about *actual products* — catalog data, availability, ownership —
requires the authenticated API. Format and spec correctness is free.

## Brands API

Brand management endpoints.

**`GET /brands/api/v1/brands`** — List brands:

Query parameters: `name`, `organization_id`, `ordering` (`name`, `created`, `-name`, `-created`), `limit` (default 25, max 250), `offset`.

Response:

```json
{
  "items": [
    {
      "id": 1,
      "name": "Happy Valley Dairy",
      "slug": "happy-valley-dairy",
      "website": "https://happyvalley.example.com",
      "description": "Family-owned organic dairy farm",
      "logo_url": "https://closient.com/media/brands/hvd-logo.png",
      "has_social_links": true,
      "created": "2025-01-15T10:30:00Z"
    }
  ],
  "count": 42
}
```

**`GET /brands/api/v1/brands/{slug}`** — Brand detail (includes social links and organization_id).

## Products API

Public read endpoints for browsing products and product content.

**`GET /products/api/v1/browse/products`** — List products:

Query parameters: `brand_slug`, `active`, `ordering` (`name`, `created`, `active`), `limit`, `offset`.

**`GET /products/api/v1/products/{gtin}/content`** — Aggregated product content:

```json
{
  "images": [
    {
      "id": 1,
      "slug": "front-view",
      "title": "Front of Package",
      "is_primary": true,
      "image_url": "https://closient.com/media/items/milk-front.jpg",
      "thumbnail_url": "https://closient.com/media/items/milk-front-thumb.jpg",
      "width": 800,
      "height": 1200
    }
  ],
  "ingredients": [
    {
      "id": 1,
      "name": "Organic Whole Milk",
      "is_major_allergen": true,
      "may_contain": false,
      "priority": 1,
      "percentage": null,
      "origin": "USA",
      "notes": ""
    }
  ],
  "nutrition_facts": [
    {
      "id": 1,
      "name": "Calories",
      "value": "150",
      "daily_percent": null
    },
    {
      "id": 2,
      "name": "Total Fat",
      "value": "8g",
      "daily_percent": 10
    }
  ],
  "certifications": [
    {
      "id": 1,
      "label": "USDA Organic",
      "code": "USDA_ORGANIC",
      "description": "Certified organic by USDA",
      "url": "https://www.usda.gov/organic",
      "logo_url": "https://closient.com/media/certs/usda-organic.png",
      "is_active": true
    }
  ],
  "recalls": [],
  "circularity": null,
  "ftl_data": null
}
```

**`GET /products/api/v1/products/{gtin}/images`** — Product images.

**`GET /compliance/api/v1/products/{gtin}/recalls`** — Product recalls.

## Product Lookup

**`GET /products/api/v1/products/{gtin}`** — Look up a GTIN (accepts 8, 12, 13, or 14 digit formats):

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "gtin": "00012345678905",
  "product_name": "Organic Whole Milk",
  "brand": "Happy Valley Dairy",
  "manufacturer": "Happy Valley Foods Inc.",
  "description": "Grade A organic whole milk, 1 gallon",
  "image_url": "https://closient.com/media/items/milk.jpg",
  "category_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "country_of_origin": "US",
  "net_content": "3.785 L",
  "is_claimed": true,
  "data_source": "brand_portal",
  "confidence_score": 0.98,
  "field_confidence": {
    "product_name": 1.0,
    "brand": 1.0,
    "description": 0.95
  }
}
```

**`POST /products/api/v1/products/{gtin}/claim`** — Claim a GTIN for your business (requires OWNER or MANAGER role).

## EPCIS 2.0

GS1 EPCIS 2.0 event capture and query for supply chain visibility. All endpoints at `/epcis/api/2.0/`.

**`POST /epcis/api/2.0/capture`** — Capture EPCIS events:

Request:

```json
{
  "epcisBody": {
    "eventList": [
      {
        "type": "ObjectEvent",
        "action": "OBSERVE",
        "eventTime": "2025-03-15T14:30:00.000Z",
        "eventTimeZoneOffset": "+00:00",
        "bizStep": "urn:epcglobal:cbv:bizstep:inspecting",
        "disposition": "urn:epcglobal:cbv:disp:in_progress",
        "readPoint": {"id": "urn:epc:id:sgln:0614141.00001.0"},
        "bizLocation": {"id": "urn:epc:id:sgln:0614141.00001.0"},
        "epcList": ["urn:epc:id:sgtin:0614141.012345.1"]
      }
    ]
  }
}
```

Response (201):

```json
{
  "captureID": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "createdEvents": 1
}
```

**`GET /epcis/api/2.0/events`** — Query EPCIS events:

Query parameters:

| Parameter | Type | Description |
|-----------|------|-------------|
| `eventType` | string | Filter by event type (e.g., `ObjectEvent`) |
| `GE_eventTime` | datetime | Events at or after this time (ISO 8601) |
| `LT_eventTime` | datetime | Events before this time (ISO 8601) |
| `EQ_bizStep` | string | Exact business step URI |
| `EQ_disposition` | string | Exact disposition URI |
| `EQ_readPoint` | string | Exact read point URI |
| `EQ_bizLocation` | string | Exact business location URI |
| `MATCH_epc` | string | Single EPC filter |
| `MATCH_anyEPC` | string | Comma-separated EPCs (matches any) |
| `EQ_action` | string | Action: `ADD`, `OBSERVE`, or `DELETE` |
| `perPage` | integer | Results per page (1-100, default 30) |
| `nextPageToken` | string | Cursor for pagination |

Response (JSON-LD EPCISQueryDocument):

```json
{
  "@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
  "type": "EPCISQueryDocument",
  "epcisBody": {
    "queryResults": {
      "eventList": [
        {
          "eventID": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
          "type": "ObjectEvent",
          "action": "OBSERVE",
          "eventTime": "2025-03-15T14:30:00.000Z",
          "bizStep": "urn:epcglobal:cbv:bizstep:inspecting",
          "disposition": "urn:epcglobal:cbv:disp:in_progress",
          "readPoint": {"id": "urn:epc:id:sgln:0614141.00001.0"},
          "bizLocation": {"id": "urn:epc:id:sgln:0614141.00001.0"},
          "epcList": ["urn:epc:id:sgtin:0614141.012345.1"]
        }
      ]
    }
  }
}
```

Response includes `GS1-EPCIS-Version: 2.0.0` and `GS1-CBV-Version: 2.0.0` headers. Pagination follows the GS1 REST binding: while more results remain, a `Link` header with `rel="next"` carries the absolute next-page URL (plus `GS1-Next-Page-Token-Expires`); no `Link` means the last page. The bare `GS1-Next-Page-Token` header is deprecated.

**`GET /epcis/api/2.0/events/{event_id}`** — Get a single EPCIS event by ID.

**`GET /epcis/api/2.0/eventTypes`** — List supported event types:

```json
{
  "eventTypes": [
    "ObjectEvent",
    "AggregationEvent",
    "TransformationEvent",
    "TransactionEvent",
    "SensorEvent"
  ]
}
```

## Features

- [Digital Link Resolver](/learn/gs1-digital-link/): GS1 Digital Link URI parsing, content negotiation, and policy-driven routing
- [Barcode Generation](/learn/2d-barcodes/): QR Code generation (PNG and SVG)
- [Traceability & FSMA 204](/learn/fsma-204/): Lot/batch tracking, serial numbers, and FDA compliance
- [Digital Product Passport](/learn/digital-product-passport/): EU DPP support
- [Sunrise 2027](/learn/sunrise-2027/): GS1 2027 migration guidance

## Blog

Thought leadership on the GS1 Sunrise 2027 transition, product traceability, compliance, and how GS1 Digital Link resolution works in practice. Published at [blog.closient.com](https://blog.closient.com); the blog has its own AI-discovery index at [blog.closient.com/llms.txt](https://blog.closient.com/llms.txt) that stays current as posts publish.

Canonical posts:

- [The Barcode is Evolving: What It Means for Your Brand](https://blog.closient.com/barcode-is-evolving-what-it-means-for-your-brand/): Why GS1 is moving the industry from UPC to 2D barcodes by 2027, and how to get ready.
- [Tesco, Walmart, and 60+ Retailers Are Already Moving to QR Codes](https://blog.closient.com/retailers-already-moving-to-qr-codes/): The Sunrise 2027 commitments already in motion at point of sale.
- [What Actually Happens When Someone Scans Your QR Code?](https://blog.closient.com/what-happens-when-someone-scans-your-qr-code/): The resolver infrastructure behind a GS1 Digital Link scan.
- [Three Regulations, One QR Code](https://blog.closient.com/three-regulations-one-qr-code/): How FSMA 204, the EU Digital Product Passport, and DSCSA converge on one data carrier.
- [The Recall That Found Every Affected Customer](https://blog.closient.com/the-recall-that-found-every-affected-customer/): Lot-level QR codes and a resolver make targeted recalls possible.
- [Why We Built Closient](https://blog.closient.com/why-we-built-closient/): The infrastructure gap behind GS1 Digital Link, and why we filled it.

## API Documentation

Interactive API documentation is served by Mintlify at [docs.closient.com](https://docs.closient.com), fed from each app's OpenAPI 3.1 spec at `/{app}/api/v1/openapi.json`:

- [Account API](https://docs.closient.com): Authentication, API keys, organizations
- [Products API](https://docs.closient.com): GTIN lookup, claim, and product browsing
- [Brands API](https://docs.closient.com): Brand management
- [Certifications API](https://docs.closient.com): Product certifications and claims
- [Compliance API](https://docs.closient.com): Product recalls and safety data
- [Sustainability API](https://docs.closient.com): Product sustainability data
- [Resolver API](https://docs.closient.com): Resolution rules management, plus the keyless GS1 Digital Link primitives
- [Search API](https://docs.closient.com): Session-based search constraint refinement
- [EPCIS API](https://docs.closient.com): EPCIS 2.0 event capture and query

## Authentication

API endpoints require authentication via the `X-API-Key` header, except the
keyless GS1 Digital Link primitives under `/resolver/api/v1/public/gs1/`
documented above, which take no credentials at all:

```
X-API-Key: csb_yourtoken_checksum
```

API keys follow the format `csb_<token>_<crc32>` where:
- `csb` is the key prefix (Closient Business)
- `<token>` is a 32-character random alphanumeric string
- `<crc32>` is an 8-character hex CRC32 checksum of the token

Generate API keys through the dashboard or the `/account/api/v1/api-keys` endpoint.

**`GET /account/api/v1/whoami`** — Introspect your authenticated identity:

```json
{
  "user_id": 42,
  "email": "dev@example.com",
  "organizations": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Happy Valley Foods",
      "slug": "happy-valley-foods",
      "role": "OWNER"
    }
  ],
  "api_key": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "description": "Production key",
    "created": "2025-01-15T10:30:00Z"
  }
}
```

## Error Format

All API errors use a standard envelope:

```json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "No product found for GTIN 00012345678905.",
    "status": 404,
    "details": null
  }
}
```

Error codes: `BAD_REQUEST`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `CONFLICT`, `VALIDATION_ERROR`, `UNPROCESSABLE_ENTITY`, `RATE_LIMITED`, `INTERNAL_ERROR`.

The `details` field contains structured context when available (e.g., field-level validation errors, retry timing).

## Pagination

All list endpoints return paginated results:

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

Query parameters: `?page=1&page_size=25` (max page_size: 100).

Catalog API uses offset pagination: `?limit=25&offset=0` (max limit: 250).

EPCIS API uses cursor pagination: `?perPage=30` (max perPage: 100), then follow the `Link: <url>; rel="next"` response header until it is absent.

## Rate Limiting

Authenticated API responses include rate limit headers:

- `X-RateLimit-Limit` — maximum requests allowed in the current window
- `X-RateLimit-Remaining` — remaining requests in the current window
- `X-RateLimit-Reset` — Unix timestamp when the window resets

Default limits: 300 requests/minute and 10,000 requests/day per API key. Search session endpoints are throttled at 30 requests/minute per IP.

When rate limited, the API returns a 429 response:

```json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Please try again later.",
    "status": 429,
    "details": {"retry_after_seconds": 31}
  }
}
```

## Standards

- [GS1 Resolver Conformance](/.well-known/gs1resolver): GS1 resolver conformance file
- [Linkset](/.well-known/linkset): IETF RFC 9264 linkset describing available link relations
- [OpenAI GPT Action manifest](/.well-known/ai-plugin.json): GPT Actions / ChatGPT Plugin schema for resolve and search.
- [MCP server descriptor](/.well-known/mcp.json): Model Context Protocol endpoint for Claude, Cursor, and other AI agents. Tools: search_local_products, lookup_product_by_gtin, check_product_availability.
- [A2A Agent Card](/.well-known/agent.json): Google Agent2Agent protocol card advertising skills, input/output modes, and capability metadata for agent-to-agent discovery.
- [Full content index](/llms-full.txt): Extended single-file content index for single-pass LLM ingestion
