Templates let you package an agent configuration for reuse or sharing. This guide walks through creating a template, testing it by deploying your own agent, and optionally submitting it to the marketplace.
Reference Template Clone this starter repo to create your own template.
Clone the Starter
Fork or clone the reference template to get started:
git clone https://github.com/PinataCloud/agent-template my-template
cd my-template
Your repository should have this structure:
manifest.json # Agent config with all options
README.md # Description shown in marketplace listing
workspace/
BOOTSTRAP.md # First-run conversation guide (self-deletes after setup)
SOUL.md # Agent personality and principles
AGENTS.md # Workspace conventions, memory system, safety rules
IDENTITY.md # Agent name, vibe, emoji (filled in during bootstrap)
USER.md # Notes about the human (learned over time)
TOOLS.md # Environment-specific notes
HEARTBEAT.md # Periodic tasks (empty by default)
The manifest defines your agent’s identity, required secrets, skills, and behavior. It includes a _docs block documenting every field.
Section What it does agentName, description, vibe, emoji modelDefault AI model secretsEncrypted API keys and credentials skillsAttachable skill packages — use CIDs or ClawHub slugs (max 20) tasksCron-scheduled prompts (max 20) scriptsLifecycle hooks — build runs after git push, start runs on agent boot routesPort forwarding for web apps/APIs (max 10) channelsTelegram, Discord, Slack configuration templateMarketplace listing metadata
Remove the _docs block before submitting to the marketplace.
Example
{
"version" : 1 ,
"agent" : {
"name" : "TradeBot" ,
"description" : "Crypto trading assistant with market analysis" ,
"emoji" : "📈" ,
"vibe" : "Professional and data-driven"
},
"template" : {
"slug" : "tradebot" ,
"category" : "trading" ,
"partnerName" : "Your Name" ,
"tags" : [ "crypto" , "defi" , "alerts" ]
},
"secrets" : [
{
"name" : "COINGECKO_API_KEY" ,
"description" : "API key from coingecko.com/api" ,
"required" : true
}
],
"scripts" : {
"build" : "npm install && npm run build" ,
"start" : "node dist/server.js"
},
"skills" : [
"@pinata/api"
],
"routes" : [
{ "path" : "/dashboard" , "port" : 3000 , "protected" : false }
]
}
Customize Workspace Files
Files in workspace/ are copied to the agent’s workspace on deploy. Customize these to define your agent’s personality and behavior:
File Purpose BOOTSTRAP.mdFirst-run conversation guide (self-deletes after setup) SOUL.mdAgent personality and principles — customize this AGENTS.mdWorkspace conventions, memory system, safety rules IDENTITY.mdAgent name, vibe, emoji (filled in during bootstrap) USER.mdNotes about the human (learned over time) TOOLS.mdEnvironment-specific notes HEARTBEAT.mdPeriodic tasks (empty by default)
Focus on SOUL.md to give your agent a distinct personality, and BOOTSTRAP.md if you want a custom onboarding flow.
Add Web App Support (Optional)
If your agent runs a server, API, or frontend dev server, add two things to manifest.json:
scripts — lifecycle hooks that install deps and start the server
routes — port forwarding rules that expose the server to the internet
Example from a Vite + React agent:
{
"scripts" : {
"build" : "cd workspace/projects/myapp && npm install --include=dev" ,
"start" : "cd workspace/projects/myapp && npx vite --host 0.0.0.0"
},
"routes" : [
{ "port" : 5173 , "path" : "/app" , "protected" : false }
]
}
Important details:
build — Runs once after deploy or git push (e.g. npm install, compile). Executes from /home/node/clawd. Output logged to /tmp/user-build.log. Max 5 min timeout. If build fails, start does not run.
start — Launches a long-running background process after build completes (e.g. a web server). Executes from /home/node/clawd. Output logged to /tmp/user-start.log. Runs detached so it survives the runner exiting.
Retry scripts — If you need to re-run the build/start lifecycle (e.g. after pushing changes), use the Retry Scripts option in your agent’s settings or call the API endpoint.
Your server must bind to 0.0.0.0 , not localhost, or it won’t be reachable
Set protected: false for public routes, or true (default) to require auth
Use __AGENT_HOST__ as a placeholder in config files — it gets replaced at runtime with the agent’s public hostname
For WebSocket/HMR setups (e.g. Vite), connect via WSS on port 443 through __AGENT_HOST__
Example Vite config using the host placeholder:
export default defineConfig ({
base: "/app" ,
server: {
host: "0.0.0.0" ,
allowedHosts: [ "__AGENT_HOST__" ],
hmr: {
host: "__AGENT_HOST__" ,
protocol: "wss" ,
clientPort: 443 ,
},
} ,
}) ;
Deploy From Your Template
You can deploy an agent from your template before submitting it to the marketplace. This lets you test and iterate on your template.
Via the UI:
Go to agents.pinata.cloud/agents and click Create Agent
Select Start from a Template
Paste your public repository URL (GitHub or GitLab)
Complete the setup flow and deploy
Via the CLI:
pinata agents create --template https://github.com/you/my-template
Push changes to your repo and redeploy to test updates. Once you’re happy with your template, you can optionally submit it to the marketplace.
Submit to Marketplace (Optional)
Share your template with the community by submitting it for review.
Via the UI:
Go to agents.pinata.cloud/templates/submit
Enter your public repository URL
Click Validate to check for required files
Review the parsed manifest and workspace files
Click Submit to send for review
Via the CLI:
# Validate your repo
pinata agents templates validate https://github.com/user/my-template
# Submit for review
pinata agents templates submit https://github.com/user/my-template
# Submit from a specific branch
pinata agents templates submit https://github.com/user/my-template --branch develop
Template status progression:
draft → pending_review → published (or rejected )
Managing Submissions
Track and update your templates in My Templates or via CLI:
# List your submissions
pinata agents templates mine
# Update (re-pull from repo)
pinata agents templates update < template-i d >
# Archive a submission
pinata agents templates delete < template-i d >