---
title: "Read the project's saved brand: business facts, overviews, colors, fonts, marks, personas, tagged context files, brand imagery, and imported Figma frames. A project without a brand returns the empty brand at version 0."
method: GET
path: "/brand"
tags: ["Brand"]
---

# Read the project's saved brand: business facts, overviews, colors, fonts, marks, personas, tagged context files, brand imagery, and imported Figma frames. A project without a brand returns the empty brand at version 0.

`GET /brand`

## Request

- Base URL: `https://api.replo.app/v1`
- URL: `https://api.replo.app/v1/brand`
- Auth: HTTP bearer

**Beta** — this endpoint may change before general availability.

## Query parameters

- `projectId` string, uuid, required: The project whose saved brand to read.

## Headers

- `Replo-Api-Version` '2026-10-29', required

## Response `200`

Read the project's saved brand: business facts, overviews, colors, fonts, marks, personas, tagged context files, brand imagery, and imported Figma frames. A project without a brand returns the empty brand at version 0.

- object
  - `version` integer, required: The brand's version; bumped on every write. Writes can't be made conditional on it, so when two callers write, the last one wins. 0 when the project has no brand yet (every field below is then empty).
  - `business` object, required: Business facts.
    - `name` string, nullable, required: Brand name as the business writes it
    - `about` string, nullable, required: One-line description
    - `audience` string, nullable, required: Who buys, in one line
    - `pricePoint` 'budget' | 'mid-market' | 'premium' | 'luxury' | 'null', nullable, required: Price positioning
    - `businessModel` string, nullable, required: How the business makes money, in a sentence (dtc, retail, subscription, wholesale, …); null when unknown
    - `foundedYear` integer, nullable, required: Founding year, null when unknown
    - `location` string, nullable, required: "City, Country", null when unknown
    - `voice` string, nullable, required: How the brand sounds, in a sentence or a few adjectives (warm, direct); null when unknown
    - `sourceUrl` string, nullable, required: Site the facts were extracted from
  - `overviews` object, required: The team's business overview (what the business is, in depth) and design overview (how pages should look), as markdown; null until written. On any disagreement the facts above win. Edit with update_brand's setOverview op.
    - `business` string, nullable, required
    - `design` string, nullable, required
  - `category` object, nullable, required: ReploOpencodeHarnessBrandingCategory
    - `id` string, uuid, required
    - `path` string, required: Sightglass path, e.g. apparel/activewear
    - `name` string, required
    - `source` 'agent' | 'user' | 'import' | 'null', nullable, required: ProjectContextCategorySource
    - `benchmarks` object, nullable, required: Sightglass rollups for the node; null when not computed
      - `companiesInCategory` integer, required
      - `medianActiveAds` number, nullable, required
      - `rankByActiveAds` integer, nullable, required
  - `marks` object, required: Logo, logomark and favicon.
    - `logo` object, nullable, required: Primary logo asset
      - `assetId` string, uuid, nullable, required: Null for a legacy URL-only mark
      - `url` string, required
      - `alt` string, nullable, required
    - `favicon` object, nullable, required: Favicon asset
      - `assetId` string, uuid, nullable, required: Null for a legacy URL-only mark
      - `url` string, required
    - `logomark` object, nullable, required: Logomark asset: the icon-only symbol without text
      - `assetId` string, uuid, nullable, required: Null for a legacy URL-only mark
      - `url` string, required: Served URL of the logomark
  - `colors` object[], required: Palette with roles; hex is authoritative.
    - `key` string, required: Stable slug key, e.g. action or gray-100
    - `name` string, required: Editable label
    - `hex` string, required: #RRGGBB
    - `category` 'brand' | 'neutral', required: brand or neutral
    - `roles` string[], required: Semantic roles this color fills (primary, background, …); one color per role per context
    - `usage` string, nullable, required: Human and agent guidance
    - `position` integer, required: Display order
  - `fonts` object[], required: Typefaces with faces and served URLs.
    - `key` string, required: Stable slug key, e.g. inter
    - `family` string, required: Font family name
    - `roles` string[], required: heading, body, mono, …; one font per role per context
    - `delivery` 'google-fonts' | 'cdn' | 'uploaded' | 'system' | 'unknown', required: How the font is served
    - `license` string, nullable, required: License name
    - `usage` string, nullable, required: Guidance
    - `position` integer, required: Display order
    - `faces` object[], required: Faces with their served URLs
      - `weight` integer, required: 1 to 1000
      - `style` 'normal' | 'italic', required: normal or italic
      - `assetId` string, uuid, nullable, required: Approved font asset holding the file; null for Google or system fonts
      - `sourceUrl` string, nullable, required: Where the face file came from
      - `url` string, nullable, required: Served URL of the face file when it is an asset
  - `personas` object[], required: Customer personas: nickname (a segment label, never a person's name), headline, age range (ageGte inclusive, ageLt exclusive), awareness stage, share of buyers, a verbatim quote with its source, descriptionMarkdown (goals, pains, objections, buying triggers), and evidence (per field, the generated value and where it came from). Empty until generated. Edit through update_brand's setPersona op.
    - `key` string, required: Stable slug key, e.g. weeknight-cook
    - `nickname` string, required: Segment label, two to four words, e.g. The weeknight cook; never a person's name
    - `headline` string, required: Situation plus problem in the buyer's own words, one line
    - `ageGte` integer, nullable, required: Youngest age in the range; null when unknown
    - `ageLt` integer, nullable, required: Exclusive upper age: 35 to 54 is ageGte 35, ageLt 55; null for open-ended
    - `awareness` 'unaware' | 'problem' | 'solution' | 'product' | 'most' | 'null', nullable, required: Where this buyer starts
    - `sharePercent` integer, nullable, required: Estimated share of buyers; the set need not sum to 100
    - `quote` string, nullable, required: In the customer's words, from the brand's reviews or copy
    - `quoteSource` string, nullable, required: Who said it, as the card attributes it: a first name or 'a verified review'
    - `quoteSourceUrl` string, uri, nullable, required: The page the quote came from
    - `descriptionMarkdown` string, required: Markdown: ## Goals, ## Pains, ## Objections, ## Buying triggers; rendered as a document, never parsed
    - `evidence` object, nullable, required: Per typed field, the value generation produced and one sentence on where it came from; null for a persona a person added by hand.
      - `nickname` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
      - `headline` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
      - `ageGte` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
      - `ageLt` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
      - `awareness` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
      - `sharePercent` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
      - `quote` object
        - `value` union, required
          - string
          - number
        - `reason` string, required
    - `avatarPath` string, required: Absolute sandbox path of the persona's avatar SVG (a brand-coloured creature, never a face), written with the brand; place it in 'who it's for' or segment-picker sections, never as a reviewer photo.
  - `contextFiles` object[], required: Drive files a person or the agent tagged as brand context. Read one by its `fileId` with the file tools or the files API; `path` is where Replo's agent reads it. On any disagreement the facts in this result win; the files add voice and detail.
    - `fileId` string, uuid, required
    - `path` string, nullable, required: Absolute sandbox path, e.g. /workspace/project/BUSINESS.md; null when missing or outside the caller's mounts
    - `kind` 'file' | 'folder' | 'null', nullable, required
    - `tags` string[], required: Brand tags the file carries, in vocabulary order
    - `status` 'ok' | 'missing' | 'no-access', required: ProjectContextFileStatus
  - `imagery` object[], required: Brand Studio imagery: the merchant's own photos, newest first. The first choice for any page image; match a photo to a section by its name and altText.
    - `id` string, required
    - `url` string, required
    - `name` string, required
    - `altText` string, nullable, required
    - `width` number, nullable, required
    - `height` number, nullable, required
  - `figmaDesigns` object[], required: The brand's own Figma designs, imported in Branding or by update_brand with a Figma link: each frame as a PNG plus its text layers. An entry appears as soon as its import starts; read its files once status is completed. `folderId` is the import's Drive folder: list it and its subfolders, and read a frame's PNG or text layers, with the file tools or the files API. The paths are where Replo's agent reads them. Build to the frames' layout, section order, spacing, type sizes and colors, and take copy and products from the brand. Empty when no Figma file is imported.
    - `importId` string, required: The Figma file key: the importId update_brand returned for this file
    - `status` 'starting' | 'running' | 'completed' | 'failed', required: running while the file imports, then completed or failed. A re-import keeps the earlier frames listed until it completes.
    - `error` string, nullable, required: On failed: why, and what to do next. Null otherwise.
    - `fileName` string, nullable, required: Null until the file's first import completes
    - `sourceUrl` string, required
    - `folder` string, required: Absolute path of the import's folder
    - `folderId` string, uuid, required: The Drive id of the import's folder
    - `styles` string, nullable, required: Absolute path of `styles.json`: the colors and type the frames use, most used first
    - `photos` string, nullable, required: Absolute path of `photos.json`: each photo the frames show, by Figma imageRef, to its hosted copy in the project's assets. Use those URLs for the photos; they don't expire
    - `frames` object[], required
      - `page` string, required: The Figma page the frame is on
      - `name` string, required
      - `path` string, required: Absolute path of the frame's PNG
      - `text` string, nullable, required: Absolute path of the frame's text layers: exact copy with font, size, weight and color
      - `nodes` string, nullable, required: Absolute path of Figma's node data for the frame at full depth: the document figma_get_file_nodes returns, layout and auto-layout included
  - `extraction` object, nullable, required: The latest website import. Null when none ran in the last 15 minutes, which doesn't mean the project never imported a site, and a failure's reason is gone by then. To follow an import update_brand started, poll until importId matches and status is completed or failed, instead of starting it again.
    - `importId` string, nullable, required: The import's id, the one update_brand returned; null for an import started from signup or Home.
    - `url` string, nullable, required: The site the import reads
    - `status` 'starting' | 'running' | 'completed' | 'failed', required: starting, then running while it reads the site, then completed or failed. Poll with increasing delays while starting or running; once completed, the brand in this reply is the result.
    - `stage` 'pending' | 'scraping' | 'extracting' | 'uploading' | 'done' | 'failed', required: Where the import is now: pending, scraping, extracting, uploading, then done or failed
    - `error` string, nullable, required: On failed: why, and what to do next. Null otherwise.
    - `lastActivityAt` string, nullable, required: When the import last reported progress (ISO 8601).
  - `object` 'brand', required

## Other responses

- `400`: Invalid request.
- `401`: Missing or invalid Replo Public API token. Send an active key as `Authorization: Bearer replo_sk_...`; if it was revoked, create a new key in Replo Settings.
- `403`: You are not authorized to access this resource. Ask a workspace owner to perform this action or to grant the key's creator access.
- `404`: Not Found. The resource may not exist, this key may lack the required scope, or the key's creator may have lost access. Check the key's scopes in Replo Settings and the creator's project or workspace access; a workspace owner can grant access.
- `409`: The resource is in a conflicting state.
- `413`: File content exceeds the 10 MiB limit.
- `429`: Too many requests. Please retry after the time indicated by the Retry-After header.
- `500`: An internal error occurred.
- `503`: Service temporarily unavailable.

## Changes

- **2026-11-04** `53d194ba2067`: 9 info
  - added the optional property `error/issues` to the response with the `400` status
  - added the optional property `error/issues` to the response with the `401` status
  - added the optional property `error/issues` to the response with the `403` status
  - added the optional property `error/issues` to the response with the `404` status
  - …5 more
- **2026-10-31** `608c19382134`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/replo/apis/replo-public-api/changes/brand/get.md)

---

[API](https://skmtc.dev/replo/apis/replo-public-api.md) - [All operations](https://skmtc.dev/replo/apis/replo-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/replo/apis/replo-public-api/revisions/53d194ba2067?raw)
