---
title: "Update Company Profile"
method: PUT
path: "/company-profile"
tags: ["GTM Context"]
---

# Update Company Profile

`PUT /company-profile`

## Request

- Base URL: `https://be.graph8.com/api/v1`
- URL: `https://be.graph8.com/api/v1/company-profile`
- Auth: HTTP bearer

Set this org's company profile (website + fields).

**Why this exists.** The company profile is the source of truth for Studio
generation. Self-serve orgs that sign up without a domain get a profile seeded
with graph8's own details, so every generated document describes the wrong
company — and the only write path was ``POST /company-profile``, an internal
JWT route absent from both the developer API and MCP. An agent could therefore
detect the problem but never fix it, and could not even read the field back to
confirm a human had fixed it.

Approved profiles are immutable. Pass ``unapprove_if_approved: true`` to
deliberately unlock and overwrite one; otherwise this returns 409 rather than
quietly discarding a human's approval.

Changing the website does NOT regenerate existing Studio documents — they were
generated from the old site. Follow with
``POST /api/v1/global-context/regenerate``.

## Headers

- `Authorization` string, nullable
- `X-Target-Org-Id` string, nullable

## Request body

- CompanyProfileUpdateRequest
  - `website_url` string, required: The client's real website. This is the source of truth Studio generation reads; setting it wrong is what makes every downstream ICP, persona and campaign describe the wrong company.
  - `fields` object, required: Profile fields to save, e.g. {'company_name': 'Acme', 'industry': 'Manufacturing'}. Replaces the stored field set.
  - `unapprove_if_approved` boolean: Approved profiles are immutable by design. Set true to explicitly unlock and overwrite a human-approved profile. Left false, an approved profile returns 409 instead of being silently unapproved.

## Response `200`

Successful Response

- ApiResponseDict
  - `data` object, required
  - `pagination` PaginationMeta
    - `page` integer, required: Current page number (1-indexed)
    - `limit` integer, required: Items per page
    - `total` integer, required: Total number of items
    - `has_next` boolean, required: Whether there are more pages
    - `next_cursor` string, nullable: Opaque cursor for the next page; null when there are no more items. Pass it back as the `cursor` query param to fetch the following page without computing page numbers.
    - `total_available` integer, nullable: Search endpoints only: how many records really match, when known. Can be larger than `total`, which is capped at the 10,000 results that can be paged. For company search this is a distinct-company estimate. Null when unknown; absent outside search.
    - `total_is_lower_bound` boolean, nullable: Search endpoints only: true when more records match than `total` shows (the result set is larger than the 10,000 results that can be paged). Absent outside search.
    - `notes` string[], nullable: Search endpoints only: plain-language notes about the result, e.g. that more records match than can be paged, or that a reversed `between` range was put in order.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/graph8/apis/graph8-developer-api.md) · [All operations](https://skmtc.dev/graph8/apis/graph8-developer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/graph8/apis/graph8-developer-api/revisions/2e7cfa0ca921?raw)
