Skip to content
Skylark Skills
Submit a skill

API

Every read endpoint is public, unauthenticated, and CORS-open. No key, no rate-limit tier, no sign-up.

https://skills.skylarkbrowser.com/api/v1

Start here if you are building an agent

Two calls, in this order. The first is cheap and cached for a day; the second only happens on a hit.

# once a day
GET https://skills.skylarkbrowser.com/api/v1/hosts
→ { "version": "…", "count": 412, "hosts": ["acme.example", …] }

# only when the host you are on is in that set
GET https://skills.skylarkbrowser.com/api/v1/sites/acme.example
→ an Agent Skills Discovery 0.2.0 document

The per-origin document

Deliberately a valid Agent Skills Discovery 0.2.0 document, so an existing client parses it with no new code path. Everything specific to us rides in x-skylark, which the standard requires clients to ignore.

{
  "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
  "skills": [
    {
      "name": "cancel-subscription",
      "type": "skill-md",
      "description": "Cancels a recurring subscription on Acme Billing…",
      "url": "https://skills.skylarkbrowser.com/api/v1/skills/billing-acme-example/cancel-subscription/SKILL.md",
      "digest": "sha256:d13d4ad61efcb1fc37bedc9d675a62caa0ea5046757146e9157ef8ce3a31a974",
      "runtime": "browser",
      "permissions": ["page:read", "page:act", "navigate"],
      "scope": ["https://billing.acme.example/account/subscriptions/*"],
      "triggers": [{ "kind": "intent", "description": "cancel my subscription" }],

      "x-skylark": {
        "url": "https://skills.skylarkbrowser.com/billing-acme-example/cancel-subscription",
        "verification": "partner",
        "publisher": { "name": "Acme, Inc.", "slug": "acme" },
        "source": "origin",
        "updatedAt": "2026-07-28T00:00:00.000Z"
      }
    }
  ]
}

Verify what you download

Hash the bytes you get from the artifact URL and compare against the digest the index advertised. If they disagree, do not use the skill. This is not defensive paperwork — it is the only thing that makes a mirrored artifact as trustworthy as one you fetched from the origin yourself.

Endpoints

GET/hosts

Every host with at least one published browser skill, plus a version token.

Fetch this once a day and consult it locally. Only call the per-origin endpoint on a hit — otherwise a browser asks about every navigation, forever, and the answer is almost always no.

max-age=86400, stale-while-revalidate=604800

GET/sites/{host}

The per-origin index, as an Agent Skills Discovery 0.2.0 document.

Accepts a hostname or a site slug. A host with no skills returns an empty 200, never a 404 — a negative answer has to be cacheable too. Send If-None-Match to get a 304.

max-age=300, s-maxage=3600, stale-while-revalidate=86400

GET/skills

Search and filter.

Parameters: q, site, category, tag, permission, verification, knowledge_only, sort, limit, cursor. Pagination is cursor-based; pass the nextCursor you were given.

max-age=60, s-maxage=300

GET/skills/{site}/{skill}

One skill, with its body, scope, triggers, and version history.

max-age=60, s-maxage=300

GET/skills/{site}/{skill}/SKILL.md

The raw artifact as text/markdown.

The bytes hash to the digest the index advertises; the ETag is that digest. This is the URL the discovery index points at.

max-age=60, s-maxage=300

GET/sites

Paged site list with skill counts.

max-age=60

GET/categories

Categories with counts.

max-age=60

GET/publishers/{slug}

A publisher, their verification, and their skills.

max-age=60

GET/stats

Directory totals.

max-age=60

POST/submissions

Propose a skill. Requires a signed-in session.

Returns 202 — the review runs asynchronously.

no-store

Errors

{ "error": { "code": "not_found", "message": "Skill not found", "requestId": "…" } }

400 validation · 401 unauthenticated · 403 wrong identity · 404 unknown · 409 conflict · 429 rate limited. The requestId is echoed in the x-request-id header — quote it if you report a problem.