Create Brand

Register a new brand for analysis. Returns the existing brand if the domain is already registered under your account.

POSThttps://api.boringmarketing.com/brands

Register a brand by its domain. If the domain is already registered under your account, the response returns the existing brand with "existing": true. The brand starts empty — identity, competitors, trust signals, and the keyword universe are populated by the pipeline endpoints (/enrich/brand, /discover-competitors, /analyze, etc).

Request body

domainstringrequired

The brand's primary domain (e.g., yourdomain.com). No protocol.

namestringrequired

Brand display name.

Response

Returns 201 Created whether the brand is newly created or already existed — the route status code is fixed. Distinguish the two cases by checking the existing field:

New brand (no existing field)

{
  "id": "ea502f67-338b-47e4-a245-5c4eea8bd8d2",
  "domain": "yourdomain.com",
  "name": "Your Brand"
}

Domain already registered under your account

{
  "id": "ea502f67-338b-47e4-a245-5c4eea8bd8d2",
  "domain": "yourdomain.com",
  "name": "Your Brand",
  "existing": true
}

Errors

StatusMeaning
403Creating this brand would exceed your tier's brand limit (1 for Builder, 3 for Pro, 10 for Agency). Body is a plain {"detail": "<tier> tier allows <N> brand(s)."} — there is no actions[] envelope on this endpoint. Upgrade via POST /auth/billing-portal.
422Request body failed validation.

Example

curl -X POST \
  https://api.boringmarketing.com/brands \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BM_API_KEY" \
  -d '{
    "domain": "yourdomain.com",
    "name": "Your Brand"
  }'

Brand identity (description, ICP, services, trust signals, voice) is extracted automatically by POST /brands/{id}/enrich/brand — no need to supply it at create time. Competitors can be discovered automatically via POST /brands/{id}/discover-competitors or set manually later with PATCH /brands/{id}.