Skip to main content
Closient indexes brands from many sources (Open Food Facts, Open Beauty Facts, USDA, manual entry, etc.). A brand with organization=null is unclaimed — crowd-sourced metadata waiting for the legitimate brand owner to claim it and start managing the record. This skill walks an authenticated brand-owner through the claim flow end-to-end.

When to use

  • A brand owner wants to manage their products on Closient.
  • The agent needs to attach an Organization to an existing Brand record (so analytics, product edits, and resolver routing work).
  • A retailer’s onboarding flow turned up an unclaimed brand the retailer also owns.
For pure brand creation (no pre-existing record on Closient), the same endpoint creates the brand already linked to the caller’s organization — see Step 2 below.

Auth

OAuth token (or API key) with brands:write scope. The caller must hold OWNER or MANAGER role on the Organization that will own the claimed brand. A VIEWER cannot claim. Once the brand is claimed, editing its profile (PATCH /brands/{id}), uploading its logo and setting its media intake address also accept the EDITOR role; a read-only key is refused with 403.

Flow

Step 1 — Discover candidate unclaimed brands

Returns paginated brands. Unclaimed brands have organization=null in the source data but are NOT filtered by the API today (see Known gaps below). The agent should:
  1. Issue the search.
  2. Pull the full brand record for each candidate via GET /brands/api/v1/brands/{id} to see organization_id.
  3. Present the user with the matches that are unclaimed.

Step 2 — Create-and-claim (the supported path today)

If no existing unclaimed record matches, this creates the brand already linked to the caller’s organization (which is the destination state of a claim anyway). The endpoint rejects duplicates within the same organization (409).

Step 3 — Enrich the claimed brand

Once the brand exists and is linked, the agent should immediately:
Social links + description materially improve brand-analytics signal and the brand’s surface on the Closient resolver pages.
JPEG, PNG, GIF, WebP or BMP, at most 20 MB and 8000 px on either side, checked against the file’s own bytes rather than its name or declared type. Anything else (an SVG included) is refused with 422 and a machine-readable reason (invalid_content_type, oversized, invalid_dimensions), and the stored logo is left as it was. The logo shows on resolver hosted pages and in search results.

Step 4b — Publish a media intake address (optional)

Consumers leaving feedback on the brand’s products may then send photos and video straight to that address from their own mail client. Closient never receives, stores, scans or relays those messages, so saving an address requires "acknowledged": true (a JSON boolean, not a string); without it the call is refused with 422. Confirm that acknowledgment with the user before sending it, and suggest a monitored shared mailbox rather than a personal one. An empty email clears the address. GET on the same path reads it back with acknowledged_at.
The organization field should reflect the caller’s organization. Once set, organization cannot be cleared (Brand.organization is a one-way claim).

Step 6 — Verify ownership of the brand’s products

Each claimed GTIN carries its own verification status. For every product the user cares about:
This returns claim_verification_status, the evidence already filed with its review state and expiry, promotion_rules (how many of your organization’s approved pieces of each strength are still missing under each rule — any one rule met qualifies), and the domain_verification token and targets. To move toward Verified:
  • POST /products/api/v1/products/{gtin}/verification/evidence with {"evidence_type": "gs1_certificate", "file_base64": "..."} or {"evidence_type": "gepir_lookup", "notes": "<registry record>"}. It is stored pending until a Closient reviewer approves it. Files are at most 1.5 MiB decoded over the API and 150 KiB over MCP.
  • POST .../verification/dns-check after the user publishes the token as a TXT record at domain_verification.dns_record_name.
  • POST .../verification/http-check only when domain_verification.http_enabled is true; otherwise it returns 409.
Over MCP the same calls are get_claim_verification, submit_claim_evidence, check_claim_dns and check_claim_http. Nothing here makes a claim Verified by itself; tell the user their evidence is awaiting review rather than that the claim is verified. All three writes are rate-limited, so don’t retry a DNS check in a loop while the record propagates.

Required inputs

  • organization_id — the caller’s organization (claim destination).
  • name — brand display name.

Optional inputs

  • website, description
  • Social links (instagram, facebook, twitter, linkedin, youtube, tiktok, pinterest, threads, bluesky) — via PATCH.
  • logo — via POST /brands/{id}/logo.
  • media_intake_email — via PUT /brands/{id}/media-intake-email.

Output

  • verification_status — currently always linked once POST returns 201 (no manual review gate today; see Known gaps).
  • brand_id — the short ID of the linked brand.
  • next_steps — recommend the user upload a logo, fill social links, and start adding products to their brand.

Guidance for agents

  • Search first, create second. Always run the discovery query (Step 1) before creating, even if the brand is well-known — the user may have a Closient-side record they don’t know about. Duplicate brands per organization are blocked (409) but cross-org duplicates are not, so this is the only protection against accidentally creating a second crowd-sourced copy.
  • Confirm the organization before posting. The caller may belong to multiple orgs; ask which one owns the brand. The account/whoami endpoint lists the caller’s organizations. Over an API key that is always exactly one — a key belongs to a single organization and acts as its own identity there — so there is nothing to disambiguate.
  • One-way claim. Once organization is set, it cannot be cleared via the API (the model raises on attempts to null it). Surface this to the user before the POST.
  • Don’t loop on duplicate errors. A 409 means the brand already exists for that organization — fetch and patch instead of retrying.

Known gaps (planned)

  • No “claim existing unclaimed brand” endpoint. Today the BrandUpdateIn schema does not accept organization, so the only way to attach an organization to an existing unclaimed record is via the POST (which creates a new linked record). A dedicated POST /brands/{id}/claim is planned so an existing crowd-sourced Brand can be claimed without duplicating it. Until then, the agent should flag candidate unclaimed records to the human owner for reconciliation.
  • No ?unclaimed=true filter. The list endpoint accepts name and organization_id filters but not a “show me only unclaimed” query. Agents must fetch detail records to determine claim state.
  • Linking a brand is not verified; claiming its products is. The brand link above is accepted on the strength of the OAuth scope alone. Ownership is proven per product instead, through the claim verification API in Step 6. Only staff-reviewed evidence (a GS1 certificate or a Verified by GS1 registry record) earns Verified; a DNS or HTTP domain check is recorded for the reviewer but does not verify on its own.
  • No brand-merge. If a duplicate linked brand was accidentally created, there is no API to merge it into the canonical record.
  • onboard-retailer — the parallel flow for retailer Organizations connecting their POS.
  • brand-scan-summary — once claimed, see engagement on your products.
  • brand-retail-footprint — once claimed, see distribution coverage.
  • brand-search-demand — once claimed, see geographic demand.