Docs
Manifest reference
Complete field-by-field reference for the v1 manifest schema, with YAML examples and common gotchas.
On this page
- Top-level fields
- Shapes
- `landing` block
- `inputs[]`
- `file_upload`
- `url`
- `text`
- `pipeline[]`
- `ingest` — extract content from files
- `ai_generate` — LLM call with structured output
- `compute_python` — sandboxed Python script
- `render_report` — final output via Mustache template
- `review_ui` (optional)
- `pricing`
- Common gotchas
Manifests are declarative JSON documents (shown here as YAML for readability) that describe a moulds.ai agent: inputs, pipeline steps, output, and pricing. The platform runtime executes the manifest — you never ship server code for Tier-1 agents.
v2 note: Tier-2 agents use
manifest_version: 2and addruntime,package,ui.routes[], andintegrations[]. See Tier-1 vs Tier-2 for the Tier-2 workflow.
Top-level fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
manifest_version | literal 1 | yes | — | Schema version. Only 1 is accepted for Tier-1. |
slug | string | yes | — | URL-safe identifier. Regex ^[a-z][a-z0-9-]{1,62}$ — starts with a lowercase letter, then lowercase letters, digits, or hyphens. 2–63 chars. |
name | string | yes | — | Human-readable display name. 1–80 chars. |
shape | enum | yes | — | batch_analyzer or knowledge_qa. |
category | string | yes | — | Marketplace category, 1–40 chars (e.g. finance, legal, demo). |
landing | object | yes | — | Landing-page copy (see below). |
inputs | array | yes | — | Input fields the user fills. Can be [] for pure knowledge agents. |
pipeline | array | yes | — | Pipeline steps, min 1. |
review_ui | object | no | — | Optional human-in-the-loop review step. |
pricing | object | yes | — | Free trial + paid plans. |
platform_fee_pct | number | no | 15 | moulds.ai revenue share (0–100). |
integrations | array | no | [] | Integrations the agent uses (see API keys & connectors). |
Shapes
batch_analyzer— user uploads a file or URL; the agent ingests, runs AI, optionally runs Python, renders a report. Good for: receipt analyzers, contract extractors, data enrichment.knowledge_qa— user submits a text query; the agent answers from a knowledge collection (vector store) and renders the response. Good for: policy Q&A, GAAP lookup, internal wikis.
landing block
landing:
tagline: Turn receipt PDFs into a clean expense ledger # 1–140 chars
description: |
Upload a folder of receipts. We extract vendor, date, line items,
tax, and total — then output CSV ready for your bookkeeper. # 1–2000 chars
hero_image_blob: mld://blobs/agent-assets/receipts-hero.png # optional, must start with mld://inputs[]
Three kinds, discriminated by kind. All share name (snake_case, ^[a-z][a-z0-9_]{0,40}$) and required (boolean, default false).
file_upload
- kind: file_upload
name: receipts
accept: [application/pdf, image/png, image/jpeg] # required, min 1 MIME type
required: true
max_size_mb: 50 # default 25, cap 100url
- kind: url
name: source_page
required: truetext
- kind: text
name: query
required: true
multiline: true # renders a textarea, default false
max_chars: 4000 # default 2000, cap 10000pipeline[]
Ordered steps; outputs of earlier steps are available as template variables in later steps. Four step types:
ingest — extract content from files
- step: ingest
config:
extract: [text, tables] # min 1 element; each must be "text" or "tables"Use {{ingest.documents.0.text}} (not {{ingest}}) in downstream templates.
ai_generate — LLM call with structured output
- step: ai_generate
config:
model: pro # "flash" (fast/cheap) or "pro" (accurate)
prompt_template: |
Extract every line item from the receipt below.
Content: {{ingest.documents.0.text}}
output_schema:
type: object
properties:
vendor: { type: string }
total_cents: { type: integer }
items:
type: array
items:
type: object
properties:
description: { type: string }
amount_cents: { type: integer }
knowledge_collections: [] # vector-store collection IDs; required for knowledge_qa shapeStep output keys default to the step type (ai_generate, ingest, etc.). Add name: to
override if you have two steps of the same kind.
compute_python — sandboxed Python script
- step: compute_python
config:
script_blob: mld://blobs/agent-scripts/receipt-totals-v3.py # must start with mld://
packages: [pandas, numpy] # PyPI packages
timeout_sec: 90 # default 120, cap 240Upload the .py file via the builder console first, then reference the returned mld:// URI.
render_report — final output via Mustache template
- step: render_report
config:
template: |
<h1>{{vendor}}</h1>
<p>Total: {{total_cents}} cents</p>
<ul>
{{#items}}
<li>{{description}} — {{amount_cents}}</li>
{{/items}}
</ul>Max template size: 100 KB. Triple-stache {{{var}}} is banned — the renderer throws
BAD_REQUEST if it sees {{{ anywhere. Use standard {{var}} (HTML-escaped).
review_ui (optional)
Pauses the pipeline after ai_generate and shows an editable form before continuing.
review_ui:
enabled: true
fields: [vendor, total_cents] # output_schema properties to expose; [] = all fieldspricing
pricing:
free_trial:
quantity: 10 # number of free runs; 0 disables the trial
period_days: 30 # trial window length in days
plans:
- id: starter # snake_case, ^[a-z][a-z0-9_]{0,40}$
price_cents: 1900 # 1900 = $19.00
interval: month # "month" or "year"
feature: report # what the plan grants
quantity_per_period: 100
- id: pro
price_cents: 14900
interval: month
feature: report
quantity_per_period: 1000pricing.plans is required but may be [] (free-only agent). platform_fee_pct defaults to 15 (moulds.ai's revenue share from Stripe Connect).
Common gotchas
- Slug format: must match
^[a-z][a-z0-9-]{1,62}$.BadSlug!,My-Agent,1agent, and single-charaall fail. Use kebab-case:receipt-analyzer,gaap-lookup. - Identifier format:
inputs[].nameandplans[].iduse^[a-z][a-z0-9_]{0,40}$(snake_case). Hyphens are not allowed — that's slug territory. {{ingest}}vs{{ingest.documents.0.text}}:{{ingest}}is the whole result object. Use the dotted path to get the raw extracted text.- Step naming collision: if you include two
ai_generatesteps, add aname:field to each so their outputs don't overwrite each other. - Blob URIs: both
landing.hero_image_blobandcompute_python.config.script_blobmust start withmld://. HTTP URLs and bare file paths are rejected. - Pipeline order matters: a
render_reportstep that references{{vendor}}only works if a priorai_generatestep produces avendorfield. - Triple-stache banned:
{{{var}}}throwsBAD_REQUESTat render time. Use{{var}}. - Limits cheat sheet:
file_upload.max_size_mb: default25, cap100text.max_chars: default2000, cap10000compute_python.timeout_sec: default120, cap240name: 1–80 charslanding.tagline: 1–140 charslanding.description: 1–2000 charscategory: 1–40 chars