Brands, memory, skills, saved creators, connectors, settings, credits and jobs.
read-only / discovery
hermoso_capabilities#
Hermoso capabilities read-only
Probe what this Hermoso account can do RIGHT NOW: available image/video model ids + their exact credit costs, aspect ratios, video durations, the recipe ids, and the canEdit/canAvatar/canPublish flags. Call this FIRST so you generate with valid model ids and known costs. Read-only, free.
No parameters.
hermoso_credits#
Credit balance read-only
Return the account credit balance, credits used this session, and recent priced calls. Check before kicking off paid generation.
No parameters.
buy_credits#
Buy credits
Out of credits? Top up with a credit PACK. Call with no argument to list the available packs (id · credits · price). If the account has a saved card and you have billing-admin rights, calling with `pack` quotes the exact charge and calling again with confirm:true AND the quote's quote_token charges the saved card instantly (same one-click top-up as the app — no redirect). If there's no saved card yet, you get a Stripe checkout URL to hand your human for the FIRST purchase; their card saves for one-click after that. Packs only; subscriptions are managed by a person in Settings → Billing. To stop running out entirely, turn on auto-reload with set_auto_reload (admin) — low balances then top themselves up from the saved card automatically.
| Parameter | Type | Description |
|---|
pack | string | the pack id to buy (e.g. pack-2k) — omit to list the available packs first |
confirm | boolean | set true to actually charge the saved card for `pack` (required for the one-click charge; ignored on the checkout-link path) |
quote_token | string | the quoteToken returned by the quote step — REQUIRED (with confirm:true) to charge; it binds the exact pack + price you quoted (10-minute validity) and makes a retried confirm idempotent |
FEEDBACK: let the AGENT report a bug or ask for a capability…
report_bug#
Report a bug
Report a bug in Hermoso to the team. Use this when something in Hermoso genuinely misbehaves — a tool errors unexpectedly, returns a wrong or malformed result, a render comes back broken, or documented behaviour doesn't match what happened. Include what you were trying to do, the exact tool call and arguments, and what came back. Do NOT use it for out-of-credits, a policy refusal, or a missing capability (use request_feature for that). Free, no credits.
| Parameter | Type | Description |
|---|
summaryrequired | string | one-line summary of the bug |
detailsrequired | string | what you were doing, the tool + arguments you called, what you expected, and what actually happened (paste the exact error) |
severity | "low" | "medium" | "high" | high = blocks the task or loses paid work; medium = wrong output but workable; low = cosmetic |
request_feature#
Request a feature
Ask the Hermoso team for a capability that doesn't exist yet. Use this when you need something Hermoso genuinely can't do — an unsupported platform or channel, a missing model, an export format, a tool that would have completed the user's task but isn't available. Say what the user was trying to achieve, not just the feature name — the use case is what gets built. Free, no credits.
| Parameter | Type | Description |
|---|
summaryrequired | string | one line: the capability you need |
detailsrequired | string | what the user was actually trying to achieve, why the current tools couldn't do it, and what you'd expect the capability to do |
billing_status#
Billing status read-only
Show this account's billing at a glance: current plan (id + label + monthly price), credit balance, whether auto-reload is on, whether a card is on file, and whether YOU (this key) have ADMIN rights to change billing. Read-only, free. Call it before upgrade_plan / set_auto_reload to know what's possible — members have read-only billing. IN A SHARED TEAM WORKSPACE A MEMBER SEES THE PLAN AND THE BALANCE ONLY: the workspace owner's payment card and auto-reload belong to them and are not reported (billingScope:'member'). Never tell a member there is no card on file — the honest answer is that you cannot see it.
No parameters.
upgrade_plan#
Upgrade plan read-only
Change this account's SUBSCRIPTION plan (admin only). Call with no argument to list the plans (id · monthly price · monthly credits); call again with `plan` set to a plan id. A NEW subscriber gets a ready-to-pay Stripe Checkout URL to hand your human — THEY pay on Stripe (agents never spend money directly). If the account already has a paid plan, or you're DOWNGRADING, the change is made by a person in the app (Settings → Billing) and the tool returns exactly what to do. Members (read-only billing) get an honest 'ask an admin' message. Nothing is charged until your human pays.
| Parameter | Type | Description |
|---|
plan | string | the plan id to move to (e.g. pro) — omit to list the available plans first |
period | "mo" | "yr" | billing cadence — monthly (default) or yearly (2 months free) |
set_auto_reload#
Set auto-reload
Turn automatic credit reloads on or off (admin only): when the balance drops below a threshold, the card on file is charged for a top-up pack — SERVER-SIDE, even with no app open. Requires a saved card, added once in the app at first checkout/top-up; if there's none the tool tells you exactly where to add it. After that one-time card setup, agents can manage auto-reload, top-ups and plan links fully. Members (read-only billing) get an 'ask an admin' message.
| Parameter | Type | Description |
|---|
enabledrequired | boolean | true to turn auto-reload on, false to turn it off |
thresholdCredits | integer | reload when the balance drops below this many credits |
reloadCredits | integer | how many credits to add each reload — must match a credit pack size (see buy_credits) |
list_brands#
List brands read-only
List every brand on this account (id + name) and which one this connection currently acts on, PLUS any brand another account shared with you (a team workspace). Multi-brand accounts: call this, then use_brand to switch. A SHARED workspace is switched into the SAME way — pass its name or the profile id printed here to use_brand. If a brand looks empty (no connected accounts, no Library) when the app shows it full, you are almost certainly acting on a different workspace: call this first. Read-only, free.
No parameters.
use_brand#
Switch brand
Pin which brand this connection acts on (multi-brand accounts). Pass the brand id or exact name from list_brands. Works for a brand on your own account AND for a workspace another account SHARED with you — for a shared one pass its name or the profile id list_brands prints, and access is verified against your real membership before it is pinned. Persists for this API key until changed, on every surface (hosted connector included — no environment variables, no restart).
| Parameter | Type | Description |
|---|
brandrequired | string | brand id (e.g. default / p_xxx), its exact name from list_brands, or the profile id of a workspace shared with you |
BRAND WORKSPACE LIFECYCLE
create_brand#
Create a brand workspace
Add a NEW brand workspace (a separate brand/client on this account) and switch to it. Each workspace has its OWN brand profile, memory, swipefile, Library, avatars, skills, playbooks and connectors — nothing leaks between them. Use this for a second brand or a new client; use draft_brand to FILL a workspace, and update_brand to edit one. Re-running with the same name returns the existing workspace instead of a duplicate. Free (the ~50-credit research cascade only starts when you then run draft_brand).
| Parameter | Type | Description |
|---|
namerequired | string | the brand / client name for the new workspace |
activate | boolean | switch this connection to the new brand (default true) — everything you do next scopes to it |
delete_brand#
Delete a brand workspace destructive
PERMANENTLY delete a brand workspace and EVERYTHING in it — brand profile, memory, swipefile, Library creations, generated assets, avatars, skills, playbooks, chats — and disconnect its connected accounts. Irreversible, and it applies to everyone the workspace is shared with. Call it WITHOUT confirm first: it reports exactly what that workspace holds. Show the user that inventory verbatim, get an unambiguous yes, then call again with confirm:true — plus, if the workspace is not empty, confirmName set to its exact name and confirmConnectors set to the number of connected accounts it reported. Those two exist because confirming INTENT does not prove you picked the right WORKSPACE, and a wrong target is how a live brand was destroyed. The account's FIRST/anchor brand cannot be deleted this way (it holds the workspace's root storage) — that one is replaced from the app.
| Parameter | Type | Description |
|---|
brandrequired | string | brand id or exact name from list_brands |
confirm | boolean | REQUIRED true — this destroys the whole workspace and cannot be undone |
confirmName | string | the workspace's EXACT name, required when it is not empty — copy it from the inventory this tool returned, after the user has agreed to it |
confirmConnectors | number | the number of connected accounts the inventory reported, required when there is at least one — the user must specifically agree to losing them, because reconnecting each needs a browser and no agent can do it |
workspace management: Memory / Skills / Employees / Brand /…
save_skill#
Save a skill
Save a reusable custom SKILL — a named creative directive/playbook applied to future ads (a hook formula, a UGC recipe, a compliance rule, “our founder-story style”). Distill an imperative, self-contained directive. Merges into the workspace Skills library (list_skills shows built-ins + your custom skills).
| Parameter | Type | Description |
|---|
namerequired | string | short skill name, e.g. “Founder-story hook” |
directiverequired | string | the full instruction the skill applies when used (1–6 sentences, imperative) |
delete_skill#
Delete a custom skill destructive
Delete one of the workspace’s CUSTOM skills by id (from list_skills). Built-in skills/recipes can’t be deleted. Minor + re-creatable, so no confirm needed.
| Parameter | Type | Description |
|---|
idrequired | string | the custom skill id (from list_skills) |
list_memory#
List memory read-only
List the durable facts & preferences saved in this workspace’s Memory (what the studio remembers about the brand, audience, taste, and do/don’t rules) — the same Memory the web app shows. These shape every future ad. Read-only, free.
| Parameter | Type | Description |
|---|
category | string | filter to one bucket (Brand/Audience/Taste/Do/Don’t/Preference) |
limit | number | max items (default 50, max 200) |
remember#
Remember a fact
Save a durable fact or PREFERENCE about the brand, audience, or the user’s creative TASTE (e.g. “audience is first-time homebuyers”, “prefers bold lime accents”, “always captions off”) into the workspace Memory so it shapes FUTURE ads. For lasting things, not one-off requests. Merges into the existing Memory (never overwrites); de-dupes on identical text.
| Parameter | Type | Description |
|---|
textrequired | string | the fact/preference, concise |
category | string | short bucket: Brand, Audience, Taste, Do, Don’t, or Preference (default General) |
forget#
Forget a memory destructive
Delete a saved Memory item by its id (from list_memory). Records a cross-device delete so it doesn’t come back. Minor + re-creatable (you can remember it again), so no confirm needed.
| Parameter | Type | Description |
|---|
idrequired | string | the memory item id (from list_memory) |
SWIPEFILE
list_swipefile#
List the swipefile read-only
List this workspace's SWIPEFILE — the saved-ad research board: every named collection and the ads/creatives kept in it (advertiser, headline, body copy, media URL, platform, when it was saved, and any taste tags). The SAME board the web app's Swipefile tab shows. Use it to answer "what have we saved?", to mine the user's own taste before planning an ad, or to find a reference to remix. Read-only, free.
| Parameter | Type | Description |
|---|
collection | string | only list ads in this collection (by name or id) — omit for every collection |
limit | number | max ads to return (default 50, max 500) |
save_to_swipefile#
Save ads to the swipefile
Save one or more ads/creatives to a named SWIPEFILE collection, creating the collection if it does not exist — the headless twin of the ♥ on every ad card in the web app. Use it whenever research turns up something worth keeping: a competitor ad from search_meta_ads / pull_competitor_ads, an organic post, or one of your own renders. Saved ads persist to the workspace board the web Swipefile tab shows, and feed the taste signal every future ad is planned against. De-dupes: re-saving the same ad (same key/link/media) MOVES it into the named collection instead of duplicating it. Free.
| Parameter | Type | Description |
|---|
collectionrequired | string | the collection name — an existing one, or a new one to create |
itemsrequired | object[] | the ads to save |
PLAYBOOKS
list_playbooks#
List playbooks read-only
List the PLAYBOOKS saved in this workspace — the reusable strategy cards (winning hooks, angles, formats and the concrete plays to run) kept from teardowns, angle mining and creatives worth repeating. The same Playbooks the web app's Playbooks tab lists. Read one before planning an ad so you re-run what already worked instead of starting cold. Read-only, free.
| Parameter | Type | Description |
|---|
limit | number | max playbooks to return (default 25, max 100) |
full | boolean | true to return every hook/angle/play in the text, not just the headline counts |
save_playbook#
Save a playbook
Save a reusable PLAYBOOK — the strategy takeaways worth re-running: the hooks that work, the angles, the formats, and the concrete plays. Use it to keep what a competitor_teardown or mine_angles just found, or to bank a creative you want to repeat. Lands in the same Playbooks library the web app lists, runs and manages. Distinct from save_skill (a directive applied to every ad) and from the swipefile (raw saved creative). Free.
| Parameter | Type | Description |
|---|
namerequired | string | the playbook headline — what it is, in a few words |
hooks | string[] | the opening hooks worth reusing, verbatim |
angles | object[] | the persuasion angles ({title, detail}) |
formats | string[] | the formats/recipes this plays best in (e.g. ugc_selfie, cinematic, static) |
plays | object[] | the concrete plays to run ({title, detail}) — the actionable half |
brand | string | which brand this is for (defaults to the workspace brand) |
source | string | where it came from, e.g. “teardown · Ridge” |
delete_playbook#
Delete a playbook destructive
Delete a saved playbook by id (from list_playbooks). Records a cross-device delete so it does not come back on the next sync. Minor + re-creatable, so no confirm needed.
| Parameter | Type | Description |
|---|
idrequired | string | the playbook id (from list_playbooks) |
list_employees#
List AI employees read-only
List the hireable AI Employee personas in this workspace — the built-in specialists (Short-Form Ad Strategist, UGC Scriptwriter, Product Photographer, …) PLUS any custom personas saved here, and which one is currently active. Read-only, free.
No parameters.
save_employee#
Save an AI employee
Create a custom AI Employee persona for this workspace — a named specialist with a role + a DIRECTIVE that frames how the studio behaves while it’s hired. Merges into the workspace Employees. Use set_active_employee to hire it.
| Parameter | Type | Description |
|---|
namerequired | string | the persona’s name (e.g. “Nadia”) |
directiverequired | string | how it should shape ads (2–5 sentences, imperative) |
title | string | job title (e.g. “Short-Form Ad Strategist”) |
pitch | string | one-line pitch |
emoji | string | an emoji badge (default ✦) |
set_active_employee#
Hire (activate) an AI employee
Set which AI Employee persona is HIRED for this workspace (by id, from list_employees) — or pass none/empty to unhire. Records the selection for the workspace so list_employees reflects it.
| Parameter | Type | Description |
|---|
id | string | the employee id to hire (from list_employees) — omit or "" to unhire |
SAVED CREATORS
list_creators#
List saved creators read-only
List this workspace’s SAVED CREATORS — the reusable on-camera cast (AI creators made here, a person pulled from a social profile, a consented photo upload). Read-only, FREE. Each entry gives the name, the PORTRAIT URL, where the portrait came from and whether a real person’s likeness consent is on file, how many extra pose plates exist, and any chosen or cloned voice. TO PUT ONE IN A FINISHED AD, pass their id or name as render_ad’s `creator` — that casts them for the whole spot (and skips the character-portrait render, so it costs less than not casting anyone). THE PORTRAIT URL IS THE REUSE HANDLE for the raw lanes — pass it as generate_avatar’s `image` (a talking clip of them), generate_video’s `refImage` (they star in the scene), recast_motion’s `image` (they perform a reference clip’s motion), or generate_image’s `refImages`. CALL THIS BEFORE OFFERING TO GENERATE A NEW PERSON: re-casting somebody the workspace already has keeps the SAME face across every ad, while a fresh person costs credits and breaks that continuity. An empty answer means the workspace genuinely has no cast yet — say so and offer generate_avatar / save_creator, never invent a roster.
| Parameter | Type | Description |
|---|
limit | number | max creators to return (default 24) |
save_creator#
Save a creator
Add a portrait to this workspace’s reusable CAST so the SAME person can star in future ads — the headless twin of the app’s + ▸ Pick a creator ▸ save. Pass the portrait’s public url (a generate_image render of a person, a headshot, any public photo) plus a name to call them by; from then on list_creators returns them and their url can be re-passed to generate_avatar / generate_video / recast_motion. Saving is FREE and renders nothing. LIKENESS — `source` says what the portrait IS: leave it "generated" for an AI-made person, and use "upload"/"social" ONLY for a REAL person. Pass consented:true only when the user has told you that person agreed to their likeness being used; never assert that on their behalf.
| Parameter | Type | Description |
|---|
namerequired | string | what to call this creator (e.g. “Sarah”) — list_creators and the app’s picker match on it |
imagerequired | string | public https url of the portrait (an existing render’s url, or any public photo). Not a local file path — upload it with upload_file first and save the url that returns |
source | "generated" | "upload" | "social" | "generated" (default) = an AI-made person; "upload" / "social" = a REAL person |
consented | boolean | REAL people only: the user has confirmed that person consented to their likeness being used in ads |
voice | string | a default voice name for this persona (engines + voices are in hermoso_capabilities) |
poses | string[] | up to 4 extra full-body / angle plates of the SAME person (public urls) — they make a wider shot hold the identity |
look | string | their canonical wardrobe/appearance in words — reused to hold the look steady across ads |
delete_creator#
Delete a creator destructive
Remove a saved creator from this workspace’s cast by id (from list_creators). Records a cross-device delete so they don’t reappear on the user’s other devices. It only drops the roster entry — ads already rendered with that person are untouched — and the same portrait can be saved again with save_creator, so no confirm is needed.
| Parameter | Type | Description |
|---|
idrequired | string | the creator id (from list_creators) |
update_brand#
Update brand fields
Patch SPECIFIC fields of the workspace brand profile (name, domain, sells, summary, category, audience, positioning, voice, style, goal) WITHOUT overwriting the rest — a read-modify-write on the saved brand. Use for “change our voice to playful”, “we sell to dentists now”. To onboard a brand from scratch, use draft_brand. Only pass the fields you’re changing.
| Parameter | Type | Description |
|---|
name | string | |
domain | string | website domain |
sells | string | what the brand sells |
summary | string | one-line description |
category | string | |
audience | string | |
positioning | string | |
voice | string | brand voice/tone |
style | string | visual style — palette, typography, aesthetic |
goal | string | current marketing goal |
store_get#
Read a workspace store read-only
Read one of this workspace’s data stores by key, for visibility into what the app holds — playbooks, swipefile, saved locations, avatars, creations, chats, brand, memory, skills, employees. Read-only, free. Allowed keys: heist.memory.v1, heist.skills.v1, heist.employees.v1, heist.playbooks.v1, heist.avatars.v1, heist.locations.v1, heist.chats.v1, heist.creations.v1, heist.assets.v1, heist.brand.v1, adInspo.swipefile.v1. (The typed tools — list_memory / list_skills / list_employees / get_brand — are friendlier for those; use store_get for the rest.)
| Parameter | Type | Description |
|---|
keyrequired | string | the store key to read (one of the allowlisted keys) |
limit | number | max array items to return (default 50) |
APP SETTINGS
get_settings#
Read app settings read-only
Read this account's app settings — the LANGUAGE Hermoso writes ads, copy and answers in, the app appearance (theme), and whether the weekly competitor-watch email is on. Same settings as the web app's Settings pane. Read-only, free.
No parameters.
update_settings#
Change app settings
Change this account's app settings. language = the language EVERY ad, script, plan and answer is written in from now on (say the language in plain English, e.g. "German", "Japanese", "Brazilian Portuguese") — it applies to renders made over MCP as well as in the app. theme = the app's appearance, "dark" or "light". watchEmail = the weekly competitor-watch email on/off. Only pass what you are changing. Account-wide (every brand), and it takes effect on the next call.
| Parameter | Type | Description |
|---|
language | string | language for generated ads, copy and answers — e.g. "English", "German", "Japanese" |
theme | "dark" | "light" | app appearance |
watchEmail | boolean | weekly competitor-watch email on/off |
list_connectors#
List connectors read-only
List the third-party accounts connected to this workspace (Meta, Google Ads, Google Drive/Sheets/Docs, YouTube, LinkedIn, OneDrive, Slack, …) — provider, status and the connected account label — PLUS which providers are available to connect. Read-only, free.
No parameters.
CONNECTOR WRITES
list_connector_accounts#
List a connector’s accounts read-only
Show every identity a connected account can act as, and which ones this BRAND is currently allowed to use — Facebook Pages + Instagram + Meta ad accounts, Google Ads customers, LinkedIn company Pages (and the personal profile), Pinterest ad accounts, Microsoft Advertising accounts. One person often administers several; only the ticked ones can be posted to or spent from. Call this before set_connector_accounts, and let the USER pick — never guess. Providers: meta, google_ads, linkedin, pinterest, linkedin_ads, reddit_ads, microsoft_ads, google_business. Read-only, free.
| Parameter | Type | Description |
|---|
providerrequired | "meta" | "google_ads" | "linkedin" | "pinterest" | "linkedin_ads" | "reddit_ads" | "microsoft_ads" | "google_business" | which connector’s accounts to list |
set_connector_accounts#
Choose which accounts a brand may use
Set WHICH of a connector's accounts this brand is allowed to post to and spend from — Facebook Pages / Instagram / Meta ad accounts, Google Ads customers, LinkedIn company Pages (and the personal profile), Pinterest or Microsoft Advertising ad accounts. Pass ids from list_connector_accounts. This REPLACES the current selection: anything you leave out is un-shared, and an EMPTY list shares nothing (publishing then refuses — it fails closed by design, and the server re-verifies every id against the live connection, so an id the account cannot actually reach is rejected rather than saved). Ask the user which accounts they mean; posting as the wrong Page is a public mistake. Providers: meta, google_ads, linkedin, pinterest, linkedin_ads, reddit_ads, microsoft_ads, google_business. Free.
| Parameter | Type | Description |
|---|
providerrequired | "meta" | "google_ads" | "linkedin" | "pinterest" | "linkedin_ads" | "reddit_ads" | "microsoft_ads" | "google_business" | which connector to scope |
accountIdsrequired | string[] | the ids (from list_connector_accounts) this brand may use — an empty array shares nothing |
disconnect_connector#
Disconnect a connected account destructive
Disconnect a third-party account from this workspace (Meta, Google Ads, Google Drive/Sheets/Docs, YouTube, TikTok, LinkedIn, X, Reddit, Pinterest, Google Business, Microsoft Advertising/OneDrive, Slack, …). This revokes our access at the provider and drops the stored credentials, so every tool for that provider stops working immediately and posts/campaigns already published are NOT affected. RECONNECTING NEEDS A BROWSER (the provider's consent screen) — an agent cannot undo this. Name the provider to the user, then call with confirm:true. Use list_connectors for the exact provider ids.
| Parameter | Type | Description |
|---|
providerrequired | string | provider id exactly as list_connectors reports it, e.g. "meta", "google_ads", "youtube", "linkedin" |
confirm | boolean | REQUIRED true — reconnecting needs the user's browser |
list_team#
List team members read-only
List the members of the current brand workspace — email, role (admin/member) and status. Read-only, free.
No parameters.
invite_member#
Invite a teammate
Invite someone to this brand workspace by email (role: member = read-only on billing, admin = full). This SENDS a real email invite / share link — an account change. Confirm the exact email + role with the user, then call with confirm:true.
| Parameter | Type | Description |
|---|
emailrequired | string | the invitee’s email |
role | "member" | "admin" | default member |
confirm | boolean | REQUIRED true — this invites a real person |
remove_member#
Remove a teammate destructive
Remove a member from this brand workspace by email — they lose access (you can re-invite them later). Confirm the exact person with the user, then call with confirm:true.
| Parameter | Type | Description |
|---|
emailrequired | string | the member’s email |
confirm | boolean | REQUIRED true |
set_role#
Change a teammate’s role
Change a workspace member’s role — admin (full access incl. billing) or member (read-only on billing). A privilege change: confirm the exact person + new role with the user, then call with confirm:true.
| Parameter | Type | Description |
|---|
emailrequired | string | the member’s email |
rolerequired | "admin" | "member" | the new role |
confirm | boolean | REQUIRED true |
list_jobs#
List render jobs read-only
List the most recent render jobs + how many are currently running, so you can report on or resume in-flight work.
No parameters.
error triage
list_errors#
List errors users hit read-only
The errors actually recorded against this workspace, GROUPED by fingerprint — the same failure at the same call site is one row with a hit count and first/last seen, sorted defects-first. Each row says whose side it is: `ours` (a defect worth fixing), `user` (a refusal we deliberately authored, e.g. not-connected or out-of-credits), or `unknown` (a vendor 4xx we cannot attribute — never guessed). Free text, tokens, emails and creative are redacted before anything is stored, so an input echo shows shapes and lengths, not content. Filter by surface (http/mcp/agent/job/client) or kind. Read-only, 0 credits. Scoped to your own workspace; an operator whose client carries the admin key sees every account.
| Parameter | Type | Description |
|---|
kind | "ours" | "user" | "unknown" | 'ours' = a defect; 'user' = a refusal we authored; 'unknown' = we could not tell |
surface | "http" | "mcp" | "agent" | "job" | "client" | where it happened: http (an API route), mcp (an agent tool), agent (the in-app Studio agent), job (an async render/publish), client (a browser crash) |
since | string | ISO timestamp — only groups last seen at or after this |
limit | number | how many groups to return (default 50, max 200) |
error_detail#
Error detail read-only
One error group in full by fingerprint (from list_errors): every field, plus the most recent redacted occurrences — status, connector, job id, workspace, and a shape-only echo of the inputs. This is what makes a bug reproducible. Read-only, 0 credits.
| Parameter | Type | Description |
|---|
fingerprintrequired | string | the `fp` value from list_errors |
brand onboarding
get_brand#
Get saved brand read-only
What Hermoso ALREADY KNOWS for this account/workspace — the same saved brand profile (products, logos, palette, positioning) + learned memory the web Studio uses. Call this FIRST: if hasBrand is true you can omit brand everywhere; if false, onboard with draft_brand. 0 credits.
No parameters.
draft_brand#
Draft brand profile
Onboard a brand profile — from a website domain, a free-text description, or a social handle — into a {name, products, logo, …} object you can pass to plan_ad / generate. 0 ScrapeCreators credits. IMPORTANT: a domain can resolve to a DIFFERENT company than intended (e.g. bala.com is an engineering firm, not the Bala fitness brand at shopbala.com). Before spending any credits on research or renders, VERIFY the returned `name` (and `summary`) match the brand the user meant; if it looks wrong, re-draft with the correct domain or a description (pass save:false until confirmed) — this tool cannot ask the user, so the caller owns that check.
| Parameter | Type | Description |
|---|
domain | string | a website to scrape |
description | string | a free-text brand description (no website) |
socialHandle | string | a social handle to draft from (influencers/creators) — pair with platform |
platform | string | platform for socialHandle (instagram/tiktok/…) |
save | boolean | save as the workspace’s brand (like Studio onboarding) so plan_ad/create use it automatically. Default: saves only when NO brand is saved yet; pass true to overwrite, false to never save |