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

# Check brand adherence

> Score a rebuild, a generated page, or a redesign against the brand it should follow

You shipped a page that is supposed to look like the brand. Does it? Brand adherence turns that question into a number and a work list: one `score` from 0 to 1, prose `recommendations`, and concrete `fixes` with exact target values.

This guide walks the workflow end to end. For the underlying model, see [Brand adherence](/concepts/brand-adherence); for what runs inside it, see [How the engine works](/concepts/architecture#the-verifier).

## When to use it

* **A rebuild against the original.** You re-implemented a site and want proof that nothing drifted.
* **A generated page against the brand it was prompted with.** An agent or a template produced the page; check it before it ships.
* **A redesign against the current brand.** Measure how far the new direction moved, and whether the moves were the ones you intended.

In every case the roles are the same: `reference_url` is the brand standard, `source_url` is the page being judged. Both URLs must be reachable by the engine.

## Run a check

<Steps>
  <Step title="Create the job">
    Call [`POST /judge/brand-adherence`](/api-reference/endpoint/create-brand-adherence) with the two URLs. Both sides are extracted automatically, so you do not create submissions first.
  </Step>

  <Step title="Poll the job">
    Call [`GET /judge/brand-adherence/{job_id}`](/api-reference/endpoint/get-brand-adherence-job) until `status` is `completed`. Stop on `failed` and read `error`.
  </Step>

  <Step title="Read the verdict">
    Call [`GET /judge/brand-adherence/{job_id}/result`](/api-reference/endpoint/get-brand-adherence-verdict) for the score, the recommendations, and the fixes.
  </Step>
</Steps>

## Full example

<CodeGroup>
  ```python Python theme={null}
  import httpx
  import time

  API_KEY = "your-api-key"
  BASE = "https://api.tastelabs.com"
  HEADERS = {"X-API-Key": API_KEY}

  def check_adherence(reference_url: str, source_url: str) -> dict:
      created = httpx.post(
          f"{BASE}/judge/brand-adherence",
          headers=HEADERS,
          json={"reference_url": reference_url, "source_url": source_url},
      )
      created.raise_for_status()
      job_id = created.json()["job_id"]
      print(f"Job created: {job_id}")

      while True:
          job = httpx.get(f"{BASE}/judge/brand-adherence/{job_id}", headers=HEADERS)
          job.raise_for_status()
          body = job.json()
          if body["status"] == "completed":
              break
          if body["status"] == "failed":
              raise RuntimeError(body.get("error") or "Adherence job failed")
          time.sleep(5)

      verdict = httpx.get(
          f"{BASE}/judge/brand-adherence/{job_id}/result", headers=HEADERS
      )
      verdict.raise_for_status()
      return verdict.json()

  verdict = check_adherence("https://stripe.com", "https://staging.example.com")
  print(f"Score: {verdict['score']:.2f}")
  for item in verdict["recommendations"]:
      print(f"- {item}")
  ```

  ```typescript TypeScript theme={null}
  const API_KEY = "your-api-key";
  const BASE = "https://api.tastelabs.com";
  const HEADERS = { "X-API-Key": API_KEY, "Content-Type": "application/json" };

  async function checkAdherence(referenceUrl: string, sourceUrl: string) {
    const created = await fetch(`${BASE}/judge/brand-adherence`, {
      method: "POST",
      headers: HEADERS,
      body: JSON.stringify({ reference_url: referenceUrl, source_url: sourceUrl }),
    });
    const { job_id } = await created.json();
    console.log(`Job created: ${job_id}`);

    while (true) {
      const job = await fetch(`${BASE}/judge/brand-adherence/${job_id}`, {
        headers: HEADERS,
      });
      const body = await job.json();
      if (body.status === "completed") break;
      if (body.status === "failed") throw new Error(body.error ?? "Failed");
      await new Promise((res) => setTimeout(res, 5000));
    }

    const verdict = await fetch(`${BASE}/judge/brand-adherence/${job_id}/result`, {
      headers: HEADERS,
    });
    return verdict.json();
  }

  const verdict = await checkAdherence(
    "https://stripe.com",
    "https://staging.example.com"
  );
  console.log(`Score: ${verdict.score}`);
  for (const item of verdict.recommendations) console.log(`- ${item}`);
  ```
</CodeGroup>

## Act on the verdict

The three parts of the verdict answer three different questions:

* **`score`** answers "how close is it?". One number from 0 to 1.
* **`recommendations`** answer "what should change?". Prose strings, worst-first, with exact target values where they exist.
* **`fixes`** answer "what can be changed mechanically?". Structured objects, worst-first. Each carries an `action` discriminator (for example `snap_to_token` or `add_color_token`) plus the fields that action needs, so a script or an agent can apply them without interpretation.

Both lists are worst-first, so the first items always move the result most. Work from the top.

## Share the result

Jobs are private by default. To share a verdict with someone who has no API key, make the job public with [`PATCH /judge/brand-adherence/{job_id}/visibility`](/api-reference/endpoint/update-brand-adherence-visibility) and `{"is_public": true}`. The result endpoint then serves the verdict without authentication, so the link works for anyone.

## Next steps

<CardGroup cols={2}>
  <Card title="Verification in an agent loop" icon="rotate" href="/use-cases/agent-loop">
    Feed the verdict back to the agent that built the page.
  </Card>

  <Card title="Brand adherence" icon="scale-balanced" href="/concepts/brand-adherence">
    The verdict, reuse, and visibility in full.
  </Card>
</CardGroup>
