RivermarkRivermark
API reference

POST /brandkit

Extract a brand from references into a structured, reusable brand kit.

Extracts a brand from any number of provided references and returns a visual and structured representation of it. Rivermark browses the provided websites, opens archives, reads brand guidelines, inspects images, and reconciles conflicting signals — such as a website palette that differs from the official guidelines — into a single coherent brand definition.

The result is a design (see Designs) whose ID can be passed as a reference to any /design call to keep everything on-brand.

Endpoint
POST https://api.rivermark.ai/brandkit

Request body

Full example
{
  "references": [
    { "type": "url", "url": "https://acmecoffee.co" },
    { "type": "file", "id": "rmf_cj4hbqz9x0001v2x8n6tqz7e" }
  ],
  "instructions": "The zip contains our official guidelines; the website is out of date, prefer the guidelines.",
  "allow_fetch": true,
  "auto_review": true
}

Parameters

Prop

Type

Response

200 OK
{
  "design_id": "rmd_cj4hbqz4f0005mz6x7p9q2xr",
  "name": "Acme Coffee Co.",
  "tagline": "Slow mornings, fast coffee",
  "palette": [
    { "hex": "#2D1B0E", "name": "Roast", "role": "primary" },
    { "hex": "#F3EAD8", "name": "Oat", "role": "background" },
    { "hex": "#C8552A", "name": "Pumpkin Spice", "role": "accent" }
  ],
  "fonts": [
    { "family": "Fraunces", "role": "title" },
    { "family": "Work Sans", "role": "body" }
  ],
  "assets": [
    {
      "kind": "logo",
      "name": "Roaster stamp",
      "description": "The circular roaster stamp, cream on transparent",
      "url": "https://cdn.rivermark.ai/rmd_cj4hbqz4f0005mz6x7p9q2xr/q7m2xk4d/logo-roaster.png"
    },
    {
      "kind": "wordmark",
      "name": "Wordmark",
      "description": "Wordmark set in Fraunces with the swash A",
      "url": "https://cdn.rivermark.ai/rmd_cj4hbqz4f0005mz6x7p9q2xr/q7m2xk4d/wordmark.png"
    }
  ],
  "voice": "Warm, playful, and unpretentious. Short sentences. Coffee puns welcome, but never at the expense of clarity.",
  "voice_examples": [
    {
      "text": "Our beans travel less than your morning commute.",
      "source": { "type": "url", "url": "https://acmecoffee.co/about" }
    }
  ],
  "brand_board": "https://cdn.rivermark.ai/rmd_cj4hbqz4f0005mz6x7p9q2xr/q7m2xk4d/board.png",
  "brand_header": "https://cdn.rivermark.ai/rmd_cj4hbqz4f0005mz6x7p9q2xr/q7m2xk4d/header.png",
  "cost": 0.75
}

Fields

Prop

Type

Sub-types

  • BrandColor — { "hex": string, "name": string, "role": "primary" | "accent" | "background" }
  • BrandFont — { "family": string, "google_match"?: string, "role": "title" | "body" | "ui" }
  • BrandAsset — { "kind": "logo" | "wordmark" | "lockup" | "mascot" | "imagery" | "other", "name": string, "description"?: string, "url": string }
  • VoiceExample — { "text": string, "source": Reference }

Asset URLs are ephemeral, like all rendered URLs — download anything you want to display permanently.

Streaming

Add ?stream=true for SSE events: progress updates like "Browsing the website…", "Reading the guidelines archive…", then completed with the full response. See Streaming.

Putting it to work

const api = (path: string, body: object) =>
  fetch("https://api.rivermark.ai" + path, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.RIVERMARK_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(body),
  }).then((r) => r.json());

const brandkit = await api("/brandkit", {
  references: [{ type: "url", url: "https://acmecoffee.co" }],
});

const design = await api("/design", {
  task: "Create an Instagram post for our new seasonal roast.",
  references: [{ type: "design", id: brandkit.design_id }],
});

For the complete flow, see the brand extraction guide.

On this page