Public API

Every skill in the catalog is built for OpenSEO and calls the OpenSEO MCP tools, so whoever runs a skill needs OpenSEO connected (https://openseo.so). Everything in the catalog is readable without an account: a JSON API, a discovery index for the skills CLI, plain-text views for language models, an MCP server, and plugin marketplace files. All of it is read-only.

The examples use BASE=https://seo.party.

Conventions#

  • No key. Every endpoint is public. GET works from any origin (CORS *).
  • Rate limit. 60 requests per minute per IP across the API, counted per Cloudflare location. Over the limit you get 429 with Retry-After: 60.
  • Caching. Lists and metadata send Cache-Control: public, max-age=60; files send max-age=300 and an ETag (the file's sha256), so If-None-Match returns 304.
  • Errors are { "error": { "code": "NOT_FOUND", "message": "Skill not found" } } with the matching status: INVALID_INPUT 400, NOT_FOUND 404, RATE_LIMITED 429, INTERNAL 500.
  • Trust. Official and Verified skills always serve the commit a person reviewed, never the author's latest commit. Community skills serve the latest indexed commit that passed automated checks. Delisted and critical skills keep their metadata but serve no files.

Response shape#

Lists follow the MCP registry API: an array plus metadata, and each entry has a portable skill core with everything catalog-specific under the so.openseo.skills/v1 key of _meta.

{
  "skills": [
    {
      "skill": {
        "name": "every-app/striking-distance",
        "title": "striking-distance",
        "description": "Turns Search Console queries in positions 8-20 into a short list of page edits.",
        "version": "bbaa46a413c10500e668eec9e1d70588e5cf5972",
        "repository": {
          "url": "https://github.com/every-app/seo-playbooks",
          "source": "github",
          "id": "9100000001",
          "subfolder": "skills/striking-distance"
        },
        "websiteUrl": "https://seo.party/skills/every-app/striking-distance"
      },
      "_meta": {
        "so.openseo.skills/v1": {
          "tier": "official",
          "trust": "official",
          "pinned": true,
          "stale": false,
          "version": {
            "sha": "bbaa46a…",
            "label": "v1.2.0",
            "committedAt": "2026-09-20T14:05:00.000Z"
          },
          "tags": [
            { "slug": "search-console-loops", "name": "Search Console loops" }
          ],
          "agents": ["claude-code", "codex", "cursor"],
          "installs": 2,
          "stars": 412,
          "author": {
            "handle": "every-app",
            "name": "every-app",
            "url": "https://seo.party/u/every-app"
          },
          "publishedAt": "…",
          "updatedAt": "…",
          "lastCommitAt": "…",
          "verifiedAt": "…",
          "links": {
            "page": "…",
            "api": "…",
            "skillMd": "…/skill.md",
            "versions": "…/versions"
          }
        }
      }
    }
  ],
  "metadata": { "count": 1, "nextCursor": null }
}

skill.name is the catalog slug, owner/name. skill.version is the full commit sha served, or null when nothing is served. stars are the GitHub stars of the source repository, shared by every skill in it, and never added to installs.

Skills#

curl "$BASE/api/v1/skills?q=search+console&tag=search-console-loops&limit=20"
ParameterMeaning
qWords to match in the name, description, tags, and owner (prefix match on every word).
tagTag slug. Repeat or comma-separate for several; all must match.
agentclaude-code, codex, cursor, gemini-cli, copilot, chatgpt, hermes, openclaw, or other.
tierofficial, verified, or community.
updated_sinceRFC 3339 time. Returns entries changed since then, including delisted, critical, archived, and deprecated ones, so a mirror can drop them.
cursormetadata.nextCursor from the previous page. Opaque.
limit1 to 100, default 30.

Results are ordered by the time the entry last changed (newest first; any change counts, including install counts), then id, so cursors stay stable while you page. To mirror the catalog, page through once, then poll with updated_since set to the time you started the previous run.

Detail, versions, files#

curl "$BASE/api/v1/skills/every-app/striking-distance"                     # detail
curl "$BASE/api/v1/skills/every-app/striking-distance?include=readme"      # plus the SKILL.md body
curl "$BASE/api/v1/skills/every-app/striking-distance/versions"            # every indexed commit
curl "$BASE/api/v1/skills/every-app/striking-distance/skill.md"            # raw SKILL.md, text/markdown
curl "$BASE/api/v1/skills/every-app/striking-distance/files/references/gsc-export.md"
curl -O "$BASE/api/v1/skills/every-app/striking-distance/archive.zip"      # every stored file
  • Detail adds the full description, license, source location, file list (each with its URL), scorecard, reviewer notes, a newer commit waiting for review (pendingVersion), lineage, and install commands per agent (install). ChatGPT has no install command, so its entry has no options and a manual step instead.
  • skill.md, files/<path>, and archive.zip serve the displayed commit. Add ?sha=<40-char sha> for any commit listed under versions. Responses carry X-Skill-Commit.
  • Binary files and files over 200 KB are not stored; those paths return 404 and should be fetched from GitHub at the same commit.

Authors and tags#

curl "$BASE/api/v1/authors/northwind-agency"   # profile and listed skills
curl "$BASE/api/v1/tags"                       # what skills do, with counts

Revocations#

curl "$BASE/api/v1/revocations"

Every delisted or critical skill, with status, reason (from the moderation log or the actioned report), changedAt, and commits, every commit we indexed for it. Clients that install skills should check installed skills against this list: delisted means stop offering it; critical means warn the user and remove it.

Discovery index#

npx skills add "$BASE"          # interactive
npx skills add "$BASE" --list   # what would be installed

/.well-known/agent-skills/index.json lists Official and Verified skills in the skills CLI discovery format (schema discovery/0.2.0). Each entry points at our own copy of the reviewed commit (a single SKILL.md, or a zip when the skill has more files) with its sha256 digest, and the CLI refuses anything that does not match. That is how npx skills add installs exactly what we reviewed even though the CLI cannot pin a commit.

Text views for language models#

  • /llms.txt: what the site is, how to use the API and MCP, and the main tags.
  • /llms-full.txt: every listed skill with its one-line description, trust, page, and install command.

MCP server#

$BASE/mcp speaks MCP over streamable HTTP, stateless (send JSON-RPC with POST; GET returns 405). No auth.

claude mcp add --transport http seo-party "$BASE/mcp"
ToolUse it to
search_skillsFind a skill for a task. Filters: q, tag, agent, tier, limit. Results include githubStars.
get_skillSee trust, the commit served, files, and install commands for owner and name.
get_skill_fileRead SKILL.md or another file at the served commit, to follow a skill without installing it.

Plugin marketplaces#

The marketplace repository lists Official and Verified skills for Claude Code (.claude-plugin/marketplace.json), Codex (.agents/plugins/marketplace.json), and Cursor (.cursor-plugin/marketplace.json). Each entry is a git source pinned to the reviewed commit's full sha; a new sha is published only after re-review. The same files are served live:

curl "$BASE/api/v1/marketplace/claude.json"   # also codex.json, cursor.json

How installs are counted#

An install is counted once per installer per skill per UTC day, across these surfaces: install and copy buttons on the site, fetches of skill.md, files/…, and archive.zip through this API, artifact downloads through the discovery index, and get_skill_file calls over MCP. The installer is a salted hash of the signed-in user, or of the IP and user agent; we never store either in the clear. Fetches by crawlers and link previews, and the skills CLI's update checks, are not counted. GitHub stars and other directories' install counts are shown separately and never added in.