---
title: "Analyze the company website"
method: POST
path: "/v1/company-profile/analyze"
tags: ["company-profile"]
---

# Analyze the company website

`POST /v1/company-profile/analyze`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/company-profile/analyze`
- Auth: HTTP bearer

Read the given site, extract the company profile (LLM, structured), self-host the brand marks (primary logo + icon), and persist. The response carries how every step of the read finished.

## Headers

- `X-Tenant-Id` string, nullable

## Request body

- AnalyzeWebsiteRequest: Body for ``POST /company-profile/analyze``: the site to read. ``mode="fill"`` (default) only fills fields currently ``missing``; ``mode="replace"`` overwrites every analyzer-produced field, colour, and logo regardless of prior state — except typography, which keeps its own fill-only guard in both modes.
  - `website_url` string, required
  - `mode` 'fill' | 'replace'

## Response `200`

Successful Response

- AnalyzeWebsiteResponse: The analyze result: the saved profile plus how every step of the read finished. The phases ride the response so the screen never has to guess a terminal state from the last thing it happened to poll: whatever the run recorded is what the checklist shows, including a step that started and finished between two polls. ``host`` travels with them for the same reason: on a deployment with no Redis, or on a read that settled before the first poll, it is the only way the screen learns which host was actually reached.
  - `website_url` string, nullable
  - `brand_name` string, nullable
  - `target_audience` string, nullable
  - `what_you_do` string, nullable
  - `differentiation` string, nullable
  - `tone_of_voice` string, nullable
  - `voice_warmth` string, nullable
  - `voice_formality` string, nullable
  - `voice_length` string, nullable
  - `voice_technical_depth` string, nullable
  - `voice_emoji` boolean, nullable
  - `sells` string[]
  - `brand_colors` string[]
  - `logo_url` string, nullable
  - `analyzed_at` string, date-time, nullable
  - `onboarding_completed` boolean
  - `color_roles` object
  - `chart_palette` string[]
  - `chart_palettes` object
  - `typography` object
  - `add_ons` object
  - `theme` object, nullable
  - `brand_rules` object
  - `voice_traits` string[]
  - `brand_words` object
  - `field_states` object
  - `brand_kit_version` integer
  - `logos` BrandLogoSlot[]
    - `slot` string, required
    - `mode` string, required
    - `url` string, required
  - `readiness` BrandReadiness: The kit's completeness meter + per-output readiness. An encouragement signal, never a gate.
    - `completeness_pct` integer
    - `outputs` BrandOutputReadiness[]
      - `code` string, required
      - `label` string, required
      - `live` boolean, required
      - `ready` boolean, required
      - `confirmed_count` integer, required
      - `required_count` integer, required
      - `needs` BrandFieldReadiness[]
        - `path` string, required
        - `state` string, required
        - `label` string, required
    - `nudges` BrandNudge[]
      - `path` string, required
      - `state` string, required
      - `label` string, required
      - `kind` 'confirm' | 'add' | 'addons_off', required
      - `tone` 'attention' | 'neutral', required
  - `host` string, nullable
  - `phases` AnalysisPhase[]
    - `code` 'reach' | 'look' | 'identity' | 'voice' | 'palette' | 'typography' | 'logo' | 'save', required
    - `state` 'pending' | 'running' | 'done' | 'empty' | 'skipped' | 'unavailable', required

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `402`: Billing blocks the read: a monthly spend cap, an inactive subscription, no credits, or a held starter grant. `code` names which. A workspace that has used its free reads carries `free_website_reads_used` as `errors[0].type`.
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `404`: Not found
- `409`: An analysis is already in progress for this workspace.
- `422`: The site could not be analyzed (unreachable/blocked/unreadable).
- `429`: Rate limited: too many analyses; retry after a moment.

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
