tools/list on a live connection is always the authoritative answer; this page documents the same set in a form a person can read.
The model behind the names: a workspace holds agents (the brains: knowledge, images, identity) and projects (the sites: the public address, the brand, the pages). A page lives inside a project and names the agent that answers on it. Several pages may share one agent; that is the point: one brain, several campaigns. The widget site key belongs to the agent too: embedding is the code surface of the brain, and needs no project and no published page.
Agents
list_agents
Every agent of the workspace with its name, its identity and its content policy. Start here: the ids it returns are what create_page and the knowledge tools take.
No arguments. Read-only. Scope: landings:read.
get_agent
One agent in full: identity (who it speaks for), content policy, timestamps.
Read-only. Scope:
landings:read.
create_agent
Creates a brain. Do this before creating pages for a new audience, but prefer reusing one agent across several pages over one agent per page: every agent is an independent knowledge corpus with its own vectors and its own plan slot.
Scope:
landings:write.
update_agent
Edits an agent’s name, identity or content policy. Partial: an absent field is left alone. Editing the identity changes every page this agent answers on.
The retired chrome field is refused with the fix named: the navbar and footer belong to the project brand now (set_chrome).
Scope:
landings:write.
delete_agent
Scope:
landings:write.
Site keys
create_site_key
Issues the public widget key (wdy_site_…) for an agent: the credential the embed SDK ships inside a customer’s HTML. It identifies the agent and authorizes nothing (the anti-abuse stack and the origin allowlist protect the public endpoint), so it is safe to paste into a page. This is the only response that carries the full key; listings show a prefix. The embed needs no project and no published page.
Scope:
landings:write.
list_site_keys
Every live widget site key of the workspace: which agent it embeds, its display prefix (wdy_site_…, never the full key) and the origins allowed to frame it. Use it to find the key to rotate, or to check which origins an embed will accept before a customer pastes the snippet.
No arguments. Read-only. Scope: landings:read.
rotate_site_key
Issues a new full key for an existing site key and answers with it; this is the one other place a full key appears. The old key keeps working for 24 hours so loaders already embedded in customer pages do not break; redeploy the snippet within that window. Rotation keeps the agent and the allowed origins as they are.
Scope:
landings:write.
revoke_site_key
Kills a widget site key immediately: the embed it powers stops answering on the very next turn, with no grace window (unlike rotation). The row is kept for the audit trail. Use it when a key leaked or an embed should come off a customer’s page for good; to swap a key without a gap, rotate instead.
Scope:
landings:write.
Projects
list_projects
Every site of the workspace, with its id, its name and its slug, the public address <slug>.wondeya.app every published page of the site shares. The ids it returns are what create_page and list_pages take as projectId. The brand, the appearance and the domains belong to the project too.
No arguments. Read-only. Scope: landings:read or projects:read; either opens it.
create_project
Creates a new site: a public address of its own, its own pages, its own brand and its own domains. slug is optional: omitted, it is derived from the name, and either way a collision is refused with an available neighbour in errors[], never repaired in silence. Plans cap how many sites a workspace holds: over the ceiling this answers the same 402 wondeya.billing.limit_reached the console turns into an upgrade path. The site is born empty; give it a page with create_page.
Scope:
projects:write.
update_project
Edits the site’s label (what the console shows) and its SEO infrastructure: the robots.txt policy, third-party analytics ids, and extra sitemap URLs. SEO describes how each setting surfaces on the site. The public address never moves here: that is set_project_address, a different act with different consequences.
Scope:
projects:write.
regenerate_llms_txt
Rebuilds the site’s English llms.txt now from its facts and its real published routes, and stores it, served at <domain>/llms.txt. Links are grounded to real routes, so it never invents a page. Fail-soft: with no model provider, or on a refusal, the previous file is kept. Returns the updated project.
Scope:
projects:write.
set_project_address
Moves the site to a new public address. The old name becomes a redirect that 308s every path to the new address and stays taken (for everybody, this site included) until its owner releases it with release_project_address. Idempotent on the current slug; collisions refuse exactly like create_project.
Scope:
projects:write.
list_project_domains
Every name the site answers on: its subdomain, any redirect a re-address left behind (with the hostId that release_project_address takes), and its custom domains with their verification challenge and certificate state.
Read-only. Scope:
landings:read or projects:read.
release_project_address
Removes one name of the site: the disconnect of the domains screen. On a redirect row it stops the 308 and frees the name for anybody, including strangers, to claim; on an active custom domain it disconnects a name that is currently serving. Destructive, and deliberately under the domains scope: dropping a live name is that surface’s permission.
Scope:
domains:write.
delete_project
Deletes the site, whole and for real: every page goes with its host rows, and the address is freed. The agent, its knowledge, its images and its widget site keys survive; they were never part of the site. Deleting the only project is allowed (“start my site over”). Answers how many pages went. Destructive.
Scope:
projects:write.
Pages
list_pages
Every page of the workspace (or of one site, when projectId is given), newest first, with its status (draft or published), its path under the site host, its languages, the projectId of the site it lives in and the agentId of the brain that answers on it. The ids it returns are what every other page tool takes.
Read-only. Scope:
landings:read.
get_page
One page in full. Use it to confirm the result of a write, for example that status really became published, or that the editorial reads the way it was sent.
Read-only. Scope:
landings:read.
create_page
Creates a page inside a site. It is born a draft and answers nobody: creating it puts nothing online. An agent page (the default) is conversational: what it says in chat comes from its agent, so create the agent first (or reuse one). A document page (a privacy policy, terms) renders an uploaded markdown body, with no agent and no editorial.
Scope:
landings:write.
update_page
Edits a page’s settings (name, address, which agent answers on it, its source language), its editorial or body, its SEO metadata and its sitemap hints. Partial: an absent field is left alone. The kinds guard their fields: an agent page refuses body, and a document page refuses editorial and agentId.
Who the agent speaks for is not here; that is
update_agent, so that editing it changes every page the agent serves. Publishing is not here either. Scope: landings:write.
publish_page
The single act that opens a page to the world: after it, the page is reachable at its public address and its agent answers visitors. Check the knowledge is ready first, because a page published with nothing to say answers nothing. A page outside / cannot be published while nothing serves the home page.
Scope:
landings:write.
unpublish_page
Takes a page off the public surface on the next request. This is the tool to reach for when an agent is saying something wrong in the business’s name. Nothing is deleted, and it can be published again. The home page cannot be withdrawn while other pages of the site are published.
Scope:
landings:write.
delete_page
Scope:
landings:write.
translate_page
Schedules a translation of one page’s editorial fields and its cover into every language of its site the owner has not written by hand. (The agent’s display copy is not a page field; it is composed and translated on the agent, in the languages the agent itself speaks.) Only what is missing or machine-written-and-outdated is touched: a language a human typed is never overwritten, even when the source moved. It answers as soon as the job is scheduled, not when it is done; the translated copy lands on the page seconds later and the served site revalidates itself. It fills gaps rather than overwriting, so it is safe to call again, at the cost of a handful of model calls per missing language.
Scope:
landings:write.
Knowledge
list_knowledge_sources
Everything the workspace has taught its agents (uploaded documents, crawled URLs and curated claims), with each source’s ingestion status, how many passages it produced, and any error. Poll this after adding knowledge: a source only affects answers once its status is ready.
Read-only. Scope:
knowledge:read.
upload_knowledge_text
Ingests a document written as text or Markdown, such as a price list, an FAQ, a service description or a policy. Headings are preserved, so ## Pricing becomes a section retrieval can cite.
Answers immediately with the source in
pending; parsing, chunking and indexing happen on a queue. Scope: knowledge:write.
add_knowledge_url
Points the knowledge base at a public page. http/https only; private, loopback and link-local addresses are refused, and every redirect hop is re-checked.
Answers with the source in
pending; the page is fetched on a queue, never on this call. Scope: knowledge:write.
upsert_knowledge_claim
A claim is one short statement the business approved, written by hand in both languages so it is never machine-translated in front of a visitor: a guarantee, a price, an opening time. Prefer it over a document when the exact wording matters.
Saving re-indexes it, so the next conversation already sees it. Scope:
knowledge:write.
delete_knowledge_source
Answers with what was removed. Scope:
knowledge:write.
list_knowledge_topics
The managed topic taxonomy of an agent: every topic with its stable slug, its title, the English description that steers which topics an answer draws on, whether it was written by enrichment (auto) or edited by a person (manual), and how much material sits under it. A high chunk count is the signal a topic grew too broad to summarize well. Read this before editing, merging or deleting: the slugs it returns are what those tools take.
Read-only. Scope:
knowledge:read.
update_knowledge_topic
Renames a topic or rewrites the English description that steers topic selection at answer time. Editing either field stamps the topic manual, and enrichment never overwrites it again. The slug never changes; consolidating two slugs is a merge, not a rename.
Scope:
knowledge:write.
merge_knowledge_topics
Folds one topic into another: every source and chunk tagged fromSlug is re-tagged intoSlug, then fromSlug is deleted. It is the way to fix a near-duplicate enrichment coined beside an existing topic (for example prices beside pricing). Both slugs must exist and differ.
The material is re-tagged, never lost, but the tool is flagged destructive (clients ask for confirmation) because deleting
fromSlug has no undo. Scope: knowledge:write.
delete_knowledge_topic
Removes a topic from the taxonomy: the row is deleted and the slug is pulled from every source and chunk. The material is kept (a passage left with no topics simply becomes universal, matched by every question), so this never makes an agent forget a document; it only removes a way of routing to it. To delete the material itself, use delete_knowledge_source.
Answers with how much material lost the tag. Flagged destructive (clients ask for confirmation): removing the slug has no undo, even though the material is kept. Scope:
knowledge:write.
probe_retrieval
Runs the exact retrieval a real conversation runs (the deterministic topic map plus the vector search, fused) and answers with the passages the agent would have had, without calling the model. This is how you debug a knowledge base: ask the question a visitor would ask and see whether the right passage comes back. Empty results mean the agent cannot answer that question yet.
Read-only and model-free, so it is cheap to call often. Scope:
knowledge:read.
Images
list_assets
The images an agent is allowed to show, with the stable key it emits, what each one shows (the description the planner reads to choose it), its alt text and its orientation. An image with an empty description will never be chosen.
Every
url in the result is signed and expires; never store one. Read-only. Scope: assets:read.
upload_asset
Registers an image an agent may show. PNG, JPEG, WebP, GIF or AVIF, up to 8 MiB: the bytes decide the format, not the file name. The file travels base64-encoded, and the limit applies to the decoded bytes. On upload the image is described automatically with vision (what it shows, in English, for the planner).
Scope:
assets:write.
Brand
get_brand
The project brand: the logo, its dark variant, the symbol, and the icon files every public page wears (favicon SVG/ICO, the apple-touch icon and the two PWA icons). Each slot says whether it was uploaded by the owner or generated from a master, and the hints say what is worth uploading by hand. The result also carries the site’s chrome: the navbar and footer set_chrome writes.
Every
url in the result is signed and expires; never store one. Read-only. Scope: brand:read.
upload_brand_asset
Stores one brand file and regenerates everything that derives from it. Start with logo: from one SVG or large transparent PNG the favicons, the apple-touch icon and the PWA icons are all generated; add mark (the symbol alone) if one exists, icons read better cut from it. The bytes decide the format. SVG must be clean: script, event handlers or external references are refused with each reason named.
An uploaded file is never touched by regeneration; a generated one re-derives whenever the master changes. Scope:
brand:write.
set_chrome
The navbar and footer every page of the site shares: up to 6 nav links, up to 4 footer groups of up to 8 links each, up to 8 social links, and the legal name the copyright line shows. Links are validated server-side; the model never emits free HTML or URLs onto a page.
Scope:
brand:write.
translate_chrome
Schedules a translation of the site’s chrome (navbar labels, footer titles and labels, the copyright name) into every language of the site whose texts the owner did not write. Provenance is per language for the whole chrome: a language edited by hand is skipped entirely, even when the source moved. It answers as soon as the job is scheduled; every page of the site revalidates when the translation lands. One model call per missing language.
Scope:
brand:write.
Theme
get_theme
The site’s appearance, plus the catalogue of values that may be written: the available typefaces, the allowed corner radii and the defaults. Read this before set_theme: colours must be 6-digit hex, and typefaces and radii are keys from this list.
The retired agentId argument is refused with an explanation: agents have no appearance; the look belongs to the project brand, one per site.
Read-only. Scope:
landings:read.
set_theme
Restyles the site. tokens is a partial patch merged onto the theme in force, so sending only colors.primary changes one colour and leaves the rest. Every page of the site changes together; there are no per-page or per-agent overrides.
Colours are
#rrggbb and nothing else; typefaces and radii are keys from the catalogue; anything else is refused with wondeya.theme.invalid. The retired agentId argument is refused, never reinterpreted. Scope: landings:write.
Usage
get_usage
How much of the product the workspace is actually using: how many pages exist and how many are published, how many knowledge sources there are by ingestion status with the passages and tokens they produced, and how many images are stored and how many bytes they take.
No arguments. Read-only. Scope: analytics:read.
Useful for answering “how big is this workspace” and for spotting knowledge stuck in failed or pending.
A working order
For an agent building a site from scratch, this order avoids the mistakes the tools cannot prevent on their own:list_agents, thencreate_agentif the list is empty: a workspace is born with no agents and no projects. Reuse an existing brain over creating one per page.update_agent: tell it who it speaks for, and which actions and links it may offer.upload_knowledge_text,add_knowledge_url,upsert_knowledge_claim: teach it.list_knowledge_sources: poll until the sources areready.upload_asset: give it something to show.probe_retrieval: ask what a visitor would ask, and check the right passage comes back.create_site_key: only if the agent will also run inside a site the business already owns. The widget needs no page and no publication; register the exact origins that may frame it.list_projects, andcreate_projectwhen none exists yet: the site and its public address.create_page: a draft inside the site; nothing is public yet.update_page: write the editorial the page opens with.get_theme, thenset_theme: restyle the site with values from the catalogue.publish_page: only now is anything public.