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

# Get a company's brand

> Get a company's name, description, logos, icons, colours, fonts, social profiles and published contact details from its domain.

`GET https://rankfield.dev/v1/brand?domain={domain}`

```bash cURL
curl 'https://rankfield.dev/v1/brand?domain=rankfield.dev' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

```python Python
import requests

response = requests.get(
    "https://rankfield.dev/v1/brand?domain=rankfield.dev",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
print(response.json())
```

```javascript JavaScript
const response = await fetch("https://rankfield.dev/v1/brand?domain=rankfield.dev", {
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});
console.log(await response.json());
```

```json 200
{
  "domain": "rankfield.dev",
  "finalUrl": "https://rankfield.dev/",
  "status": 200,
  "blocked": null,
  "name": {
    "value": "Rankfield",
    "source": "title"
  },
  "description": {
    "value": "Get a key without signing up and query Site Strength and referring domain metrics.",
    "source": "meta description"
  },
  "logos": [
    {
      "url": "data:image/svg+xml,%3Csvg%20class=%22brand-mark%22%20aria-hidden=%22true%22%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2064%2064%22%3E%3Crect%20x=%228%22%20y=%2231%22%20width=%2212%22%20height=%2226%22%20rx=%224%22%20fill=%22%23ff766a%22%20stroke=%22%23252238%22%20stroke-width=%222.5%22%3E%3C/rect%3E%3Crect%20x=%2226%22%20y=%229%22%20width=%2212%22%20height=%2248%22%20rx=%224%22%20fill=%22%238067ed%22%20stroke=%22%23252238%22%20stroke-width=%222.5%22%3E%3C/rect%3E%3Crect%20x=%2244%22%20y=%2221%22%20width=%2212%22%20height=%2236%22%20rx=%224%22%20fill=%22%236edfc5%22%20stroke=%22%23252238%22%20stroke-width=%222.5%22%3E%3C/rect%3E%3C/svg%3E",
      "source": "header inline <svg>",
      "confidence": 0.88,
      "type": "image/svg+xml",
      "width": null,
      "height": null,
      "variant": null,
      "colors": [
        "#ff766a",
        "#8067ed",
        "#6edfc5",
        "…"
      ],
      "fallback": false
    }
  ],
  "logosReason": null,
  "wordmark": null,
  "icons": {
    "best": {
      "url": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Crect%20x%3D%228%22%20y%3D%2231%22%20width%3D%2212%22%20height%3D%2226%22%20rx%3D%224%22%20fill%3D%22%23ff766a%22%20stroke%3D%22%23252238%22%20stroke-width%3D%222.5%22%2F%3E%3Crect%20x%3D%2226%22%20y%3D%229%22%20width%3D%2212%22%20height%3D%2248%22%20rx%3D%224%22%20fill%3D%22%238067ed%22%20stroke%3D%22%23252238%22%20stroke-width%3D%222.5%22%2F%3E%3Crect%20x%3D%2244%22%20y%3D%2221%22%20width%3D%2212%22%20height%3D%2236%22%20rx%3D%224%22%20fill%3D%22%236edfc5%22%20stroke%3D%22%23252238%22%20stroke-width%3D%222.5%22%2F%3E%3C%2Fsvg%3E",
      "sizes": null,
      "type": "image/svg+xml",
      "source": "link rel=icon"
    },
    "favicon": [
      {
        "url": "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Crect%20x%3D%228%22%20y%3D%2231%22%20width%3D%2212%22%20height%3D%2226%22%20rx%3D%224%22%20fill%3D%22%23ff766a%22%20stroke%3D%22%23252238%22%20stroke-width%3D%222.5%22%2F%3E%3Crect%20x%3D%2226%22%20y%3D%229%22%20width%3D%2212%22%20height%3D%2248%22%20rx%3D%224%22%20fill%3D%22%238067ed%22%20stroke%3D%22%23252238%22%20stroke-width%3D%222.5%22%2F%3E%3Crect%20x%3D%2244%22%20y%3D%2221%22%20width%3D%2212%22%20height%3D%2236%22%20rx%3D%224%22%20fill%3D%22%236edfc5%22%20stroke%3D%22%23252238%22%20stroke-width%3D%222.5%22%2F%3E%3C%2Fsvg%3E",
        "sizes": null,
        "type": "image/svg+xml",
        "source": "link rel=icon"
      }
    ],
    "appleTouch": [],
    "manifest": [],
    "maskIcon": null
  },
  "images": {
    "ogImage": null,
    "twitterImage": null
  },
  "colors": {
    "themeColor": [],
    "manifest": {
      "theme": null,
      "background": null
    },
    "cssVariables": [
      {
        "name": "--ink",
        "value": "#252238",
        "hex": "#252238",
        "uses": 106,
        "stock": false
      },
      {
        "name": "--lime",
        "value": "#dff582",
        "hex": "#dff582",
        "uses": 11,
        "stock": false
      },
      {
        "name": "--line",
        "value": "#252238",
        "hex": "#252238",
        "uses": 10,
        "stock": false
      },
      "…"
    ],
    "mostUsed": [
      {
        "hex": "#252238",
        "count": 131,
        "neutral": false,
        "score": 450,
        "stock": false,
        "seen": [
          "button",
          "header",
          "nav",
          "…"
        ]
      },
      {
        "hex": "#ffffff",
        "count": 35,
        "neutral": true,
        "score": 164,
        "stock": false,
        "seen": [
          "button",
          "header",
          "body"
        ]
      },
      {
        "hex": "#35304f",
        "count": 10,
        "neutral": false,
        "score": 61,
        "stock": false,
        "seen": [
          "button"
        ]
      },
      "…"
    ],
    "roles": {
      "primary": {
        "hex": "#ffb9ce",
        "from": "button background",
        "element": "body>header.site-header>nav.top-nav>a.nav-key",
        "method": "computed"
      },
      "accent": null,
      "background": {
        "hex": "#f5f1e9",
        "from": "body background",
        "element": "body",
        "method": "computed"
      },
      "text": {
        "hex": "#252238",
        "from": "body colour",
        "element": "body",
        "method": "computed"
      },
      "headerBackground": {
        "hex": "#fffaf3f5",
        "from": "header background",
        "element": "body>header.site-header",
        "method": "computed"
      }
    },
    "rolesDark": null,
    "rolesReason": null
  },
  "fonts": [
    {
      "family": "Inter",
      "source": "css font-family",
      "uses": 5
    },
    {
      "family": "Trebuchet MS",
      "source": "css font-family",
      "uses": 3
    },
    {
      "family": "Avenir Next",
      "source": "css font-family",
      "uses": 1
    }
  ],
  "typography": {
    "method": "stylesheet",
    "viewport": {
      "width": 1280.0,
      "height": 800.0
    },
    "rootFontSize": {
      "px": 16.0,
      "basis": "16px: the CSS default (html declares no font-size)"
    },
    "body": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": "15px",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": 15.0,
        "basis": "px",
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": null
      },
      "weight": {
        "value": "normal",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "number": 400.0,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": null
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": 22.5,
        "basis": "1.5 × font size 15px",
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": null
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for body nor on html"
      }
    },
    "h1": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: the browser default for h1 is 2em"
      },
      "weight": {
        "value": null,
        "declared": null,
        "number": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: browsers make headings bold"
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": null,
        "basis": null,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": "1.5 × the font size, which isn't declared"
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for h1 nor on body"
      }
    },
    "h2": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: the browser default for h2 is 1.5em"
      },
      "weight": {
        "value": null,
        "declared": null,
        "number": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: browsers make headings bold"
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": null,
        "basis": null,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": "1.5 × the font size, which isn't declared"
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for h2 nor on body"
      }
    },
    "h3": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: the browser default for h3 is 1.17em"
      },
      "weight": {
        "value": null,
        "declared": null,
        "number": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: browsers make headings bold"
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": null,
        "basis": null,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": "1.5 × the font size, which isn't declared"
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for h3 nor on body"
      }
    },
    "h4": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: the browser default for h4 is 1em"
      },
      "weight": {
        "value": null,
        "declared": null,
        "number": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: browsers make headings bold"
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": null,
        "basis": null,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": "1.5 × the font size, which isn't declared"
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for h4 nor on body"
      }
    },
    "h5": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: the browser default for h5 is 0.83em"
      },
      "weight": {
        "value": null,
        "declared": null,
        "number": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: browsers make headings bold"
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": null,
        "basis": null,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": "1.5 × the font size, which isn't declared"
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for h5 nor on body"
      }
    },
    "h6": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: the browser default for h6 is 0.67em"
      },
      "weight": {
        "value": null,
        "declared": null,
        "number": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: browsers make headings bold"
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": null,
        "basis": null,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": "1.5 × the font size, which isn't declared"
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for h6 nor on body"
      }
    },
    "button": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "inherit",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": "15px",
        "declared": "font: inherit",
        "px": 15.0,
        "basis": "px",
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "weight": {
        "value": "normal",
        "declared": "font: inherit",
        "number": 400.0,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: inherit",
        "px": 22.5,
        "basis": "1.5 × font size 15px",
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared: buttons use the browser's own control font"
      }
    },
    "link": {
      "family": {
        "value": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "declared": "\"Trebuchet MS\",\"Avenir Next\",Arial,sans-serif",
        "primary": "Trebuchet MS",
        "generic": false,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "size": {
        "value": "15px",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": 15.0,
        "basis": "px",
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "weight": {
        "value": "normal",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "number": 400.0,
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "lineHeight": {
        "value": "1.5",
        "declared": "font: 15px/1.5 \"Avenir Next\",Arial,Helvetica,sans-serif",
        "px": 22.5,
        "basis": "1.5 × font size 15px",
        "source": "style element",
        "selector": "body",
        "media": null,
        "inherited": "body",
        "method": "stylesheet",
        "reason": null
      },
      "letterSpacing": {
        "value": null,
        "declared": null,
        "px": null,
        "basis": null,
        "source": null,
        "selector": null,
        "media": null,
        "inherited": null,
        "method": "stylesheet",
        "reason": "not declared for link nor on body"
      }
    }
  },
  "social": [],
  "contact": {
    "source": null,
    "email": null,
    "telephone": null,
    "address": null,
    "contactPoints": []
  },
  "language": {
    "code": "en",
    "script": "Latn",
    "confidence": 1.0,
    "source": "content",
    "declared": "en"
  },
  "fetches": [
    {
      "url": "https://rankfield.dev/robots.txt",
      "purpose": "robots.txt",
      "status": 404,
      "bytes": null,
      "error": null
    },
    {
      "url": "https://rankfield.dev/",
      "purpose": "page",
      "status": 200,
      "bytes": 133865,
      "error": null
    }
  ],
  "cached": false,
  "ageSeconds": 0
}
```

```json 401
{
  "error": {
    "code": "unauthorized",
    "message": "A valid API key is required"
  }
}
```

We read the homepage, its web app manifest, up to 4 of its own stylesheets (on its own host or its CDN), and `/favicon.ico` when the page names no icon: 8 requests at most, robots.txt included. Every value says where on the site it came from, so you can judge how far to trust it.

Send the parameters as a query string with `GET`, or as a JSON object (up to 1 MB) with `POST` to the same path. For many domains, [start a job](/docs/brand/start-a-job).

## Parameters

### Headers

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `Authorization` | string | Yes | – | `Bearer` followed by your API key. See [Authentication](/docs/get-started/authentication). |

### Query parameters

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `domain` | string | Yes, or `url` | – | The company's domain, such as `acme.com`. `www.acme.com` is read as given; a URL here means its domain. Send `domain` or `url`, not both. |
| `url` | string | Instead of `domain` | – | A full `http(s)` URL on the site. The site's homepage is read, not this page. |
| `roles` | boolean | No | `false` | `true` computes the colour roles on a large page too. By default they are computed on pages up to about 6,000 tags and 1.6 MB of CSS, four times the earlier limit: almost every small-business site and most large brand homepages. On a larger page `colors.roles` is `null` with a reason unless you ask. On a very large page even `roles=true` can come back `null` with `over the CPU budget`. A call with `roles=true` is stored apart from one without. |
| `screenshot` | string | No | – | `viewport` or `fullPage`: also return a WebP image of the homepage as a browser shows it, the first screen or the whole page up to 12,000 px tall. |
| `viewport` | string | No | `desktop` | `desktop` (1366×768) or `mobile` (412×915): the screen for the screenshot. |
| `maxAge` | integer | No | `86400` | How old a stored answer may be, in seconds, up to 2,592,000 (30 days). `0` fetches fresh. |
| `timeout` | integer | No | `20` | How long the call may take, in seconds, 1–60. |

## Response

| Field | Type | Description |
|---|---|---|
| `url` | string | The URL you sent, when you sent one. |
| `domain` | string | The site read (lowercase; international names in `xn--` form). |
| `finalUrl`, `status` | string, integer | The homepage that answered, and its HTTP status. On a 404 or 500 every brand field is empty. |
| `blocked` | object \| null | The firewall that answered instead of the homepage. Then every brand field is empty: we never guess. |
| `name` | object | `{value, source}`. Sources, best first: schema.org Organization, schema.org WebSite, `og:site_name`, `application-name`, `apple-mobile-web-app-title`, the manifest, the title. |
| `description` | object | `{value, source}`. Sources, best first: schema.org Organization, the meta description, `og:description`, `twitter:description`, schema.org WebSite, the manifest. |
| `logos` | array | The site's own logos, best first, each `{url, source, confidence, type, width, height, variant, fallback}`: the logo the page shows in its header or link home (an image, or an inline SVG as a `data:` URL with its `colors`), then the schema.org logo (marked when it differs from the one the page shows) and `og:logo`. Never a favicon or share image: those are in `icons` and `images`, with one exception. When the page has no logo image, the site's best icon (`icons.best`) stands in as the only entry, with `fallback: true`, a `source` of `icon fallback (…)` naming where the icon came from, and `confidence` 0.3. Every real logo has `fallback: false`. `variant` is `light` for a logo drawn for dark backgrounds, `dark` for the opposite, or `null`. Image-proxy URLs (`/_next/image?url=…`) are given as the original file. |
| `logosReason` | string \| null | Why `logos` is empty, or holds only the fallback icon, when it does. |
| `wordmark` | object \| null | `{text, source: "home link text"}`: the site's name as the page sets it in type, from its first link home when that link holds no image and its text names the site (the domain's name or the brand name, such as `KYLIAN` on kylian.ai). Menu items, skip links and written-out addresses are left out. `null` otherwise. |
| `icons` | object | `best`, the one icon to show the site by: an SVG icon (it scales), else the largest declared size; `null` when the site declares none. Then the `favicon`, `appleTouch` and `manifest` lists, and `maskIcon`. Each icon is `{url, sizes, type, source}`, manifest icons with `purpose`. |
| `images` | object | `ogImage` and `twitterImage`. |
| `colors` | object | `themeColor` (with light and dark variants), the manifest's `theme` and `background`, `cssVariables` (custom properties holding colours, with how often they are used) and `mostUsed` (colours across the CSS read, weighted by where they paint: `score`, and `seen`, the roles they paint). `neutral` marks greys, black and white; `stock` marks a shared framework's default colours (WordPress presets, Bootstrap, Tailwind's palette, shadcn/ui's greys), ranked after the site's own. Each has a `hex`. |
| `colors.roles` | object \| null | The colours the page's own elements get, computed by a style engine over the page and its stylesheets: `primary` (the main button's background, else the link colour, else a coloured header), `accent` (the link colour when it differs), `background` and `text` (body), and `headerBackground`. Each is `{hex, from, element, method: "computed"}`. `null` when not computed, with `rolesReason`. |
| `colors.rolesDark` | object \| null | The same roles in the visitor's dark mode, when the site has one. |
| `colors.rolesReason` | string \| null | Why `roles` is `null`: `a large page: colour roles are computed when asked (roles=true)`, `the page or its stylesheets are over the size cap`, `the page has too much markup for the pass`, `over the CPU budget`, `no <body>` or `the style engine failed on this page`. `null` when the roles are there. |
| `fonts` | array | `{family, source, uses}`: Google Fonts, `@font-face`, Adobe Fonts, then fonts the CSS asks for. |
| `typography` | object \| null | The site's base typography, read from its CSS as a 1280 × 800 desktop window applies it: `rootFontSize`, and for `body`, `h1`–`h6`, `button` and `link` the `family`, `size`, `weight`, `lineHeight` and `letterSpacing`. Each value has `value` (in force, `var()` resolved, or `null`), `declared` (as written), `px` with its `basis` for lengths, `number` for weight, `primary` and `generic` for families, its `source` stylesheet (or `style element`), `selector`, `media`, `inherited` (`body` or `html`) and, when `null`, a `reason` naming the browser default. `null` on a blocked or error page. |
| `social` | array | `{network, url, source}` from schema.org `sameAs`, then links to known social sites. Never visited. |
| `contact` | object | `{source, email, telephone, address, contactPoints}`, only from the site's own schema.org Organization or LocalBusiness data. |
| `language` | object | The homepage's language. |
| `fetches` | array | Each request made: `{url, purpose, status, bytes, error}`. |
| `screenshot` | object | With `screenshot`: `{format: "webp", kind, viewport, bytes, data}`, the image in base64. |
| `cached`, `ageSeconds` | boolean, integer | Whether this answer came from our store, and how old it is. |

Colour roles are computed on the page as fetched, without JavaScript: a page whose buttons get their colours from script gets the colours of its static HTML and CSS.

Names and descriptions never carry an email address or phone number: where the site's text has one, it shows as "…". Contact details only appear in `contact`.

`typography` reads the site's base rules (`body`, `h1`, `h1, .h1`, `button` and `.btn`, `a`), not each widget's styling. Nothing is guessed: a value the CSS does not declare is `null`, with a `reason`.

## How we fetch

We fetch as `Rankfield-User` (`Mozilla/5.0 (compatible; Rankfield-User/1.0; +https://rankfield.dev/bot)`), as plain HTML without running JavaScript, unless you ask for a rendered page or a screenshot.

- **robots.txt:** obeyed on every request and redirect, following the rules for `Rankfield-User`, or for `RankfieldBot` when the file has none for it, or `*` when it has neither. Social sites and font services are named from their links, never fetched.
- **Firewalls:** a challenge, CAPTCHA or block page is reported in the answer, never worked around and never retried.
- **Never:** cookies, logins, proxies or other bots' names. JavaScript runs only when you ask for it.
- **Excluded sites:** Reddit, LinkedIn, Facebook, Instagram, X/Twitter and TikTok (subdomains included), Google search result pages, and sites whose owners asked us are never fetched.
- **Pace:** each website is fetched gently, shared by all customers, slower when its robots.txt sets a `Crawl-delay` or after a slow answer. Many URLs on one site go at that site's pace.

Repeat calls to the same website within about a minute can wait their turn for that site's slot. If the wait runs past the call's time limit (20 seconds by default), the call ends with `504` `timeout` and `details.reason` `sitePace`. It doesn't count as usage: retry after `Retry-After`, or allow a longer `timeout`.

More: [Rankfield crawlers](/bot).

## Errors

Errors are `{"error": {"code", "message", "details"}}`. Branch on `code`; `message` is for people.

| Status | Code | When |
|---|---|---|
| 400 | `invalid_input` | A parameter is missing, unknown or malformed. |
| 401 | `unauthorized` | No valid API key. |
| 403 | `robots_disallowed` | robots.txt disallows Rankfield-User for the homepage (a server error counts as no); `details` has the rule and line. |
| 403 | `site_excluded` | The site is on the exclusion list. |
| 403 | `blocked` | The website's bot protection refused us. Reported at once and never worked around; `details` says which protection. Not counted as usage. |
| 415 | `unsupported_content_type` | The homepage answered 2xx but isn't HTML. |
| 422 | `address_not_public` | The host resolves to a private or internal address. |
| 429 | `busy` | Our fetch capacity is busy: the call was refused at once, waited 4 seconds without a turn, or its time limit ran out while it waited (then `details.reason` is `capacity`). Not counted as usage. Retry after `Retry-After` seconds. |
| 500 | `internal` | Our bug. Retry. |
| 502 | `fetch_failed` | The site could not be reached: DNS failed, neither https nor http connected, or more than 5 redirects. |
| 503 | `unavailable` | The service is restarting or briefly unavailable. Retry after `Retry-After`. (A full fetch capacity answers `429` `busy`.) |
| 504 | `timeout` | The website didn't answer within the call's time limit. When `details.reason` is `sitePace`, the call waited its turn for this website instead, which we fetch gently, shared by all customers: retry after `Retry-After`, or allow a longer `timeout`. |

Only answered calls and the `502` and website-side `504` errors count as usage; refusals, our own errors (`500`, `503`), `429` `busy` and a `504` with `details.reason` `sitePace` don't.

## Limits

No per-key limits. When the server is busy you get `429` `busy` with `Retry-After`. Waiting calls are served in turn across keys, so a key with a few calls is never stuck behind one with thousands.

## MCP

On the [MCP server](/docs/agents/mcp-server), the tool for this is `brand_profile`.
