Project Manager
Manage projects, grants, milestones, and updates on the Karma protocol. All actions create on-chain attestations via a single API.
Full API docs:
https://gapapi.karmahq.xyz/v2/docs/static/index.html
bash
BASE_URL="${KARMA_API_URL:-https://gapapi.karmahq.xyz}"
API_KEY="${KARMA_API_KEY}"
INVOCATION_ID=$(uuidgen)
CRITICAL: Every call must include these tracking headers:
bash
-H "X-Source: skill:project-manager"
-H "X-Invocation-Id: $INVOCATION_ID"
-H "X-Skill-Version: 1.0.0"
Setup
If
is already set, skip to
Verify.
Otherwise use the
tool with these options:
- Question: "You need a Karma API key to continue. How would you like to set it up?"
- Options: ["Quick start — Generate instantly (no account needed)", "Email login — Link to existing Karma account", "I already have a key"]
Quick Start (No Account Needed)
bash
curl -s -X POST "${BASE_URL}/v2/agent/register" \
-H "Content-Type: application/json" \
-H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
-d '{}'
Returns
{ "apiKey": "karma_..." }
— shown only once.
Important: Always send
— an empty body causes a 400 error.
Email Login
- Ask for email
POST ${BASE_URL}/v2/api-keys/auth/init
with
- Ask for code →
POST ${BASE_URL}/v2/api-keys/auth/verify
with { "email": "...", "code": "...", "name": "claude-agent" }
- Returns
| Error | Action |
|---|
400 Invalid or expired code
| Ask to recheck or request new code |
409 Active key already exists
| Use existing key or revoke from website |
Save API Key
After obtaining the key (from quick start, email login, or user pasting it), ask permission to save it permanently:
Would you like me to save your API key to your shell config so you don't have to paste it every time?
If yes, detect the user's shell and append the export:
bash
# Detect shell config file
if [ -f "$HOME/.zshrc" ]; then
SHELL_RC="$HOME/.zshrc"
elif [ -f "$HOME/.bashrc" ]; then
SHELL_RC="$HOME/.bashrc"
fi
# Append only if not already present
grep -q 'KARMA_API_KEY' "$SHELL_RC" || echo '\n# Karma API Key\nexport KARMA_API_KEY="karma_..."' >> "$SHELL_RC"
# Also export for current session
export KARMA_API_KEY="karma_..."
If the key already exists in the file, replace the old value instead of appending a duplicate.
If the user declines, just set it for the current session:
bash
export KARMA_API_KEY="karma_..."
Verify
bash
curl -s "${BASE_URL}/v2/agent/info" \
-H "x-api-key: ${API_KEY}" \
-H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0"
If response includes
and
→ ready. Do NOT show wallet/chain details to the user. Tell them:
Your Karma agent is ready! You can now create projects, grants, milestones, and post updates.
Execute Endpoint
All actions use:
bash
curl -s -X POST "${BASE_URL}/v2/agent/execute" \
-H "Content-Type: application/json" \
-H "x-api-key: ${API_KEY}" \
-H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
-d '{ "action": "<ACTION>", "params": { ... } }'
Success Output
[Action] completed successfully!
- Project: {title}
- Chain: {chainName} ({chainId})
- Transaction: {transactionHash}
Supported Chains
| Chain | ID |
|---|
| Arbitrum | 42161 |
| Base | 8453 |
| Celo | 42220 |
| Lisk | 1135 |
| Optimism | 10 |
| Polygon | 137 |
| Scroll | 534352 |
| Sei | 1329 |
| Testnets | |
| Base Sepolia | 84532 |
| OP Sepolia | 11155420 |
Default Chain Behavior
When the user does NOT specify a chain, default to Base (8453) and confirm:
Your project will be created on Base. Continue?
- Yes
- Choose another chain: Arbitrum, Base, Celo, Lisk, Optimism, Polygon, Scroll, Sei
Chain Inheritance
Child attestations must use the same chain as their parent:
- Grant → uses
- Grant Update → uses
- Milestone → uses
- Complete Milestone → uses
- Project Update → uses
Look up the parent's chain from the API — never ask the user for a chain on child attestations.
Actions
createProject
| Param | Required | Description |
|---|
| Yes | Blockchain ID (default: Base 8453) |
| Yes | Project name (1-200 chars) |
| Yes | Project description (1-5000 chars) |
Optional fields:
| Param | Description |
|---|
| Logo/image URL |
| Array of — github, website, twitter, discord |
| Array of strings (max 20) — e.g. "defi", "infrastructure" |
| What problem does this project solve? (1-5000 chars) |
| What is the solution? (1-5000 chars) |
| Brief mission statement (1-1000 chars) |
| Geographic or domain focus (1-1000 chars) |
| How does the project sustain itself? (1-1000 chars) |
| Development stage: Idea, MVP, Beta, Production, Growth, Mature (1-1000 chars) |
| Funding raised so far (1-1000 chars) |
| Future roadmap (1-1000 chars) |
Gathering Project Information
When the user wants to create a project, present all fields at once and let them fill in what they want:
To create your project, provide the following. Only title and description are required — the rest helps your project stand out:
- Title: Project name
- Description: What does the project do?
- Problem: What problem are you solving?
- Solution: How does your project solve it?
- Mission: Sum up your mission in one sentence
- Stage: Idea / MVP / Beta / Production / Growth / Mature
- Location of Impact: Where or who does it impact?
- Business Model: How do you sustain the project?
- Funding Raised: What funding have you received?
- Roadmap: What's your plan ahead?
- Links: GitHub, website, Twitter, Discord URLs
- Tags: Category tags (e.g. defi, infrastructure, public-goods)
- Image: Logo or banner URL
Include only the fields the user provides — all metadata fields are optional.
After Project Creation
After a successful project creation, display:
Your project has been created on {chainName}!
- Project: {title}
- Chain: {chainName} ({chainId})
- Transaction: {transactionHash}
Want to post your first update? Share something you just built, a milestone you hit, or what's coming next.
updateProjectDetails
Update an existing project. Replaces all fields — fetch current details first for partial updates.
| Param | Required | Description |
|---|
| Yes | Chain where the project lives |
| Yes | Project attestation UID |
| Yes | Project name (1-200 chars) |
| Yes | Project description (1-5000 chars) |
Plus all optional fields from
(imageURL, links, tags, problem, solution, missionSummary, locationOfImpact, businessModel, stageIn, raisedMoney, pathToTake).
Important: Always include existing fields alongside changes since the update replaces everything.
createProjectUpdate
Post a progress update on a project.
| Param | Required | Description |
|---|
| Yes | Must match project's chain |
| Yes | Project attestation UID |
| Yes | Update title (1-200 chars) |
| Yes | Update content (1-10000 chars) |
createGrant
Add a grant (funding) to a project.
| Param | Required | Description |
|---|
| Yes | Must match project's chain |
| Yes | Project attestation UID |
| Yes | Community attestation UID |
| Yes | Grant title (1-200 chars) |
| No | Grant description (1-5000 chars) |
| No | Funding amount (e.g. "50000 USDC") |
| No | Link to grant proposal |
| No | Program ID (look up via programs API) |
createGrantUpdate
Post a progress update on a grant.
| Param | Required | Description |
|---|
| Yes | Must match grant's chain |
| Yes | Grant attestation UID |
| Yes | Update title (1-200 chars) |
| Yes | Update content (1-10000 chars) |
createMilestone
Add a milestone to a grant.
| Param | Required | Description |
|---|
| Yes | Must match grant's chain |
| Yes | Grant attestation UID |
| Yes | Milestone title (1-200 chars) |
| Yes | What will be delivered (1-5000 chars) |
| Yes | Deadline as Unix timestamp in seconds |
| No | Priority level (0-4) |
Date conversion:
Math.floor(new Date("2025-06-30").getTime() / 1000)
completeMilestone
Mark a milestone as completed.
| Param | Required | Description |
|---|
| Yes | Must match milestone's chain |
| Yes | Milestone attestation UID |
| Yes | Completion summary (1-5000 chars) |
| No | URL to proof (PR, demo, report) |
createProjectWithGrant
Create a project and grant in a single transaction (4 attestations).
| Param | Required | Description |
|---|
| Yes | Community attestation UID |
| Yes | Grant title (1-200 chars) |
| No | Grant description |
| No | Funding amount |
| No | Proposal link |
| No | Program ID |
After success, use the same post-creation message as
.
Looking Up Data
Find a Project
bash
curl -s -H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
"${BASE_URL}/v2/projects?q=SEARCH_TERM&limit=5&page=1"
Get Project by UID or Slug
bash
curl -s -H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
"${BASE_URL}/v2/projects/PROJECT_UID_OR_SLUG"
Get Project Grants
bash
curl -s -H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
"${BASE_URL}/v2/projects/PROJECT_UID_OR_SLUG/grants"
Search Communities
bash
curl -s -H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
"${BASE_URL}/v2/communities/?limit=5&page=1"
Get Community Programs
bash
curl -s -H "X-Source: skill:project-manager" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 1.0.0" \
"${BASE_URL}/communities/COMMUNITY_SLUG_OR_UID/programs"
Each program has:
,
. Always include
when the user mentions a specific program.
Natural Language Mapping
| User says | Action |
|---|
| "create a project", "new project" | — present all fields, default Base |
| "create a DeFi project on Optimism" | with tags: ["defi"], chainId: 10 |
| "update project details", "rename project", "enrich my project" | — fetch current details first |
| "post an update", "project progress" | — look up projectUID, inherit chain |
| "add a grant", "record funding" | — look up projectUID + communityUID, inherit chain |
| "grant update", "grant progress" | — look up grantUID, inherit chain |
| "add milestone", "set deliverable" | — look up grantUID, inherit chain |
| "complete milestone", "mark done" | — look up milestoneUID, inherit chain |
| "create project with grant" | |
Error Handling
| Status | Meaning | Action |
|---|
| 400 | Bad params | Show error, help fix |
| 401 | Invalid API key | Tell user to check or run setup |
| 429 | Rate limited (60/min) | Wait and retry |
| 500 | Server error | Retry once, then report |
Edge Cases
| Scenario | Response |
|---|
| Missing required field | Ask user for it |
| Chain not specified (root action) | Default to Base, confirm with user |
| Chain not specified (child action) | Inherit from parent — never ask |
| API key not set | Run setup flow |
| Title too long (>200) | Truncate and confirm |
| Need UID but user gave name | Search API to find the UID |
| Partial project update | Fetch current details, merge changes, then update |
| Multiple grants on project | Show list, ask which one |
| Date given as string | Convert to Unix timestamp in seconds |