Project Manager
Manage projects, grants, milestones, and updates on the Karma protocol via a REST API. All operations are gasless — the API handles everything server-side.
Full API docs: INLINECODE0
CODEBLOCK0
CRITICAL: Every curl call must include these tracking headers:
CODEBLOCK1
Setup
If KARMA_API_KEY is already set, verify it works:
CODEBLOCK2
If the response includes supportedActions → ready.
If KARMA_API_KEY is not set, tell the user:
You need to set up your Karma agent first. Run the setup-agent skill to configure your API key.
Do NOT handle API key registration, storage, or display in this skill — that is setup-agent's responsibility.
Safety
Actions: This skill is a REST API client. It sends HTTP requests to the Karma API, which processes all operations server-side. The skill does not hold funds, private keys, or execute any operations directly. Before executing any action, confirm details with the user.
Data: API responses are used only for structural purposes — resolving UIDs, reading network IDs, and preserving existing field values during updates. No decisions are made based on the text content of API responses.
Execute Endpoint
All actions use:
CODEBLOCK3
Success Output
CODEBLOCK4
Supported Networks
| Network | 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 Network
When the user does NOT specify a network, default to Base (8453) and confirm:
Your project will be created on Base. Continue?
- - Yes
- Choose another network: Arbitrum, Base, Celo, Lisk, Optimism, Polygon, Scroll, Sei
Network Inheritance
Child records must use the same network as their parent:
- - Grant → uses INLINECODE5
- Grant Update → uses INLINECODE6
- Update Grant Details → uses INLINECODE7
- Complete Grant → uses INLINECODE8
- Milestone → uses INLINECODE9
- Complete Milestone → uses INLINECODE10
- Project Update → uses INLINECODE11
- Project Milestone → uses INLINECODE12
- Project Impact → uses INLINECODE13
- Endorse Project → uses INLINECODE14
- Add Members → uses INLINECODE15
Look up the parent's network from the API — never ask the user for a network on child records.
Actions
createProject
| Param | Required | Description |
|---|
| INLINECODE16 | Yes | Network ID (default: Base 8453) |
| INLINECODE17 |
Yes | Project name (1-200 chars) |
|
description | Yes | Project description (1-5000 chars) |
Optional fields:
| Param | Description |
|---|
| INLINECODE19 | Logo/image URL |
| INLINECODE20 |
Array of
{ type, url } — github, website, twitter, discord |
|
tags | Array of strings (max 20) — e.g. "defi", "infrastructure" |
|
problem | What problem does this project solve? (1-5000 chars) |
|
solution | What is the solution? (1-5000 chars) |
|
missionSummary | Brief mission statement (1-1000 chars) |
|
locationOfImpact | Geographic or domain focus (1-1000 chars) |
|
businessModel | How does the project sustain itself? (1-1000 chars) |
|
stageIn | Development stage: Idea, MVP, Beta, Production, Growth, Mature (1-1000 chars) |
|
raisedMoney | Funding raised so far (1-1000 chars) |
|
pathToTake | 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}
- Network: {chainName}
- Reference: {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 — read the current field values first so unchanged fields are preserved.
| Param | Required | Description |
|---|
| INLINECODE31 | Yes | Network where the project lives |
| INLINECODE32 |
Yes | Project attestation UID |
|
title | Yes | Project name (1-200 chars) |
|
description | Yes | Project description (1-5000 chars) |
Plus all optional fields from createProject (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 |
|---|
| INLINECODE36 | Yes | Must match project's network |
| INLINECODE37 |
Yes | Project attestation UID |
|
title | Yes | Update title (1-200 chars) |
|
text | Yes | Update content (1-10000 chars) |
createGrant
Add a grant (funding) to a project.
| Param | Required | Description |
|---|
| INLINECODE40 | Yes | Must match project's network |
| INLINECODE41 |
Yes | Project attestation UID |
|
communityUID | Yes | Community attestation UID |
|
title | Yes | Grant title (1-200 chars) |
|
description | No | Grant description (1-5000 chars) |
|
amount | No | Funding amount as text (e.g. "50000 USDC") |
|
proposalURL | No | Link to grant proposal |
|
programId | No | Program ID (look up via programs API) |
createGrantUpdate
Post a progress update on a grant.
| Param | Required | Description |
|---|
| INLINECODE48 | Yes | Must match grant's network |
| INLINECODE49 |
Yes | Grant attestation UID |
|
title | Yes | Update title (1-200 chars) |
|
text | Yes | Update content (1-10000 chars) |
createMilestone
Add a milestone to a grant.
| Param | Required | Description |
|---|
| INLINECODE52 | Yes | Must match grant's network |
| INLINECODE53 |
Yes | Grant attestation UID |
|
title | Yes | Milestone title (1-200 chars) |
|
description | Yes | What will be delivered (1-5000 chars) |
|
endsAt | Yes | Deadline as Unix timestamp in
seconds |
|
priority | 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 |
|---|
| INLINECODE59 | Yes | Must match milestone's network |
| INLINECODE60 |
Yes | Milestone attestation UID |
|
reason | Yes | Completion summary (1-5000 chars) |
|
proofOfWork | No | URL to proof (PR, demo, report) |
createProjectWithGrant
Create a project and grant in a single transaction (4 attestations).
All createProject params plus:
| Param | Required | Description |
|---|
| INLINECODE64 | Yes | Community attestation UID |
| INLINECODE65 |
Yes | Grant title (1-200 chars) |
|
grant.description | No | Grant description |
|
grant.amount | No | Funding amount |
|
grant.proposalURL | No | Proposal link |
|
grant.programId | No | Program ID |
After success, use the same post-creation message as createProject.
updateGrantDetails
Update an existing grant's details. Attests new details — the indexer uses the latest one.
| Param | Required | Description |
|---|
| INLINECODE71 | Yes | Must match grant's network |
| INLINECODE72 |
Yes | Grant attestation UID |
|
title | Yes | Grant title (1-200 chars) |
|
description | No | Grant description (1-5000 chars) |
|
amount | No | Funding amount as text (e.g. "50000 USDC") |
|
proposalURL | No | Link to grant proposal |
|
programId | No | Program ID |
Important: Read the current grant field values first, apply the user's changes, then send all fields so unchanged values are preserved.
completeGrant
Mark a grant as fully completed with a final summary.
| Param | Required | Description |
|---|
| INLINECODE78 | Yes | Must match grant's network |
| INLINECODE79 |
Yes | Grant attestation UID |
|
title | Yes | Completion title (1-200 chars) |
|
text | Yes | Completion summary (1-10000 chars) |
|
proofOfWork | No | URL to proof (demo, report, repo) |
|
pitchDeck | No | URL to pitch deck |
|
demoVideo | No | URL to demo video |
|
trackExplanations | No | Array of
{ trackId, trackName, explanation } — how the grant fulfilled each track |
After completion:
Grant {title} has been marked as completed!
- - Grant: {title}
- Network: {chainName}
- Reference: {transactionHash}
createProjectMilestone
Create a project-level roadmap milestone (not tied to a specific grant).
| Param | Required | Description |
|---|
| INLINECODE87 | Yes | Must match project's network |
| INLINECODE88 |
Yes | Project attestation UID |
|
title | Yes | Milestone title (1-200 chars) |
|
text | Yes | Milestone description (1-5000 chars) |
createProjectImpact
Report impact achieved by a project.
| Param | Required | Description |
|---|
| INLINECODE91 | Yes | Must match project's network |
| INLINECODE92 |
Yes | Project attestation UID |
|
work | Yes | Description of work done (1-5000 chars) |
|
impact | Yes | Description of impact achieved (1-5000 chars) |
|
proof | Yes | Proof of impact — URL or description (1-5000 chars) |
|
startedAt | No | When work started (Unix timestamp in seconds) |
|
completedAt | Yes | When work was completed (Unix timestamp in seconds) |
endorseProject
Endorse a project with an optional comment.
| Param | Required | Description |
|---|
| INLINECODE98 | Yes | Must match project's network |
| INLINECODE99 |
Yes | Project attestation UID |
|
comment | No | Endorsement comment (1-5000 chars) |
addProjectMembers
Add team members to a project.
| Param | Required | Description |
|---|
| INLINECODE101 | Yes | Must match project's network |
| INLINECODE102 |
Yes | Project attestation UID |
|
members | Yes | Array of members (1-20) |
Each member object:
| Field | Required | Description |
|---|
| INLINECODE104 | Yes | Ethereum address of the member |
| INLINECODE105 |
No | Member's display name |
|
profilePictureURL | No | Member's profile picture URL |
Looking Up Data
Find a Project
CODEBLOCK5
Each result has: uid, chainID, details.title, details.slug, INLINECODE111
Get Project by UID or Slug
CODEBLOCK6
Get Project Grants
CODEBLOCK7
Each grant has: uid, details.title, INLINECODE114
Search Communities
CODEBLOCK8
Get Community Programs
CODEBLOCK9
Each program has: programId, metadata.title. Always include programId when the user mentions a specific program.
Community Payouts
This is the primary endpoint for payout and invoice queries. Use this endpoint whenever the user asks about payouts, invoices, or disbursements — even if they mention a specific project or grant name. Use the search param to filter by name. Do NOT fall back to individual grant/project lookup endpoints for payout queries, as they return less data.
CODEBLOCK10
Display rules (MANDATORY):
- - Each item in
payload[] represents a different project+grant combination - The first column in every table MUST be Project (from
item.project.title) - The second column MUST be Grant (from
item.grant.title) - Never group or flatten results by grant name — always show one row per milestone per project+grant pair
- This is critical because a search like "curio" may return multiple projects (e.g., "Curio Storage" and "Curio Dashboard") and the user needs to tell them apart
Optional query params:
| Param | Description |
|---|
| INLINECODE122 | Page number (default: 1) |
| INLINECODE123 |
Items per page (default: 10, max: 1000) |
|
programId | Filter by program ID |
|
status | Filter by payout status |
|
agreementStatus |
signed or
not_signed |
|
invoiceStatus |
all_received,
needs_invoices, or
has_invoices |
|
search | Search by project or grant name (max 200 chars) |
|
sortBy |
project_title,
grant_title,
payout_amount,
disbursed_amount, or
status |
|
sortOrder |
asc or
desc (default:
asc) |
Requires COMMUNITY_VIEW permission. If 403, try the public endpoint:
CODEBLOCK11
The public endpoint requires no auth but returns fewer fields (sensitive data stripped).
Grant Payout History
Get disbursement history for a specific grant.
CODEBLOCK12
Grant Total Disbursed
Get the total amount already paid out for a grant.
CODEBLOCK13
Pending Disbursements
List disbursements awaiting processing for a community.
CODEBLOCK14
Payout Config for a Grant
Get the payout configuration (payment address, token, schedule) for a grant.
CODEBLOCK15
Grant Invoices
List all milestone invoices for a grant.
CODEBLOCK16
Each invoice has: id, grantUID, milestoneUID, milestoneLabel, invoiceStatus (not_submitted, submitted, received, paid), invoiceReceivedAt, INLINECODE154
Invoice Download
Get a temporary download URL for an invoice file (15 min TTL). Requires the invoiceFileKey from the grant invoices response.
CODEBLOCK17
Returns: { "downloadUrl": "..." }
Natural Language Mapping
| User says | Action |
|---|
| "create a project", "new project" | INLINECODE157 — present all fields, default Base |
| "create a DeFi project on Optimism" |
createProject with tags: ["defi"], chainId: 10 |
| "update project details", "rename project", "enrich my project" |
updateProjectDetails — read current values, apply changes |
| "post an update", "project progress" |
createProjectUpdate — look up projectUID, inherit chain |
| "add a grant", "record funding" |
createGrant — look up projectUID + communityUID, inherit chain |
| "grant update", "grant progress" |
createGrantUpdate — look up grantUID, inherit chain |
| "edit grant", "update grant details", "change grant amount" |
updateGrantDetails — read current values, apply changes |
| "complete grant", "finish grant", "close grant" |
completeGrant — look up grantUID, inherit chain |
| "add milestone", "set deliverable" |
createMilestone — look up grantUID, inherit chain |
| "complete milestone", "mark done" |
completeMilestone — look up milestoneUID, inherit chain |
| "add roadmap milestone", "project milestone" |
createProjectMilestone — look up projectUID, inherit chain |
| "report impact", "log impact", "share impact" |
createProjectImpact — look up projectUID, inherit chain |
| "endorse project", "support project" |
endorseProject — look up projectUID, inherit chain |
| "add team member", "add member", "invite to project" |
addProjectMembers — look up projectUID, inherit chain |
| "create project with grant" |
createProjectWithGrant |
| "check payouts", "payout status", "show payouts", "invoices", "check invoices" |
Always use Community Payouts endpoint (
/v2/communities/:id/payouts) with
search param — this is the primary endpoint for all payout/invoice queries |
| "payout history", "disbursement history" | Grant Payout History — look up grantUID first |
| "total disbursed", "how much was paid" | Grant Total Disbursed — look up grantUID first |
| "pending payouts", "pending disbursements" | Pending Disbursements — look up communityUID |
| "payout config", "payment setup" | Payout Config — look up grantUID first |
| "view invoices", "check invoices", "invoice status" | Grant Invoices — look up grantUID first |
| "download invoice" | Invoice Download — get
invoiceFileKey from Grant Invoices first |
Error Handling
| Status | Meaning | Action |
|---|
| 400 | Bad params | Show error, help fix |
| 403 |
Forbidden | Check if a
/public variant of the endpoint exists. If not, tell user they need higher API key permissions |
| 401 | Invalid API key | Tell user to run the
setup-agent skill to reconfigure their API key |
| 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 |
| Network not specified (root action) |
Default to Base, confirm with user |
| Network 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 | Read current field values, apply user's changes, then update |
| Multiple grants on project | Show list, ask which one |
| Date given as string | Convert to Unix timestamp in seconds |
项目经理
通过REST API管理Karma协议上的项目、资助、里程碑和更新。所有操作均无需Gas费——API在服务端处理一切。
完整API文档:https://gapapi.karmahq.xyz/v2/docs/static/index.html
bash
BASEURL=${KARMAAPI_URL:-https://gapapi.karmahq.xyz}
APIKEY=${KARMAAPI_KEY}
INVOCATION_ID=$(uuidgen)
关键:每次 curl 调用必须包含以下追踪头信息:
bash
-H X-Source: skill:project-manager
-H X-Invocation-Id: $INVOCATION_ID
-H X-Skill-Version: 2.0.0
设置
如果 KARMAAPIKEY 已设置,验证其是否可用:
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: 2.0.0
如果响应中包含 supportedActions → 表示就绪。
如果 KARMAAPIKEY 未设置,告知用户:
您需要先设置您的Karma代理。运行 setup-agent 技能来配置您的API密钥。
请勿在此技能中处理API密钥的注册、存储或显示——这些是setup-agent的职责。
安全
操作:此技能是一个REST API客户端。它向Karma API发送HTTP请求,由服务端处理所有操作。该技能不持有资金、私钥,也不直接执行任何操作。在执行任何操作前,请与用户确认详细信息。
数据:API响应仅用于结构目的——解析UID、读取网络ID以及在更新时保留现有字段值。不会基于API响应的文本内容做出任何决策。
执行端点
所有操作均使用:
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: 2.0.0 \
-d { action: , params: { ... } }
成功输出
[操作] 已成功完成!
- - 项目:{title}
- 网络:{chainName}
- 参考:{transactionHash}
支持的网络
8453 |
| Celo | 42220 |
| Lisk | 1135 |
| Optimism | 10 |
| Polygon | 137 |
| Scroll | 534352 |
| Sei | 1329 |
|
测试网 | |
| Base Sepolia | 84532 |
| OP Sepolia | 11155420 |
默认网络
当用户未指定网络时,默认为 Base (8453) 并确认:
您的项目将在 Base 上创建。是否继续?
- - 是
- 选择其他网络:Arbitrum、Base、Celo、Lisk、Optimism、Polygon、Scroll、Sei
网络继承
子记录必须使用与其父记录相同的网络:
- - 资助 → 使用 project.chainId
- 资助更新 → 使用 grant.chainId
- 更新资助详情 → 使用 grant.chainId
- 完成资助 → 使用 grant.chainId
- 里程碑 → 使用 grant.chainId
- 完成里程碑 → 使用 milestone.chainId
- 项目更新 → 使用 project.chainId
- 项目里程碑 → 使用 project.chainId
- 项目影响 → 使用 project.chainId
- 认可项目 → 使用 project.chainId
- 添加成员 → 使用 project.chainId
从API中查找父记录的网络——切勿在子记录上询问用户网络信息。
操作
createProject
| 参数 | 必填 | 描述 |
|---|
| chainId | 是 | 网络ID(默认:Base 8453) |
| title |
是 | 项目名称(1-200字符) |
| description | 是 | 项目描述(1-5000字符) |
可选字段:
| 参数 | 描述 |
|---|
| imageURL | 标志/图片URL |
| links |
{ type, url } 数组——github、website、twitter、discord |
| tags | 字符串数组(最多20个)——例如 defi、infrastructure |
| problem | 该项目解决什么问题?(1-5000字符) |
| solution | 解决方案是什么?(1-5000字符) |
| missionSummary | 简要使命陈述(1-1000字符) |
| locationOfImpact | 地理或领域关注点(1-1000字符) |
| businessModel | 项目如何维持自身?(1-1000字符) |
| stageIn | 发展阶段:Idea、MVP、Beta、Production、Growth、Mature(1-1000字符) |
| raisedMoney | 迄今已筹集的资金(1-1000字符) |
| pathToTake | 未来路线图(1-1000字符) |
收集项目信息
当用户想要创建项目时,一次性展示所有字段,让他们填写所需内容:
要创建您的项目,请提供以下信息。只有 标题 和 描述 是必填项——其余信息有助于您的项目脱颖而出:
- - 标题:项目名称
- 描述:项目是做什么的?
- 问题:您正在解决什么问题?
- 解决方案:您的项目如何解决它?
- 使命:用一句话概括您的使命
- 阶段:Idea / MVP / Beta / Production / Growth / Mature
- 影响范围:影响哪里或谁?
- 商业模式:您如何维持项目?
- 已筹资金:您已获得哪些资金?
- 路线图:您未来的计划是什么?
- 链接:GitHub、网站、Twitter、Discord URL
- 标签:分类标签(例如 defi、infrastructure、public-goods)
- 图片:标志或横幅URL
仅包含用户提供的字段——所有元数据字段均为可选。
项目创建后
项目成功创建后,显示:
您的项目已在 {chainName} 上创建!
- - 项目:{title}
- 网络:{chainName}
- 参考:{transactionHash}
想要发布您的第一个更新吗?分享您刚刚构建的内容、达成的里程碑或接下来的计划。
updateProjectDetails
更新现有项目。替换所有字段——首先读取当前字段值,以便保留未更改的字段。
| 参数 | 必填 | 描述 |
|---|
| chainId | 是 | 项目所在的网络 |
| projectUID |
是 | 项目认证UID |
| title | 是 | 项目名称(1-200字符) |
| description | 是 | 项目描述(1-5000字符) |
加上 createProject 中的所有可选字段(imageURL、links、tags、problem、solution、missionSummary、locationOfImpact、businessModel、stageIn、raisedMoney、pathToTake)。
重要:由于更新会替换所有内容,请始终将现有字段与更改一起包含。
createProjectUpdate
发布项目的进度更新。
| 参数 | 必填 | 描述 |
|---|
| chainId | 是 | 必须与项目的网络匹配 |
| projectUID |
是 | 项目认证UID |
| title | 是 | 更新标题(1-200字符) |
| text | 是 | 更新内容(1-10000字符) |
createGrant
向项目添加资助(资金)。
| 参数 | 必填 | 描述 |
|---|
| chainId | 是 | 必须与项目的网络匹配 |
| projectUID |
是 | 项目认证UID |
| communityUID | 是 | 社区认证UID |
| title | 是 | 资助标题(1-200字符) |
| description | 否 | 资助描述(1-5000字符) |
| amount | 否 | 资金金额(文本