Base URL: https://strawhub.dev/api/v1/
Most read endpoints are public. Write endpoints require a Bearer token.
Authorization: Bearer sh_xxxxx
Tokens are created via Settings > API Tokens.
All rate limits are per IP address.
| Bucket | Limit |
|---|---|
| Read | 100/min |
| Write | 10/min |
| Search | 30/min |
A 429 response includes a Retry-After: 60 header.
GET /api/v1/skills?limit=50&sort=updated
Query params:
limit(1-200, default 50)sort(updated|downloads|stars)
Response:
{
"items": [
{
"slug": "git-workflow",
"displayName": "Git Workflow",
"summary": "...",
"stats": { "downloads": 0, "stars": 0, "versions": 1, "comments": 0 },
"badges": {},
"updatedAt": 1700000000000
}
],
"count": 1
}POST /api/v1/skills
Content-Type: multipart/form-data
payload: { slug, displayName, version, changelog, dependencies?, customTags?, files[] }
The dependencies field is optional JSON: {"skills": ["security-baseline", "git-workflow==1.0.0"]}. Skills can only depend on other skills. If omitted, dependencies are read from metadata.strawpot.dependencies in the SKILL.md frontmatter.
File constraints: up to 100 files, 10 MB each, 50 MB total. Allowed extensions: .md, .txt, .json, .yaml, .yml, .toml.
Additional constraints:
- Slug must be unique within skills.
- If the skill already has published versions, the new version must be strictly greater than the latest.
- Dependency validation errors are aggregated — all issues are reported together in a single error message.
GET /api/v1/roles?limit=50&sort=updated
Query params:
limit(1-200, default 50)sort(updated|downloads|stars)
Response shape matches List Skills.
POST /api/v1/roles
Content-Type: multipart/form-data
payload: { slug, displayName, version, changelog, dependencies?, customTags?, files[] }
The dependencies field is optional JSON: {"skills": ["git-workflow==1.0.0", "code-review"], "roles": ["reviewer"]}. If omitted, dependencies are read from metadata.strawpot.dependencies in the ROLE.md frontmatter. The roles list supports "*" as a wildcard meaning "all available roles" — this is stored as-is and expanded at runtime by StrawPot.
Roles must contain exactly one file named ROLE.md.
Additional constraints:
- Slug must be unique within roles.
- If the role already has published versions, the new version must be strictly greater than the latest.
- Dependency validation errors are aggregated — all issues are reported together in a single error message.
GET /api/v1/search?q=review&kind=all&limit=20
Query params:
q(required) — search querykind(all|skill|role|agent|memory|integration, defaultall)limit(1-100, default 20)
Uses hybrid ranking: vector similarity + lexical matching + popularity boost.
GET /api/v1/skills/:slug
Returns full detail for a single skill (public).
GET /api/v1/skills/:slug/file?path=SKILL.md
Returns the raw file content for a skill. path defaults to SKILL.md.
GET /api/v1/skills/:slug/resolve
Returns the resolved dependency tree for a skill (public).
DELETE /api/v1/skills/:slug
Authorization: Bearer sh_xxxxx
Soft-deletes a skill. Requires moderator or admin role.
GET /api/v1/roles/:slug
Returns full detail for a single role (public).
GET /api/v1/roles/:slug/file?path=ROLE.md
Returns the raw file content for a role. path defaults to ROLE.md.
GET /api/v1/roles/:slug/resolve
Returns the resolved dependency tree for a role (public).
DELETE /api/v1/roles/:slug
Authorization: Bearer sh_xxxxx
Soft-deletes a role. Requires moderator or admin role.
GET /api/v1/agents?limit=50&sort=updated
Query params:
limit(1-200, default 50)sort(updated|downloads|stars)
Response shape matches List Skills.
POST /api/v1/agents
Content-Type: multipart/form-data
payload: { slug, displayName, version, changelog, customTags?, files[] }
File constraints: up to 100 files, 10 MB each, 50 MB total. Supports binary files.
GET /api/v1/agents/:slug
Returns full detail for a single agent (public).
GET /api/v1/agents/:slug/file?path=AGENT.md
Returns the raw file content for an agent. path defaults to AGENT.md.
DELETE /api/v1/agents/:slug
Authorization: Bearer sh_xxxxx
Soft-deletes an agent. Requires moderator or admin role.
GET /api/v1/memories?limit=50&sort=updated
Query params:
limit(1-200, default 50)sort(updated|downloads|stars)
Response shape matches List Skills.
POST /api/v1/memories
Content-Type: multipart/form-data
payload: { slug, displayName, version, changelog, customTags?, files[] }
File constraints: up to 100 files, 10 MB each, 50 MB total. Supports binary files.
GET /api/v1/memories/:slug
Returns full detail for a single memory (public).
GET /api/v1/memories/:slug/file?path=MEMORY.md
Returns the raw file content for a memory. path defaults to MEMORY.md.
DELETE /api/v1/memories/:slug
Authorization: Bearer sh_xxxxx
Soft-deletes a memory. Requires moderator or admin role.
GET /api/v1/integrations?limit=50&sort=updated
Query params:
limit(1-200, default 50)sort(updated|downloads|stars)
Response shape matches List Skills.
POST /api/v1/integrations
Content-Type: multipart/form-data
payload: { slug, displayName, version, changelog, customTags?, files[] }
File constraints: up to 100 files, 10 MB each, 50 MB total. Supports binary files.
GET /api/v1/integrations/:slug
Returns full detail for a single integration (public).
GET /api/v1/integrations/:slug/file?path=INTEGRATION.md
Returns the raw file content for an integration. path defaults to INTEGRATION.md.
DELETE /api/v1/integrations/:slug
Authorization: Bearer sh_xxxxx
Soft-deletes an integration. Requires moderator or admin role.
POST /api/v1/stars/toggle
Authorization: Bearer sh_xxxxx
Content-Type: application/json
{ "slug": "git-workflow", "kind": "skill|role|agent|memory|integration" }
Toggles the star status for the authenticated user. Returns { "starred": true } or { "starred": false }.
POST /api/v1/downloads
Content-Type: application/json
{ "kind": "skill|role|agent|memory|integration", "slug": "...", "version": "..." }
No auth required — download tracking is public (like npm). The version field is optional. Downloads are tracked via event sourcing: events are inserted into statEvents and flushed into target stats every 15 minutes by a cron job.
GET /api/v1/whoami
Authorization: Bearer sh_xxxxx
Returns current user info: { handle, displayName, email, role, image }.
POST /api/v1/admin/set-role
Authorization: Bearer sh_xxxxx
Content-Type: application/json
{ "handle": "someuser", "role": "moderator" }
Sets a user's role. Valid roles: admin, moderator, user.
POST /api/v1/admin/ban-user
Authorization: Bearer sh_xxxxx
Content-Type: application/json
{ "handle": "baduser", "blocked": true, "reason": "spam" }
Blocks or unblocks a user. The reason field is optional and only used when blocking.