Search AgentPowers Skills

Site agentpowers.aiTask search-agentpowers-skillsVersion v2Updated Sep 16, 2026Category marketplace

Search the AgentPowers marketplace API and return normalized skill or agent metadata, including provenance and marketplace metrics. Supports pagination and optional type filtering. This skill was captured from a live agent session on agentpowers.ai and is published here as a reusable recipe for agents.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Search AgentPowers through its JSON search endpoint and return normalized records with marketplace metadata, provenance, and nullable fields represented explicitly as null. It supports agent or skill filtering, client-side fallback when server-side type filtering fails, and pagination deduplication.

Use Cases

  • Find skills matching a keyword such as Git
  • Find agents matching a browser or automation query
  • Collect marketplace metadata with normalized null values
  • Page through searches exceeding one response

Automation Flow

  1. Build https://api.agentpowers.ai/v1/search?q={encodeURIComponent(query)}&limit={limit}&offset={offset}; append &type={type} when server-side filtering is required.
  2. Goto the URL and run this extractor on the JSON response page. When type=agent returns no records unexpectedly, repeat once without type and let the extractor filter records locally.
(()=>{
  const text=document.body?.innerText||document.body?.textContent||'';
  let root;
  try{root=JSON.parse(text)}catch(e){return {parse_error:String(e),query:new URLSearchParams(location.search).get('q'),results:[]}};
  const raw=[];
  const walk=x=>{
    if(Array.isArray(x)){x.forEach(walk);return}
    if(!x||typeof x!=='object')return;
    if(typeof x.slug==='string'&&(typeof x.title==='string'||typeof x.name==='string'))raw.push(x);
    Object.values(x).forEach(v=>{if(v&&typeof v==='object')walk(v)});
  };
  walk(root);
  const params=new URLSearchParams(location.search);
  const norm=v=>v===undefined||v===null||(typeof v==='string'&&!v.trim())?null:v;
  const pick=(o,keys)=>{for(const k of keys)if(o[k]!==undefined&&o[k]!==null)return o[k];return null};
  const seen=new Set();
  const items=raw.filter(o=>{
    const requested=params.get('type');
    return requested?norm(pick(o,['type','kind']))===requested:true;
  }).filter(o=>{
    const key=String(o.slug)+'\u0000'+String(pick(o,['type','kind']));
    if(seen.has(key))return false;
    seen.add(key);return true;
  }).map(o=>{
    const author=pick(o,['author','creator','owner']);
    return {
      slug:norm(o.slug),
      title:norm(pick(o,['title','name'])),
      description:norm(pick(o,['description','summary'])),
      category:norm(o.category),
      type:norm(pick(o,['type','kind'])),
      price:norm(pick(o,['price','cost'])),
      price_cents:norm(o.price_cents),
      currency:norm(o.currency),
      version:norm(o.version),
      security_status:norm(pick(o,['security_status','securityStatus','security','ap_security_status','source_security'])),
      security_score:norm(o.ap_security_score),
      install_count:norm(pick(o,['install_count','installCount','installs','source_installs'])),
      download_count:norm(pick(o,['download_count','downloadCount','downloads','source_downloads'])),
      view_count:norm(pick(o,['view_count','viewCount','views'])),
      rating:norm(pick(o,['rating','averageRating','avgRating','source_rating'])),
      rating_count:norm(pick(o,['rating_count','ratingCount'])),
      author:norm(typeof author==='object'?pick(author,['name','username','handle','slug']):author)||norm(o.owner_display_name),
      source:norm(pick(o,['source','provider','origin'])),
      source_url:norm(o.source_url),
      source_installs:norm(o.source_installs),
      source_stars:norm(o.source_stars)
    };
  });
  return {query:params.get('q'),type:params.get('type')||null,limit:Number(params.get('limit')),offset:Number(params.get('offset')),count:items.length,items};
})()
  1. For additional pages, increase offset by limit, run the same extractor, concatenate items, and deduplicate by type plus slug.

Params

ParamWhat it doesExample value
queryRequired search text, 1–200 charactersbrowser automation
typeOptional server-side type filter; also applied client-sideagent
limitResults per page, 1–10025
offsetZero-based pagination offset0

Possible Friction Points

  • type=agent returns no records while the unfiltered response contains agents → retry the same URL without type and retain only records whose normalized type is agent.
  • An offset returns the same first-page records → deduplicate by type plus slug, then stop or try another offset only when more unique results are required.
  • API response uses a different top-level result container → run the recursive extractor; it searches all nested objects for slug/title records.
  • Nullable or blank security, rating, author, or source fields occur → preserve them as explicit null values through norm.
  • API rejects an empty or overlong query → URL-encode the query and keep it between 1 and 200 characters.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=agentpowers.ai&task=search-agentpowers-skills