Templates
Let people make independent copies of an app, then choose whether to publish it in the public Template directory.
What you can do
Turn an app into a Template. People who can already view the source App can make an independent copy. Each copy has its own owner and empty storage, and can be edited as soon as Charming creates it. Changing a copy never changes the Template, and changing the Template never changes copies already made.
Publish it as Listed. A Listed Template appears in the public Template directory. Anyone can discover and copy it without gaining access to the source App or its data. Listed always includes Template. Template alone does not make an App public or let strangers copy it from a shared link.
Choose how the listing looks. Save a draft title, summary, longer Markdown description, category, cover image, and ordered screenshot gallery before publishing. A cover or screenshot needs alt text; its caption is optional. Publishing needs a nonblank title and summary. The other fields are optional.
Keep Public separate. Public opens the live App Viewer to anyone with its link. It does not make the App a Template. Template does not make the live App public. If an App is both Public and a Template, visitors open the live, read-only App and see an option to create a copy. See Privacy and sharing for the full access model.
Set what visitors see first. The owner can write a starter prompt so a visitor who clicks “Open in Claude” or “Open in ChatGPT” gets that instruction instead of the generic prompt. A fresh copy takes the current starter prompt once. Later changes to the Template do not alter existing copies.
How Templates work
For an app using the opt-in ESM contract, a new copy also requires an author eligible for that contract. Copy selects the active source and its completed server/browser output, even if a newer edit is pending or failed. If that output needs preparation under the current runner profile, the response supplies a build to inspect; no new app exists until it publishes. Repeating the request while pending returns the same build. See npm and platform imports.
Making a copy copies source and the starter prompt. Data and secrets stay on the source App. The person who copies starts with empty storage and adds their own secrets if the code needs any.
Every enabled Template has a detail page at https://charm.ing/templates/<owner>/<app-name>. Listed pages are public and search-indexable. An unlisted page at the same stable path is available only to an authorized App reader and sends noindex, nofollow, and private no-store headers.
Public owner profiles live at https://charm.ing/<handle> and show that owner’s Public Apps and Listed Templates. The same route works for people and teams. A signed-in team member normally sees Team Home at the team’s route; adding ?view=public shows the public team profile instead.
Technical
Open the App’s App settings, then choose Template. Its canonical settings path is /<owner>/~/apps/<app-name>/settings/template. Listing content can stay as a draft while Template and Listed are off.
Copy this prompt for your agent
Set up one of my Charming apps as a Template. Read
https://charm.ing/docs/capabilities/templates.md first. List my apps
and ask me which one, then ask whether its current viewers should be
able to copy it or whether I want to publish a public listing. If I
choose a listing, help me prepare its required title and summary plus
any optional detail and media, then give me its canonical Template URL.
How an agent performs this job
Call set_template with { app_id } to enable Template. It accepts an optional listing patch with title, summary, content_markdown, category, cover_asset_key, cover_alt, cover_caption, and gallery. Each gallery item has asset_key, alt, and an optional caption. Media must use safe image assets owned by the same App, and alt text must not be blank.
Pass listed: true to apply the patch, enable Template, and publish the listing. The resulting title and summary must both be nonblank. Pass listed: false to unpublish while keeping Template enabled. Omit listed to preserve the current Listed state. Omitted patch fields also keep their current values; null clears a nullable field, and gallery: null or an empty gallery clears the gallery.
Call unset_template to disable Template and clear Listed. Existing copies keep working. The deprecated set_remixable tool accepts only app_id: it enables Template but cannot edit listing metadata and leaves the Listed state unchanged. Its deprecated unset_remixable partner has the same effect as unset_template.
set_public is a separate action that grants the live App Viewer by link. It does not enable Template or Listed. set_starter_prompt is also separate: it sets or clears the App’s chat starter prompt and does not change listing fields or state.
To find Listed Templates, call search_templates with an optional query. Results include the resolved listing title, summary, Markdown detail, category, cover, starter prompt, creator, builder count, canonical templatePageUrl, and browser copyUrl. The copy URL starts browser navigation where the visitor chooses to copy and signs in before Charming creates the owned App. It is not an MCP or REST write. After creation, find the copy with list_apps or GET /app, then read its source with get_app_source or GET /app/<id>/source.
First-party Template listing API
The session-gated resource is /api/v1/apps/{appId}/template-listing and requires app:template-edit:
| Method | Path | Effect |
|---|---|---|
GET |
/api/v1/apps/{appId}/template-listing |
Read the draft, resolved fallback values, media URLs, validation state, and Template flags. |
PATCH |
/api/v1/apps/{appId}/template-listing |
Patch draft content only. It does not enable, disable, publish, or unpublish. |
POST |
/api/v1/apps/{appId}/template-listing/enable |
Enable Template while preserving the draft and Listed state. |
POST |
/api/v1/apps/{appId}/template-listing/publish |
Require a title and summary, then enable Template and publish Listed atomically. |
POST |
/api/v1/apps/{appId}/template-listing/unpublish |
Clear Listed while preserving Template and the draft. |
POST |
/api/v1/apps/{appId}/template-listing/disable |
Disable Template and clear Listed while preserving the draft. |
The first-party API uses camelCase draft fields: contentMarkdown, cover: { assetKey, alt, caption? }, and gallery: [{ assetKey, alt, caption? }]. The older public-agent PUT /app/{id}/remixable route changes only the Template and Listed flags; use the first-party resource or set_template for listing metadata.
The contract
An owner, collaborator, or team member with app:template-edit can change Template content and state. An anonymous App must be claimed first.
Template copying requires both an enabled Template and either Listed or existing app:read access to the source App. Listed grants public discovery and copying, not app:read on the source App. It exposes neither the live App nor its data. Public grants app:read to the live hosted App Viewer but does not by itself allow a Template copy.
The App belongs to the signed-in user from creation. The copy flow creates no pre-auth App and no copy or Claim cookie. An existing copy remains in the user’s App list and opens only after they choose “Open my copy.”
Listing requires the app to already be copyable — a listed app can’t be made uncopyable without also being unlisted. Any listed app appears in the store, whether or not it’s also public (per Privacy and sharing): a public template renders the live app directly for visitors, with a “Create my copy” action in place of the usual template interstitial.
Disabling Template also unpublishes it. Unpublishing alone keeps Template enabled. Neither action removes existing copies or the saved listing draft.
An owner-facing app UI can call window.charming.remixable.set(true) or .set(false) from a Charming browser shell. It resolves with { remixable, public_url }. See Owner controls for availability and errors.
The starter prompt visitors get
Use set_starter_prompt to set or clear the prompt. A copy carries the current prompt once; later template changes do not alter existing copies.
Limits, access, and deletion
- See Limits for the starter prompt cap.
- Deleting or unlisting the source App does not remove copies already made.
- Listed pages and public owner profiles expose listing content, creator identity, and builder counts. They do not expose source App data or secrets.
Related
- Privacy and sharing: how Public, App roles, and Template access differ
- Code export: export source directly instead of using the browser copy flow
- Data storage: what does and does not carry into a copy
- How Charming works
- Browser runtime API
- Docs home
- llms-full.txt