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:
- Extract brand DNA from a URL → receive a
job_id
- Poll the job → receive a
brand_id
- Get the stored brand (optional, for inspection)
- Project the brand into a compact use-case payload
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-...." }
}
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. (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"
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.
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"