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

# Brand API

> 把公司網域或工作 email 轉成結構化的品牌資料。

Brand API 把公司網域或工作 email 轉成結構化的品牌資料：名稱、描述、logo、顏色、社群帳號和主要連結。回傳的每個欄位都附有自己的來源，你的產品可以顯示每個值是從哪裡來的。

把網域或 email 送到 `POST /v1/brand/retrieve`。Hermai 有近期的資料時會回傳快取，沒有時會啟動新的擷取。

## 取得品牌資料

`domain` 和 `email` 只能擇一送出。

```bash theme={null}
export HERMAI_API_KEY="hm_sk_..."

curl -sS -X POST "https://api.hermai.ai/v1/brand/retrieve" \
  -H "Authorization: Bearer ${HERMAI_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"domain":"stripe.com"}'
```

送 `email` 時，Hermai 只保留網域，絕不儲存或轉送 email 的信箱名稱部分。

### 請求內容

| 欄位 | 型別 | 必填 | 說明 |
| - | - | - | - |
| `domain` | string | 擇一 | 公司網域。用這個欄位或 `email`，不能同時用。 |
| `email` | string | 擇一 | 工作 email。用這個欄位或 `domain`，不能同時用。個人信箱服務的網域（例如 `gmail.com`）會被拒絕。 |
| `max_age_s` | integer | 否 | 可接受的最大快取年齡，單位秒。低於方案下限的值會被 Hermai 提高到下限：免費方案 2,592,000 秒（30 天），付費方案 604,800 秒（7 天）。`refresh.clamped` 會回報 Hermai 是否提高了你的值。 |
| `wait_ms` | integer | 否 | 冷擷取時等待多久才回傳 pending 結果。預設 1500，最大 15000。設為 `0` 會立即回傳 pending 結果。 |
| `include_synthesized` | boolean | 否 | 保留給未來選擇加入生成欄位變體之用，目前沒有作用。 |
| `force_refresh` | boolean | 否 | 目前不提供。任何把它設為 `true` 的請求都會以 `BRAND_FORCE_REFRESH_FORBIDDEN` 失敗。 |

## 回應

```json theme={null}
{
  "status": "ok",
  "requested": {
    "input_type": "domain",
    "domain": "stripe.com"
  },
  "resolved": {
    "canonical_domain": "stripe.com",
    "ambiguity": null,
    "redirect_terminal": "https://stripe.com"
  },
  "brand": {
    "name": {
      "value": "Stripe",
      "source": { "url": "https://stripe.com/", "signal": "json_ld" },
      "observed_at": "2026-08-18T16:41:47Z",
      "origin": "observed"
    },
    "description": {
      "value": "Stripe powers online and in-person payment processing and financial solutions for businesses of all sizes.",
      "source": { "url": "https://stripe.com/", "signal": "json_ld" },
      "observed_at": "2026-08-18T16:41:47Z",
      "origin": "observed"
    },
    "logos": [
      {
        "url": "https://api.hermai.ai/v1/brand/logo/61a219a0...",
        "kind": "wordmark",
        "theme": "light",
        "format": "svg",
        "width": 60,
        "height": 25,
        "source": { "url": "https://stripe.com/", "signal": "header_dom" },
        "observed_at": "2026-08-18T16:41:47Z",
        "origin": "observed"
      }
    ],
    "colors": [
      {
        "hex": "#031323",
        "role": "accent",
        "source": { "url": "https://stripe.com/", "signal": "header_dom" },
        "observed_at": "2026-08-18T16:41:47Z",
        "origin": "inferred"
      }
    ],
    "socials": [
      { "type": "twitter", "url": "https://twitter.com/stripe", "source": { "url": "https://stripe.com/", "signal": "json_ld" }, "observed_at": "2026-08-18T16:41:47Z", "origin": "observed" }
    ],
    "links": {
      "careers": { "value": "https://stripe.com/careers", "source": { "url": "https://stripe.com/", "signal": "header_dom" }, "observed_at": "2026-08-18T16:41:47Z", "origin": "observed" },
      "pricing": { "value": "https://stripe.com/pricing", "source": { "url": "https://stripe.com/", "signal": "header_dom" }, "observed_at": "2026-08-18T16:41:47Z", "origin": "observed" },
      "privacy": null,
      "terms": null,
      "contact": null,
      "blog": null
    }
  },
  "application_theme": {
    "version": "v1",
    "mode": "observed",
    "colors": { "action": "#031323", "on_action": "#FFFFFF", "text_accent": "#031323", "tint": "#E6E7E9", "on_tint": "#111827", "border": "#959CA3", "focus": "#031323", "data_primary": "#031323" },
    "identity": {
      "standard": { "asset": { "url": "https://api.hermai.ai/v1/brand/logo/61a219a0...", "kind": "wordmark" }, "show_company_name": false, "fallback": "none" },
      "compact": { "asset": null, "show_company_name": true, "fallback": "monogram" },
      "on_dark": { "asset": { "url": "https://api.hermai.ai/v1/brand/logo/cb86ad33...", "kind": "icon" }, "show_company_name": true, "fallback": "asset_with_company_name" }
    },
    "fallback": null
  },
  "assembled_at": "2026-08-18T16:41:47Z",
  "profile_generation": 1,
  "theme_readiness": "observed",
  "fallback_fields": ["accent"],
  "enrichment_status": "",
  "refresh": { "state": "stale", "clamped": false },
  "pending": null,
  "usage": { "credits_consumed": 1, "credits_remaining": 999 }
}
```

這個範例是對 `stripe.com` 的實際結果，為了篇幅有刪節；實際呼叫會回傳比這裡更多的 logo、顏色、社群帳號和連結。

### 頂層欄位

| 欄位 | 說明 |
| - | - |
| `status` | 這次查詢的結果。見下方「狀態值」。 |
| `requested` | 你送出的 `input_type`（`domain` 或 `email`）和值。 |
| `resolved` | Hermai 比對到的正規網域，加上 `redirect_terminal`（Hermai 跟隨轉址後最終落在的 URL）和 `ambiguity`。正常比對時 `ambiguity` 為 `null`；`parked` 表示該網域是停放或待售頁面，`multi_brand` 表示該網域承載一個以上的品牌，`unresolved` 表示 Hermai 無法確定是哪一家公司。 |
| `brand` | 品牌欄位：`name`、`description`、`logos`、`colors`、`fonts`、`socials`、`links`。見下方「欄位來源」。 |
| `application_theme` | 可直接用來在你的產品介面套用這家公司品牌的主題 token。Hermai 尚未推導出主題時不會出現。見下方「套用主題」。 |
| `assembled_at` | Hermai 組合這份回應的時間。 |
| `refresh` | `state` 為 `fresh`（在你的快取視窗內）、`stale`（超過視窗，先回傳最後一份已知資料，背景可能正在更新）或 `refreshing`（背景更新進行中）。Hermai 把你的 `max_age_s` 提高到方案下限時，`clamped` 為 `true`。 |
| `pending` | 只在 `status` 為 `pending` 時出現。帶有 `poll_after_ms` 和用來輪詢冷查詢的 `token`。見下方「冷查詢與輪詢」。 |
| `usage` | 這次呼叫的 `credits_consumed` 和 `credits_remaining`。見下方「計費」。 |
| `profile_generation` | 每當 Hermai 觀察到這家公司的識別有重大變動就會加一。用它判斷你那邊快取的主題或 logo 是否需要更新。 |
| `theme_readiness` | Hermai 為 `application_theme` 找到真實的 logo 和顏色證據時為 `observed`；你的產品應改用自己的主題時為 `fallback`。 |
| `fallback_fields` | 列出哪些主題輸入退回了備援，例如 `["accent"]` 或 `["logo"]`。`theme_readiness` 為 `observed` 時為空。 |
| `enrichment_status` | 回報選擇性的第二階段樣式處理。它絕不會延遲上面的回應。 |

## 欄位來源

`brand` 裡的每個欄位都帶有 Hermai 找到它的位置：

| 屬性 | 說明 |
| - | - |
| `source.url` | Hermai 讀到這個值的頁面。 |
| `source.signal` | 承載這個值的訊號，例如 `json_ld`、`header_dom`、`apple_touch_icon` 或 `manifest`。 |
| `observed_at` | Hermai 最後一次確認這個值的時間。 |
| `origin` | Hermai 得到這個值的方式。見下表。 |

`origin` 是以下之一：

| 值 | 意義 |
| - | - |
| `observed` | Hermai 直接從頁面或結構化訊號（例如 JSON-LD 或 manifest 檔）讀到這個值。 |
| `inferred` | Hermai 從其他觀察到的證據推導出這個值，例如從 logo 的主色計算出的強調色。 |
| `synthesized` | Hermai 生成了這個值，而不是從網站讀取或推導。 |
| `corrected` | Hermai 用更好的值覆蓋了品質不佳的觀察值。 |

任何欄位都沒有信心分數。請用 `origin` 和 `source` 判斷一個值可信到什麼程度。

## 描述

`description` 是公司自己撰寫的簡介，不是 Hermai 生成的摘要。Hermai 依下列優先順序檢查來源，採用第一個通過的：

1. JSON-LD 的 `Organization` 描述，且只在 JSON-LD 確認該組織屬於所請求的網域時採用。未經確認的 JSON-LD 組織描述會被丟棄，不作為備援。
2. `og:description` meta 標籤。
3. 一般的 `<meta name="description">` 標籤。

Hermai 把描述限制在 500 字元內，並在該限制內最後一個完整句子的結尾截斷，絕不補上省略號。

Hermai 會拒絕過短的文字、插頁或機器人驗證頁面、cookie 與同意聲明，以及堆砌關鍵字的文字。都不通過時，`description` 不會出現。

來自 `stripe.com` 的實際範例：

```json theme={null}
{
  "value": "Stripe powers online and in-person payment processing and financial solutions for businesses of all sizes.",
  "source": { "url": "https://stripe.com/", "signal": "json_ld" },
  "origin": "observed"
}
```

## 狀態值

| 狀態 | 意義 |
| - | - |
| `ok` | Hermai 找到完整可用的資料。 |
| `partial` | Hermai 找到部分可用的欄位。 |
| `pending` | 擷取仍在進行。見下方「冷查詢與輪詢」。 |
| `personal_email` | 這個 email 屬於常見的個人信箱服務。 |
| `disposable_email` | 這個 email 屬於拋棄式信箱服務。 |
| `not_found` | Hermai 無法解析出可用的公司網域。 |
| `fetch_failed` | Hermai 解析出網域但無法完成擷取。封鎖自動存取的網站會回傳 `fetch_failed`。 |

## 冷查詢與輪詢

Hermai 已有新鮮資料的網域會立即回傳，`status` 為 `ok`、`partial` 或其他終態值之一。

Hermai 近期沒有擷取過的網域會啟動新的擷取。若在 `wait_ms` 內沒有完成，`POST /v1/brand/retrieve` 會回傳 HTTP `202`，`status` 為 `pending`：

```json theme={null}
{
  "status": "pending",
  "pending": { "poll_after_ms": 1000, "token": "..." }
}
```

等待 `pending.poll_after_ms` 之後，帶著 token 呼叫 `POST /v1/brand/poll`：

```bash theme={null}
curl -sS -X POST "https://api.hermai.ai/v1/brand/poll" \
  -H "Authorization: Bearer ${HERMAI_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"token":"..."}'
```

回應持續回傳 `202` 和 `status: pending` 時，用同一個 token 再輪詢。token 的有效期是 5 分鐘。擷取完成後，poll 會回傳 HTTP `200` 和完成的資料。

輪詢本身免費。第一次送達終態結果時，不論來自 `retrieve` 或 `poll`，都依下方的一般規則計費。

## 套用主題

`application_theme` 提供現成的 token，讓你用這家公司的品牌來設計自己的產品，不必自己排序 logo 或挑選強調色。

| 欄位 | 說明 |
| - | - |
| `colors` | 八個顏色 token：`action`、`on_action`、`text_accent`、`tint`、`on_tint`、`border`、`focus`、`data_primary`。 |
| `identity.standard` | 淺色背景用的主要 logo 位置。 |
| `identity.compact` | 適合小空間的 logo 位置，例如 favicon 大小的區域。 |
| `identity.on_dark` | 為深色背景挑選的 logo 位置。 |
| `mode` | 由真實證據建立時為 `observed`，否則為 `fallback`。 |

每個 identity 位置都帶有 `asset`（一個 logo，或 `null`）、`show_company_name`（是否在素材旁一併顯示公司名稱）和 `fallback`（`asset` 為 `null` 時要顯示什麼，例如 `monogram` 或 `asset_with_company_name`）。

## 計費

成功的資料計 1 個一般 Hermai credit，與其他所有 Hermai 端點共用同一個 credit 池。`status` 為 `ok` 或 `partial`，且資料至少有名稱、logo 或顏色其中之一時，Hermai 才計費。只有描述、社群帳號或連結而沒有名稱、logo 或顏色的 `partial` 結果不計費。

Pending 結果和失敗的查詢一律不計費。

```json theme={null}
{
  "usage": { "credits_consumed": 1, "credits_remaining": 999 }
}
```

## 速率限制

Brand 端點疊加三層限制。由近期快取資料回應的暖請求只計入前兩層；啟動新擷取的冷請求三層都計入。

與其他所有 Hermai 端點共用的每把 key 標準速率限制：

| 方案 | 每分鐘 |
| - | - |
| Free | 20 |
| Starter | 60 |
| Pro | 100 |
| Enterprise | 120 |

Brand 專用的 workspace 限制，由 workspace 內所有 key 共用：

| 方案 | 每分鐘 |
| - | - |
| Free | 10 |
| Starter | 60 |
| Pro | 200 |
| Enterprise | 200 |

僅套用於啟動新擷取的冷擷取限制：

| 方案 | 每分鐘 |
| - | - |
| Free | 5 |
| Starter | 20 |
| Pro | 50 |
| Enterprise | 50 |

三層中任何一層超過都會回傳 HTTP `429`。

## 匿名 brand demo

`POST /v1/brand/demo` 不需要 API key、不消耗 credits 就能執行品牌查詢。它只接受網域，回傳較小的公開投影：`status`、`domain`，以及 `brand.name`、`brand.description`、`brand.logos`、`brand.colors`。它絕不回傳 `socials`、`links` 或 `usage`。

```bash theme={null}
curl -sS -X POST "https://api.hermai.ai/v1/brand/demo" \
  -H "Content-Type: application/json" \
  -d '{"domain":"stripe.com"}'
```

```json theme={null}
{
  "status": "ok",
  "domain": "stripe.com",
  "brand": {
    "name": { "value": "Stripe", "origin": "observed" },
    "description": { "value": "Stripe powers online and in-person payment processing and financial solutions for businesses of all sizes.", "origin": "observed" },
    "logos": [ { "url": "https://api.hermai.ai/v1/brand/logo/61a219a0...", "kind": "wordmark" } ],
    "colors": [ { "hex": "#031323", "role": "accent" } ]
  }
}
```

冷的 demo 查詢會回傳 HTTP `202`、`status: pending` 和一個 `poll_after_ms` 提示。等那段時間後再送一次同樣的網域。demo 端點沒有 poll token。

demo 端點有自己的限制，與上面的驗證限制分開：

| 限制 | 值 | 錯誤碼 |
| - | - | - |
| 每個 IP 每小時的總請求數 | 10 | `DEMO_RATE_LIMITED` |
| 每個 IP 每小時的新網域查詢數 | 3 | `DEMO_COLD_RATE_LIMITED` |
| 所有呼叫方每天的新網域查詢數 | 共用的每日額度 | `DEMO_BUDGET_EXHAUSTED` |

每一項都會回傳 HTTP `429` 和 `Retry-After` header。

## 錯誤

錯誤使用標準的 API 封包：

```json theme={null}
{
  "success": false,
  "error": {
    "code": "BRAND_RATE_LIMITED",
    "message": "brand rate limit exceeded",
    "retryable": false,
    "retry_after": 30
  }
}
```

`retry_after` 只在速率限制錯誤時出現，單位秒。其他錯誤都沒有這個欄位。

| 代碼 | HTTP | 意義 |
| - | - | - |
| `UNAUTHORIZED` | 401 | API key 缺少、無效或已過期。 |
| `RATE_LIMITED` | 429 | 超過每把 key 的標準速率限制。 |
| `BRAND_RATE_LIMITED` | 429 | 超過 brand 專用的 workspace 限制。 |
| `BRAND_INVALID_REQUEST` | 400 | 請求內容格式錯誤，或同時送了 `domain` 和 `email`，或兩者都沒送。 |
| `BRAND_FORCE_REFRESH_FORBIDDEN` | 403 | 請求把 `force_refresh` 設為 `true`。目前不提供。 |
| `DOMAIN_IS_MAILBOX_PROVIDER` | 422 | 這個網域屬於個人信箱服務（例如 `gmail.com`），不是公司。請改用公司網域。 |
| `INSUFFICIENT_CREDITS` | 402 | workspace 的 credits 不足。 |
| `BRAND_DISABLED` | 503 | 品牌查詢暫時無法使用。 |
| `BRAND_UNAVAILABLE` | 503 | poll token 背後的結果暫時無法取得。 |
| `CREDIT_UNAVAILABLE` | 503 | 計費暫時無法使用。請重試。 |
| `BRAND_INVALID_POLL_TOKEN` | 400 | poll token 缺少、格式錯誤或已過期。請重新查詢。 |
| `BRAND_NOT_READY` | 404 | 請求的 logo 素材不存在。 |
| `DEMO_RATE_LIMITED`、`DEMO_COLD_RATE_LIMITED`、`DEMO_BUDGET_EXHAUSTED` | 429 | 超過 demo 端點的限制。見上方「匿名 brand demo」。 |

`5xx` 回應（例如 `BRAND_RESPONSE_INVALID`）表示 Hermai 這邊失敗了。請重試。

## 驗證

使用與其他所有 Hermai API 路由相同的 Bearer token。見 [API keys](/zh-Hant/concepts/api-keys)。


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