Agent Skill · posts

search-apis

Find APIs and contracts in the api-evangelist network by keyword, provider, or tag, using the RFC 9264 api-catalog endpoints.

Provider: posts Path in repo: SKILL.md

Skill body

search-apis

Description: Find APIs and contracts in the api-evangelist network by keyword, provider, or tag. Returns structured matches the agent can hand to the user or feed to other skills.

When to use this skill

Use when the user asks “what APIs are there for X”, “find an API to do Y”, “which providers offer Z”, or any other intent that requires filtering the api-evangelist catalog. Prefer this over scraping search HTML.

Inputs

How it works

Two catalogs cover the network:

Each entry looks like:

{
  "anchor": "https://apis.apievangelist.com/store/<slug>/",
  "title": "<API name>",
  "description": "<API description>",
  "service-desc": [{"href": "...", "type": "application/vnd.oai.openapi"}],
  "service-doc":  [{"href": "...", "type": "text/html"}],
  "describedby": [{"href": "...", "title": "JSONSchema"}]
}

Filter linkset[] client-side. Title, description, and anchor are searchable; the anchor encodes the slug.

Recipe

import json, urllib.request, re

CATALOGS = {
    "apis": "https://apis.apievangelist.com/.well-known/api-catalog",
    "contracts": "https://contracts.apievangelist.com/.well-known/api-catalog",
}

def search(query, *, scope="apis", provider=None, tag=None, limit=20):
    """Return up to `limit` linkset entries matching `query`.

    scope    -- "apis" (individual API surfaces) or "contracts" (providers).
    provider -- restrict matches whose anchor URL contains this provider slug.
    tag      -- match if `tag` (case-insensitive) appears in the title or description.
    """
    with urllib.request.urlopen(CATALOGS[scope]) as r:
        catalog = json.load(r)

    q = query.lower()
    hits = []
    for entry in catalog["linkset"]:
        anchor = entry.get("anchor", "")
        title = (entry.get("title") or "").lower()
        desc = (entry.get("description") or "").lower()
        if provider and provider.lower() not in anchor.lower():
            continue
        if tag and tag.lower() not in (title + " " + desc):
            continue
        if q and q not in title and q not in desc and q not in anchor.lower():
            continue
        hits.append(entry)
        if len(hits) >= limit:
            break
    return hits

if __name__ == "__main__":
    import sys
    results = search(sys.argv[1] if len(sys.argv) > 1 else "")
    for r in results:
        print(f"- {r.get('title')} <{r.get('anchor')}>")

Tips