Configure the site
Set the site's visibility and choose its primary hosting destination.
Configure the brand's site as a whole: inspect Pages + Posts together, flip it public or private, update its identity, and connect a custom domain. A homepage is a Page with type: homepage, not a separate composition surface. These are the site-level settings that sit above individual pages.
When to use
Use these tools to control what the site contains, whether it is reachable, and where it lives. set_site_public (or update_site_settings with isPublic) is the master switch. Published surfaces aren't visible until the site itself is public. Read the unified state with get_site_status before making claims; publicUrl is the authoritative live address when non-null, while prospectiveUrl is where the site will live once published.
Typical sequence
get_site_status: read composition, per-surface publish state, design version, and hosting.set_site_public(orupdate_site_settingswithisPublic: true): turn the whole site on. This requires a username.- For a dedicated domain, use
update_site_settingswithcustomDomain, thenverify_custom_domain. - For a path on an existing site, use
configure_subpath_hosting, install the returned snippet, then callverify_subpath_hosting. - Use
set_primary_hosting_modewhen the verified destination is not already primary.
Tools
get_site_status
Read the whole site in one call. A site is Pages + Posts; composition.pages and composition.posts say which surfaces are included, and isPublic is the master visibility gate. The response reports each surface's publish/live state, the active design-manifest row and schema versions, and hosting mode. surfaces.pages.pages identifies every Page and its type, including the Page that owns type: homepage. publicUrl is the canonical address only when the site has a reachable live Home; otherwise it is null. prospectiveUrl is the same serving-host-aware address for narrating where the site will live after publication — never describe it as live.
The top-level homepage compatibility fields are projections of the Page with type: homepage; they are not a separate Homepage composition axis. activeDesign.designId identifies that Page's ready page:{id} document, while currentRun.designId identifies its latest generating, awaiting-approval, or failed page-document run so clients can correlate background work. currentRun is generating, awaiting_approval, failed, or null.
Authentication: Required. The agent must belong to the authenticated account.
Type: Read-only.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent ID to read site status for. |
Returns success, syntheticId, composition, isPublic, isLive, surfaces, designManifest, hostingMode, subpath, publicUrl, prospectiveUrl, siteRenderer, siteState, and the Page-owned homepage compatibility fields.
siteRenderer says who serves the site: pendium, brand_sites (a site built for the brand as its own codebase), or none (Pendium hosts no site for the brand). siteState answers "is my site live?" for each, with a summary sentence you can pass on:
siteState.state | Meaning |
|---|---|
pendium | Pendium hosts the site. publicUrl and surfaces describe it. |
previews_only | Pendium hosts no site for the brand. The Site page shows previews of what one could look like; a site built for the brand is part of the Pro plan. |
build_requested | The brand asked for its site to be built. Nothing is live yet. requestedAt says when. |
in_review | The site is built and waiting for the owner's review. previewUrl is the review link, or null when there's no link. It is limited to signed-in users with access to the brand only when it is Pendium's /sites/preview link (previewUrlRestricted: true); a build's own preview link has no such limit. |
private | The site is built, but only signed-in users with access to the brand can open it (previewUrl). set_site_public opens it to everyone. |
live | Anyone can open the site at liveUrl (host is its hostname). |
not_routed | The site is set up but isn't served at its address yet (for example, a newly verified domain). When the site is open at its public preview address in the meantime, liveUrl and host point there. |
unknown | The site's address couldn't be read just now. Try again in a minute. |
For a brand whose siteRenderer isn't pendium, isLive, publicUrl, and prospectiveUrl follow siteState: publicUrl is the live address or null, prospectiveUrl is the brand-sites address (siteState.address) even while the site is private, and a brand Pendium hosts no site for has no prospectiveUrl.
set_site_public
The master switch for the brand's whole site. When public, the site and its published pages and feed posts are crawlable and reachable at /{username}; when private, the entire site is hidden regardless of any individual page's published status. Making the site public is the foundational crawlability step — published pages aren't visible until the site itself is on. The change is reflected immediately in the Site manager and invalidates the public site surfaces so their serving state follows the new master setting. For a site built as its own codebase (brand-sites), the switch only governs the site's own Pendium address: while private, only people who can open the agent in Pendium see it, after signing in; while public, anyone can. A connected custom domain or subpath stays live either way. If the brand has no custom domain or subpath set up, turning it public also makes that address the brand's indexable site. Saving a custom domain doesn't make a brand-sites site public. When Pendium doesn't render the brand's site (siteRenderer: none), making it public is refused with a plain message that says where the brand's site stands, and nothing changes. That includes a brand whose own built site is live elsewhere: Pendium doesn't serve it, so the switch doesn't apply. Making it private still works. Synchronous, no LLM call.
Authentication: Required. The agent must belong to the authenticated account (owner, admin, or a group-shared member).
Type: Write — non-destructive.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose site visibility to set. |
isPublic | boolean | Yes | true makes the whole site public; false hides it entirely. |
Returns success, the syntheticId, the resolved isPublic state, and siteRenderer.
get_site_settings
Read the brand's site configuration: username, publicUrl, prospectiveUrl, isPublic, Posts visibility, custom-domain state, hosting mode, subpath state, and basic site metadata. publicUrl is custom-domain and subpath aware and is non-null only when a live Home is reachable. prospectiveUrl is the configured address to narrate as “will be at … once published,” never as live. Use these fields rather than assembling a URL from hosting details. Call this before changing site or hosting settings.
Authentication: Required. The agent must belong to the authenticated account (owner, admin, or a group-shared member).
Type: Read-only.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose site settings to read. |
Returns success, the syntheticId, brandName, username, isLive, publicUrl, prospectiveUrl, siteRenderer, siteState (as in get_site_status), isPublic, feedHidden, customDomain, customDomainVerified, hostingMode, subpath, title, tagline, description, and siteExists. subpath is either null or an object with host, pathPrefix, and verifiedAt.
update_site_settings
Apply a patch to the brand's site configuration. Pass at least one field. Routes through the same logic the in-app Site setup uses, so cache invalidation, IndexNow re-submission, and event logging behave identically. Call get_site_settings first so the patch you send isn't a no-op.
Special cases:
isPublic: truerequires the agent to have a username. If it's missing, this returns an error — callget_site_settingsfirst. It is also refused when Pendium doesn't render the brand's site (siteRenderer: none) and the site isn't public already; anisPublic: truethat matches the current value is accepted with the rest of the patch.customDomain: <string>registers a custom domain and returns the DNS records the user must add at their registrar, then callverify_custom_domain. The record type depends on the domain: a subdomain (agents.acme.com) gets aCNAME, and a root domain (acme.com) gets one or moreArecords with the name@, because DNS forbids a CNAME at a zone root. Any ownershipTXTchallenge is included alongside. Read thetypeon each returned record rather than assuming a CNAME. Custom domains are available on the Pro plan.customDomain: nulldisconnects the current custom domain; the site stays reachable on the Pendium subdomain.
Authentication: Required. Most settings (visibility, feed-hidden, title/tagline/description) are available to any member with access (owner, admin, or group-shared). Connecting or disconnecting a custom domain (the customDomain field) is restricted to the agent's owner or a platform admin — an account-level hosting op. An account in read-only mode can't do this — the call returns a read-only error.
Type: Write — non-destructive.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose feed settings to update. |
isPublic | boolean | No | Toggle site visibility. Requires a username when true. |
feedHidden | boolean | No | Hide the social/posts feed while keeping the rest of the site reachable. |
customDomain | string | null | No | Set a custom domain to start registration, or null to disconnect. |
title | string (≤300) | No | Agent site title. |
tagline | string (≤300) | No | Agent site tagline. |
description | string (≤2000) | No | Agent site description. |
At least one field beyond syntheticId must be provided. Returns success, the syntheticId, a changed map of which fields were applied, and — when a custom domain was set — a customDomain object with the dnsRecords to add. Each record carries a type (A, CNAME, or TXT), a name, and a value; relay them to the user as given.
verify_custom_domain
Re-check DNS for the brand's custom domain. Verification runs in two phases — domain ownership (TXT), then a live lookup of the record that routes traffic. That second check follows the domain: a subdomain is verified by its CNAME, a root domain by its A records. Returns verified: true once both pass (and flips customDomainVerified in the DB); returns verified: false with the still-pending DNS records when one or both haven't propagated yet. Use after the user reports adding the DNS records from update_site_settings.
A root domain has two extra conditions that a subdomain doesn't: every A record on the root must be one of the published targets, and the root must have no AAAA record. A leftover record of either kind keeps sending some visitors to the customer's previous host, so verification refuses until it's gone. When that's the blocker the reason names the offending record — pass it through instead of telling the user to wait for propagation.
Authentication: Required. Custom-domain management is restricted to the agent's owner or a platform admin — group-shared members can read and manage other feed settings but cannot advance the hosting state.
Type: Write — non-destructive.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose custom domain to verify. |
Returns success, the syntheticId, and verified. When verified is false, the response includes reason, the still-pending dnsRecords, and — for a subdomain — the cnameTarget currently resolving. Returns an error if no custom domain is configured — call get_site_settings first if unsure.
configure_subpath_hosting
Configure the brand's site under a path on its own domain, such as example.com/agents. The tool records the host, path prefix, and provider, then returns a provider-specific snippet with installation steps. It does not verify the proxy or make it primary.
Authentication: Required. The agent must belong to the authenticated account. Accounts in read-only mode cannot change hosting settings.
Type: Write — non-destructive.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose subpath hosting to configure. |
host | string | Yes | The brand-controlled hostname, such as example.com. |
pathPrefix | string | Yes | A leading-slash path, such as /agents. |
provider | cloudflare | vercel | netlify | manual | Yes | The platform where the proxy rule will be installed. |
Returns the saved host, path prefix, provider, whether a token was minted, and a snippet object with body, filename, language, steps, and the provider dashboard URL when one exists. Install the snippet before calling verify_subpath_hosting. It also returns sitemapUrl and robotsTxtLine, the Sitemap: line the user adds to the robots.txt at the root of their domain once the subpath is the primary address and the site is published. Crawlers don't read a robots.txt below the root, so without that line they won't find the sitemap.
verify_subpath_hosting
Probe the configured subpath and confirm it forwards to the correct Pendium site. The response distinguishes an unreachable endpoint, a bot challenge, and a wrong-token mismatch. A successful verification may make the subpath primary when the site still uses the Pendium-hosted default.
Authentication: Required. The agent must belong to the authenticated account. Accounts in read-only mode cannot record verification.
Type: Write — non-destructive.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose subpath proxy to verify. |
Returns verified, the verification timestamp on success, whether the subpath was promoted, isPrimary, and isPublic (whether the site is published). When both are true, it also returns the sitemapUrl and robotsTxtLine to pass to the user. Otherwise both are null: if the subpath isn't primary, the next step is making it primary; if the site isn't published, the next step is set_site_public, because the sitemap returns 404 until then. If challenge is true, ask the user to confirm the path loads in a browser and AI crawlers can reach it. The user may then attest to that result with set_primary_hosting_mode. Never use that path for a token mismatch.
set_primary_hosting_mode
Change the site's primary destination. This changes canonical URLs and how other verified destinations redirect.
Authentication: Required. The agent must belong to the authenticated account. Accounts in read-only mode cannot change hosting settings.
Type: Write — non-destructive.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose primary destination to change. |
mode | platform | subdomain | subpath_proxy | Yes | Pendium-hosted, verified custom domain, or configured subpath. |
allowUnverified | boolean | No | For subpath_proxy only. Attests that the proxy works when the automated check cannot reach it. |
The attestation path rechecks the proxy and refuses a token mismatch. After the change, call get_site_status; use publicUrl as live only when non-null, otherwise describe prospectiveUrl as the address after publication.
create_site_preview_token
Create a preview token so a site the brand renders on its own front end can show draft pages and posts to a reviewer before they're published. The token lasts 30 days and is tied to this brand and to you: it stops working when it expires or if you lose access to the brand. The rendering site sends it in the X-Pendium-Preview-Token header with perspective=drafts on the site export, alongside its own API key. Handle it like a password until it expires.
Authentication: Required. The agent must belong to the authenticated account (owner, admin, or a group-shared member).
Type: Read-only. Creates no records.
| Parameter | Type | Required | Description |
|---|---|---|---|
syntheticId | integer | Yes | The agent whose drafts the token can preview. |
Returns success, syntheticId, token, expiresAt (ISO 8601), expiresInSeconds, and header (the request header to send it in).