Skip to main content

Brand Pipeline

Pi’s brand intelligence suite turns a website URL (or logo/image assets) into a structured Brand DNA record. You then pass that brand_id to any campaign, ad, or avatar endpoint to ground generation in your client’s actual identity. The full pipeline:
  1. Extract brand DNA from a URL → receive a job_id
  2. Poll the job → receive a brand_id
  3. Get the stored brand (optional, for inspection)
  4. Project the brand into a compact use-case payload
1

Extract brand DNA

Send a URL (and optionally a logo or reference images) to kick off extraction.
export BASE="https://api.example.com"
export API_KEY="pi_live_***"

extract_job_id=$(curl -sS -X POST "$BASE/api/v1/brands/extract" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}' | jq -r '.data.job_id')

echo "Extraction job: $extract_job_id"
The endpoint returns 202 Accepted immediately. Heavy work runs in the background.
{
  "id": "req_pi_...",
  "object": "job",
  "status": "queued",
  "created_at": 1760000000,
  "data": { "job_id": "a4f52db4-...." }
}
2

Poll the job and capture brand_id

Use expand=brand to receive the full brand object inline with the completed job — no second request required.
brand_id=$(curl -sS \
  "$BASE/api/v1/jobs/$extract_job_id?wait_for_completion=true&timeout_seconds=30&expand=brand" \
  -H "Authorization: Bearer $API_KEY" \
  | jq -r '.data.job_result.brand.id')

echo "Brand ID: $brand_id"
Pass expand=brand on the poll call to get the full brand object inline. Without it you receive only brand_id in job_result and need a separate GET /api/v1/brands/:id call.
Save brand_id in your database. You reuse it for every campaign, edit, localization, and avatar generation tied to this client. Extraction is the expensive step; projection and generation are cheap by comparison.
3

(Optional) Inspect the stored brand

At any time you can retrieve the full Brand DNA JSON:
curl -sS "$BASE/api/v1/brands/$brand_id" \
  -H "Authorization: Bearer $API_KEY"
4

Project brand identity for a use case

POST /api/v1/brands/:id/project converts the “fat JSON” stored during extraction into a compact, use-case-specific payload. This is ideal when you need concise brand context for a code-generation agent or a frontend token contract.
curl -X POST "$BASE/api/v1/brands/$brand_id/project" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"use_case":"create lovable.dev-ready UI variables and button style guide"}'
Projection is synchronous — it returns 200 with the result directly:
{
  "id": "req_pi_2f2b3de6-aaaa-bbbb-cccc-ddddeeeeffff",
  "object": "brand.projection",
  "status": "completed",
  "data": {
    "use_case": "generate shadcn design tokens for a SaaS dashboard",
    "payload": {
      "brand_projection": {
        "primary_background_hex": "#FFFFFF",
        "primary_accent_hex": "#0071E3",
        "color_palette": ["#FFFFFF", "#0071E3", "#1D1D1F"],
        "typography_rules": "…",
        "core_slogan": "…",
        "imagen_style_conditioning": "…",
        "logo_url": null
      }
    }
  }
}

How brand_id flows downstream

Once you have a brand_id, pass it to generation endpoints so every asset is grounded in the extracted identity:
// Generate a campaign ad grounded in the extracted brand
const gen = await pi("/api/v1/campaigns/generate", {
  method: "POST",
  body: JSON.stringify({
    prompt: "Premium hero ad for summer launch",
    brand_id: brandId,
    output: { aspect_ratio: "4:5", resolution: "1K" },
  }),
});

// Localize the result — reuse the same brand_id
const localize = await pi("/api/v1/campaigns/localize-ad", {
  method: "POST",
  body: JSON.stringify({
    source_job_id: gen.data.job_id,
    brand_id: brandId,
    target_culture: "French urban premium",
    target_language: "fr",
    target_currency: "EUR",
    prompt: "Keep composition exactly the same",
  }),
});
Store brand_id alongside your client or product record. Re-extracting on every campaign wastes credits — extraction is the costly step. Re-use the stored brand_id freely across campaigns, edits, localizations, and avatar runs.

Full extract → generate → localize (curl walkthrough)

export BASE="https://api.example.com"
export API_KEY="pi_live_***"

# 1) Extract brand
extract_job_id=$(curl -sS -X POST "$BASE/api/v1/brands/extract" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}' | jq -r '.data.job_id')

# 2) Wait for extraction and get brand id
brand_id=$(curl -sS \
  "$BASE/api/v1/jobs/$extract_job_id?wait_for_completion=true&timeout_seconds=30&expand=brand" \
  -H "Authorization: Bearer $API_KEY" | jq -r '.data.job_result.brand.id')

# 3) Generate base campaign
generate_job_id=$(curl -sS -X POST "$BASE/api/v1/campaigns/generate" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"prompt\":\"Premium hero ad for summer launch\",
    \"brand_id\":\"$brand_id\",
    \"output\":{\"aspect_ratio\":\"4:5\",\"resolution\":\"1K\"}
  }" | jq -r '.data.job_id')

# 4) Localize to French using source_job_id
fr_job_id=$(curl -sS -X POST "$BASE/api/v1/campaigns/localize-ad" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"prompt\":\"Keep composition exactly the same\",
    \"source_job_id\":\"$generate_job_id\",
    \"target_culture\":\"French urban premium\",
    \"target_language\":\"fr\",
    \"target_currency\":\"EUR\",
    \"brand_id\":\"$brand_id\"
  }" | jq -r '.data.job_id')

# 5) Poll localized result
curl -sS \
  "$BASE/api/v1/jobs/$fr_job_id?wait_for_completion=true&timeout_seconds=30&expand=ad" \
  -H "Authorization: Bearer $API_KEY"